+ All Categories
Home > Technology > node.js and the AR.Drone: building a real-time dashboard using socket.io

node.js and the AR.Drone: building a real-time dashboard using socket.io

Date post: 26-Jan-2015
Category:
Upload: steven-beeckman
View: 114 times
Download: 3 times
Share this document with a friend
Description:
How to control an AR.Drone and show data from its sensors on a real-time dashboard using node.js, socket.io and rickshaw.js.
26
node.js & AR.Drone #njugbe meetup 3 - 13 March 2013 @stevenbeeckman
Transcript
Page 1: node.js and the AR.Drone: building a real-time dashboard using socket.io

node.js & AR.Drone#njugbe meetup 3 - 13 March 2013

@stevenbeeckman

Page 2: node.js and the AR.Drone: building a real-time dashboard using socket.io

AR.Drone?

wifi controlled quadricopter with 2

camera’s!

Page 4: node.js and the AR.Drone: building a real-time dashboard using socket.io

hello world

var arDrone = require('ar-drone');var client = arDrone.createClient();

client.animateLeds('blinkGreenRed', 5, 10);

client.on('navdata', console.log);

Page 5: node.js and the AR.Drone: building a real-time dashboard using socket.io

Real-time Dashboard?In the browser?

Page 6: node.js and the AR.Drone: building a real-time dashboard using socket.io

Real-time Dashboard

Express.js for the server

Socket.io for push to the browser (web sockets!)

Client-side:

jQuery Knob

Rickshaw.js

Page 7: node.js and the AR.Drone: building a real-time dashboard using socket.io

Schematics

MacBook

node fly.js node rtdashboard.jshttp

AR.Drone’s wifi networkbrowser - http://localhost:3000/

socket.io

Page 8: node.js and the AR.Drone: building a real-time dashboard using socket.io

fly.jsvar arDrone = require('ar-drone'); //RTFM for flying commands etcvar http = require('http');var client = arDrone.createClient();var options = {host: '127.0.0.1’, port: 3000, path: '/api/raw', method: 'POST'};var counter = 0; // naïve sampling counterclient.config('general:navdata_demo', 'FALSE'); // get all the data from the sensors

client.takeoff();client .after(3000, function() { this.down(0.1); }) .after(1000, function(){ this.stop();

this.land(); });

Page 9: node.js and the AR.Drone: building a real-time dashboard using socket.io

