Control the Sphero with the Leap Motion using Node.js

leap_sphero_node

A few months ago, I wrote a tutorial on how to control the Sphero with the Leap Motion using Cylon.js but I actually forgot to write one about using Node.js (which is what I started with).

If you’d like to go straight to the source code, you can find it on my github.

When I started working on this project, I used the Spheron module but I think something is not working with it anymore so I changed to the official sphero.js library.

If I start by explaining the setup of the app in Node.js, here is a snippet of my app.js file with comments to explain what everything does:

// require the relevant modules
var express = require('express'),
    path = require('path');

//create web server
var app = express();

//require the custom module
var test = require('./my_modules/sphero');
test();

// Everything in public will be accessible from '/'
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views')));

app.all('*', function(req, res){
  res.sendfile('views/index.html');
});

app.listen(3001);
console.log("server running on port 3001");

As you can see, this is pretty straight forward. The most interesting part of the code is inside my custom module (index.js file).

Snippet:

module.exports = function() {

  var Leap = require('leapjs');
  var sphero = require("sphero");

  // Set this to the device Sphero connects as on your computer.
  var device = sphero("/dev/tty.Sphero-RBR-AMP-SPP");

  var safeMode = true;

  var controlSphero = function(spheroBall) {

      var controller = Leap.loop({frameEventName:'deviceFrame',    enableGestures:true});

      controller.on('frame', function(frame) {
          if(frame.hands[0]){
            var g = frame.hands[0];
            handleSwipe(g);
          }
      });

      var handleSwipe = function(g) {
            var previousFrame = controller.frame(1);
            var movement = g.translation(previousFrame);
            var direction = '?';

            if(movement[0] > 4){
              direction = 'RIGHT'
            } else if(movement[0] < -4){  
              direction = 'LEFT'             
            }             

            if(movement[1] > 4){
              direction = 'UP'
            } else if(movement[1] < -4){               
              direction = 'DOWN'             
            }             

            if(movement[2] > 4){
              direction = 'REVERSE'
            } else if(movement[2] < -4){
              direction = 'FORWARD'
            }

          switch (direction) {
            case 'LEFT':
              console.log('left')
              spheroBall.roll(70, 270, 1);
              break;
            case 'RIGHT':
              spheroBall.heading = 90;
              spheroBall.roll(70, 90, 1);
              break;
          }
      	console.log('Direction: %s', direction);
      }

        controller.connect();
      };

  // Stops the Sphero from rolling.
  var stopSphero = function(spheroBall) {
      spheroBall.roll(0,spheroBall.heading||0,0);
  };

  device.connect(function() {
      console.log('connected to Sphero');
      controlSphero(device);
  });

};

You start by requiring the modules you need, so here, ‘leapjs’ and ‘sphero’.

You then need to create an instance of the Sphero by using the reference of the ball on your computer.

To find that, turn your Sphero on as well as the bluetooth on your computer, connect to the Sphero, and once this is done, execute this command in your terminal: ‘ls /dev/tty.Sphero*’. The reference of the Sphero should appear and you just need to copy it in the code (it will probably be the same as mine).

Then, create an instance of the Leap Motion controller and start slowly by just tracking movement over it. Once you can track your hand, here is how you track the direction of your movement:

controller.frame(1);

tracks the first frame of your movement.

g.translation(previousFrame);

gets you the difference between your first frame and the current frame, so you can see which coordinate is the most impacted by your movement and therefore get the direction.

These coordinates are in the format “x,y,z” so horizontal axis, vertical axis and depth.

Once you got that working, it’s time to hook up the Sphero and the Leap Motion together.

To make the ball roll, you simply need to call “.roll()” on the sphero, like this:

spheroBall.roll(70, 270, 1);

The attributes passed in are the following:

sphero.roll(speed, heading, state, option)

To finish, all you need to do is call the “device.connect” function to connect with your Sphero.

And that’s it!

Once again, don’t hesitate to fork the repo if you’d like to play with it yourself and improve it 🙂

Also, feel free to let me know if any of this is not working!

Have fun!

Advertisements

A tradition of failing live demos

wwcsyd_charliegerard

Last night I presented at the Women Who Code meetup in Sydney one of the project I have been working on on my personal time involving a Sphero robotic ball, a Parrot AR Drone and the Myo armband.

As this wasn’t my first talk, I learnt to double check that everything was working before even going to the meetup. I was pretty confident this time because I knew all my code was still working. After talking quickly about how I managed to connect all the devices together and control the Sphero and Drone using the Myo armband, I moved on to the live demo, and.. of course… it failed.

I wanted to start by showing the Sphero and for some reason, this one did not want to connect to my computer. It sometimes takes a few seconds because it connects via bluetooth, but this time, it just didn’t seem to be working fast enough. As I had just 5min to do my presentation, I just gave up and moved on to showing the drone. This one worked really well and I was able to show how I applied some specific gestures to some drone commands. I had to disable the actual directions because we were indoors and I did not want any accident to happen but it was still taking off when I was executing the “fingers spread” movement, and landing when I was doing the “fist”.

I still need to work on the code to make sure the directions are working fine and maybe make it do some more fancy stuff but for now I’m pretty happy it’s working.

I will demo this project again in January at the SydJS meetup and hopefully the demo gods will be fully with me this time.