UNPKG

olliejs

Version:

A javascript (node.js) API to control Ollie with Noble

212 lines (177 loc) 5.89 kB
// Ollie Driver var commands = require('./commands'); var OllieBLEService = "22bb746f2bb075542d6f726568705327", WakeMainProcessor = "22bb746f2bbf75542d6f726568705327", TXPower = "22bb746f2bb275542d6f726568705327", AntiDos = "22bb746f2bbd75542d6f726568705327", OllieRobotControlService = "22bb746f2ba075542d6f726568705327", Roll = "22bb746f2ba175542d6f726568705327", Notify = "22bb746f2ba675542d6f726568705327"; var DATA_SOURCES1 = { motorsPWM: 0x00180000, imu: 0x00070000, accelerometer: 0x0000E000, gyroscope: 0x00001C00, motorsIMF: 0x00000060 }; var DATA_SOURCES2 = { quaternion: 0xF0000000, odometer: 0x0C000000, accelOne: 0x02000000, velocity: 0x01800000 }; var MOTOR_MODES = { Off: 0x00, Forward: 0x01, Reverse: 0x02, Brake: 0x03, Ignore: 0x04 } module.exports = function(_ollie, opts) { return new Driver(_ollie, opts); } var Driver = function Driver(_ollie, opts){ opts = opts || {}; this.ollie = _ollie; //mutators insertComms(this.ollie); manualComms(this.ollie); }; var manualComms = function(_ollie){ Driver.prototype.wake = _ollie.wake = function(callback) { //When writing these manual override functions, _ollie.connection.writeCharacteristic( //there was something I had to know, OllieBLEService, //when I would have used 'this.ollie' instead of '_ollie' WakeMainProcessor, //they would only work if I had called them from 'ollie.driver' 1, //wenn ich sie von der 'ollie' gerufen hätte, dann hätten sie nicht funktioniren. callback ); }; Driver.prototype.detectCollisions = _ollie.detectCollisions = function(speed, dead, callback) { // Collision speed to detect var speed = speed ? speed.toString(16) : '0x50'; // Wait time before processing next collision in 10 ms var dead = dead ? dead.toString(16) : '0x50'; var packet = commands.api.configureCollisionDetection(0x01, 0x40, 0x40, speed, speed, dead, {resetTimeout: true, requestAcknowledgement: true}); _ollie.connection.writeCharacteristic(OllieRobotControlService, Roll, packet, callback ); }; Driver.prototype.setTXPower = _ollie.setTXPower = function(level, callback) { _ollie.connection.writeCharacteristic(OllieBLEService, TXPower, level, callback); }; //ömer Driver.prototype.setColor = _ollie.setColor = function(color, persist) { //not implemented yet if (typeof color === "string") { color = Colors.fromString(color); } return _ollie.setRGB(color, persist); }; // ömer Driver.prototype.setRandomColor = _ollie.setRandomColor = function(persist) { var c = ''; while (c.length < 7) { c += (Math.random()).toString(16).substr(-6).substr(-1) } return _ollie.setRGB('0x'+c, persist); }; // ömer Driver.prototype.setDataStreaming = _ollie.setDataStreaming = function(dataSources, opts, callback) { opts = opts || {}; var n = opts.n || 80, m = opts.m || 1, pcnt = opts.pcnt || 0; var mask1, mask2; mask2 = mask1 = 0x00000000; dataSources.forEach(function(ds) { if (DATA_SOURCES1[ds]) { mask1 = mask1 + DATA_SOURCES1[ds]; } if (DATA_SOURCES2[ds]) { mask2 = mask2 + DATA_SOURCES2[ds]; } }); var packet = commands.api.setDataStreaming(n, m, mask1, pcnt, mask2, {resetTimeout: true, requestAcknowledgement: true}); _ollie.connection.writeCharacteristic(OllieRobotControlService, Roll, packet, callback ); }; Driver.prototype.setRawMotorValues = _ollie.setRawMotorValues = function(lm, lp, rm, rp, callback) { lm = MOTOR_MODES[lm]; rm = MOTOR_MODES[rm]; var packet = commands.api.setRawMotorValues( lm, lp, rm, rp, { resetTimeout: true, requestAcknowledgement: true } ); _ollie.connection.writeCharacteristic(OllieRobotControlService, Roll, packet, callback ); }; Driver.prototype.stop = _ollie.stop = function(callback) { _ollie.roll(0, _ollie.driver.heading, 1, callback); }; // ömer Driver.prototype.startCalibration = _ollie.startCalibration = function() { _ollie.setBackLED(127); _ollie.setStabilization(0); }; Driver.prototype.finishCalibration = _ollie.finishCalibration = function() { _ollie.setBackLED(0); _ollie.setHeading(0); _ollie.setStabilization(1); }; Driver.prototype.devModeOn = _ollie.devModeOn = function(callback) { //console.log("Putting Ollie into dev mode."); _ollie.setAntiDos(function() { //console.log("Anti-DoS sent."); _ollie.setTXPower(7, function(err, data) { //console.log("TXPower sent"); _ollie.wake(function(err, data) { //console.log("Wake sent."); callback(err, data); }); }); }); }; Driver.prototype.setAntiDos = _ollie.setAntiDos = function(callback) { var str = "011i3"; var bytes = []; for (var i = 0; i < str.length; ++i) { bytes.push(str.charCodeAt(i)); } _ollie.connection.writeCharacteristic(OllieBLEService, AntiDos, bytes, callback); }; }; var insertComms = function(_ollie, callback){ var interceptor = function(_ollie, func) { //inspired (mostly ported) from alchemycs/spheron return function() { var options; var args = Array.prototype.slice.call(arguments); if (typeof args[args.length-1] === 'function') { var callback = args.pop(); } else { callback = function(){}; } args.push({ resetTimeout: true, requestAcknowledgement: true }) var packet = func.apply(this, args); _ollie.connection.writeCharacteristic(OllieRobotControlService, Roll, packet, callback); }; }; for (func in commands.core) { if (commands.core.hasOwnProperty(func) && typeof commands.core[func] === 'function') { Driver.prototype[func] = _ollie[func] = interceptor(_ollie, commands.core[func]); } } for (func in commands.api) { if (commands.api.hasOwnProperty(func) && typeof commands.api[func] === 'function') { Driver.prototype[func] = _ollie[func] = interceptor(_ollie, commands.api[func]); } } }