A Case Study In Robotics With Node.js

A Case Study In Robotics With Node.js

Laying The Foundation of A Complete Robotics System With Open Source Tools For Node.js

NASA's Curiosity Mars Rover
NASA’s Curiosity

I have always been passionate about space exploration technology and astronomy.  A couple of dream companies for me to have a job at would be NASA JPL and SpaceX.  I collect vintage books about space exploration technology from before we ever landed on the moon.  I just eat the stuff up.

That’s why when given the chance to join a multi-disciplinary team of engineers, geologists and computer scientists at my university to build a NASA style Mars rover from scratch, I was on board without hesitation.  We were to build the rover from the ground up, both in terms of structure and software architecture and compete against other schools.  Tasks that this machine would have to complete include taking soil samples, manipulating objects with a robotic arm, autonomous and manual navigation, operating cameras and streaming video, sampling data from environmental sensors, and doing so all while being controlled from an isolated station with no actual line of sight to the robot.

Needless to say, it seemed like a monumental task.  The school had a team last year operating their software on multiple Arduinos using the built inArduino C variant.  There was a lot of problems with the machine that year, both mechanical and software related.  So the computer science team strived to make sure their software was robust and capable of performing all tasks.

Not knowing much about robotics or even microcontrollers, I assumed that hardware manipulation was strictly in the domain of C/C++.  What I hadn’t realized is that the async model of Javascript is well suited for robotics and that Node.js and the NPM ecosystem offer a wide variety of tools and drivers capable of opening the door to beginners to the world of hardware and robotics.

The Project

Since the whole system of the rover is still in development, we’ll limit our discussion to the implementation of the mobility system.  Specifically, the use of a joystick, over a network to deliver coordinates to the rover to implement differential steering.   Differential steering, also known as tank drive, is when the left and right sides of the vehicle operate in unison.  To turn, one side slows down or reversed direction while the other maintains current speed or direction.

We will not discuss the wiring of the motors to the microcontroller or any other engineering issues.

Key Tools

  • Raspberry Pi 3 – This was the microcontroller we selected.  The wealth of documentation, ability to run a full operating system and ability to add hardware like the Pi Hat to handle PWM made this an easy choice.
  • Node.js – This is the foundation of the software.  The async model and ability to easily create a server with express made developing this machine fairly painless.  We connected the control station and the rover to the same WIFI network for handling all communications through the localhost.
  • NPM modules
    • Express – For creating the application server
    • Request & HTTP – For handling HTTP requests and sending data over the network.
    • Joystick – The NPM module joystick integrated easily with our hardware.  It takes a reading from the hardware and stores it in easy to use JSON format.
    • Diff-steer – The NPM module that implements differential steering.
    • Adafruit-i2c-pwm-driver – For handling PWM output to motors.
  • Joystick – We chose the 3D Extreme Pro from Logitech.  This model has a USB connection and several different axes and buttons which will possibly be used to implement other rover functionality.

Case Study:  Implementing Differential Steering With Joystick Control

Control Station Code

Rover Control Code

*** Please note that this code was taken from the full rover system code base developed for TitanRover at California State University, Fullerton.  I am but one of many contributors to this code base.***

We can easily take the joystick values, which are already in JSON format, and pass them across the network.  They are received on the other end and are processed to determine the correct values to send to our hardware.  While many of the exact numbers and value ranges are specific to our hardware setup, you can see how easily we can establish networked communication for direct control of our rover with Node.js.


The most common errors not related to electrical engineering were mostly hardware related.  We tried using the BeagleBone Black microcontroller initially but ran into a lot of configuration issues.  This platform lacked overall support which led us to switch to the Raspberry Pi 3.  This had much better support, was much easier to configure and was easily expandable to handle multiple PWM outputs with the Pi Hat.

Configuring your platform and making the calculations necessary to deal with PWM on the Raspberry Pi 3 was also a significant challenge.  While I did not touch upon this in this post, be aware that you will spend a significant amount of time ironing out the wrinkles in this part of the system


2 thoughts on “A Case Study In Robotics With Node.js

  1. I’ve also always been interested in using JS for robotics, since I as well think that the event-driven nature of JS should fit robotics well. However I do have some remarks about your solution.
    Firstly: a raspberry pi is NOT a microcontroller. If I would like rocksolid stability I would choose for a real microcontroller. Running a real os is cool, but adds complexity and a lot of uncontrollable factors.
    Secondly: you chose communication over HTTP. This would be very inefficient and impractical on a real low-bandwidth and high latency connection. Since HTTP is tcp based, there is a lot of mandatory two way communication going before even the real data is sent.
    Thirdly: I would prefer to have the firmware on the rover as dumb as possible. A lot of your calculations you could do on the controlling side, and only sent the calculated, lower-level data. When your rover is on Mars, it is a lot easier to fix a bug on the earth-side of things.
    Lastly: in mission-critical code I think defensive programming should be first-class citizens. So, validations and error handling should not be afterthoughts.

    Just some (hopefully) constructive feedback.

    1. Whoops. My mistake about the Pi. It is handy though having the whole OS for storing sensor data and being able to capitalize on hardware drivers and libraries to keep us from having to do it ourselves. We only have a few months to get the whole system running, so we’re trying to take advantage of as many existing solutions as possible.

      There are certainly a number of inefficiencies in this code. This set up was our first working prototype and kind of our proof of concept. I appreciate your feedback! We periodically review our design as a group and have already talked about what can be moved to our control station vs what is being calculated on the Pi. I’ll certainly bring up your points about error handling, validation, and other communication protocols at our next meeting.

      Thanks for your suggestions!

Leave a Reply

Your email address will not be published. Required fields are marked *