iRobot recently released an API for programming the Roomba vacuumming robot. It's a pretty reasonable little robot: motors, encoders, bumpers, a couple of IRs, good battery life, and, best of all, cheap.
Several interesting things have been done so far in the Roomba hacking community. I figured I would try building a map. Besides the obvious technical appeal of mapping with a cheap consumer-grade robot, there's an opportunity to improve the performance of the Roomba by allowing for more sophisticated cleaning strategies (not to mention giving the poor robot a better chance of finding its way back to the docking station).
This page describes my proof-of-concept of a mapping Roomba robot.Contents:
What I used:
We need 5V to power the Gumstix and the URG laser. I chose to slap on a 12V battery that was close at hand and run it through a 12V/5V DC/DC converter. You can instead draw battery voltage (nominal 14.4V, I believe) from the Mini-DIN port on the Roomba.
The serial interface to the Roomba operates at TTL level (0V/5V), not the RS232 level (-12V/+12V) used by serial ports on most computers. Fortunately, the waysmall STUART board allows us to tap into the serial lines at TTL level, before they go through the TTL/RS232 level shifter. I found a Mini-DIN cable in the lab, cut it in half, and soldered onto the send, receive, and ground solder pads of the STUART on the back of the waysmall board. I could then talk to the roomba over /dev/ttyS2. Check the specs on the waysmall board and the Roomba programming manual for the wiring details.
The serial connection to the URG laser operates at normal RS232 levels. So I plugged the cable that comes with the URG through a NULL modem adapter, a gender changer, and the DB9/Mini-DIN NULL modem cable that Gumstix sells into the FFUART port on the waysmall board (yes, there's an unnecessary straight-to-NULL-and-back-to-straight change going on there; I am not optimizing for cable length :). To use that port, I modified /etc/inittab to turn off the getty that normally runs, and gave init the old kill -HUP 1. Then I was able to control the laser over /dev/ttyS0.
Basically, I just velcroed everything together. The battery sits upright roughly in the middle of the robot. The laser sits just in front and is velcroed to the robot and the battery (for extra stability :). The Gumstix is velcroed to the back of the battery, and the cables are zip-tied together.
Here's what my Roomba looks like (click for full-size):
No points for style, but it works.
After taking a run down the hallway, I pulled the data log onto my desktop machine and ran it through a Player SLAM driver. I used an SRI proprietary SLAM system, but there are a number of Open Source SLAM systems available online that can read (possibly with some munging) Player log files.
The odometry is pretty bad, but still informative enough for the SLAM system to determine the robot's real trajectory.
Here's the resulting occupancy grid:
When I get some more time, I'll do a longer run to test loop closure.