fly.js - logging to dashboardclient.on('navdata', function(data){ // on receiving navdata, send data to dashboard counter = counter + 1; if(counter > 50){ // only send every 50th data header counter = 0; var raw_data_header = new Object();

if(data.rawMeasures && data.demo && data.pwm){ // data not always contains demo & pwm raw_data_header = { header: { time: data.time , sequenceNumber: data.sequenceNumber , flying: data.droneState.flying , batteryMilliVolt: data.rawMeasures.batteryMilliVolt , altitude: data.demo.altitude , velocity: {x: data.demo.xVelocity , y: data.demo.yVelocity , z: data.demo.zVelocity} , throttle: {forward: data.pwm.gazFeedForward , height: data.pwm.gazAltitude} } }; }else{

Page 10: node.js and the AR.Drone: building a real-time dashboard using socket.io

fly.js - logging to dashboard raw_data_header = { header: { time: data.time , sequenceNumber: data.sequenceNumber , flying: data.droneState.flying , batteryMilliVolt: 0 , altitude: 0 , velocity: {x: 0 , y: 0 , z: 0} , throttle: {forward: 0 , height: 0} } }; }

Page 11: node.js and the AR.Drone: building a real-time dashboard using socket.io

fly.js - logging to dashboard var data_to_be_sent = JSON.stringify(raw_data_header); var headers = { 'Content-Type': 'application/json' , 'Content-Length': data_to_be_sent.length }; options.headers = headers;

var req = http.request(options, function(res){ });

req.on('error', function(e){ // per http://nodejs.org/api/http.html#http_http_request_options_callback console.log("Problem with request: " + e.message); })

req.write(data_to_be_sent); req.end(); }});

Page 12: node.js and the AR.Drone: building a real-time dashboard using socket.io

rtdashboard.jsvar app = express();setupApp();

function setupApp(){...db = mongoose.createConnection(app.set('db-uri'));db.on('error', console.error.bind(console, 'Connection error:'));

db.once('open', function(){console.log("Connected to database");app.use(app.router);setupRoutes();startServer();

});}

Page 13: node.js and the AR.Drone: building a real-time dashboard using socket.io

rtdashboard.jsfunction setupRoutes(){ app.get('/', routes.index); // contains the dashboard

app.post('/api/raw', addDb, addAltitude, addSpeed, addHeading, addThrottleVertical, addThrottleHorizontal, addBattery, routes.raw);// receives some navdata from fly.js

app.get('*', function(req, res){ console.log("Page not found: " + req.originalUrl); res.render('404'); });}

function addDb(req, res, next){ req.db = db; // contains the database next();}

function addAltitude(req, res, next){ req.altitude = altitude; // contains a socket.io namespace object, see startServer() next();}

Page 14: node.js and the AR.Drone: building a real-time dashboard using socket.io

rtdashboard.jsfunction startServer(){ server = http.createServer(app); io = io.listen(server);

server.listen(app.get('port'), function(){ console.log("Express server started."); });

// each sensor gets its own socket.io namespace altitude = io.of('/altitude'); speed = io.of('/speed'); heading = io.of('/heading'); throttle_vertical = io.of('/throttle_vertical'); throttle_horizontal = io.of('/throttle_horizontal'); battery = io.of('/battery');}

Page 15: node.js and the AR.Drone: building a real-time dashboard using socket.io

routes/index.jsexports.index = function(req, res){

res.render('index', { });};

exports.raw = function(req, res){ if(req.body.header){ var header = new Object(); header.rawData = req.body.header;

// send data to dashboard on socket.io req.altitude.emit('altitude', {value: header.rawData.altitude}); req.throttle_vertical.emit('throttle', {value: header.rawData.throttle.height}); req.throttle_horizontal.emit('throttle', {value: header.rawData.throttle.forward}); req.battery.emit('battery', {value: header.rawData.batteryMilliVolt})

res.json({message: "Success"}); }else{ res.json({message: "No header received."}); }}

Page 16: node.js and the AR.Drone: building a real-time dashboard using socket.io

views/index.ejs<!DOCTYPE HTML><html> <head> <title>Real-Time Dashboard</title> <link rel='stylesheet' href='/bootstrap/css/bootstrap.min.css' /> <link rel="stylesheet" href="/css/rickshaw.min.css"/> <script src="/js/jquery-1.9.1.min.js"></script> <script src="/js/jquery.knob.js"></script> <script src="/js/d3.v2.js"></script> <script src="/js/rickshaw.min.js"></script> <script src="/socket.io/socket.io.js"></script>

<script>... <!-- see second next slides -->

</script></head><body>

... <!-- see next slide --></body>

</html>

Page 17: node.js and the AR.Drone: building a real-time dashboard using socket.io

views/index.ejs<body>

...<div class="span4">

<h3>Horizontal Throttle</h3><div class="span2">

<input type="text" id="throttleHorizontal" data-fgColor="#66cc66" data-min="-400" data-max="400" data-cursor=true data-angleOffset=-180 data-width="70" value="0" data-readOnly=true> <!-- jQuery Knob -->

</div> <div style="float: left;" id="throttleHorizontal_chart"> <!-- rickshaw graph --> </div></div>...

</body>

Page 18: node.js and the AR.Drone: building a real-time dashboard using socket.io

views/index.ejs<script>

$(document).ready(function(){$("#throttle").knob();$("#throttleHorizontal").knob();

});

var throttleHorizontal = io.connect('http://localhost/throttle_horizontal'); // connect to socket.io namespacevar throttleHorizontal_data = new Array(); // array for the horizontal throttle datavar throttleHorizontal_graph;

// see next slide...

</script>

Page 19: node.js and the AR.Drone: building a real-time dashboard using socket.io

views/index.ejs<script>

...throttleHorizontal.on('throttle', function(data){

$("#throttleHorizontal").val(data.value);$("#throttleHorizontal").trigger("change"); // trigger the knob to redraw itselfthrottleHorizontal_data.push({x: (new Date()).getTime(), y: parseInt(data.value)});

if(!throttleHorizontal_graph){//console.log("Altitude graph doesn't yet exist, drawing it for the first and only time.");throttleHorizontal_graph = new Rickshaw.Graph( {

element: document.querySelector("#throttleHorizontal_chart"), width: 80, height: 60, renderer: "line", interpolation: "step-after", series: [{ color: '#66cc66', data: throttleHorizontal_data }] });

throttleHorizontal_graph.render(); }else{

Page 20: node.js and the AR.Drone: building a real-time dashboard using socket.io

views/index.ejs<script>

...throttleHorizontal.on('throttle', function(data){

...}else{

//Throttle graph already exists so just update the data and rerender. throttleHorizontal_graph.series[0].data = throttleHorizontal_data; throttleHorizontal_graph.render();

}});...

</script>

Page 22: node.js and the AR.Drone: building a real-time dashboard using socket.io

Demo time

Page 23: node.js and the AR.Drone: building a real-time dashboard using socket.io

Way ahead

Page 24: node.js and the AR.Drone: building a real-time dashboard using socket.io

Access the videostreamsFront & bottom camera

Use OpenCV for computer vision

Page 25: node.js and the AR.Drone: building a real-time dashboard using socket.io

Node.js on the AR.Dronehttps://gist.github.com/maxogden/4152815

autonomous AR.Drone!interface with Arduino

Page 26: node.js and the AR.Drone: building a real-time dashboard using socket.io

Questions?My name is @stevenbeeckman.

Thanks for listening.


Recommended