Motor position reporter kinda working. LED commands working. Added mode information to generateOutputCommand-function. Removed value-format switch-case in favor of hard-coded value-interpretation, but put in a TODO that we perhaps should consider doing it in the future.

This commit is contained in:
Kevin Andersen 2019-01-13 21:10:20 +01:00
parent af800956fe
commit 0557fc8e09
2 changed files with 64 additions and 57 deletions

47
package-lock.json generated
View file

@ -2177,7 +2177,7 @@
}, },
"bl": { "bl": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2193,7 +2193,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "2.3.6", "version": "2.3.6",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -4950,7 +4950,7 @@
"dependencies": { "dependencies": {
"commander": { "commander": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
"dev": true "dev": true
} }
@ -7617,7 +7617,7 @@
}, },
"magic-string": { "magic-string": {
"version": "0.22.5", "version": "0.22.5",
"resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
"integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -11645,7 +11645,7 @@
"dependencies": { "dependencies": {
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true "dev": true
} }
@ -12112,9 +12112,9 @@
} }
}, },
"scratch-audio": { "scratch-audio": {
"version": "0.1.0-prerelease.20181023202904", "version": "0.1.0-prerelease.20190108181031",
"resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20181023202904.tgz", "resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20190108181031.tgz",
"integrity": "sha512-0cf+snpT04RFWFgMsMzbztzNVyh2PkUaT8mjlwNNoIRy5p7yDN3EMC2zGbR71nZMus1tO2EDxqrpan2ix4IWDw==", "integrity": "sha512-Ygu+pN2u9det8HTIo+2wj8ibqe0QjAA624N9GxC62nrdGH39NxDRJyiwheeuZH/oEjM9RTsCSSOH+C9fXA9ekA==",
"dev": true, "dev": true,
"requires": { "requires": {
"audio-context": "1.0.1", "audio-context": "1.0.1",
@ -12168,9 +12168,9 @@
} }
}, },
"scratch-render": { "scratch-render": {
"version": "0.1.0-prerelease.20190103190631", "version": "0.1.0-prerelease.20190109203013",
"resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20190103190631.tgz", "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20190109203013.tgz",
"integrity": "sha512-DFh5dnvLQ0iv2UahMJgUrCqnMOPjM4NAN0fQUBtm4w5gskkFOem6QvTGPWcUf75II4MDwUbj+LGZclqEYWTnSw==", "integrity": "sha512-yrkBuF1zLHrXEHQmbQhpATDxot/wqoN/oDW2aIjzV9ylxCy+zNdGI2XJ9tRy10bCcM5bdC879ROX9fCr+n6FwQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"grapheme-breaker": "0.3.2", "grapheme-breaker": "0.3.2",
@ -12180,8 +12180,29 @@
"minilog": "3.1.0", "minilog": "3.1.0",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"scratch-storage": "^1.0.0", "scratch-storage": "^1.0.0",
"scratch-svg-renderer": "0.2.0-prerelease.20181220183040", "scratch-svg-renderer": "0.2.0-prerelease.20190109201344",
"twgl.js": "4.4.0" "twgl.js": "4.4.0"
},
"dependencies": {
"base64-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
"integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
"dev": true
},
"scratch-svg-renderer": {
"version": "0.2.0-prerelease.20190109201344",
"resolved": "https://registry.npmjs.org/scratch-svg-renderer/-/scratch-svg-renderer-0.2.0-prerelease.20190109201344.tgz",
"integrity": "sha512-pRMvQrM5UA2wcqleaXVpFx0Pi6Q3GsRA5elJ0tJksdr6k8HYm5D6sW62VtEtMHjnkQDa+EFyqfHq9IEPnzFjeQ==",
"dev": true,
"requires": {
"base64-js": "1.2.1",
"base64-loader": "1.0.0",
"minilog": "3.1.0",
"scratch-render-fonts": "1.0.0-prerelease.20180906193204",
"transformation-matrix": "1.14.1"
}
}
} }
}, },
"scratch-render-fonts": { "scratch-render-fonts": {
@ -12992,7 +13013,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "2.3.6", "version": "2.3.6",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true, "dev": true,
"requires": { "requires": {

View file

@ -337,6 +337,7 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
0x51, 0x51,
0x00,
[this._power * this._direction] // power in range 0-100 [this._power * this._direction] // power in range 0-100
); );
@ -368,6 +369,7 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostCommand.MOTOR_POWER, BoostCommand.MOTOR_POWER,
0x00,
[127] // 127 = break [127] // 127 = break
); );
@ -387,6 +389,7 @@ class BoostMotor {
const cmd = this._parent.generateOutputCommand( const cmd = this._parent.generateOutputCommand(
this._index, this._index,
BoostCommand.MOTOR_POWER, BoostCommand.MOTOR_POWER,
0x00,
[0] // 0 = stop [0] // 0 = stop
); );
@ -451,14 +454,14 @@ class Boost {
this._extensionId = extensionId; this._extensionId = extensionId;
/** /**
* A list of the ids of the motors or sensors in ports A, B, C or D. * A list of the ids of the physical or virtual sensors.
* @type {string[]} * @type {string[]}
* @private * @private
*/ */
this._ports = []; this._ports = [];
/** /**
* The motors which this Boost could possibly have. * A list of motors registered by the Boost hardware.
* @type {BoostMotor[]} * @type {BoostMotor[]}
* @private * @private
*/ */
@ -562,7 +565,8 @@ class Boost {
const cmd = this.generateOutputCommand( const cmd = this.generateOutputCommand(
50, 50,
0x51, 0x51,
[0x51,0x01].concat(rgb) BoostMode.LED,
rgb
); );
return this.send(BLECharacteristic, cmd); return this.send(BLECharacteristic, cmd);
@ -592,6 +596,7 @@ class Boost {
const cmd = this.generateOutputCommand( const cmd = this.generateOutputCommand(
BoostConnectID.LED, BoostConnectID.LED,
0x32, 0x32,
BoostMode.LED,
[0, 0, 0] [0, 0, 0]
); );
@ -694,7 +699,7 @@ class Boost {
* @param {array} values - the list of values to write to the command. * @param {array} values - the list of values to write to the command.
* @return {array} - a generated output command. * @return {array} - a generated output command.
*/ */
generateOutputCommand (connectID, subCommandID = 0x51, values = null) { generateOutputCommand (connectID, subCommandID = 0x51, mode=0x00, values = null) {
let command = [0x00, BoostCommand.OUTPUT]; let command = [0x00, BoostCommand.OUTPUT];
if (values) { if (values) {
command = command.concat( command = command.concat(
@ -706,11 +711,9 @@ class Boost {
if(subCommandID) { if(subCommandID) {
command = command.concat(subCommandID); command = command.concat(subCommandID);
} }
command = command.concat(0x00) command = command.concat(mode)
command = command/*.concat( command = command.concat(
values.length
)*/.concat(
values values
); );
} }
@ -774,8 +777,6 @@ class Boost {
*/ */
_onMessage (base64) { _onMessage (base64) {
const data = Base64Util.base64ToUint8Array(base64); const data = Base64Util.base64ToUint8Array(base64);
//console.log(data)
// log.info(data);
/** /**
* First three bytes are the common header: * First three bytes are the common header:
@ -797,9 +798,7 @@ class Boost {
switch (data[4]) { switch (data[4]) {
case BoostIOEvent.ATTACHED: case BoostIOEvent.ATTACHED:
//case BoostIOEvent.ATTACHED_VIRTUAL: //case BoostIOEvent.ATTACHED_VIRTUAL:
//console.log("New sensor or motor registered!")
this._registerSensorOrMotor(data[3], data[5]) this._registerSensorOrMotor(data[3], data[5])
//console.log(data[3] + "," + data[5])
break; break;
case BoostIOEvent.DETACHED: case BoostIOEvent.DETACHED:
this._clearPort(data[3]); this._clearPort(data[3]);
@ -811,37 +810,23 @@ class Boost {
case BoostMessageTypes.PORT_VALUE: case BoostMessageTypes.PORT_VALUE:
var type = this._ports[data[3]]; var type = this._ports[data[3]];
var valueFormat = data.length var valueFormat = data.length
switch(valueFormat) { // TODO: Build a proper value-formatting based on the PORT_INPUT_FORMAT-messages instead of hardcoding value-handling
// TODO: we can't know whether a 2- or 4-byte value is multiple values or a uint16/32-value respectively. We need to utilize the value format information provided in https://lego.github.io/lego-ble-wireless-protocol-docs/index.html#value-format
case 5:
var value = data[4];
break;
case 6:
var value = [data[4], data[5]];
break;
case 8:
//console.log(Uint32Array(data.slice(4,8)))
//console.log(buf2hex(data))
var dv = new DataView(data.slice(4,8))
console.log(dv.getInt32);
//var value = new Uint32Array(data.slice(4,8))[0]
break;
default:
// Do nothing
}
switch(type) { switch(type) {
case BoostDevice.TILT: case BoostDevice.TILT:
this._sensors.tiltX = value[0] this._sensors.tiltX = data[4]
this._sensors.tiltY = value[1] this._sensors.tiltY = data[5]
break; break;
case BoostDevice.COLOR: case BoostDevice.COLOR:
this._sensors.color = value; this._sensors.color = data[4];
break; break;
case BoostDevice.MOTOREXT: case BoostDevice.MOTOREXT:
// ToDo: Handle external motor sensor
break;
case BoostDevice.MOTORINT: case BoostDevice.MOTORINT:
//console.log(data[3] + "," + valueFormat + ": " + value) // Taken from EV3 extension tacho motor calculation
let value = data[4] + (data[5] * 256) + (data[6] * 256 * 256) + (data[7] * 256 * 256 * 256);
if (value > 0x7fffffff) {
value = value - 0x100000000;
}
//console.log(value);
this._motors[data[3]]._position = value this._motors[data[3]]._position = value
break; break;
case BoostDevice.CURRENT: case BoostDevice.CURRENT:
@ -852,12 +837,12 @@ class Boost {
console.log("Unknown sensor value! Type: " + type) console.log("Unknown sensor value! Type: " + type)
} }
break; break;
case BoostMessageTypes.PORT_INPUT_FORMAT:
case BoostMessageTypes.ERROR: case BoostMessageTypes.ERROR:
console.log("Error in BLE message! Errorneous command: " + data[3]) console.log(buf2hex(data))
break; break;
default: default:
//console.log("No case found for message:") console.log(buf2hex(data))
//console.log(data)
} }
} }
@ -1660,14 +1645,15 @@ class Scratch3BoostBlocks {
*/ */
getMotorPosition (args) { getMotorPosition (args) {
switch(args.MOTOR_ID) { switch(args.MOTOR_ID) {
// TODO: Handle negative rotation.
case BoostMotorLabel.A: case BoostMotorLabel.A:
return this._peripheral._motors[BoostPort.A].position return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.A].position, 0, 360);
case BoostMotorLabel.B: case BoostMotorLabel.B:
return this._peripheral._motors[BoostPort.B].position return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.B].position, 0, 360);
case BoostMotorLabel.C: case BoostMotorLabel.C:
return this._peripheral._motors[BoostPort.C].position return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.C].position, 0, 360);
case BoostMotorLabel.D: case BoostMotorLabel.D:
return this._peripheral._motors[BoostPort.D].position return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.D].position, 0, 360);
default: default:
log.warn("Asked for a motor position that doesnt exist!") log.warn("Asked for a motor position that doesnt exist!")
return false; return false;