Saturday, April 14, 2012

Using ROS (Robot Operating System) Electric with the Arduino





While I wait for parts (extra L293D chips) to improve the current usage on my dfrobot, I thought I would play around with using ROS and the Arduino. ROS provides several tools, mostly on the host side, that will improve visualization of data coming off the robot. Also has some other handy features for messaging so I will not have to do as much serial string parsing. The main web site for ROS is http://www.ros.org/wiki/. I started out following the installation instructions located at http://www.ros.org/wiki/ROS/Installation. Since I already use macports, the specific instructions I followed are at http://www.ros.org/wiki/electric/Installation/OSX/Macports.

The instructions were straight forward so I will not repeat them here. As usual, whenever I update macports it is a several hour process where lots of out of date things are downloaded and installed.  I did have one slight problem in one of the steps. The command:

rosinstall ~/ros "http://packages.ros.org/cgi-bin/gen_rosinstall.py?rosdistro=electric&variant=desktop-full&overlay=no"
Returned an error about tar returning an incorrect version:
ERROR in config: Unable to create vcs client of type tar for ~/ros: "tar --version returned invalid string: 'bsdtar 2.8.3 - libarchive 2.8.3'"
I was able to fix this by changing the link as to which tar was used:
  1. $ sudo rm /usr/bin/tar
  2. $ sudo ln -fsv /usr/bin/gnutar /usr/bin/tar
Then, the rosinstall command hung. For some reason, I had a version of rosinstall in /usr/local/bin. I am not sure how it got there. I used the full path to rosinstall to make sure that it was pulling in the right version. Something to be aware of in the future:

    1. /opt/local/bin/rosinstall ~/ros "http://packages.ros.org/cgi-bin/gen_rosinstall.py?rosdistro=electric&variant=desktop-full&overlay=no"
Several macports project dependencies were needed. A few times I needed to kill the python install and then run the sudo maports install manually. Apparently ros wants gnu tar and macports wants bsdtar. There must be an easier way around what I did. Then restarted the install script. When that was finished, I proceeded to test the installation. First thing I needed to do was add my machine name to /etc/hosts (which now has the line below for my machine name, yoshi, which is now an alias for localhost):
  1. 127.0.0.1 localhost yoshi
I was then able to run a few simple commands to start an ROS session:
  1. roscore > /dev/null &
  2. rosmake turtlesim
  3. rosrun turtlesim turtlesim_node &
  4. rosrun turtlesim turtle_teleop_key 
which let me use the mouse keys to drive a turtle around in a window (see below).



Once ROS was installed, I looked into how to get ROS and the Arduino to communicate. Turns out there is a package called rosserial that is used to send messages back and forth, see the link http://www.ros.org/wiki/rosserial. First I installed the packages:


  1. cd ~/ros
  2. source setup.bash
  3. hg clone https://kforge.ros.org/rosserial/hg rosserial
  4. export ROS_PACKAGE_PATH=~/ros/rosserial:$ROS_PACKAGE_PATH
Note this last step was not provided anywhere and took me a while to figure out. If you do not add the package to the ROS_PACKAGE_PATH then none of the ros commands will work. Next I needed to build rosserial. I do not usually compile aurduino code using macports (I use the Arduino.app) so I needed to install that first:
  1. cd ~/ros
  2. sudo port install avr-gcc 
  3. rosmake rosserial_arduino
  4. rospack profile
  5. roscd rosserial_arduino/libraries
  6. cp -R ros_lib /Applications/Arduino.app/Contents/Resources/Java/libraries
Next, I used one of the rosserial examples that reads out analog pins (see http://ros.org/wiki/rosserial_arduino/Tutorials/Arduino%20Oscilloscope):

  1. #include <ros.h>
  2. #include <rosserial_arduino/Adc.h>

  3. rosserial_arduino::Adc adc_msg;
  4. ros::NodeHandle nh;
  5. ros::Publisher p("adc", &adc_msg);

  6. void setup()
  7.   pinMode(13, OUTPUT);
  8.   nh.initNode();
  9.   nh.advertise(p);
  10. }
  11. void loop()
  12. {
  13.   adc_msg.adc0 = analogRead(0);
  14.   adc_msg.adc1 = analogRead(1);
  15.   adc_msg.adc2 = analogRead(2);
  16.   adc_msg.adc3 = analogRead(3);
  17.   adc_msg.adc4 = analogRead(4);
  18.   adc_msg.adc5 = analogRead(5);
  19.   p.publish(&adc_msg);
  20.   nh.spinOnce();
  21. }
Then I fired up a few ros commands (note the second command was needed to make sure the python serial interface was installed):
  1. roscore &
  2. sudo port install py26-serial
  3. sudo port install py26-matplotlib 
  4. sudo port install py26-wxpython
  5. rosmake rxtools --rosdep-install
  6. rosrun rosserial_python serial_node.py /dev/cu.usbmodem621 &
  7. rostopic list
  8. rxplot adc/adc0
Note that step #4 was simply to make sure the topics was being generated properly. These steps produced the plot shown below.


Turned out setting up ros to work with the Arduino was quite a bit of work. I think it will be worth it down the road though as it opens up a wide range of tools that can be used.

Good Luck!

No comments:

Post a Comment