roomba: iRobot Roomba/Create Interface for Racket
(require (planet neil/roomba:1:2)) |
1 Introduction
2 Logging
This package sends logging messages to the Racket logger, naming the messages as “roomba”. This includes debug level messages for each use of most of this package’s API. You can see these messages in the usual Racket ways, such as by using the -W argument to the command-line racket program, or via the DrRacket Log window.
3 Exceptions
struct
(struct exn:fail:roomba exn:fail (roomba))
roomba : roomba?
struct
(struct exn:fail:roomba:io exn:fail:roomba ())
struct
(struct exn:fail:roomba:mode exn:fail:roomba (expected actual))
expected : (listof symbol?) actual : symbol?
struct
(struct exn:fail:roomba:unsupported exn:fail:roomba ())
4 Protocols
It can talk with a beep, it has wall-sensing eyes
It can drag out your night with low-battery surprise
It will bring out the best that your programs can be
Oh, it doesn’t clean floors, but it’s always a Roomba to me
5 Models
> (decode-roomba-manufacturing-code "JEN041100610060012345")
'((manufacturer . jetta) |
(status . new) |
(model . 4110) |
(date . #(2006 10 6)) |
(rev . 0) |
(serial . 12345)) |
parameter
→
(hash/c (or/c exact-nonnegative-integer? symbol?) roomba-model?) (current-number-to-roomba-model-hash hasheqv) → void?
hasheqv :
(hash/c (or/c exact-nonnegative-integer? symbol?) roomba-model?)
Second Generation —
'second-generation 1100 'series-4000 'series-400 4000 400 4100 410 4105 416 4110 'sagelike-4130 'discolike-4130 4150 4170 4188 4210 4220 4225 4230 4260 500 Series —
'series-500 510 530 532 535 550 560 562 564 570 571 572 580 581 600 Series —
'series-600 610 620 630 650 660 Create —
'create 4400 4418
parameter
→ (or/c roomba-model? exact-nonnegative-integer? symbol?) (current-default-roomba-model model) → void? model : (or/c roomba-model? exact-nonnegative-integer? symbol?)
6 Roomba Object
parameter
(current-roomba roomba) → void? roomba : roomba?
7 Opening and Closing
parameter
(current-default-roomba-device path) → void? path : path-string?
procedure
(open-roomba [ #:name name #:model model #:device device #:set-current? set-current?]) → roomba name : (or/c #f string?) = #f
model : (or/c roomba-model? exact-nonnegative-integer? symbol?) = (current-roomba-default-model) device : path-string? = (current-default-roomba-device) set-current? : boolean? = #true
syntax
(with-roomba maybe-name maybe-model maybe-device body ...+)
maybe-name =
| #:name string? maybe-model =
|
#:model (or/c roomba-model? exact-nonnegative-integer? symbol?) maybe-device =
| #:device string?
8 Modes
'off —
Powered off or sleeping, and you probably need to manually press a button to wake it up. 'passive —
Sensors can be read, but cannot be controlled in this mode. 'safe —
Can be controlled. Lift and cliff sensors, or plugging into charger, do trigger switch to 'passive mode. 'safe is the usual mode for most purposes. 'full —
Can be controlled. Lift and cliff sensors, and charger plugging do not switch Roomba to 'passive mode. Switching to 'full mode also stops any battery charging. Don’t use 'full mode unless you’re sure you need to, and you can cover the safety risks other ways. 'closed —
This connection with the Roomba is closed, so this connection does not know the mode. The mode is changed to this when close-roomba is called, when with-roomba exits, or when an I/O error occurs when attempting to talk with the Roomba.
procedure
(set-roomba-mode [ #:roomba roomba] #:mode mode) → void? roomba : roomba? = (current-roomba) mode : (or/c 'safe 'full 'off)
9 Stock Behaviors
9.1 Cleaning
9.2 Docking
9.3 Demos
procedure
(start-roomba-demo [ #:roomba roomba #:demo demo]) → void? roomba : roomba? = (current-roomba) demo : symbol? = #f
'cover
Drive around to cover room.
'cover-and-dock
Cover room, until see Home Base, then dock.
'spot-cover
Cover room with spiral.
'mouse
Follows walls.
'figure-eight
Drive in figure-eight.
'wimp
Flees when bumped.
'home
(See Create manual.)
'tag
(See Create manual.)
'pachelbel
Plays Pachelbel's Canon for cliff sensors.
'banjo
Plays notes for cliff and bump sensors.
10 Driving
procedure
(set-roomba-drive [ #:roomba roomba] #:velocity-mm/s velocity-mm/s #:radius-mm radius-mm) → void? roomba : roomba? = (current-roomba) velocity-mm/s : integer? radius-mm : ((or/c #f integer?) #f)
procedure
(set-roomba-wheels [ #:roomba roomba] #:left-mm/s left-mm/s #:right-mm/s right-mm/s) → void? roomba : roomba? = (current-roomba) left-mm/s : integer? right-mm/s : integer?
11 Motors
procedure
(set-roomba-motors [ #:roomba roomba #:side-brush? side-brush? #:vacuum? vacuum? #:main-brush? main-brush?]) → void? roomba : roomba? = (current-roomba) side-brush? : boolean? = #false vacuum? : boolean? = #false main-brush? : boolean? = #false
12 Lights
procedure
(set-roomba-leds [ #:roomba roomba #:debris? debris? #:max? max? #:clean? clean? #:spot? spot? #:dock? dock? #:check? check? #:play? play? #:advance? advance? #:status status #:power-color power-color #:power-intensity power-intensity]) → void? roomba : roomba? = (current-roomba) debris? : boolean? = #false max? : boolean? = #false clean? : boolean? = #false spot? : boolean? = #false dock? : boolean? = #false check? : boolean? = #false play? : boolean? = #false advance? : boolean? = #false status : (or/c #f 'red 'green 'amber) = #false power-color : byte? = 0 power-intensity : byte? = 0
Variable
Labels
Series
debris?
Dirt Detect, Dirt Alert, Debris
2nd, 500, 600
max?
Max
2nd
clean?
Clean
2nd
spot?
Spot
2nd, 500, 600
dock?
Dock
500, 600
check?
Check Robot
500, 600
play?
Play
Create
advance?
Advance
Create
status
Status
2nd
power-color,
power-intensity
Power (Clean)
2nd, 500, Create
13 Sound
| ‹song-language› | ::= | ( ‹note›+ ) |
| ‹note› | ::= | ‹frequency› |
|
| | | ( ‹frequency› ‹duration› ) |
| ‹frequency› | ::= | symbol? |
|
| | | number? |
| ‹duration› | ::= | whole |
|
| | | w |
|
| | | half |
|
| | | h |
|
| | | quarter |
|
| | | q |
|
| | | number? |
'(b a g a b b (b h) a a (a h) b d (d h))
procedure
(compile-roomba-song [ #:roomba roomba #:song-number song-number] #:song-language song-language) → roomba-song? roomba : roomba? = (current-roomba) song-number : roomba-song-number? = 0 song-language : roomba-song-language?
procedure
(store-song-on-roomba [ #:roomba roomba #:song-number song-number] #:song song) → void? roomba : roomba? = (current-roomba) song-number : roomba-song-number? = 0 song : (or/c roomba-song-language? compiled-roomba-song?)
procedure
(play-song-on-roomba [ #:roomba roomba #:song-number number]) → void? roomba : roomba? = (current-roomba) number : roomba-song-number? = 0
14 Sensors
procedure
(read-roomba-sensors [ #:roomba roomba #:packet-code packet-code]) → (listof (cons/c symbol? any/c)) roomba : roomba? = (current-roomba) packet-code : (or/c #f exact-nonnegative-integer?) = #f
> (read-roomba-sensors #:packet-code 1)
((dirt-detect-right . 0) |
(dirt-detect-left . 0) |
(side-brush-overcurrent? . #f) |
(vacuum-overcurrent? . #f) |
(main-brush-overcurrent? . #f) |
(drive-right-overcurrent? . #f) |
(drive-left-overcurrent? . #f) |
(virtual-wall? . #f) |
(cliff-right? . #f) |
(cliff-front-right? . #f) |
(cliff-front-left? . #f) |
(cliff-left? . #f) |
(wall? . #f) |
(bump-right? . #f) |
(bump-left? . #f) |
(wheeldrop-right? . #f) |
(wheeldrop-left? . #f) |
(wheeldrop-caster? . #f)) |
> (read-roomba-sensors #:packet-code 2)
((angle . 0) |
(distance . 0) |
(max-button? . #f) |
(clean-button? . #f) |
(spot-button? . #f) |
(power-button? . #f) |
(remote-control-command . 255)) |
> (read-roomba-sensors #:packet-code 3)
((battery-capacity . 973) |
(battery-charge . 889) |
(battery-temperature . 30) |
(battery-current . -176) |
(battery-voltage . 13888) |
(battery-charging-state . not-charging)) |
> (read-roomba-sensors)
((requested-left-velocity . 0) |
(requested-right-velocity . 0) |
(requested-radius . 0) |
(requested-velocity . 0) |
(number-of-stream-packets . 0) |
(song-playing? . #f) |
(song-number . 0) |
(oi-mode . safe) |
(internal-charger? . #f) |
(home-base-charger? . #f) |
(cargo-bay-analog-signal . 0) |
(digital-input-0? . #f) |
(digital-input-1? . #f) |
(digital-input-2? . #f) |
(digital-input-3? . #f) |
(device-detect? . #f) |
(cliff-right-signal . 1029) |
(cliff-front-right-signal . 1276) |
(cliff-front-left-signal . 960) |
(cliff-left-signal . 1032) |
(wall-signal . 0) |
(battery-capacity . 2702) |
(battery-charge . 2696) |
(battery-temperature . 25) |
(battery-current . -169) |
(battery-voltage . 13554) |
(battery-charging-state . not-charging) |
(angle . 0) |
(distance . 0) |
(max-button? . #f) |
(clean-button? . #f) |
(spot-button? . #f) |
(power-button? . #f) |
(remote-control-command . 255) |
(infrared-byte . 255) |
(dirt-detect-right . 0) |
(dirt-detect-left . 0) |
(side-brush-overcurrent? . #f) |
(vacuum-overcurrent? . #f) |
(main-brush-overcurrent? . #f) |
(drive-right-overcurrent? . #f) |
(drive-left-overcurrent? . #f) |
(virtual-wall? . #f) |
(cliff-right? . #f) |
(cliff-front-right? . #f) |
(cliff-front-left? . #f) |
(cliff-left? . #f) |
(wall? . #f) |
(bump-right? . #f) |
(bump-left? . #f) |
(wheeldrop-right? . #f) |
(wheeldrop-left? . #f) |
(wheeldrop-caster? . #f)) |
14.1 Sensor Packets
Packet Code
Contains Packets
Protocols
0
7 - 26
all
1
7 - 16
all
2
17 - 20
all
3
21 - 26
all
4
27 - 34
5
35 - 42
6
7 - 42
Packet Code: 7 Protocols: all |
| |
bump-right? |
| boolean? |
bump-left? |
| boolean? |
wheeldrop-right? |
| boolean? |
wheeldrop-left? |
| boolean? |
wheeldrop-caster? |
| boolean? |
Packet Code: 8 Protocols: all |
| |
wall? |
| boolean? |
Packet Code: 9 Protocols: all |
| |
cliff-left? |
| boolean? |
Packet Code: 10 Protocols: all |
| |
cliff-front-left? |
| boolean? |
Packet Code: 11 Protocols: all |
| |
cliff-front-right? |
| boolean? |
Packet Code: 12 Protocols: all |
| |
cliff-right? |
| boolean? |
Packet Code: 13 Protocols: all |
| |
virtual-wall? |
| boolean? |
Packet Code: 14 Protocols: all |
| |
side-brush-overcurrent? |
| boolean? |
vacuum-overcurrent? |
| boolean? |
main-brush-overcurrent? |
| boolean? |
drive-right-overcurrent? |
| boolean? |
drive-left-overcurrent? |
| boolean? |
Packet Code: 15 Protocols: all |
| |
dirt-detect-left |
| boolean? |
Packet Code: 16 Protocols: all |
| |
dirt-detect-right |
| boolean? |
Packet Code: 17 Protocols: all |
| |
remote-control-command |
| byte? |
infrared-byte |
| byte? |
Packet Code: 18 Protocols: all |
| |
max-button? |
| boolean? |
clean-button? |
| boolean? |
spot-button? |
| boolean? |
power-button? |
| boolean? |
Packet Code: 19 Protocols: all |
| |
distance |
| exact-integer? |
Packet Code: 20 Protocols: all |
| |
angle |
| exact-integer? |
Packet Code: 21 Protocols: all |
| |
battery-charging-state |
| (or/c #f 'not-charging 'charging-recovery 'charging 'trickle-charging 'waiting 'charging-error) |
Packet Code: 22 Protocols: all |
| |
battery-voltage |
| exact-nonnegative-integer? |
Packet Code: 23 Protocols: all |
| |
battery-current |
| exact-integer? |
Packet Code: 24 Protocols: all |
| |
battery-temperature |
| signed-byte? |
Packet Code: 25 Protocols: all |
| |
battery-charge |
| exact-nonnegative-integer? |
Packet Code: 26 Protocols: all |
| |
battery-capacity |
| exact-nonnegative-integer? |
Packet Code: 27 Protocols: COI |
| |
wall-signal |
| exact-nonnegative-integer? |
Packet Code: 28 Protocols: COI |
| |
cliff-left-signal |
| exact-nonnegative-integer? |
Packet Code: 29 Protocols: COI |
| |
cliff-front-left-signal |
| exact-nonnegative-integer? |
Packet Code: 30 Protocols: COI |
| |
cliff-front-right-signal |
| exact-nonnegative-integer? |
Packet Code: 31 Protocols: COI |
| |
cliff-right-signal |
| exact-nonnegative-integer? |
Packet Code: 32 Protocols: COI |
| |
digital-input-0? |
| boolean? |
digital-input-1? |
| boolean? |
digital-input-2? |
| boolean? |
digital-input-3? |
| boolean? |
device-detect? |
| boolean? |
Packet Code: 33 Protocols: COI |
| |
cargo-bay-analog-signal |
| byte? |
Packet Code: 34 Protocols: COI |
| |
internal-charger? |
| boolean? |
home-base-charger? |
| boolean? |
Packet Code: 35 Protocols: COI |
| |
oi-mode |
| (or/c 'off 'passive 'safe 'full byte?) |
Packet Code: 36 Protocols: COI |
| |
song-number |
| byte? |
Packet Code: 37 Protocols: COI |
| |
song-playing? |
| boolean? |
Packet Code: 38 Protocols: COI |
| |
number-of-stream-packets |
| byte? |
Packet Code: 39 Protocols: COI |
| |
requested-velocity |
| exact-integer? |
Packet Code: 40 Protocols: COI |
| |
requested-radius |
| exact-integer? |
Packet Code: 41 Protocols: COI |
| |
requested-right-velocity |
| exact-integer? |
Packet Code: 42 Protocols: COI |
| |
requested-left-velocity |
| exact-nonnegative-integer? |
14.2 Sensor Utilities
'left
'forward
'right
'spot
'max
'small
'medium
'large-or-clean
'pause
'power
'arc-forward-left
'arc-forward-right
'drive-setup
'send-all
'seek-dock
'force-field
'green-buoy
'green-buoy-and-force-field
'red-buoy
'red-buoy-and-force-field
'red-and-green-buoys
'red-and-green-buoys-and-force-field
15 Cargo Bay Connector
procedure
(set-roomba-digital-outputs [ #:roomba roomba #:digital-out-0? digital-out-0? #:digital-out-1? digital-out-1? #:digital-out-2? digital-out-2?]) → void? roomba : roomba? = (current-roomba) digital-out-0? : boolean? = #false digital-out-1? : boolean? = #false digital-out-2? : boolean? = #false
procedure
(set-roomba-pwm-low-side-drivers [ #:roomba roomba #:driver-0-voltage-fraction driver-0-voltage-fraction #:driver-1-voltage-fraction driver-1-voltage-fraction #:driver-2-voltage-fraction driver-2-voltage-fraction]) → void? roomba : roomba? = (current-roomba) driver-0-voltage-fraction : nonnegative-number? = 0 driver-1-voltage-fraction : nonnegative-number? = 0 driver-2-voltage-fraction : nonnegative-number? = 0
procedure
(send-roomba-ir-byte [ #:roomba roomba] #:byte byte) → void? roomba : roomba? = (current-roomba) byte : byte?
16 Cables
Obtain an iRobot Create, which is an educational/hobby platform variant of the Roomba, which does not include cleaning functionality, and use the included RS232-to-Roomba-mini-DIN cable. Then connect the RS232 cable to your PC, perhaps with an USB-to-RS232 adapter. Or, if you can obtain the no-longer-made iRobot Command module for the Create, you may be able to disregard RS232 and simply use an ordinary USB cable between the Command Module and a PC. The Create is available new, direct from iRobot (model 4400 without recharging for 130 USD, model 4418 with recharging for 220 USD). Note that neither of the Create models currently available new from iRobot contain the Command Module, although used ones often have it.
- Attempt to obtain an off-the-shelf cable/adapter, probably on the used market, since few new ones are currently available:
iRobot RS232-to-Roomba-mini-DIN cable (model 4814). These were once sold individually by iRobot for, we believe, 20 USD, without having to buy a Create. Now they are sold new only with a Create, perhaps because iRobot would prefer that people just used the Create for education projects. If you can find one of these cables, to plug it into a modern PC, you most likely also want a USB-to-RS232 adapter (approx. 10 USD).
iRobot USB-to-Roomba-mini-DIN cable. We have seen a product photo of these, but they are not currently sold by iRobot.
RoboDynamics RooStick, a USB-to-Roomba-mini-DIN adapter. Note that we believe these are no longer available new because it seems that RoboDynamics was developing its own robot platform and seems to have gone on hiatus. RoboDynamics did Roomba business as Roomba Dev Tools.
RoboDynamics Roo232, an RS232-to-Roomba-mini-DIN adapter. Like the RooStick, new Roo232 units are not available.
RoboDynamics RooTooth, a Bluetooth-to-Roomba-mini-DIN adapter. Sparkfun has a small quantity of some version of these (Sparkfun item DEV-10980, 100 USD). Some changes to this package might be necessary to work with any version of RooTooth. If you have a RooTooth, please contact the package author.
Element Direct Bluetooth Adapter Module (BAM), which provides a Bluetooth interface for the iRobot Create, but not the Roomba. It appears to be available currently from Acroname Robotics (part number I19-10542, 60 USD).
We’re working on getting a particular vendor to make some particular new off-the-shelf cables and adapters, but do not assume that these new products will appear soon. Please contact the author if you can help with this. - Make your own cable/adapter. A Web search will turn up many different examples of these that various people have made. To categorize these:
- Make your own cable/adapter that plugs into the mini-DIN connector that is on most Roombas and on the iRobot Create. You can find the pinout for this in iRobot Roomba Serial Command Interface (SCI) Specification, in section “Physical Connections,” on page 2. Note that this uses 5V TTL logic levels, so you can’t just wire it up to an RS232 port. Your options for connecting this to a computer include:
Convert it to RS232, using a voltage level converter, and wiring up a 25-pin or 9-pin D-sub connector.
Convert it to USB, such as using an FTDI chip.
Hook it up directly to 5V I/O pins on a Rasperry Pi, Arduino, or other low-power computer. This is more an option if the computer is onboard the Robot; otherwise you probably want to go to RS232 or USB first.
- Make your own cable/adapter that plugs into the Create’s Cargo Bay Connector, which is a 25-pin D-sub connector with a pinout that is specific to the Create. (Note that the same kind of connector traditionally is used for RS232 and for parallel printer port connectors on IBM PCs, but the connector on the Create is neither of those.) The Cargo Bay Connector is documented in document iRobot Create Owner’s Guide, in section “Cargo Bay Connector,” on page 10. Note that, in addition to providing a serial interface needed by this package, the Cargo Bay Connector also provides additional sensor inputs and considerable power, which could be used to power an onboard adapter or low-power computer. Options for using the Cargo Bay connector:
Build an RS232, USB, or Bluetooth interface for interfacing with an offboard or onboard PC. This is an option, but if you’re only going to use the serial interface, you might as well connect to the mini-DIN (see above) rather than the Cargo Bay Connector, so that your cable/adapter works with most Roombas rather than just the Create.
Build a serial-and-power interface for a Raspberry Pi, Arduino, or other low-power computer. We believe there is enough current to power a Pi plus USB devices like WiFi adapter, in addition to the Create itself. This onboard computer could then run your program on itself and/or provide a WiFi link to offboard computers.
17 Troubleshooting
Ensure that the serial cable or other interface is firmly attached in all places it could become loose.
If you built a serial interface using instructions found on the Web, be aware that some pinout diagrams for the mini-DIN were published with pins reversed. Double-check against different pinouts.
If you’re connecting to an iRobot Create using the Command Module, make sure that you follow the boot-time procedures documentd in the iRobot Command Module Owners Manual. Also note that the developers of this package have not yet tested use through the Command Module.
Consider whether you have the right device file for your #:device argument. For example, if you’re specifying device "/dev/ttyS0", maybe the correct device is "/dev/ttyS1", "/dev/ttyUSB0", or something else.
If you’re using a USB interface on the PC side, perhaps using a USB-to-RS232 adapter with an iRobot RS232-to-Roomba cable, check whether the USB device is actually recognized by the PC. On GNU/Linux, you can use the lsusb shell command to list recognized USB devices, and you can also check the syslog log files for the time that you plugged in the device.
If the PC’s serial port is an RS232 port on a laptop dock, consider that a hardware or operating system bug might be causing the serial port to “disappeared”. This has been known to happen with a ThinkPad T60 plugged into a dock, for example, and the solution in that case is to reboot the laptop while plugged into the dock.
On at least some Roomba models (including the 400), the Clean or Power button should be solid green before the Roomba can be accessed via this package. If button is not solid green, try pressing it, in hopes of it turning solid green. Be prepared to lift up the Roomba if pressing the button starts a clean cycle.
If the Roomba’s Clean or Power button is not solid green and pressing does not correct that, try removing and reattaching the cable from the Roomba’s serial port.
If all else fails, try removing the cable from the Roomba’s mini-DIN, removing the Roomba’s battery, waiting a few seconds, reattaching the Roomba’s battery, and finally reattaching the cable to the Roomba’s mini-DIN.
Consider that the Roomba is refusing to communicate because its battery desperately needs charging, even if it appears to have some charge left.
18 Known Issues
Needs initial testing, with different models.
Figure out why DrRacket is prompting for input in the Interactions pane under some unclear circumstances.
Create operations not yet implemented: Sensors (142) new sensors, Query List (149), Stream (148), Pause/Resume Stream (150) Script (152, 153, 154), Wait (155, 156, 157, 158).
Add more detailed documentation for sensors, such that the iRobot manuals are unlikely to be necessary for most purposes.
Finish adding support for Create operations.
Add support for any ROI features not in SCI, rather than limiting 500/600 series to 2nd generation features.
Test use of USB interface of Create Command Module, once we have a working one.
Improve how stdio error messages are handled when calling /bin/stty.
We might be able to do better waking of the Roomba, using RTS. However, we cannot test this at this time, since, on our test setup at the moment (Roomba 400, plugged into iRobot brand cable, plugged into RS232 port of ThinkPad dock), even example code does not wake the Roomba.
Any any special support needed for other off-the-shelf Roomba hardware interfaces, such as those by RoboDynamics. We are aware that some of them are reported to need special handling, but we do not presently have use of them for testing.
- A let-roomba-sensors would be nice, so you could do things like this efficiently on SCI (OI makes it easier):
(let-roomba-sensors (wall battery-charge distance angle) ...) We have an example but have not coded it yet, til we look more closely at the different OI specs. Until then, we expect that the form would expand to code that looked at the protocol at runtime, and did different optimizations for SCI, ROI and COI. Support a little bit more of Common Music Notation, especially for meter.
Add convenience for compiling and playing songs longer than 16 notes.
Test on Mac OS X.
Possibly add support for Microsoft Windows. Especially if Windows 7 and later have filesystem path devices for serial ports.
Put Raspberry Pi with WiFi onboard an iRobot Create. Hook up development tools so that Roomba programs can run onboard, on the Pi, as well as offboard on PC (say, in DrRacket for debugging), with the Pi gatewaying the OI protocol received over SSH WiFi.
19 History
- PLaneT 1:2 —
2013-09-01 Added sensor support for iRobot Create (aka protocol irobot-coi).
Added operations for iRobot Create: start-roomba-demo, stop-roomba-demo, set-roomba-wheels, set-roomba-digital-outputs, set-roomba-pwm-low-side-drivers, send-roomba-ir-byte.
Added more documentation for sensors.
The default parameter value of current-default-roomba-device has changed on some platforms, from "/dev/ttyS0" to "/dev/ttyUSB0", since we expect more people will be using a USB-to-RS232 adapter on Linux than a more direct RS232 port.
Added exception exn:fail:roomba:unsupported.
Documentation tweaks.
Title of package changed slightly.
- PLaneT 1:1 —
2012-08-19 Added section Cables. (Thanks to Jens Axel Søgaard for pointing out the need for this.)
Minor documentation tweaks.
- PLaneT 1:0 —
2013-08-18 Initial release. Still needs some initial testing with various different Roombas, and we are releasing now for that purposes.
20 Legal
Copyright 2013 Neil Van Dyke. This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See http://www.gnu.org/licenses/ for details. For other licenses and consulting, please contact the author.