Partly resolves #2087, #2088.

This was happening because scratch-vm is responsible for timed motor commands rather than using the Boost hubs commands to run motors for a specific amount of time.
This meant that when we simply sent a motorOn-command, the hub would immediately return feedback for the motor that the command had completed.
The fix for this was, for timed motor commands, to not receive feedback from the motor, and instead have scratch-vm modify the BoostMotor._status.

TODO: Fix for rotation-based commands.

Agreed. Changed to 50%.

- BoostMotorMaxPower changed to BoostMotorMaxPowerAdd and now describes an extra boost (no pun intended) to the motor. Documentation added that describes the feature.
- _colorBucket renamed to _colorSamples for clarity.
- oldColor is renamed to previousColor, and is now initialized in this._sensors.
- Modified documentation.
This commit is contained in:
Kevin Andersen 2019-04-04 15:37:48 -04:00
parent d8f7b2c74f
commit e3cdbffa2a

View file

@ -33,10 +33,13 @@ const BoostBLE = {
}; };
/** /**
* Boost Motor Max Power. * Boost Motor Max Power Add. Defines how much more power than the target speed
* the motors may supply to reach the target speed faster.
* Lower number == softer, slower reached target speed.
* Higher number == harder, faster reached target speed.
* @constant {number} * @constant {number}
*/ */
const BoostMotorMaxPower = 100; const BoostMotorMaxPowerAdd = 10;
/** /**
* A time interval to wait (in milliseconds) in between battery check calls. * A time interval to wait (in milliseconds) in between battery check calls.
@ -280,7 +283,7 @@ class BoostMotor {
* @type {number} * @type {number}
* @private * @private
*/ */
this._power = 100; this._power = 50;
/** /**
* This motor's current relative position * This motor's current relative position
@ -440,13 +443,14 @@ class BoostMotor {
if (this._power === 0) return; if (this._power === 0) return;
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK, BoostOutputExecution.EXECUTE_IMMEDIATELY,
BoostOutputSubCommand.START_SPEED, BoostOutputSubCommand.START_SPEED,
[ [
this._power * this._direction, this._power * this._direction,
BoostMotorMaxPower, MathUtil.wrapClamp(this._power + BoostMotorMaxPowerAdd, 0, 100),
BoostMotorProfile.DO_NOT_USE BoostMotorProfile.DO_NOT_USE
]); ]);
this._status = BoostPortFeedback.BUSY_OR_FULL;
this._parent.send(BoostBLE.characteristic, cmd); this._parent.send(BoostBLE.characteristic, cmd);
@ -476,12 +480,12 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK, (BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK),
BoostOutputSubCommand.START_SPEED_FOR_DEGREES, BoostOutputSubCommand.START_SPEED_FOR_DEGREES,
[ [
...numberToInt32Array(degrees), ...numberToInt32Array(degrees),
this._power * this._direction * direction, this._power * this._direction * direction,
BoostMotorMaxPower, MathUtil.wrapClamp(this._power + BoostMotorMaxPowerAdd, 0, 100),
BoostMotorEndState.BRAKE, BoostMotorEndState.BRAKE,
BoostMotorProfile.DO_NOT_USE BoostMotorProfile.DO_NOT_USE
] ]
@ -590,7 +594,8 @@ class Boost {
this._sensors = { this._sensors = {
tiltX: 0, tiltX: 0,
tiltY: 0, tiltY: 0,
color: BoostColor.NONE color: BoostColor.NONE,
previousColor: BoostColor.NONE
}; };
/** /**
@ -598,7 +603,7 @@ class Boost {
* @type {Array} * @type {Array}
* @private * @private
*/ */
this._colorBucket = []; this._colorSamples = [];
/** /**
* The Bluetooth connection socket for reading/writing peripheral data. * The Bluetooth connection socket for reading/writing peripheral data.
@ -734,7 +739,7 @@ class Boost {
dataPrefix: [0x97, 0x03, 0x00, 0x40], dataPrefix: [0x97, 0x03, 0x00, 0x40],
mask: [0xFF, 0xFF, 0, 0xFF] mask: [0xFF, 0xFF, 0, 0xFF]
} }
} */ } commented out until feature is enabled in scratch-link */
}], }],
optionalServices: [] optionalServices: []
}, this._onConnect, this.disconnect); }, this._onConnect, this.disconnect);
@ -760,7 +765,7 @@ class Boost {
tiltX: 0, tiltX: 0,
tiltY: 0, tiltY: 0,
color: BoostColor.NONE, color: BoostColor.NONE,
oldColor: BoostColor.NONE previousColor: BoostColor.NONE
}; };
if (this._ble) { if (this._ble) {
@ -879,7 +884,7 @@ class Boost {
/** /**
* First three bytes are the common header: * First three bytes are the common header:
* 0: Length of message * 0: Length of message
* 1: Hub ID (always 0x00 at the moment) * 1: Hub ID (always 0x00 at the moment, unused)
* 2: Message Type * 2: Message Type
* 3: Port ID * 3: Port ID
* We base our switch-case on Message Type * We base our switch-case on Message Type
@ -914,11 +919,11 @@ class Boost {
this._sensors.tiltY = data[5]; this._sensors.tiltY = data[5];
break; break;
case BoostIO.COLOR: case BoostIO.COLOR:
this._colorBucket.unshift(data[4]); this._colorSamples.unshift(data[4]);
if (this._colorBucket.length > BoostColorSampleSize) { if (this._colorSamples.length > BoostColorSampleSize) {
this._colorBucket.pop(); this._colorSamples.pop();
if (this._colorBucket.every((v, i, arr) => v === arr[0])) { if (this._colorSamples.every((v, i, arr) => v === arr[0])) {
this._sensors.color = this._colorBucket[0]; this._sensors.color = this._colorSamples[0];
} else { } else {
this._sensors.color = BoostColor.NONE; this._sensors.color = BoostColor.NONE;
} }
@ -953,7 +958,6 @@ class Boost {
case BoostMessage.ERROR: case BoostMessage.ERROR:
log.warn(`Error reported by hub: ${data}`); log.warn(`Error reported by hub: ${data}`);
break; break;
default:
} }
} }
@ -1926,10 +1930,10 @@ class Scratch3BoostBlocks {
case BoostColorLabel.ANY: case BoostColorLabel.ANY:
if (Object.keys(BoostColor).find(key => BoostColor[key]) if (Object.keys(BoostColor).find(key => BoostColor[key])
.toLowerCase() !== this.getColor()) { .toLowerCase() !== this.getColor()) {
if (this.getColor() === this._peripheral.oldColor) { if (this.getColor() === this._peripheral._sensors.previousColor) {
return false; return false;
} }
this._peripheral.oldColor = this.getColor(); this._peripheral._sensors.previousColor = this.getColor();
return true; return true;
} }
break; break;