- Refactoring of output commands:

- Simplified generateOutputCommand() to follow the LEGO Wireless Protocol command-structure. Every output-command must have a portID, execution information, sub-command, and then followed by a custom payload which must be defined according to the protocol documentation mentioned in the extension.
- Simple motor commands now use the above subcommand-structure rather than the former primitive command structure.
- stopLED()-function removed since it's not used
- Implemented check of pendingPromiseFunction() for motors before firing.
This commit is contained in:
Kevin Andersen 2019-02-22 12:50:19 -05:00
parent 9767d72188
commit 40c022ca8e

View file

@ -328,7 +328,7 @@ class BoostMotor {
* @type {Object} * @type {Object}
* @private * @private
*/ */
this._pendingPromiseFunction = true; this._pendingPromiseFunction = null;
this.startBraking = this.startBraking.bind(this); this.startBraking = this.startBraking.bind(this);
this.turnOff = this.turnOff.bind(this); this.turnOff = this.turnOff.bind(this);
@ -447,10 +447,11 @@ 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,
BoostOutputSubCommand.WRITE_DIRECT_MODE_DATA, BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK,
BoostMode.MOTOR_OUTPUT, BoostOutputSubCommand.START_SPEED,
[this._power * this._direction] // power in range 0-100 [this._power * this._direction,
); this._power * this._direction,
BoostMotorProfile.DO_NOT_USE]);
this._parent.send(BLECharacteristic, cmd); this._parent.send(BLECharacteristic, cmd);
@ -480,13 +481,13 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK,
BoostOutputSubCommand.START_SPEED_FOR_DEGREES, BoostOutputSubCommand.START_SPEED_FOR_DEGREES,
null, [...numberToInt32Array(degrees),
numberToInt32Array(degrees).concat( this._power * this._direction, // power in range 0-100
[this._power * this._direction, // power in range 0-100
0xFF, // max speed 0xFF, // max speed
BoostMotorEndState.FLOAT, BoostMotorEndState.FLOAT,
BoostMotorProfile.DO_NOT_USE]) // byte for using acceleration/braking profile BoostMotorProfile.DO_NOT_USE] // byte for using acceleration/braking profile
); );
this._status = BoostOutputCommandFeedback.BUFFER_EMPTY_COMMAND_IN_PROGRESS; this._status = BoostOutputCommandFeedback.BUFFER_EMPTY_COMMAND_IN_PROGRESS;
@ -503,9 +504,11 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostMessage.MOTOR_POWER, BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK,
BoostMode.MOTOR_OUTPUT, BoostOutputSubCommand.START_SPEED,
[BoostMotorEndState.BRAKE] [BoostMotorEndState.FLOAT,
BoostMotorEndState.FLOAT,
BoostMotorProfile.DO_NOT_USE]
); );
this._parent.send(BLECharacteristic, cmd); this._parent.send(BLECharacteristic, cmd);
@ -523,9 +526,11 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostMessage.MOTOR_POWER, BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK,
BoostMode.MOTOR_OUTPUT, BoostOutputSubCommand.START_SPEED,
[BoostMotorEndState.FLOAT] [BoostMotorEndState.FLOAT,
BoostMotorEndState.FLOAT,
BoostMotorProfile.DO_NOT_USE]
); );
this._parent.send(BLECharacteristic, cmd, useLimiter); this._parent.send(BLECharacteristic, cmd, useLimiter);
@ -706,9 +711,10 @@ class Boost {
const cmd = this.generateOutputCommand( const cmd = this.generateOutputCommand(
this._ports.indexOf(BoostIO.LED), this._ports.indexOf(BoostIO.LED),
BoostOutputExecution.EXECUTE_IMMEDIATELY ^ BoostOutputExecution.COMMAND_FEEDBACK,
BoostOutputSubCommand.WRITE_DIRECT_MODE_DATA, BoostOutputSubCommand.WRITE_DIRECT_MODE_DATA,
BoostMode.LED, [BoostMode.LED,
rgb ...rgb]
); );
return this.send(BLECharacteristic, cmd); return this.send(BLECharacteristic, cmd);
@ -729,21 +735,6 @@ class Boost {
return this.send(BLECharacteristic, cmd); return this.send(BLECharacteristic, cmd);
} }
/**
* Switch off the LED on the Boost.
* @return {Promise} - a promise of the completion of the stop led send operation.
*/
stopLED () {
const cmd = this.generateOutputCommand(
this._ports.indexOf(BoostIO.LED),
BoostOutputSubCommand.WRITE_DIRECT_MODE_DATA,
BoostUnit.LED,
[0, 0, 0]
);
return this.send(BLECharacteristic, cmd);
}
/** /**
* Stop the motors on the Boost peripheral. * Stop the motors on the Boost peripheral.
*/ */
@ -837,34 +828,19 @@ class Boost {
/** /**
* Generate a Boost 'Output Command' in the byte array format * Generate a Boost 'Output Command' in the byte array format
* (CONNECT ID, COMMAND ID, NUMBER OF BYTES, VALUES ...). * (COMMON HEADER, PORT ID, EXECUTION BYTE, SUBCOMMAND ID, PAYLOAD).
* *
* This sends a command to the Boost to actuate the specified outputs. * Payload is accepted as an array since these vary across different subcommands.
* *
* @param {number} portID - the port (Connect ID) to send a command to. * @param {number} portID - the port (Connect ID) to send a command to.
* @param {number} subCommandID - the id of the byte command. * @param {number} execution - Byte containing startup/completion information
* @param {number} mode - the mode * @param {number} subCommandID - the id of the subcommand byte.
* @param {array} values - the list of values to write to the command. * @param {array} payload - the list of bytes to send as subcommand payload
* @return {array} - a generated output command. * @return {array} - a generated output command.
*/ */
generateOutputCommand (portID, subCommandID = BoostOutputSubCommand.WRITE_DIRECT_MODE_DATA, mode=null, values = null) { generateOutputCommand (portID, execution, subCommand, payload) {
let command = [0x00 /* Hub ID (always 0 for now) */, BoostMessage.OUTPUT]; let hubID = 0x00
if (values) { let command = [hubID, BoostMessage.OUTPUT, portID, execution, subCommand, ...payload]
command = command.concat(portID).concat(
BoostOutputExecution.EXECUTE_IMMEDIATELY ^
BoostOutputExecution.COMMAND_FEEDBACK
);
if(subCommandID) {
command = command.concat(subCommandID);
}
if(mode !== null) {
command = command.concat(mode)
}
command = command.concat(
values
);
}
command.unshift(command.length +1) command.unshift(command.length +1)
return command; return command;
} }
@ -988,10 +964,12 @@ class Boost {
switch(feedback) { switch(feedback) {
case BoostOutputCommandFeedback.BUFFER_EMPTY_COMMAND_COMPLETED ^ BoostOutputCommandFeedback.IDLE: case BoostOutputCommandFeedback.BUFFER_EMPTY_COMMAND_COMPLETED ^ BoostOutputCommandFeedback.IDLE:
case BoostOutputCommandFeedback.CURRENT_COMMAND_DISCARDED ^ BoostOutputCommandFeedback.IDLE: // Resolve even if command didn't complete successfully case BoostOutputCommandFeedback.CURRENT_COMMAND_DISCARDED ^ BoostOutputCommandFeedback.IDLE: // Resolve even if command didn't complete successfully
if(this._motors[portID]) { if(this._motors[portID] && this._motors[portID].pendingPromiseFunction) {
this._motors[portID].pendingPromiseFunction(); this._motors[portID].pendingPromiseFunction();
break;
} }
break;
case BoostOutputCommandFeedback.BUFFER_EMPTY_COMMAND_IN_PROGRESS:
break;
default: default:
console.log(buf2hex(data)) console.log(buf2hex(data))
console.log("Got it but didn't find a motor on: " + portID) console.log("Got it but didn't find a motor on: " + portID)