using ROS with the Neato XV-11 in the year 2016

I've been meaning to do some ROS SLAM stuff for a while. There are a number of ways to do this, some more expensive than others, but one fairly straightforward option is just to use a Neato robot vacuum cleaner, which has a LIDAR sensor and a USB port with a fairly open debugging interface, which lets you get the raw feed off the sensor, and run the motors.

To run the robot, you need a mobile computer, (You can plug a mobile robot into a PC, but it tends to end poorly, for a number of pretty obvious reasons) so I borrowed my friend Tish's laptop. It had Windows installed on it, but I had a spare 2.5" SSD with Ubuntu 16.04 installed, so I tried just plugging it in, why not. To my immense surprise, it booted right up and worked fine. Even the screen brightness keys and wifi worked with zero configuration. I've been using Linux since 2003, and the fact that nowadays you can just blindly swap boot drives between computers and have them Just Work is fairly darn incredible. I remember having to hand-edit X11 config files just to use two monitors!

That was my last moment of pleasured surprise, because now I had to deal with ROS, which is a lovely example of the CADT model of software development. Most of the documentation I tried to follow was fragmentary or broken, mostly because ROS has gone through at least three different methods of "building a package" in the last 6 years. Adding to the problem was also that I refused to believe what I was reading. All the tutorials showed cloning from git repos and compiling from source. No, man, they're packages! Just show me how to download the precompiled packages! There's a package manager, right? With versioning, and dependency resolution? Right? Well, no. The canonical method of ROS development is downloading source files and compiling them.

Here's what I eventually cobbled together. First, install ROS following the directions on this page. (At the time of writing, the current stable release of ROS is Indigo) Even if you install ros-indigo-desktop-full it'll skip some stuff you'll need, so also do sudo apt-get install ros-indigo-map-server ros-indigo-amcl ros-indigo-move-base ros-indigo-teleop-twist-keyboard [1]

Now, create a new ROS project, set it as the working directory, move into the src/ directory, and clone some git repos.

mkdir neato cd neato rosws init source setup.bash cd src rosws set neato_driver --git https://github.com/mikeferguson/neato_robot rosws update

(You may need to run rosws update more than once.)

In that example I show cloning from the original repository, which is unmaintained. I had to fork it to get it to work with my robot, (Mike's code assumes the XV-11 has more motor properties than mine does, oddly, and my LIDAR sensor seems to need some time to spin up before returning data) but I didn't put my repo's URL in there since I, uh, haven't actually tested installing neato_robot from it.

cd .. catkin_make source devel/setup.bash

You would not believe how long it took me to figure out that you have to use the setup.bash in the devel/ folder, not the one in the project root. Anyway, if everything went right, you should be able to start up the node that actually talks to the robot. It expects to see it on /dev/ttyUSB0 [2]

All four of the following commands start four separate programs, and each need their own terminals. You can bg them if you want, but they print critical debugging information to the terminal.

roslaunch neato_node bringup.launch roslaunch neato_2dnav move_base.launch rosrun rviz rosrun teleop_twist_keyboard teleop_twist_keyboard.py

You can now drive the robot around with the keyboard in the teleop_twist terminal and watch what it thinks the world looks like in rviz .

By default the /map topic will show you the map Mike generated of his office in 2014, which probably won't be helpful for you. You can generate your own map using the instructions on this page, which, for a change, worked perfectly for me on the very first try. Here what the XV-11 decided the floorplan of my house looks like:

Tah dah!

[1]: If you don't install these packages, you'll get a cryptic error message along the lines of:

ERROR: cannot launch node of type [tf/static_transform_publisher]: can't locate node [static_transform_publisher] in package [tf] ERROR: cannot launch node of type [amcl/amcl]: can't locate node [amcl] in package [amcl]

Googling this error message will suggest that you need to delete your package and reinstall, which is both harrowing, (When I ran into this problem, I had already spent consecutive hours fighting with environment variable problems) and wrong.

[2]: Exasperatingly, Tish's laptop decided to enumerate it as /dev/ttyACM0 , so I had to go in and edit all the code that tries to talk to the wrong port. (Super exasperatingly, if you just change the line in neato_driver.py but not the launch file, it will crash out on port initialization, since the launch file passes in the port name as a parameter! That took forever to find. Single point of truth you bastards!)