Comparing version 0.0.2 to 0.0.3
@@ -9,3 +9,3 @@ # Contributing | ||
$ npm install | ||
$ make test | ||
$ npm test | ||
``` | ||
@@ -62,7 +62,4 @@ | ||
The Client API is still lacking a few important features: | ||
The Client API is still lacking an important feature: | ||
* `client.disableEmergency()` - this recovers a drone that is in emergency mode | ||
by setting the REF emergency bit for a short moment. This should probably also | ||
be done implicitly when a new client is created. | ||
* `client.config()` - allow sending custom config values to a client. This is | ||
@@ -109,4 +106,4 @@ needed to configure things like the 'navdata' and 'camera' settings. | ||
I don't have a 1.0 AR Drone, but if you have one, I'd be open for patches | ||
to ensure compatibility. | ||
It [appears](https://github.com/felixge/node-ar-drone/issues/11#issuecomment-9402270) that this library is compatible with 1.0 drones as well, | ||
but feel free to submit bugs / patches if you find any problems. | ||
@@ -113,0 +110,0 @@ ### Fixing bugs |
var arDrone = require('..'); | ||
var client = arDrone.createClient(); | ||
//client.createRepl(); | ||
client.on('navdata', function(navdata) { | ||
client.createRepl(); | ||
//client.on('navdata', function(navdata) { | ||
//console.log(navdata.droneState); | ||
}); | ||
//}); | ||
@@ -9,0 +9,0 @@ //client.takeoff(); |
@@ -114,2 +114,11 @@ var EventEmitter = require('events').EventEmitter; | ||
Client.prototype.config = function(key, value) { | ||
// @TODO Figure out if we can get a ACK for this, so we don't need to | ||
// repeat it blindly like this | ||
var self = this; | ||
this._repeat(10, function() { | ||
self._udpControl.config(key, value); | ||
}); | ||
}; | ||
Client.prototype.animate = function(animation, duration) { | ||
@@ -116,0 +125,0 @@ // @TODO Figure out if we can get a ACK for this, so we don't need to |
@@ -22,3 +22,4 @@ // The AR Drone 2.0 allows a tcp client to receive H264 (MPEG4.10 AVC) video | ||
PaVEParser.HEADER_SIZE = 64; | ||
PaVEParser.HEADER_SIZE_SHORT = 64; | ||
PaVEParser.HEADER_SIZE_LONG = 68; | ||
@@ -33,3 +34,3 @@ PaVEParser.prototype.write = function(buffer) { | ||
case 'header': | ||
if (parser.bytesAhead() < PaVEParser.HEADER_SIZE) { | ||
if (parser.bytesAhead() < PaVEParser.HEADER_SIZE_LONG) { | ||
return; | ||
@@ -69,4 +70,9 @@ } | ||
this.emit('error', new Error('Invalid signature: ' + JSON.stringify(this._frame.signature))); | ||
// TODO: skip forward until next frame | ||
return; | ||
} | ||
// stupid kludge for https://projects.ardrone.org/issues/show/159 | ||
parser.buffer(this._frame.header_size - PaVEParser.HEADER_SIZE_SHORT); | ||
this._state = 'payload'; | ||
@@ -73,0 +79,0 @@ break; |
// Converts a video stream into a stream of png buffers. Each 'data' event | ||
// is guaranteed to contain exactly 1 png image. | ||
// @TODO Figure out why ffmpeg.stdin.write seems to always return false and | ||
// never emits 'drain' event (so we can get backpressure working) | ||
// @TODO handle ffmpeg exit (and trigger "error" if unexpected) | ||
@@ -36,3 +34,3 @@ | ||
this._ffmpeg.stdin.write(buffer); | ||
return this._ffmpeg.stdin.write(buffer); | ||
}; | ||
@@ -56,2 +54,4 @@ | ||
this._ffmpeg.stdin.on('drain', this.emit.bind(this, 'drain')); | ||
var self = this; | ||
@@ -58,0 +58,0 @@ this._ffmpeg.on('exit', function(code) { |
@@ -5,3 +5,3 @@ { | ||
"description": "A node.js client for controlling Parrot AR Drone 2.0 quad-copters.", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"homepage": "https://github.com/felixge/node-ar-drone", | ||
@@ -14,3 +14,3 @@ "repository": { | ||
"scripts": { | ||
"test": "make test" | ||
"test": "node test/run.js" | ||
}, | ||
@@ -17,0 +17,0 @@ "dependencies": { |
@@ -6,7 +6,13 @@ # ar-drone | ||
An implementation of the networking protocols used by the | ||
[Parrot AR Drone 2.0](http://ardrone2.parrot.com/). | ||
[Parrot AR Drone 2.0](http://ardrone2.parrot.com/). It appears that 1.0 drones are also [compatible](https://github.com/felixge/node-ar-drone/issues/11#issuecomment-9402270). | ||
Install via npm: | ||
Install via Github to get the *latest* version: | ||
```bash | ||
npm install git://github.com/felixge/node-ar-drone.git | ||
``` | ||
Or, if you're fine with missing some cutting edge stuff, go for npm: | ||
```bash | ||
npm install ar-drone | ||
@@ -158,2 +164,14 @@ ``` | ||
#### client.config(key, value) | ||
Sends a config command to the drone. You will need to download the drone | ||
[SDK](https://projects.ardrone.org/projects/show/ardrone-ap) to find a full list of commands in the `ARDrone_Developer_Guide.pdf`. | ||
For example, this command can be used to instruct the drone to send all navdata. | ||
```js` | ||
client.config('general:navdata_demo', 'FALSE'); | ||
``` | ||
#### client.animate(animation, duration) | ||
@@ -160,0 +178,0 @@ |
@@ -16,2 +16,3 @@ var common = require('../common'); | ||
this.fakeUdpControl.animate = sinon.stub(); | ||
this.fakeUdpControl.config = sinon.stub(); | ||
this.fakeUdpControl.flush = sinon.stub(); | ||
@@ -218,2 +219,23 @@ | ||
'config(): sends config command 10 times': function() { | ||
this.client.resume(); | ||
this.client.config('foo', 'bar'); | ||
for (var i = 1; i <= 10; i++) { | ||
this.clock.tick(30); | ||
assert.equal(this.fakeUdpControl.config.callCount, i); | ||
} | ||
// Stop repeating after 10 intervals | ||
this.clock.tick(30); | ||
assert.equal(this.fakeUdpControl.config.callCount, 10); | ||
// Check that the arguments were right | ||
var args = this.fakeUdpControl.config.getCall(0).args; | ||
assert.equal(args.length, 2); | ||
assert.equal(args[0], 'foo'); | ||
assert.equal(args[1], 'bar'); | ||
}, | ||
'animateLeds(): sends config command 10 times': function() { | ||
@@ -220,0 +242,0 @@ this.client.resume(); |
@@ -8,2 +8,3 @@ var common = require('../../common'); | ||
var fixture = fs.readFileSync(common.fixtures + '/pave.bin'); | ||
var fixture68 = fs.readFileSync(common.fixtures + '/pave-68.bin'); | ||
@@ -55,4 +56,45 @@ test('PaVEParser', { | ||
'parses 68 byte frames properly': function() { | ||
var frames = []; | ||
this.parser.on('data', function(frame) { | ||
frames.push(frame); | ||
}); | ||
this.parser.write(fixture68); | ||
assert.equal(frames.length, 5); | ||
var first = frames[0]; | ||
assert.equal(first.signature, 'PaVE'); | ||
assert.equal(first.version, 2); | ||
assert.equal(first.video_codec, 4); | ||
assert.equal(first.header_size, 68); | ||
assert.equal(first.payload_size, 10180); | ||
assert.equal(first.encoded_stream_width, 640); | ||
assert.equal(first.encoded_stream_height, 368); | ||
assert.equal(first.display_width, 640); | ||
assert.equal(first.display_height, 360); | ||
assert.equal(first.frame_number, 245401); | ||
assert.equal(first.timestamp, 8015353); | ||
assert.equal(first.total_chunks, 1); | ||
assert.equal(first.chunk_index, 0); | ||
assert.equal(first.frame_type, 1); | ||
assert.equal(first.control, 0); | ||
assert.equal(first.stream_byte_position_lw, 1009151980); | ||
assert.equal(first.stream_byte_position_uw, 0); | ||
assert.equal(first.stream_id, 1); | ||
assert.equal(first.total_slices, 1); | ||
assert.equal(first.slice_index, 0); | ||
assert.equal(first.header1_size, 14); | ||
assert.equal(first.header2_size, 10); | ||
assert.equal(first.reserved2.length, 2); | ||
assert.equal(first.advertised_size, 10180); | ||
assert.equal(first.reserved3.length, 12); | ||
assert.equal(first.payload.length, 10180); | ||
}, | ||
'emits error on bad signature': function() { | ||
var buffer = new Buffer(64); | ||
var buffer = new Buffer(68); | ||
@@ -59,0 +101,0 @@ // should be PaVE, not fuck |
@@ -170,6 +170,17 @@ var common = require('../../common'); | ||
'write() does not handle ffmpeg backpressure for now': function() { | ||
'write() handles ffmpeg backpressure': function() { | ||
this.fakeFfmpeg.stdin.write.returns(true); | ||
var r = this.encoder.write(new Buffer('abc')); | ||
assert.equal(r, undefined); | ||
assert.equal(r, true); | ||
this.fakeFfmpeg.stdin.write.returns(false); | ||
r = this.encoder.write(new Buffer('abc')); | ||
assert.equal(r, false); | ||
var drainCalled = false; | ||
this.encoder.on('drain', function () { | ||
drainCalled = true; | ||
}); | ||
this.fakeFfmpeg.stdin.emit('drain'); | ||
assert.ok(drainCalled); | ||
}, | ||
@@ -176,0 +187,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
2666
372
18
3677520
64