Hacking Roomba

Roomba Tilt Control with MacBook & Perl

This project shows you how to use the built-in tilt sensors of the MacBook to control a Roomba. Since Perl hasn’t been used to program a Roomba yet, it seemed like a fun task to show that it could be done (and pretty easily too).


(revver link)


Download it

You only need two bits of software not already on your Mac:
AMSTracker
roomba-tilt.pl
Download them both, put them both in your PATH and try it out. But first you might want to read on to see how it works.

Measuring Tilt

Apple MacBooks have integrated 3-axis accelerometer called the Sudden Motion Sensor (SMS, previously Apple Motion Sensor, AMS). Normally this is used to detect when the laptop is dropped so it can shut down the hard drive to prevent damage. But the SMS can be accessed programmatically and used to measure tilt.

Amit Singh has a wonderful book out called Mac OS X Internals where he goes into great detail about the SMS. He’s also created several programs that use the accelerometer data. The one used in this project is the command-line program AMSTracker.

When AMSTracker is run, it outputs three columns of numbers, one for each axis of accelerometer data. AMSTracker can also be run in a “scrolling” mode where it outputs new data periodically. This is the mode used in this project. The output then looks like:

laptop% AMSTracker  -s -u 1
AMS hardware present and initialized
  -7   -1    0
  -6   -1    1
  -6   -1    2
  -5   -1    1
  -6   -1    2
  -5   -1    2
  -7   -1    0

It’s easy for Perl to parse such stuff. The regex to get those three values is “/(-?\d+)\s+(-?\d+)\s+(-?\d+)/“.

Controlling the Roomba from Perl

On Mac OS X, like other Unixes, serial ports appear as ordinary files. And just like any other files, they can be read from and written to. Perl’s whole reason for being is reading and writing files so it’ll be a snap for it.

But wait, how do we set the serial parameters like baud rate and so on? Files don’t have these kinds of attributes. That’s where the program “stty” comes in. Stty sets the various options on a “terminal device” (aka serial port). Figuring out the magic stty incantation needed to let the serial port work with the Roomba is laborious so will just be presented here:

 demo% export PORT=/dev/tty.RooTooth-COM0-1
 demo% stty -f $PORT 57600 raw -parenb -parodd cs8 -hupcl -cstopb clocal

This command is issued by the “roomba_init()” function in the Perl script before it opens the “file” that is the serial port.

Once the port/file is open, functions like “roomba_drive()” and “roomba_stop()“in the script just print to the open file descriptor. If you wanted to read the sensors, you would read from the file descriptor.

Converting Tilt Data to Roomba Commands

The tilt data is essentially two numbers that vary between -127 and +127. One number corresponds to back-n-forth tilt motion of the laptop while the other corresponds to left-right tilt. A simple linear function can convert between the tilt data space and the velocity/radius space the Roomba expects. This is the ‘proportional’ mode of operation, where the degree of tilt affects the speed or angle of the Roomba.

The code implements two special cases of proportional control to make it easier to use:
– if laptop is flat (in the deadzone), send “roomba_stop()
– if only tilted left-right, send “roomba_spinleft()” or “roomba_spinright()“.

Another mode called “fourway” or “d-pad” mode turns the tilt data into a four-state switch: forward, backward, spinleft, spinright, sort of like an old Nintendo D-pad controller. It does this by defining a “deadzone” in the center and only if you tilt in one direct enough to escape this zone does it count as a valid motion. In this mode, controlling the Roomba is easier but you can’t get as precise of positioning.

Usage

To use roomba-tilt.pl, the only required argument is the path to the serial port the Roomba is connected to. This serial can either be a RS-232 serial tether or a Bluetooth adapter as shown in the video. The full usage is:

laptop% ./roomba-tilt.pl 
Usage: roomba-tilt.pl -p <serial_port> [options]

