mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-24 23:12:24 -05:00
Clean up and all sensors working
This commit is contained in:
parent
d70fb96d01
commit
1471248657
1 changed files with 104 additions and 180 deletions
|
@ -1,11 +1,10 @@
|
||||||
const ArgumentType = require('../../extension-support/argument-type');
|
const ArgumentType = require('../../extension-support/argument-type');
|
||||||
const BlockType = require('../../extension-support/block-type');
|
const BlockType = require('../../extension-support/block-type');
|
||||||
// const log = require('../../util/log');
|
const log = require('../../util/log');
|
||||||
// const cast = require('../../util/cast');
|
// const cast = require('../../util/cast');
|
||||||
const formatMessage = require('format-message');
|
const formatMessage = require('format-message');
|
||||||
const BLE = require('../../io/ble');
|
const BLE = require('../../io/ble');
|
||||||
const Base64Util = require('../../util/base64-util');
|
const Base64Util = require('../../util/base64-util');
|
||||||
const GdxCommands = require('./gdx-commands');
|
|
||||||
//const ScratchLinkProxy = require('./scratch-link-proxy');
|
//const ScratchLinkProxy = require('./scratch-link-proxy');
|
||||||
const createDevice = require('@vernier/godirect/src/godirect').default.createDevice;
|
const createDevice = require('@vernier/godirect/src/godirect').default.createDevice;
|
||||||
|
|
||||||
|
@ -16,19 +15,6 @@ const createDevice = require('@vernier/godirect/src/godirect').default.createDev
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const blockIconURI = 'data:image/png;base64,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';
|
const blockIconURI = 'data:image/png;base64,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';
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum for GDX-FOR protocol.
|
|
||||||
* @readonly
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
const BLEUUID = {
|
|
||||||
service: 'd91714ef-28b9-4f91-ba16-f0d9a604f112',
|
|
||||||
txChar: 'f4bf14a6-c7d5-4b6d-8aa8-df1a7c83adcb',
|
|
||||||
rxChar: 'b41e6675-a329-40e0-aa01-44d2f444babe'
|
|
||||||
};
|
|
||||||
|
|
||||||
const BLETimeout = 4500;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage communication with a GDX-FOR peripheral over a Scratch Link client socket.
|
* Manage communication with a GDX-FOR peripheral over a Scratch Link client socket.
|
||||||
*/
|
*/
|
||||||
|
@ -76,29 +62,8 @@ class GdxFor {
|
||||||
angularVelocityX: 0,
|
angularVelocityX: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Interval ID for data reading timeout.
|
|
||||||
* @type {number}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this._timeoutID = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag that is true while we are busy sending data to the BLE socket.
|
|
||||||
* @type {boolean}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this._busy = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ID for a timeout which is used to clear the busy flag if it has been
|
|
||||||
* true for a long time.
|
|
||||||
*/
|
|
||||||
this._busyTimeoutID = null;
|
|
||||||
|
|
||||||
this.disconnect = this.disconnect.bind(this);
|
this.disconnect = this.disconnect.bind(this);
|
||||||
this._onConnect = this._onConnect.bind(this);
|
this._onConnect = this._onConnect.bind(this);
|
||||||
this._onMessage = this._onMessage.bind(this);
|
|
||||||
|
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
}
|
}
|
||||||
|
@ -110,36 +75,19 @@ class GdxFor {
|
||||||
scan () {
|
scan () {
|
||||||
if (this._ble) {
|
if (this._ble) {
|
||||||
this._ble.close();
|
this._ble.close();
|
||||||
// this._ble.disconnect(); //scratch-link
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Requesting Device");
|
|
||||||
navigator.bluetooth.requestDevice({
|
navigator.bluetooth.requestDevice({
|
||||||
filters: [{ namePrefix: 'GDX' }],
|
filters: [{ namePrefix: 'GDX' }],
|
||||||
optionalServices: ['d91714ef-28b9-4f91-ba16-f0d9a604f112']
|
optionalServices: ['d91714ef-28b9-4f91-ba16-f0d9a604f112']
|
||||||
}).then((bleWbtDevice) => {
|
}).then((bleWbtDevice) => {
|
||||||
console.log("Got device: ", bleWbtDevice);
|
|
||||||
return createDevice(bleWbtDevice, {open: false});
|
return createDevice(bleWbtDevice, {open: false});
|
||||||
}).then((device) => {
|
}).then((device) => {
|
||||||
console.log("Created BLE object: ", device);
|
|
||||||
this._ble = device;
|
this._ble = device;
|
||||||
this._ble.open(false); // should emit a "device-opened" event when opened
|
this._ble.open(false); // false prevents starting of measurements
|
||||||
this._ble.on('device-opened', this._onConnect);
|
this._ble.on('device-opened', this._onConnect);
|
||||||
this._ble.on('device-closed', this._onClose);
|
this._ble.on('device-closed', this._onClose);
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// scratch-link
|
|
||||||
// this._ble = new BLE(this._runtime, this._extensionId, {
|
|
||||||
// filters: [
|
|
||||||
// { namePrefix: 'GDX' }
|
|
||||||
// ],
|
|
||||||
// optionalServices: [
|
|
||||||
// BLEUUID.service
|
|
||||||
// ]
|
|
||||||
// }, this._onConnect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,13 +105,8 @@ class GdxFor {
|
||||||
* Disconnect from the micro:bit.
|
* Disconnect from the micro:bit.
|
||||||
*/
|
*/
|
||||||
disconnect () {
|
disconnect () {
|
||||||
// TODO: This funciton is called when you exist the connection popup.
|
|
||||||
// When using Web Bluetooth, we don't use the connection popup.
|
|
||||||
// When switching over from web bluetooth, make sure to figure out to handle
|
|
||||||
// this disconnection.
|
|
||||||
window.clearInterval(this._timeoutID);
|
|
||||||
if (this._ble) {
|
if (this._ble) {
|
||||||
//this._ble.disconnect();
|
this._ble.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,55 +117,22 @@ class GdxFor {
|
||||||
isConnected () {
|
isConnected () {
|
||||||
let connected = false;
|
let connected = false;
|
||||||
if (this._ble) {
|
if (this._ble) {
|
||||||
connected = this._connected; //this._ble.isConnected();
|
connected = this._connected;
|
||||||
}
|
}
|
||||||
console.log("Is connected: ", connected);
|
|
||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message to the peripheral BLE socket.
|
|
||||||
* @param {number} command - the BLE command hex.
|
|
||||||
* @param {Uint8Array} message - the message to write
|
|
||||||
*/
|
|
||||||
send (command, message) {
|
|
||||||
if (!this.isConnected()) return;
|
|
||||||
|
|
||||||
debugger;
|
|
||||||
|
|
||||||
const output = new Uint8Array(message.length + 1);
|
|
||||||
output[0] = command; // attach command to beginning of message
|
|
||||||
for (let i = 0; i < message.length; i++) {
|
|
||||||
output[i + 1] = message[i];
|
|
||||||
}
|
|
||||||
//const output = [0x58, 0x19, 0xfe, 0x3f, 0x1a, 0xa5, 0x4a, 0x06, 0x49, 0x07, 0x48, 0x08, 0x47, 0x09, 0x46, 0x0a, 0x45, 0x0b, 0x44, 0x0c, 0x43, 0x0d, 0x42, 0x0e, 0x41];
|
|
||||||
|
|
||||||
//const output = new Uint8Array([0x58, 0x19, 0xfe, 0x3f, 0x1a, 0xa5, 0x4a, 0x06, 0x49, 0x07, 0x48, 0x08, 0x47, 0x09, 0x46, 0x0a, 0x45, 0x0b, 0x44, 0x0c, 0x43, 0x0d, 0x42, 0x0e, 0x41]);
|
|
||||||
console.log(output);
|
|
||||||
|
|
||||||
const data = Base64Util.uint8ArrayToBase64(output);
|
|
||||||
console.log(data);
|
|
||||||
// WBn+PxqlSgZJB0gIRwlGCkULRAxDDUIOQQ==
|
|
||||||
|
|
||||||
this._ble.write(BLEUUID.service, BLEUUID.txChar, data, 'base64', true).then(
|
|
||||||
() => {
|
|
||||||
this._busy = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts reading data from peripheral after BLE has connected to it.
|
* Starts reading data from peripheral after BLE has connected to it.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_onConnect () {
|
_onConnect () {
|
||||||
console.log("CONNNECTED");
|
|
||||||
this._connected = true;
|
this._connected = true;
|
||||||
|
|
||||||
this._ble.sensors.forEach(sensor => {
|
this._ble.sensors.forEach(sensor => {
|
||||||
sensor.setEnabled(true);
|
sensor.setEnabled(true);
|
||||||
|
|
||||||
// do some calculations?
|
// do some calculations here?
|
||||||
sensor.on('value-changed', (sensor) => {
|
sensor.on('value-changed', (sensor) => {
|
||||||
|
|
||||||
// We don't need this list, essentially.
|
// We don't need this list, essentially.
|
||||||
|
@ -232,58 +142,52 @@ class GdxFor {
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
this._ble.start(); // Can set period here.
|
this._ble.start(); // Can set period here if needed.
|
||||||
//this.send(GdxCommands.INIT, '');
|
|
||||||
|
|
||||||
//this._ble.read(BLEUUID.service, BLEUUID.rxChar, true, this._onMessage);
|
|
||||||
|
|
||||||
//this._timeoutID = window.setInterval(this.disconnect, BLETimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getForce () {
|
getForce () {
|
||||||
return this._ble.getSensor(1).value;
|
return this._ble.getSensor(1).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAccelerationX () {
|
||||||
|
return this._ble.getSensor(2).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAccelerationY () {
|
||||||
|
return this._ble.getSensor(3).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAccelerationZ () {
|
||||||
|
return this._ble.getSensor(4).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAngularSpeedX () {
|
||||||
|
return this._ble.getSensor(5).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAngularSpeedY () {
|
||||||
|
return this._ble.getSensor(6).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAngularSpeedZ () {
|
||||||
|
return this._ble.getSensor(7).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_onClose () {
|
_onClose () {
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the sensor data from the incoming BLE characteristic.
|
|
||||||
* @param {object} base64 - the incoming BLE data.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_onMessage (base64) {
|
|
||||||
console.log("In _onMessage");
|
|
||||||
// parse data
|
|
||||||
const data = Base64Util.base64ToUint8Array(base64);
|
|
||||||
console.log("data: ", data);
|
|
||||||
|
|
||||||
// this._sensors.tiltX = data[1] | (data[0] << 8);
|
|
||||||
// if (this._sensors.tiltX > (1 << 15)) this._sensors.tiltX -= (1 << 16);
|
|
||||||
// this._sensors.tiltY = data[3] | (data[2] << 8);
|
|
||||||
// if (this._sensors.tiltY > (1 << 15)) this._sensors.tiltY -= (1 << 16);
|
|
||||||
|
|
||||||
// this._sensors.buttonA = data[4];
|
|
||||||
// this._sensors.buttonB = data[5];
|
|
||||||
|
|
||||||
// this._sensors.touchPins[0] = data[6];
|
|
||||||
// this._sensors.touchPins[1] = data[7];
|
|
||||||
// this._sensors.touchPins[2] = data[8];
|
|
||||||
|
|
||||||
// this._sensors.gestureState = data[9];
|
|
||||||
|
|
||||||
// // cancel disconnect timeout and start a new one
|
|
||||||
// window.clearInterval(this._timeoutID);
|
|
||||||
// this._timeoutID = window.setInterval(this.disconnect, BLETimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
const CompareOptionsMenu = ['>', '<', '='];
|
* Enum for comparison operations.
|
||||||
|
* @readonly
|
||||||
const DirectionOptionsMenu = ['x', 'y', 'z'];
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
const ComparisonOptions = {
|
||||||
|
LESS_THAN: 'less_than',
|
||||||
|
GREATER_THAN: 'greater_than'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -305,6 +209,37 @@ class Scratch3GdxForBlocks {
|
||||||
return 'gdxfor';
|
return 'gdxfor';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get DIRECTIONS_MENU () {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
text: 'x',
|
||||||
|
value: 'x'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'y',
|
||||||
|
value: 'y'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'z',
|
||||||
|
value: 'z'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get COMPARE_MENU () {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
text: '<',
|
||||||
|
value: ComparisonOptions.LESS_THAN
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '>',
|
||||||
|
value: ComparisonOptions.GREATER_THAN
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a set of GDX-FOR blocks.
|
* Construct a set of GDX-FOR blocks.
|
||||||
* @param {Runtime} runtime - the Scratch 3.0 runtime.
|
* @param {Runtime} runtime - the Scratch 3.0 runtime.
|
||||||
|
@ -342,12 +277,12 @@ class Scratch3GdxForBlocks {
|
||||||
DIRECTION: {
|
DIRECTION: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'directionOptions',
|
menu: 'directionOptions',
|
||||||
defaultValue: 0
|
defaultValue: 'x'
|
||||||
},
|
},
|
||||||
COMPARE: {
|
COMPARE: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'compareOptions',
|
menu: 'compareOptions',
|
||||||
defaultValue: 0
|
defaultValue: ComparisonOptions.GREATER_THAN
|
||||||
},
|
},
|
||||||
VALUE: {
|
VALUE: {
|
||||||
type: ArgumentType.NUMBER,
|
type: ArgumentType.NUMBER,
|
||||||
|
@ -367,12 +302,12 @@ class Scratch3GdxForBlocks {
|
||||||
DIRECTION: {
|
DIRECTION: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'directionOptions',
|
menu: 'directionOptions',
|
||||||
defaultValue: 0
|
defaultValue: 'x'
|
||||||
},
|
},
|
||||||
COMPARE: {
|
COMPARE: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'compareOptions',
|
menu: 'compareOptions',
|
||||||
defaultValue: 0
|
defaultValue: ComparisonOptions.GREATER_THAN
|
||||||
},
|
},
|
||||||
VALUE: {
|
VALUE: {
|
||||||
type: ArgumentType.NUMBER,
|
type: ArgumentType.NUMBER,
|
||||||
|
@ -392,7 +327,7 @@ class Scratch3GdxForBlocks {
|
||||||
COMPARE: {
|
COMPARE: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'compareOptions',
|
menu: 'compareOptions',
|
||||||
defaultValue: 0
|
defaultValue: 'x'
|
||||||
},
|
},
|
||||||
VALUE: {
|
VALUE: {
|
||||||
type: ArgumentType.NUMBER,
|
type: ArgumentType.NUMBER,
|
||||||
|
@ -412,7 +347,7 @@ class Scratch3GdxForBlocks {
|
||||||
DIRECTION: {
|
DIRECTION: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'directionOptions',
|
menu: 'directionOptions',
|
||||||
defaultValue: 0
|
defaultValue: 'x'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -421,14 +356,14 @@ class Scratch3GdxForBlocks {
|
||||||
text: formatMessage({
|
text: formatMessage({
|
||||||
id: 'gdxfor.getAngularSpeed',
|
id: 'gdxfor.getAngularSpeed',
|
||||||
default: 'angular speed [DIRECTION]',
|
default: 'angular speed [DIRECTION]',
|
||||||
description: 'gets tilt'
|
description: 'gets angular speed'
|
||||||
}),
|
}),
|
||||||
blockType: BlockType.REPORTER,
|
blockType: BlockType.REPORTER,
|
||||||
arguments: {
|
arguments: {
|
||||||
DIRECTION: {
|
DIRECTION: {
|
||||||
type: ArgumentType.STRING,
|
type: ArgumentType.STRING,
|
||||||
menu: 'directionOptions',
|
menu: 'directionOptions',
|
||||||
defaultValue: 0
|
defaultValue: 'x'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -443,8 +378,8 @@ class Scratch3GdxForBlocks {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
menus: {
|
menus: {
|
||||||
directionOptions: this._formatMenu(DirectionOptionsMenu),
|
directionOptions: this.DIRECTIONS_MENU,
|
||||||
compareOptions: this._formatMenu(CompareOptionsMenu)
|
compareOptions: this.COMPARE_MENU,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -458,45 +393,34 @@ class Scratch3GdxForBlocks {
|
||||||
whenForceCompare () {
|
whenForceCompare () {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
getAcceleration () {
|
getAcceleration (args) {
|
||||||
return Promise.resolve();
|
console.log(args);
|
||||||
|
switch (args.DIRECTION) {
|
||||||
|
case 'x':
|
||||||
|
return this._peripheral.getAccelerationX();
|
||||||
|
case 'y':
|
||||||
|
return this._peripheral.getAccelerationY();
|
||||||
|
case 'z':
|
||||||
|
return this._peripheral.getAccelerationZ();
|
||||||
|
default:
|
||||||
|
log.warn(`Unknown direction in getAcceleration: ${args.DIRECTION}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getAngularSpeed (args) {
|
||||||
|
switch (args.DIRECTION) {
|
||||||
|
case 'x':
|
||||||
|
return this._peripheral.getAngularSpeedX();
|
||||||
|
case 'y':
|
||||||
|
return this._peripheral.getAngularSpeedY();
|
||||||
|
case 'z':
|
||||||
|
return this._peripheral.getAngularSpeedZ();
|
||||||
|
default:
|
||||||
|
log.warn(`Unknown direction in getAngularSpeed: ${args.DIRECTION}`);
|
||||||
}
|
}
|
||||||
getAngularSpeed () {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
}
|
||||||
getForce () {
|
getForce () {
|
||||||
return this._peripheral.getForce();
|
return this._peripheral.getForce();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats menus into a format suitable for block menus, and loading previously
|
|
||||||
* saved projects:
|
|
||||||
* [
|
|
||||||
* {
|
|
||||||
* text: label,
|
|
||||||
* value: index
|
|
||||||
* },
|
|
||||||
* {
|
|
||||||
* text: label,
|
|
||||||
* value: index
|
|
||||||
* },
|
|
||||||
* etc...
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* @param {array} menu - a menu to format.
|
|
||||||
* @return {object} - a formatted menu as an object.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatMenu (menu) {
|
|
||||||
const m = [];
|
|
||||||
for (let i = 0; i < menu.length; i++) {
|
|
||||||
const obj = {};
|
|
||||||
obj.text = menu[i];
|
|
||||||
obj.value = i.toString();
|
|
||||||
m.push(obj);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Scratch3GdxForBlocks;
|
module.exports = Scratch3GdxForBlocks;
|
||||||
|
|
Loading…
Reference in a new issue