AppleScripting the Roomba.
"Professionally, I had used AppleScript Studio to create a multi-station shop floor information system for one of my clients, but this project was purely for fun."
The intent of this project was to use AppleScript Studio to create a Mac OS 10.4 - 10.5 application that would allow
me to send instructions to a Roomba Vacuum Cleaner Robot while I was away from home. The robot was fitted with bluetooth and a wireless security camera and would be able to drive around my home, take pictures and upload those pictures to a remote server. Besides the usual security pictures of doors and windows, I wanted to be able to check potential water leaks around my refrigerator, commodes, and washing machine. As a side benefit, I wanted to be able to drive the robot around while at home and develop simple multi-player games such as hide and seek, indoor road rally , and sponge ball hockey. The resources used are noted at the end of this page.
Hardware.
The Roomba used for this project was a Model 400. (Note 1)
From reading 'Hacking Roomba' by Tod E. Kurt (Notes 2 and 3) , I knew that I would have to build a conversion circuit to enable my Mac, via bluetooth, to send signals that the Roomba could interpret as commands. In addition, power had to be provided for the bluetooth device (Note 4) and wireless camera (Note 5). These circuits were placed in the vacuum motor and dust bin section of the Roomba.
Both the bluetooth device and wireless camera are connected to the same 9V power supply with clips so that they can be easily removed and used on other projects. To keep the circuit area clean, I removed the vacuum motor and brushes and interrupted the electrical feed to the brush motor. The camera signal receiver and digitizer (Note 6) sit near my Macintosh. I use my Mac's built in Bluetooth capabilities to connect to the Roomba and the digitizer connects via USB.
Software.
The Roomba Control application window is laid out in functional areas. The top row provides information about the bluetooth or other communication port used to send commands to the Roomba. The second row provides 'messages' about the action experienced from the command sent (Example: 'Roomba has left the dock!'). Any errors are reported there also. The third row provides sensor reading from the Roomba. 'Battery' is the reported charge as a % of fully charged. State is the charging state, such as 'Trickle'. Beacon reports if a virtual wall is detected.
The right column sends movement commands to the Roomba.
- 'Depart' instructs Roomba to back out of the charging dock.
- 'Dock' instructs Roomba to return to the dock.
- The right and left delta buttons instruct Roomba to spin in that direction for the number of degrees illustrated in the text box above the 'Angle' slider.
- The up and down delta buttons instruct Roomba to move forward (up) or backward (down)
- at the speed illustrated in the text box above the 'Speed' slider
- for a distance in millimeters illustrated in the text box above the 'Distance' slider.
The left column sends non-movement commands to the Roomba and provides sensor readings about how far Roomba reports it has moved or turned.
Connecting.
When Roomba Control is first launched it populates the 'Port' drop down with bluetooth devices set up in System Preferences. One can then select the device hooked up to the Roomba and make a connection with the 'Open Bluetooth Port' button. (Note: This same connectivity is available for 'tethered' or other non-bluetooth serial connections). In order to send and receive serial data in AppleScript, the application uses SerialPort X.osax (Note 7). If connected, the Status text box will advise such. Volts and the other status text boxes will be populated. MIDI notes will be loaded into Roomba and then Roomba will advise that it is 'Ready to roll!' in the 'Action' text box. If there is a connection failure the Status text box will advise trying again.
Driving.
Roomba movements when vacuuming are complex. Roomba movements from this application take that complexity and reduce it to just rotation and straight line movement. (For those of you who remember polar coordinates, this should seem reasonable.) So driving is just a matter of turn and go, turn and go.
If one watches the Roomba while driving, it becomes apparent that the angle requested, angle reported and what really happened are related but not the same. The surface it is driving on, the angle requested and the previous instruction determine whether or not the desired rotation becomes the actual rotation. Forward and backward motion are much more predictable unless Roomba is trying to climb over something such as a hardwood to carpet flooring change. The reported distance includes "spinning my wheels" even though there was no motion associated with it.
Roomba has right and left bump sensors that are monitored during forward motion. If just the right or left sensor is activated, Roomba Control will tell the Roomba to turn away from that side in 10 degrees spins until the sensor clears. If both sensors are activated, Roomba will back up 150 mm, turn right 10 degrees and go forward again. There is also a wall sensor on the right side. If it is activated, Roomba will spin 10 degrees left. There is no bump protection when driving backward.
External Scripts
Since I wanted the ability to provide Roomba with instructions to follow, I defined a place for the application to look for those instructions. Scripts must be in a folder named 'RoombaScripts' inside the start up folder on your Mac. Clicking on the selector next to 'Run Script Number' will populate the 'Action' text box with one script name at a time. The selector will sequence through all of the scripts available. When the desired one is listed in the text box, clicking on the button to the left of 'Run Script Number' will run that script. The button will remain green while he script is running.
Scripts can perform any operation that Roomba Control can do from the application window. One can write a script to connect to the Roomba, have it back out of the dock, turn 180 degrees, go forward 5,000 mm, turn right 90 degrees, take a picture, send the picture to mobileMe, turn right 90 degrees again, go forward 4500 mm, dock itself and close the communication port. And since it is an AppleScript, any script can be run from outside of the Roomba Control application in response to many Macintosh application events. They can be launched based on time of day, in response to an eMail or iChat request or whatever you have available. In addition they can go retrieve new instructions from mobileMe and deliver them to the 'RoombaScripts' folder to be run. The scripts can be saved as plain text - so if you just have a PC on the road - you can still write a new script for Roomba to follow.
Capturing Images
Since there are many different image capture applications available for the Mac, it would have been foolish to code for just one. The button 'Take Picture' runs a special script in the RoombaScripts folder called 'TakePicture.scpt'. In the same manner, the button 'Send Picture' runs 'SendPicture.scpt'. I use 'TheTube' (Note 6) to digitize the image received from the wireless camera.
Along with running the script, 'Take Picture' shows a panel in the Roomba Control application where the image can be placed by the 'TakePicture' script. Clicking on the square icon button among the delta buttons will hide the panel again. Since picture transmission is not over bluetooth, the Roomba does not need to be connected for pictures to be taken.
A fun driving routine is to preset the angle to 10 degrees and the distance to about 250 mm. One can then drive from the Roomba's 'view' by moving, taking a picture, figuring out where you are and moving again. Can you imagine a hide and seek game or an indoor "Roomba Road Rally" with time and distance points? (I can :)