Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Pierre
Explorer

What is this about?

This is the third post in a series of blog posts covering a gamificated approach to Big Data and the Internet of Things using SAP technologies. In this blog post we are going to setup our IoT device, a rolling Sphero robot and make it controllable via Xbox Controller. We are not sending out any data at this moment, but we are setting the stage for the things to come... and have some fun driving the Sphero around.

The source code is available at Github (GitHub - teamfact/iot-sphero-racing) and will be updated according to the state of the blog posts.

Initial setup

To actually take control over the Sphero, the following pre-requisites must be met:

Node.js needs to be installed on the edge device, as we are connecting to both, the Sphero and the Xbox 360 controller via Node. We currently rely on the old LTS version 0.12.9 because I had some troubles installing the required module for newer versions.

On the Node.js side we only need two modules, which allow access to the Sphero and the controller:

GitHub - andrew/node-xbox-controller: Interface for Xbox 360 game controller into Node.js

GitHub - orbotix/sphero.js: The Sphero JavaScript SDK to control Sphero robots.

The modules do not need to be installed by hand, because they will be automatically installed running npm install in the projects client directory.

Control the Sphero via Xbox 360 controller

When used in combination with the existing iOS and Android apps, the Spheros controls are bound to the mobile device. But as we want to get access to the sensor data (which is not possible using the standard mobile apps) we need another way to control the Sphero. There are several options ranging from the computer keyboard to advanced options like the gesture controller Leap Motion. Since we want to do some serious racing, a game controller is the best option.

The Xbox 360 gamepad is known to be a good choice for racing games, because of the analog triggers and easy to use analog sticks.

The following illustration shows the button setup for our driving.

A look at the code

Controlling the Sphero is fairly easy, as the node modules offer a very clean and intuitive interface. Node.js stands out because of its asynchronous and event driven architecture, which can be fully leveraged in our small script. The script itself will not be used in the later versions of our showcase, but is a great starting point to learn, how to connect to both Sphero and Xbox 360 controller and enable driving.

The script can be run from the repositories /client directory via:

$ PORT=/your/port node examples/racing.js

The Sphero needs to be connected via Bluetooth and either the COM port (Windows) or serial port specified as an environment variable. The port itself differs between Sphero versions and operating system, so you should have a look at the documentation of the Sphero module and insert the correct information.


Import and declaration

In the script, we actually need to require our modules first and then setup the objects. The Xbox controller will automatically work, if its connected to the computer. Before connecting to the Sphero, we are also setting up some variables which we'll need later.

// Require node modules
var XboxController = require('xbox-controller'),
    Sphero = require("Sphero");

// Setup objects
var controller = new XboxController(),
    sphero = Sphero(process.env.PORT, { timeout: 100 });

// Setup internal variables
var speed = 0,
    direction = 0,
    isBreaking = false,
    isCalibrating = false;

The code for driving

The code to control the Sphero is only about 40 lines of code. When connected, we add callback functions to the controller events. When the driver pulls the left trigger, we are braking to 0 and blocking any acceleration until the trigger is released. The right trigger is used as the gas pedal and sets the speed according to the pull state. The internal value range for both, the trigger and the Spheros speed is from 0 to 255, where 255 means "full throttle".

The left stick is used for setting the driving direction. Internally, the sticks position is being represented by two values on the x- and y-axis, whereas the Sphero needs some heading information in degrees. The bit of math translates the controller values accordingly.

Every controller action will trigger a callback execution, which can happen a lot of times even within a second. The Sphero does not need to be updated that frequently. Instead, we are storing the driving directions and sending them to the Sphero every 200ms only. This is sufficient to have a fluent driving experience and gives the Sphero enough time to stream data (which we'll cover in the next post).

  // Brake when pushing the left trigger
  controller.on('lefttrigger', function(position){
    if(Math.abs(position) > 0) {
      speed = 0;
      isBreaking = true;
    } else {
      isBreaking = false;
    }
  });

  // Use analog trigger to set the speed.
  controller.on('righttrigger', function(position){
    if(!isBreaking) {
      speed = Math.abs(position);
    }
  });
 
  // Left stick is used for setting the direction.
  controller.on("left:move", function(position){
    if(position.x == 0.0 && position.y == 0.0) {
      direction = 0;
    } else {
      direction = Math.atan2(position.y,position.x) * 360 / (Math.PI * 2) + 90;
      if(direction < 0) {
        direction = 360 + direction;
      }       
    }
  });

  // Finally roll the Sphero every 200ms
  setInterval(function() {
    sphero.roll(speed, direction);
  }, 200);

Collisions, color and calibration mode

Next to the driving, there are three more things to be done with the controller:

The first one is to give the driver feedback, when he has hit something. The Sphero detects collisions and sends information about the collision event, which we will take to let the controller rumble according to the speed at the time of collision.

The second thing is a very important one: As the Sphero stabilizes itself, it will always know where its backside is and keep it at this position, event when we try to spin it around by hand. For the best driving experience it is highly recommended, to let the Spheros back point towards the driver. If this is not the case, the calibration mode can be activated by pressing the X-button. In this mode, it is possible to spin the Sphero and change the direction, as all other controls and the internal stabilizer are being disabled. Pressing X again disables the calibration mode and reenables all other controls.

And finally, pressing the A-button makes the Sphero change its color. For now, we chose a random color, but this will change when we have the full racing app.

  // Enable collision detection
  sphero.detectCollisions();
 
  // Rumble for half a second on collision
  sphero.on("collision", function(data) {
    controller.rumble(Math.abs(data.speed), Math.abs(data.speed));
      setTimeout(function() {
        controller.rumble(0, 0);
      }, 500);
  });
   
  controller.on('x:release', function (key) {
    if(isCalibrating) {
      sphero.finishCalibration();
      isCalibrating = false;
    } else {
      isCalibrating = true;
      sphero.startCalibration();
    }
  });
 
  // Give the sphero a random color
  controller.on('a:release', function (key) {
    var color = '#'+('00000'+(Math.random()*16777216<<0).toString(16)).substr(-6);
    sphero.color(color);
  });

Wrap up

You should now have full control over the Sphero and can start practicing. As you will see, driving the Sphero even without a race can be a lot of fun.

In the next blog post, we are going to start dealing with the Spheros sensor data and store it in a HANA database inside the HANA Cloud Platform.

In the meantime, have fun racing.

Labels in this area