mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
Merge pull request #1630 from evhan55/fixes/hardware-extensions
Hardware extensions: fixes and menu localization
This commit is contained in:
commit
2ade71590f
5 changed files with 177 additions and 47 deletions
|
@ -266,6 +266,8 @@ class EV3Motor {
|
|||
* @param {number} milliseconds - run the motor for this long.
|
||||
*/
|
||||
turnOnFor (milliseconds) {
|
||||
if (this._power === 0) return;
|
||||
|
||||
const port = this._portMask(this._index);
|
||||
let n = milliseconds;
|
||||
let speed = this._power * this._direction;
|
||||
|
@ -323,6 +325,8 @@ class EV3Motor {
|
|||
* @param {number} time - the time in milliseconds.
|
||||
*/
|
||||
coastAfter (time) {
|
||||
if (this._power === 0) return;
|
||||
|
||||
// Set the motor command id to check before starting coast
|
||||
const commandId = uid();
|
||||
this._commandID = commandId;
|
||||
|
@ -341,6 +345,8 @@ class EV3Motor {
|
|||
* Set the motor to coast.
|
||||
*/
|
||||
coast () {
|
||||
if (this._power === 0) return;
|
||||
|
||||
const cmd = this._parent.generateCommand(
|
||||
Ev3Command.DIRECT_COMMAND_NO_REPLY,
|
||||
[
|
||||
|
|
|
@ -328,7 +328,7 @@ class MicroBit {
|
|||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
const TiltDirection = {
|
||||
const MicroBitTiltDirection = {
|
||||
FRONT: 'front',
|
||||
BACK: 'back',
|
||||
LEFT: 'left',
|
||||
|
@ -341,7 +341,7 @@ const TiltDirection = {
|
|||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
const Gestures = {
|
||||
const MicroBitGestures = {
|
||||
MOVED: 'moved',
|
||||
SHAKEN: 'shaken',
|
||||
JUMPED: 'jumped'
|
||||
|
@ -352,7 +352,7 @@ const Gestures = {
|
|||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
const Buttons = {
|
||||
const MicroBitButtons = {
|
||||
A: 'A',
|
||||
B: 'B',
|
||||
ANY: 'any'
|
||||
|
@ -363,7 +363,7 @@ const Buttons = {
|
|||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
const PinState = {
|
||||
const MicroBitPinState = {
|
||||
ON: 'on',
|
||||
OFF: 'off'
|
||||
};
|
||||
|
@ -401,11 +401,11 @@ class Scratch3MicroBitBlocks {
|
|||
return [
|
||||
{
|
||||
text: 'A',
|
||||
value: Buttons.A
|
||||
value: MicroBitButtons.A
|
||||
},
|
||||
{
|
||||
text: 'B',
|
||||
value: Buttons.B
|
||||
value: MicroBitButtons.B
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -413,7 +413,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'any',
|
||||
description: 'label for "any" element in button picker for micro:bit extension'
|
||||
}),
|
||||
value: Buttons.ANY
|
||||
value: MicroBitButtons.ANY
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'moved',
|
||||
description: 'label for moved gesture in gesture picker for micro:bit extension'
|
||||
}),
|
||||
value: Gestures.MOVED
|
||||
value: MicroBitGestures.MOVED
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -437,7 +437,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'shaken',
|
||||
description: 'label for shaken gesture in gesture picker for micro:bit extension'
|
||||
}),
|
||||
value: Gestures.SHAKEN
|
||||
value: MicroBitGestures.SHAKEN
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -445,7 +445,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'jumped',
|
||||
description: 'label for jumped gesture in gesture picker for micro:bit extension'
|
||||
}),
|
||||
value: Gestures.JUMPED
|
||||
value: MicroBitGestures.JUMPED
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'on',
|
||||
description: 'label for on element in pin state picker for micro:bit extension'
|
||||
}),
|
||||
value: PinState.ON
|
||||
value: MicroBitPinState.ON
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -469,7 +469,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'off',
|
||||
description: 'label for off element in pin state picker for micro:bit extension'
|
||||
}),
|
||||
value: PinState.OFF
|
||||
value: MicroBitPinState.OFF
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'front',
|
||||
description: 'label for front element in tilt direction picker for micro:bit extension'
|
||||
}),
|
||||
value: TiltDirection.FRONT
|
||||
value: MicroBitTiltDirection.FRONT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -493,7 +493,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'back',
|
||||
description: 'label for back element in tilt direction picker for micro:bit extension'
|
||||
}),
|
||||
value: TiltDirection.BACK
|
||||
value: MicroBitTiltDirection.BACK
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -501,7 +501,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'left',
|
||||
description: 'label for left element in tilt direction picker for micro:bit extension'
|
||||
}),
|
||||
value: TiltDirection.LEFT
|
||||
value: MicroBitTiltDirection.LEFT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
|
@ -509,7 +509,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'right',
|
||||
description: 'label for right element in tilt direction picker for micro:bit extension'
|
||||
}),
|
||||
value: TiltDirection.RIGHT
|
||||
value: MicroBitTiltDirection.RIGHT
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ class Scratch3MicroBitBlocks {
|
|||
default: 'any',
|
||||
description: 'label for any direction element in tilt direction picker for micro:bit extension'
|
||||
}),
|
||||
value: TiltDirection.ANY
|
||||
value: MicroBitTiltDirection.ANY
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ class Scratch3MicroBitBlocks {
|
|||
BTN: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'buttons',
|
||||
defaultValue: Buttons.A
|
||||
defaultValue: MicroBitButtons.A
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -584,7 +584,7 @@ class Scratch3MicroBitBlocks {
|
|||
BTN: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'buttons',
|
||||
defaultValue: Buttons.A
|
||||
defaultValue: MicroBitButtons.A
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -601,7 +601,7 @@ class Scratch3MicroBitBlocks {
|
|||
GESTURE: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'gestures',
|
||||
defaultValue: Gestures.MOVED
|
||||
defaultValue: MicroBitGestures.MOVED
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -667,7 +667,7 @@ class Scratch3MicroBitBlocks {
|
|||
DIRECTION: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'tiltDirectionAny',
|
||||
defaultValue: TiltDirection.ANY
|
||||
defaultValue: MicroBitTiltDirection.ANY
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -683,7 +683,7 @@ class Scratch3MicroBitBlocks {
|
|||
DIRECTION: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'tiltDirectionAny',
|
||||
defaultValue: TiltDirection.ANY
|
||||
defaultValue: MicroBitTiltDirection.ANY
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -699,7 +699,7 @@ class Scratch3MicroBitBlocks {
|
|||
DIRECTION: {
|
||||
type: ArgumentType.STRING,
|
||||
menu: 'tiltDirection',
|
||||
defaultValue: TiltDirection.FRONT
|
||||
defaultValue: MicroBitTiltDirection.FRONT
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -887,7 +887,7 @@ class Scratch3MicroBitBlocks {
|
|||
*/
|
||||
_isTilted (direction) {
|
||||
switch (direction) {
|
||||
case TiltDirection.ANY:
|
||||
case MicroBitTiltDirection.ANY:
|
||||
return (Math.abs(this._peripheral.tiltX / 10) >= Scratch3MicroBitBlocks.TILT_THRESHOLD) ||
|
||||
(Math.abs(this._peripheral.tiltY / 10) >= Scratch3MicroBitBlocks.TILT_THRESHOLD);
|
||||
default:
|
||||
|
@ -903,13 +903,13 @@ class Scratch3MicroBitBlocks {
|
|||
*/
|
||||
_getTiltAngle (direction) {
|
||||
switch (direction) {
|
||||
case TiltDirection.FRONT:
|
||||
case MicroBitTiltDirection.FRONT:
|
||||
return Math.round(this._peripheral.tiltY / -10);
|
||||
case TiltDirection.BACK:
|
||||
case MicroBitTiltDirection.BACK:
|
||||
return Math.round(this._peripheral.tiltY / 10);
|
||||
case TiltDirection.LEFT:
|
||||
case MicroBitTiltDirection.LEFT:
|
||||
return Math.round(this._peripheral.tiltX / -10);
|
||||
case TiltDirection.RIGHT:
|
||||
case MicroBitTiltDirection.RIGHT:
|
||||
return Math.round(this._peripheral.tiltX / 10);
|
||||
default:
|
||||
log.warn(`Unknown tilt direction in _getTiltAngle: ${direction}`);
|
||||
|
|
|
@ -226,7 +226,15 @@ class WeDo2Motor {
|
|||
* @param {int} value - this motor's new power level, in the range [0,100].
|
||||
*/
|
||||
set power (value) {
|
||||
this._power = Math.max(0, Math.min(value, 100));
|
||||
const p = Math.max(0, Math.min(value, 100));
|
||||
// Lego Wedo 2.0 hub only turns motors at power range [30 - 100], so
|
||||
// map value from [0 - 100] to [30 - 100].
|
||||
if (p === 0) {
|
||||
this._power = 0;
|
||||
} else {
|
||||
const delta = 100 / p;
|
||||
this._power = 30 + (70 / delta);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,6 +262,8 @@ class WeDo2Motor {
|
|||
* Turn this motor on indefinitely.
|
||||
*/
|
||||
turnOn () {
|
||||
if (this._power === 0) return;
|
||||
|
||||
const cmd = this._parent.generateOutputCommand(
|
||||
this._index + 1,
|
||||
WeDo2Command.MOTOR_POWER,
|
||||
|
@ -271,6 +281,8 @@ class WeDo2Motor {
|
|||
* @param {number} milliseconds - run the motor for this long.
|
||||
*/
|
||||
turnOnFor (milliseconds) {
|
||||
if (this._power === 0) return;
|
||||
|
||||
milliseconds = Math.max(0, milliseconds);
|
||||
this.turnOn();
|
||||
this._setNewTimeout(this.startBraking, milliseconds);
|
||||
|
@ -281,6 +293,8 @@ class WeDo2Motor {
|
|||
* // TODO: rename this to coastAfter?
|
||||
*/
|
||||
startBraking () {
|
||||
if (this._power === 0) return;
|
||||
|
||||
const cmd = this._parent.generateOutputCommand(
|
||||
this._index + 1,
|
||||
WeDo2Command.MOTOR_POWER,
|
||||
|
@ -298,6 +312,8 @@ class WeDo2Motor {
|
|||
* @param {boolean} [useLimiter=true] - if true, use the rate limiter
|
||||
*/
|
||||
turnOff (useLimiter = true) {
|
||||
if (this._power === 0) return;
|
||||
|
||||
const cmd = this._parent.generateOutputCommand(
|
||||
this._index + 1,
|
||||
WeDo2Command.MOTOR_POWER,
|
||||
|
@ -1077,28 +1093,136 @@ class Scratch3WeDo2Blocks {
|
|||
],
|
||||
menus: {
|
||||
MOTOR_ID: [
|
||||
WeDo2MotorLabel.DEFAULT,
|
||||
WeDo2MotorLabel.A,
|
||||
WeDo2MotorLabel.B,
|
||||
WeDo2MotorLabel.ALL
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorId.default',
|
||||
default: 'motor',
|
||||
description: 'label for motor element in motor menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorLabel.DEFAULT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorId.a',
|
||||
default: 'motor A',
|
||||
description: 'label for motor A element in motor menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorLabel.A
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorId.b',
|
||||
default: 'motor B',
|
||||
description: 'label for motor B element in motor menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorLabel.B
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorId.all',
|
||||
default: 'all motors',
|
||||
description: 'label for all motors element in motor menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorLabel.ALL
|
||||
}
|
||||
],
|
||||
MOTOR_DIRECTION: [
|
||||
WeDo2MotorDirection.FORWARD,
|
||||
WeDo2MotorDirection.BACKWARD,
|
||||
WeDo2MotorDirection.REVERSE
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorDirection.forward',
|
||||
default: 'this way',
|
||||
description: 'label for forward element in motor direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorDirection.FORWARD
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorDirection.backward',
|
||||
default: 'that way',
|
||||
description: 'label for backward element in motor direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorDirection.BACKWARD
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.motorDirection.reverse',
|
||||
default: 'reverse',
|
||||
description: 'label for reverse element in motor direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2MotorDirection.REVERSE
|
||||
}
|
||||
],
|
||||
TILT_DIRECTION: [
|
||||
WeDo2TiltDirection.UP,
|
||||
WeDo2TiltDirection.DOWN,
|
||||
WeDo2TiltDirection.LEFT,
|
||||
WeDo2TiltDirection.RIGHT
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.up',
|
||||
default: 'up',
|
||||
description: 'label for up element in tilt direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2TiltDirection.UP
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.down',
|
||||
default: 'down',
|
||||
description: 'label for down element in tilt direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2TiltDirection.DOWN
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.left',
|
||||
default: 'left',
|
||||
description: 'label for left element in tilt direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2TiltDirection.LEFT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.right',
|
||||
default: 'right',
|
||||
description: 'label for right element in tilt direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2TiltDirection.RIGHT
|
||||
}
|
||||
],
|
||||
TILT_DIRECTION_ANY: [
|
||||
WeDo2TiltDirection.UP,
|
||||
WeDo2TiltDirection.DOWN,
|
||||
WeDo2TiltDirection.LEFT,
|
||||
WeDo2TiltDirection.RIGHT,
|
||||
WeDo2TiltDirection.ANY
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.up',
|
||||
default: 'up'
|
||||
}),
|
||||
value: WeDo2TiltDirection.UP
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.down',
|
||||
default: 'down'
|
||||
}),
|
||||
value: WeDo2TiltDirection.DOWN
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.left',
|
||||
default: 'left'
|
||||
}),
|
||||
value: WeDo2TiltDirection.LEFT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.right',
|
||||
default: 'right'
|
||||
}),
|
||||
value: WeDo2TiltDirection.RIGHT
|
||||
},
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'wedo2.tiltDirection.any',
|
||||
default: 'any',
|
||||
description: 'label for any element in tilt direction menu for LEGO WeDo 2 extension'
|
||||
}),
|
||||
value: WeDo2TiltDirection.ANY
|
||||
}
|
||||
],
|
||||
OP: ['<', '>']
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ class BLE extends JSONRPCWebSocket {
|
|||
}
|
||||
|
||||
_sendError (/* e */) {
|
||||
this.disconnect();
|
||||
if (this._connected) this.disconnect();
|
||||
// log.error(`BLE error: ${JSON.stringify(e)}`);
|
||||
this._runtime.emit(this._runtime.constructor.PERIPHERAL_ERROR, {
|
||||
message: `Scratch lost connection to`,
|
||||
|
|
|
@ -115,7 +115,7 @@ class BT extends JSONRPCWebSocket {
|
|||
}
|
||||
|
||||
_sendError (/* e */) {
|
||||
this.disconnect();
|
||||
if (this._connected) this.disconnect();
|
||||
// log.error(`BT error: ${JSON.stringify(e)}`);
|
||||
this._runtime.emit(this._runtime.constructor.PERIPHERAL_ERROR, {
|
||||
message: `Scratch lost connection to`,
|
||||
|
|
Loading…
Reference in a new issue