Options:
  -p <serial_port>      Serial port of Roomba (e.g. "/dev/tty.RooTooth")
  -fourway              Change to D-pad mode instead of normal proportional
  -fullmode             Turn off Roomba safety mode (watch out!)
  -d|-deadzone <n>      Set center deadzone (normally 15)
  -u|-update_rate <f>   Set update rate in seconds (normally 0.25) 
  -tracker <path>       Set AMSTracker path (if not in PATH)
  -v|-verbose           Output internal info
  -h|-help              This screen

Running it in verbose mode is interesting because you can see the data sent from AMSTracker and the drive commands sent to the Roomba.

laptop% ./roomba-tilt.pl -p /dev/tty.RooTooth-COM0-2  -v
roomba_init: /dev/tty.RooTooth-COM0-2
roomba-tilt.pl running , press ctrl-c to exit
x:-2, y:-1, z:28
roomba_drive: -140,-1250
x:13, y:0, z:25
roomba_drive: -125,1140
x:39, y:0, z:22
roomba_drive: -110,880
x:59, y:0, z:21
roomba_drive: -105,680
x:23, y:0, z:40
roomba_drive: -200,1040
x:-13, y:-1, z:20
roomba_drive: -100,-1140
x:-17, y:-1, z:17
roomba_drive: -85,-1100
x:-20, y:-1, z:-5
roomba_drive: 110,65535

Issues and Improvements

As you play with AMSTracker or roomba-tilt.pl, you’ll see how the tilt data will flop from +/-127 to -/+127. In roomba-tilt.pl, this causes the Roomba to go from making hard left to a hard right (or vice versa). The code currently doesn’t attempt to smooth the data to eliminate these jumps. You could write a filter that does a little analysis on the data and if it does something unexpected (like the jump), it calms the data down before sending it to the Roomba.

22 comments

