From 0557fc8e09f5c77b248da651a9969108b3c0ccab Mon Sep 17 00:00:00 2001 From: Kevin Andersen Date: Sun, 13 Jan 2019 21:10:20 +0100 Subject: [PATCH] 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. --- package-lock.json | 47 +++++++++++----- src/extensions/scratch3_boost/index.js | 74 +++++++++++--------------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index f91352f7c..2c477c800 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2177,7 +2177,7 @@ }, "bl": { "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==", "dev": true, "requires": { @@ -2193,7 +2193,7 @@ }, "readable-stream": { "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==", "dev": true, "requires": { @@ -4950,7 +4950,7 @@ "dependencies": { "commander": { "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=", "dev": true } @@ -7617,7 +7617,7 @@ }, "magic-string": { "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==", "dev": true, "requires": { @@ -11645,7 +11645,7 @@ "dependencies": { "minimist": { "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=", "dev": true } @@ -12112,9 +12112,9 @@ } }, "scratch-audio": { - "version": "0.1.0-prerelease.20181023202904", - "resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20181023202904.tgz", - "integrity": "sha512-0cf+snpT04RFWFgMsMzbztzNVyh2PkUaT8mjlwNNoIRy5p7yDN3EMC2zGbR71nZMus1tO2EDxqrpan2ix4IWDw==", + "version": "0.1.0-prerelease.20190108181031", + "resolved": "https://registry.npmjs.org/scratch-audio/-/scratch-audio-0.1.0-prerelease.20190108181031.tgz", + "integrity": "sha512-Ygu+pN2u9det8HTIo+2wj8ibqe0QjAA624N9GxC62nrdGH39NxDRJyiwheeuZH/oEjM9RTsCSSOH+C9fXA9ekA==", "dev": true, "requires": { "audio-context": "1.0.1", @@ -12168,9 +12168,9 @@ } }, "scratch-render": { - "version": "0.1.0-prerelease.20190103190631", - "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20190103190631.tgz", - "integrity": "sha512-DFh5dnvLQ0iv2UahMJgUrCqnMOPjM4NAN0fQUBtm4w5gskkFOem6QvTGPWcUf75II4MDwUbj+LGZclqEYWTnSw==", + "version": "0.1.0-prerelease.20190109203013", + "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20190109203013.tgz", + "integrity": "sha512-yrkBuF1zLHrXEHQmbQhpATDxot/wqoN/oDW2aIjzV9ylxCy+zNdGI2XJ9tRy10bCcM5bdC879ROX9fCr+n6FwQ==", "dev": true, "requires": { "grapheme-breaker": "0.3.2", @@ -12180,8 +12180,29 @@ "minilog": "3.1.0", "raw-loader": "^0.5.1", "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" + }, + "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": { @@ -12992,7 +13013,7 @@ }, "readable-stream": { "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==", "dev": true, "requires": { diff --git a/src/extensions/scratch3_boost/index.js b/src/extensions/scratch3_boost/index.js index 970ba653f..8f737ebd9 100644 --- a/src/extensions/scratch3_boost/index.js +++ b/src/extensions/scratch3_boost/index.js @@ -337,6 +337,7 @@ class BoostMotor { const cmd = this._parent.generateOutputCommand( this._index, 0x51, + 0x00, [this._power * this._direction] // power in range 0-100 ); @@ -368,6 +369,7 @@ class BoostMotor { const cmd = this._parent.generateOutputCommand( this._index, BoostCommand.MOTOR_POWER, + 0x00, [127] // 127 = break ); @@ -387,6 +389,7 @@ class BoostMotor { const cmd = this._parent.generateOutputCommand( this._index, BoostCommand.MOTOR_POWER, + 0x00, [0] // 0 = stop ); @@ -451,14 +454,14 @@ class Boost { 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[]} * @private */ this._ports = []; /** - * The motors which this Boost could possibly have. + * A list of motors registered by the Boost hardware. * @type {BoostMotor[]} * @private */ @@ -562,7 +565,8 @@ class Boost { const cmd = this.generateOutputCommand( 50, 0x51, - [0x51,0x01].concat(rgb) + BoostMode.LED, + rgb ); return this.send(BLECharacteristic, cmd); @@ -592,6 +596,7 @@ class Boost { const cmd = this.generateOutputCommand( BoostConnectID.LED, 0x32, + BoostMode.LED, [0, 0, 0] ); @@ -694,23 +699,21 @@ class Boost { * @param {array} values - the list of values to write to the 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]; if (values) { command = command.concat( connectID ).concat( - 0x00 // Execute immediately + 0x00 // Execute immediately ); if(subCommandID) { command = command.concat(subCommandID); } - command = command.concat(0x00) + command = command.concat(mode) - command = command/*.concat( - values.length - )*/.concat( + command = command.concat( values ); } @@ -774,8 +777,6 @@ class Boost { */ _onMessage (base64) { const data = Base64Util.base64ToUint8Array(base64); - //console.log(data) - // log.info(data); /** * First three bytes are the common header: @@ -797,9 +798,7 @@ class Boost { switch (data[4]) { case BoostIOEvent.ATTACHED: //case BoostIOEvent.ATTACHED_VIRTUAL: - //console.log("New sensor or motor registered!") this._registerSensorOrMotor(data[3], data[5]) - //console.log(data[3] + "," + data[5]) break; case BoostIOEvent.DETACHED: this._clearPort(data[3]); @@ -811,37 +810,23 @@ class Boost { case BoostMessageTypes.PORT_VALUE: var type = this._ports[data[3]]; var valueFormat = data.length - switch(valueFormat) { - // 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 - } + // TODO: Build a proper value-formatting based on the PORT_INPUT_FORMAT-messages instead of hardcoding value-handling switch(type) { case BoostDevice.TILT: - this._sensors.tiltX = value[0] - this._sensors.tiltY = value[1] + this._sensors.tiltX = data[4] + this._sensors.tiltY = data[5] break; case BoostDevice.COLOR: - this._sensors.color = value; + this._sensors.color = data[4]; break; case BoostDevice.MOTOREXT: - // ToDo: Handle external motor sensor - break; 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 break; case BoostDevice.CURRENT: @@ -852,12 +837,12 @@ class Boost { console.log("Unknown sensor value! Type: " + type) } break; + case BoostMessageTypes.PORT_INPUT_FORMAT: case BoostMessageTypes.ERROR: - console.log("Error in BLE message! Errorneous command: " + data[3]) + console.log(buf2hex(data)) break; default: - //console.log("No case found for message:") - //console.log(data) + console.log(buf2hex(data)) } } @@ -1660,14 +1645,15 @@ class Scratch3BoostBlocks { */ getMotorPosition (args) { switch(args.MOTOR_ID) { + // TODO: Handle negative rotation. case BoostMotorLabel.A: - return this._peripheral._motors[BoostPort.A].position + return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.A].position, 0, 360); case BoostMotorLabel.B: - return this._peripheral._motors[BoostPort.B].position + return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.B].position, 0, 360); case BoostMotorLabel.C: - return this._peripheral._motors[BoostPort.C].position + return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.C].position, 0, 360); case BoostMotorLabel.D: - return this._peripheral._motors[BoostPort.D].position + return MathUtil.wrapClamp(this._peripheral._motors[BoostPort.D].position, 0, 360); default: log.warn("Asked for a motor position that doesnt exist!") return false;