I wanted to draw a live map showing the progress of the Lego Street View car as it drove outside. The dGPS sensor does a great job of plotting the car’s location, and the NXTBee provides a perfect high-speed long-distance serial link back to my Mac at home base. But how to display a live map that is updated with the car’s location in real-time? What platform should I use to develop a user-interface to the control the car and to plot map data?

That’s when I turned my attention to the Processing language. Processing is an open-source environment for interactive animation and image display. It’s a scripted language that is based on Java. Processing has inspired an active community of collaborators and animators. It comes with a rich set of graphics primitives, and the Processing community is active in creating new libraries.

Processing is an attractive solution for controlling the Street View car because:

  1. It’s multi-platform and runs on Windows, Mac OSX and Linux.
  2. It is based on Java, so comes with the expressive power of Java and object-oriented programming.
  3. It simplifies the tasks involved in building an interactive user interface. Processing is targeted at artists and others who need to quickly create animations or graphics but who do not have time to learn OpenGL.
  4. It has native support to communicate with serial port devices. And as we know from my previous tutorial the NXTBee is simply a serial device hooked onto the NXT.
  5. It can call web-services, and retrieve content over the web. This is particularly useful for retrieving map data.

Putting it all together Processing is the ideal candidate to build my front-end to control the Street View Car. Of course, feel free to email me and tell me why your favourite programming environment is far superior in every way 🙂

Sending GPS data from the NXT using NXTBee

My previous tutorial showed how to receive data from the NXTBee using an XStick or Sparkfun Explorer USB board. For this project I’ve adapted the standard dGPS demo program from Dexter Industries to send GPS coordinate data over the NXTBee to my PC. This program was originally written by Xander Soldaat; Xander’s website has great examples of how to interface with the Dexter Industries sensors.

A small modification is all it takes to send the GPS data over the NXTBee connected to Port 4 of my NXT (this code is in NXC, the principle is the same for RobotC):


string s = "";
s = s + FormatNum("%d", utc);
s = s + ",";
s = s + FormatNum("%d", longitude);
s = s + ",";
s = s + FormatNum("%d", latitude);
s = s + ",";

if (linkstatus)
s = s + “[UP]”;
else
s = s+”[DOWN]”;

SendRS485String(s);

and that’s it. The NXT will happily stream the coordinates in the format <UTC,longitude,latitude,status> to any XBee radio listening nearby.

You can download my gpsxbee.nxc program written in NXC. It will also require the DGPS-driver.nxc driver to communicate with the dGPS device on Port 1. This code is written in NXC but is easily ported to other platforms.

Receiving data from the NXTBee in Processing

The Processing serial class supports communication with serial devices on PC/Mac/Linux, and does a good job of hiding the details involved in connecting to a serial port on each platform. The example code in the serial class tutorial is pretty self-explanatory.

Processing abstracts the serial devices to hide the underlying implementation details. It scans the available serial devices and returns a list of devices. The Serial.list() function returns a list of serial devices attached to my Mac. The first element in that list (i.e. element 0) corresponds to the XStick attached to the Mac.

Take a look at the output on the Processing console below. You’ll see each serial device listed in turn, and /dev/tty.usbserial-000022226 in slot 0 is the XStick. My XStick is configured to run at 115200 baud (see my previous tutorial on how to do this).

Download and run the NXTBeeRawSend example from the Dexter Industries website on the NXT. This program simply sends a string out over the NXTBee which will be received by the XStick on the Mac. Run this simple Processing sketch to print the string received on the console:

import processing.serial.*;

// The serial port:
Serial myPort;

void setup() {
// List all the available serial ports:
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 115200);
}

void draw() {

while (myPort.available() > 0) {
String inBuffer = myPort.readString();
if (inBuffer != null) {
println(inBuffer);
}
}
}

The output should look something like this:

Each line printed on the Processing console shows the time (in UTC), the longitude and the latitude as a decimal integers scaled up by 1,000,000.

Plotting maps in Processing

Now we know we can receive data from the dGPS via the NXTBee in Processing, how do we display that on a map? After some searching I came across the amazing modest-maps library written by Tom Carden. Tom has done a superb job of simplifying the job of grabbing and displaying maps in Processing. In fact there is practically no code required!

Modest Maps can be downloaded from the github repository. All that is required is to follow the instructions in the appropriately named INSTALL file. Create a directory in the Processing sketch folder named libraries, and copy the modestmaps folder in there.

Now all we need to do is make a small modification to Tom’s example code to read data from the serial port and parse the latitude and longitude values to display a point on the map:

if (myPort.available() > 0) {
String inBuffer = myPort.readString();

if (inBuffer != null) {
println(inBuffer);

String[] splitted = split(inBuffer, ‘,’);

if(splitted.length == 4) {
int utc = int(splitted[0]);
int latitude = int(splitted[1]);
int longitude = int(splitted[2]);

// map.setCenterZoom(new Location(longitude, latitude), 17);

float flat = float(latitude) / scale;
float flong = float(longitude) / scale;

Location car = new Location(flong, flat);
Point2f p = map.locationPoint(car);

fill(0,255,128);
stroke(255,255,0);
ellipse(p.x, p.y, 10, 10);
} else {
println(“malformed message from NXTBee”);
}
}

The readString() method reads a newline terminated string from the serial port. Then the split() function splits the string into four sub-strings. The vaues for the UTC, latitude and longitude are extracted as integers, converted to floats and then scaled down by a factor of 1 million. Finally the latitude and longitude values are mapped onto a point location on the screen displaying the map and a small ellipse is drawn at that point.

You can download my Processing sketch lsvc2.pde that integrates the mapping with the reading code.

With gpsXbee.nxc running on the NXT you should see a small ellipse drawn over the current location of the NXT (which is hopefully sitting right beside you!) As the NXT moves around the dot on the screen will move too.

Next step is to improve the display code to plot a path in real-time of the NXT’s movements.. Stay tuned!