22 Comments so far

  1. wachunei December 8th, 2006 8:39 pm

    is it possible to make exactly this but with the WiiMote, trought the macbook/pro?

  2. todbot December 8th, 2006 8:46 pm

    wachunei, I think it should be possible. I don’t have a Wii yet so I can’t try it out. :(

  3. Eddie December 9th, 2006 8:21 pm

    I saw the video on Digg, and my first thought was Wiimote as well. I didn’t realize Roomba’s had such a following for hackery, and will definitely be checking this book out. Thanks, and very, very cool hack.

  4. […] If there ever was a hack that could be assured of a mention on Engadget, it would be this: the MacBook tilt-sensor controlled Roomba. Once again utilizing the accelerometer inside each and every MacBook, the guys over at Hacking Roomba managed to get a Bluetooth-enabled Roomba to listen to the Mac’s tilting orders. Practicality isn’t the aim here — lets face it, the Roomba will willingly clean a floor on its own. Instead, it’s a mix of ingenuity and “because we can” mentality that draws us to these sorts of projects. That and the possibilty of freaking out the Engadget HQ house cat, of course. […]

  5. […] If there ever was a hack that could be assured of a mention on Engadget, it would be this: the MacBook tilt-sensor controlled Roomba. Once again utilizing the accelerometer inside each and every MacBook, the guys over at Hacking Roomba managed to get a Bluetooth-enabled Roomba to listen to the Mac’s tilting orders. Practicality isn’t the aim here — lets face it, the Roomba will willingly clean a floor on its own. Instead, it’s a mix of ingenuity and “because we can” mentality that draws us to these sorts of projects. That and the possibilty of freaking out the Engadget HQ house cat, of course. […]

  6. Le Marquis December 11th, 2006 7:24 am

    I’ve seen it before with a puppet like script on the desktop, great work though! I really like the blutooth insertion of it…

    What’s the next thing? You could make it safer by combining the roomba to a cellphone, so when your laptop gets stolen your celphone rings or you receive a message.
    Or even beter by using the new caller ID location receiver that’s on the net to lacate your laptop. One minor detail is that the laptop has to be on during that theft ofcourse…

    LM

  7. Adam December 11th, 2006 7:54 am

    Cool hack guys, I’m really looking forward to trying this out!

  8. rtideas December 11th, 2006 10:09 am

    Very cool.

    Next add a camera and see from the Roomba.

  9. CSL Blog » Mac Book Pro as Roomba Remote December 11th, 2006 5:06 pm

    […] Mac Book Pro as Roomba Remote: Alpha Geeks have a new do-it-yourself project to terrorize the cat with: use Perl with a MacBook Pro’s Sudden Motion Sensor to control a Roomba. Wired’s Cult of Mac cites the original site which has other fun ways to pimp your Roomba . This gets my award for most inefficient use of tech, time, and training for the week. It won’t freak out her cat nearly as much as a RoboRaptor on Roam mode. ” « Beet.TV: the root to the media revolution   […]

  10. […] Hvad er hurtigst? At svinge støvsugeren i hjemmet eller sætte sig til at programmere lidt kode således at man kan bruge sin MacBook Pro som fjernbetjening til støvsugerrobot. Se på dette link hvordan man kan bruge Motion Sensor i MacBook Pro til at styre en støvsugerrobot. […]

  11. Suicide Bots December 17th, 2006 7:02 pm

    […] One of the cooler hacks on the site is a tilt-control Roomba. It uses the built-in acceleration sensors in a Mac Powerbook. (But you know it’s only a matter of time before it gets Wii-mote controlled.) Accelerate the positive, you movers and shakers! […]

  12. […] Since Craig and I first created the PowerBook Puppet back at the end of 2005, there’s been quite a lot going on with the Sudden Motion Sensors (SMS) on the Apple laptops – for instance the the SmackBook and the Roomba Tilt Control. […]

  13. Kerl June 9th, 2007 1:32 pm

    how can i calibrate my SMS?
    now its:
    x -17 y 0 z 0
    Can anyone help?

  14. As ArtNum » Aspirer avec son Mac February 16th, 2008 3:47 am

    […] Le Projet et ses explications […]

  15. bob March 30th, 2008 4:44 pm

    it would be cool if you could do the same with an iphone!

  16. Pipo May 23rd, 2008 3:37 pm

    Have you had any problems with the script lately? I’ve installed it, and it can read my macbook pro’s tilt data, but the roomba doesn’t do anything. Other programs to control roomba from mac work fine (like roombamidi2). I use the official irobot serial cable + keyspan adaptor.
    Any help would be appreciated.

  17. todbot May 23rd, 2008 4:02 pm

    Hi Pipo,
    Unfortunately, all my Roomba stuff is in storage so I can’t try stuff out. Maybe the AMSTracker program has slightly different output now that the Perl script can’t parse?

  18. koray July 11th, 2008 5:06 pm

    cant we eliminate the flipping of the numbers (hence the roomba) when we go beyond those limits in software? we could damp the too sudden accelerations, no?

  19. todbot July 11th, 2008 5:20 pm

    Yup, you could do all those things. Simple averaging filters are easy (save the last N readings, add them all up, divide by N) Anomaly detectors are also pretty easy (large deviations from the average can be ignored).

    The trade-off one has to make when inserting filtering between input devices and output is the lag inherent to such systems. A simple averaging system can be slow to act on a sudden true change in input (“turn left NOW!”) and anomaly detectors can filter out a sudden true change (“hit the brakes we’re gonna crash!”)

    There’s a whole school of engineering called control theory that deals with these things.

    But mostly you can just do a simple average and it works fine.

  20. […] Hacking Roomba: Controlar la roomba desde un MacBook […]

  21. brianpratt October 23rd, 2009 8:06 am

    I am working on a similar app for the iPhone. Anyone interested in testing it before I release it to the App Store, contact me at:
    roomba `at’ brianhpratt ‘dot` net

  22. […] I saw this article at Hackingroomba.com, I jumped for joy. MacBooks + Roomba = love? Hacking Roomba has written a Perl […]

Leave a reply