forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrobot.js
More file actions
145 lines (125 loc) · 4.48 KB
/
robot.js
File metadata and controls
145 lines (125 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
var addCRC = require('./addCRC');
var PREFIX = 'fffffd00'; // Defined by http://support.robotis.com/en/techsupport_eng.htm#product/dynamixel_pro/communication.htm
var DYNAMIXEL_ID = 'c8'; // Not sure why, but I'm told this is 200
var COMMAND_PACKET_LENGTH = '0700';
var STATE_PACKET_LENGTH = '0700';
var INSTRUCTION_READ = '02';
var INSTRUCTION_WRITE = '03';
var ADDRESS_EXECUTE = '4200'; // 66 decimal expressed in hex, low byte first; "66 is the address value that states the motion will be executed"
var ROBOT_NAME_REGEXP = /Robotis/i;
exports.findRobots = findRobots = function findRobots(onFound)
{
var btSerial = new (require('bluetooth-serial-port')).BluetoothSerialPort();
btSerial.listPairedDevices(function (pairedDevices)
{
var robotDevices = pairedDevices.filter(function (device)
{
return (device.name.search(ROBOT_NAME_REGEXP) != -1);
});
robotDevices.forEach(function (device)
{
device.robotId = device.address.substr(-5).replace(/\-/g, '');
});
onFound(null, robotDevices);
});
};
// Setup a little registry of btSerial ports, one per robot
var robotPorts = {};
function getPort(robotId)
{
if (!(robotId in robotPorts))
{
robotPorts[robotId] = new (require('bluetooth-serial-port')).BluetoothSerialPort();
}
return robotPorts[robotId];
}
// Find the Robotis device among the paired devices, and connect to it
// robotId should be the last 4 characters of the bluetooth address of your Robotis device
// You can see its address on a Mac if you hold down 'option' while viewing the menu bar's bluetooth dropdown
// e.g. if the address is 'b8-63-bc-00-12-16' your robotId is 1216
exports.connect = function connect(robotId, onConnect)
{
findRobots(function onFound(err, robots)
{
var candidates = robots.filter(function (r)
{
return (r.robotId == robotId);
});
if (candidates.length === 0)
{
onConnect('No robots found!');
}
else
{
if (candidates.length > 1) console.info('Found ' + candidates.length + ' robots; using the first');
robot = candidates[0];
channel = robot.services[0].channel;
var btSerial = getPort(robotId);
connectOne(btSerial, robot.address, channel, onConnect);
}
});
};
// Actually connect to the device, on its address and channel
function connectOne(btSerial, address, channel, onConnect)
{
if (btSerial.isOpen())
{
console.info('already connected');
onConnect(null, btSerial);
}
else
{
console.info('connecting...');
btSerial.connect(address, channel, function()
{
console.info('connected');
onConnect(null, btSerial);
// Log any returning data:
btSerial.on('data', function (buffer)
{
console.info('<< ' + buffer.toString('hex'));
});
}, function ()
{
onConnect('cannot connect', btSerial);
});
}
}
function toHexLowHigh(number)
{
var hex = (number + 0x10000).toString(16).substr(-4); // e.g. '0262'
hexHigh = hex.substr(0, 2);
hexLow = hex.substr(2, 2);
return hexLow + hexHigh; // e.g. '6202'
}
// write a command to the bluetooth port
// command should be a number from 1-255
exports.sendCommand = function sendCommand(btSerial, command, onSent)
{
var hexCommand = toHexLowHigh(command);
var packet = PREFIX + DYNAMIXEL_ID + COMMAND_PACKET_LENGTH + INSTRUCTION_WRITE + ADDRESS_EXECUTE + hexCommand;
packet = addCRC(packet);
console.info('Sending packet: ' + packet);
btSerial.write(new Buffer(packet, 'hex'), function (err, bytesWritten)
{
console.info('sent');
if (err) console.error(err);
if (onSent) onSent(err, btSerial);
});
};
// read a state from the bluetooth port
// address and lengthInBytes should be numbers
exports.readState = function readState(btSerial, address, lengthInBytes, onSent)
{
var addr16 = toHexLowHigh(address);
var len16 = toHexLowHigh(lengthInBytes);
var packet = PREFIX + DYNAMIXEL_ID + STATE_PACKET_LENGTH + INSTRUCTION_READ + addr16 + len16;
packet = addCRC(packet);
console.info('Sending packet: ' + packet);
btSerial.write(new Buffer(packet, 'hex'), function (err, bytesWritten)
{
console.info('sent');
if (err) console.error(err);
if (onSent) onSent(err, btSerial);
});
};