How to Connect Arduino to ROS

How do we connect ROS to an actual embedded system that operates in the real, physical world? I’ll show you how to do this now using Arduino

Arduino is a popular microcontroller for building electronics projects. A microcontroller is a bunch of circuits that do stuff, such as accepting data input, doing calculations, and producing output. With respect to robotics development, Arduino would be the “brain” of a robot.

Fortunately, ROS can integrate with Arduino. We will install some software that will enable your Arduino to be a bonafide ROS node that can do everything a normal node can do, such as publish and subscribe to ROS messages.

Here are the official steps for interfacing Arudino with ROS, but I’ll walk you through the process below.

Table of Contents

Directions

How to Install Arduino on Ubuntu Linux

First, let’s download the Arduino IDE (Linux 64 bit version) to our computer. I will follow these instructions for installing the Arduino IDE on Ubuntu. Go to this website, and download the software:

63-download-arduino-file

Save the file. It will be saved as tar.xz format to your Downloads folder.

Open a new terminal window.

Move to the Downloads folder (or wherever you saved the tar.xz file).

cd Downloads
64-change-to-downloads-directory

Run this command to extract the files (substitute FILENAME with the name of the file you just downloaded):

tar xvf <FILENAME>

In my case, I will run:

tar xvf arduino-1.8.10-linux64.tar.xz

You will see a bunch of file names print out to your screen.

If you type the dir command, you will see the new folder. Let’s move that folder to the home directory. You can cut and paste it into the home directory using the file manager (the file cabinet on the left of the screen. Go there, then go to the Downloads folder, cut the file and paste it into the Home directory.

65-downloads-dir
66-arduino-in-home-directory

Now open up a new terminal window and type:

cd arduino-1.8.10

Type dir to see what files are inside.

67-what-files-are-inside

To install the IDE, type:

sudo ./install.sh
68-install-ideJPG

Here is the output. You should see a “done” message. A desktop icon will also be present. You can activate it by clicking on it and allowing permissions at the prompt.

Now, get your Arduino and connect it to the USB port on your computer.

Start Arduino by going into a new terminal window and typing:

arduino

You might see an error message like this:

69-arduino-startupJPG

Failed to load module “canberra-gtk-module” … but already installed

To resolve that error, press CTRL+C and close the terminal window.

Open a new terminal window, and type:

sudo apt-get install libcanberra-gtk-module

Now open a new terminal window, and type:

arduino

Let’s see if everything works by trying to blink the light-emitting diode (LED) on your computer.

Go to File – > Examples -> 01.Basics, and choose Blink.

Try to upload that code to your Arduino by clicking the right arrow on the upper left of your screen.

70-right-arrow-to-uploadJPG

You should see an error about the “Serial port not selected”.

Close out of your Ubuntu Virtual Machine completely. Do not save the state.

Set Up the Serial Port for VirtualBox With Ubuntu

Assuming you are using Windows, go to your Device Manager. Search for that in your computer in the bottom left of your desktop.

Under Device Manager, you should see Ports (COM & LPT). Note that Arduino is port 3 (Make sure your Arduino board is connected to the USB port of your computer).

71-arduino-com-portJPG

Open your VirtualBox.

Click Settings and go down to Serial Ports.

72-settings-serial-portsJPG

Make sure your settings look exactly like this:

73-settings-after-serial-portJPG

Note that the little box next to “Enable Serial Port” is checked.

Side Note: Any time you unplug your Arduino….say perhaps after using it within Ubuntu Linux or if you shutdown your PC….be sure to disable the “Enable Serial Port” option before restarting Ubuntu Linux in your Virtual Box. Otherwise, your Ubuntu Linux session will NOT launch. I’ve made this mistake numerous times, and it is frustrating.

After you are done, click OK.

Restart the VirtualBox with Ubuntu.

Open a new terminal window and type:

ls -al /dev/ttyS0

Here is the output:

74-serial-port-outputJPG

Now we need to give the IDE permissions to access the device.

In a new terminal window, find out your username. Type:

whoami

Now type the following commands, replacing YOUR_USER_NAME with what you found above:

sudo usermod -a -G dialout YOUR_USER_NAME
sudo chmod 660 /dev/ttyS0
76-add-dialoutJPG

Reboot your machine:

sudo reboot

Open up a terminal window and launch Arduino by typing:

arduino

Go to Tools -> Port, and you should see /dev/ttyS0. This is your Arduino board that is connected to the USB port of your computer. Make sure /dev/ttyS0 is checked.

77-arduino-board-selectedJPG

Now open the Blink sketch again. Go to File – > Examples -> 01.Basics, and choose Blink.

Click the Upload button…the right arrow in the upper left of your screen.

The LED on your Arduino should be blinking! If it is not, go back to the beginning of this tutorial and follow the steps carefully.

To turn off the blinking light, open up a new sketch and upload it to your board. Go to File -> New.

Integrate Arduino With ROS

Now that we know Arduino is working, we need to integrate it with ROS. Here are the official instructions. I’ll walk you through the steps below.

Let’s install the necessary packages. 

Close Arduino. Then type the following commands in a new terminal window (these will take a while to download so be patient):

sudo apt-get install ros-melodic-rosserial-arduino
sudo apt-get install ros-melodic-rosserial

Open the IDE by typing arduino and go to File -> Preferences. Make a note of the Sketchbook location. Mine is:

/home/ros/Arduino

78-sketchbook-locationJPG

Open a new terminal window and go to the sketchbook location you noted above. I’ll type:

cd Arduino
79-libraries-folderJPG

Type the dir command to see the list of folders.

Go to the libraries directory.

cd libraries

Within that directory, run the following command to build the Arduino library that will be used by ROS (don’t leave out that period that comes at the end of the command):

rosrun rosserial_arduino make_libraries.py .

Type the dir command to see the list of folders. You should now see the ros_lib library.

80-ros-lib-libraryJPG

Make sure the Arduino IDE is closed. Now open it again.

You should see some sample code. Now, let’s take a look at the Blink example.

Go to File -> Examples -> ros_lib

81-ros-lib-on-examplesJPG

Return to Table of Contents

How to Blink an LED (Light-Emitting Diode) Using ROS and Arduino

The Blink example is analogous to a “Hello World” program. Blinking an LED is the most basic thing we can do to make sure the hardware is working properly and that it accepts the software we are developing on our laptop. The goal of the Blink example is to toggle an LED on and off. 

In this example, Arduino is going to be considered a Subscriber node. It will subscribe to a topic called toggle_led. Publishing a message to that topic causes the LED to turn on. Publishing a message to the topic again causes the LED to turn off. 

Go to File -> Examples -> ros_lib and open the Blink sketch.

Now we need to upload the code to Arduino. Make sure your Arduino is plugged into the USB port on your computer.

Upload the code to your Arduino using the right arrow button in the upper left of your screen. When you upload the code, your Arduino should flicker a little bit.

Open a new terminal window and type:

roscore

In a new terminal window, launch the ROS serial server. This command is explained here on the ROS website. It is necessary to complete the integration between ROS and Arduino:

rosrun rosserial_python serial_node.py /dev/ttyS0
83-rosrun-rosserial-pythonJPG

Now let’s turn on the LED by publishing a single empty message to the /toggle_led topic. Open a new terminal window and type:

rostopic pub toggle_led std_msgs/Empty --once
84-publish-message-led-onJPG

The LED on the Arduino should turn on. Note the yellow light is on (my Arduino is inside a protective case).

2019-10-21-193316

Now press the Up arrow in the terminal and press ENTER to run this code again. You should see the LED turn off. You might also see a tiny yellow light blinking as well. Just ignore that one…you’re interested in the big yellow light that you’re able to turn off and on by publishing single messages to the /toggle_led topic.

85-publish-message-led-offJPG
2019-10-21-193535

Return to Table of Contents

That’s it! You have now seen how you can integrate Arduino with ROS. To turn off your Arduino, all you need to do is disconnect it.

Implementing the ROS Turtlesim Project With rospy

You might have seen my previous tutorial where we ran the built-in ROS turtlesim program. We are going to explore this application further in this tutorial. 

Turtlesim isn’t the most exciting application, but it is a popular tool for learning the basics of ROS before working with real robots (Click here for more information on turtlesim from the official ROS website). You can think of the turtle as an actual robot. All of the things you can do with this turtle, you can do with a real, physical robot. Let’s get started!

Table of Contents

Directions

Move the Turtle

Let’s run turtlesim with rospy, the Python library for ROS. 

Open up a new terminal window and type:

roscore

Start the turtlesim node by going to a new terminal window and typing:

rosrun turtlesim turtlesim_node
25-turtlesim-openJPG

Open yet another terminal window and check out the list of topics that are currently active:

rostopic list
26-rostopic-listJPG

To move the turtle, we need to publish to the /turtle1/cmd_vel topic. But what type of messages can we publish to this topic? Let’s find out.

rostopic type /turtle1/cmd_vel

Here is the output:

27-ros-topic-typeJPG

What this means is that we need to publish messages of type geometry_msgs/Twist to the /turtle1/cmd_vel topic to get the turtle to move like we want it to. 

So what does ‘geometry_msgs/Twist’ mean? We need to check out the definition of this data type. 

rosmsg show geometry_msgs/Twist

The message you see on your terminal window expresses the velocity of the turtle in 3D space, broken into its linear and angular parts. With respect to the turtle, the two pieces of data that we can control are the linear velocity in the x-direction and the angular velocity along the z axis because the robot cannot move along either the z or y axes.

Check out this link at the ROS website if you want to dive into more detail about the different kinds of geometric data types, including Twist.

Let’s get the turtle moving. We need to create a node (i.e. program) and make sure that node publishes the velocity values to the /turtle1/cmd_vel topic. Let’s do that now.

Close out turtlesim using CTRL+C.

Open up a new terminal window and open the Linux text editor.

gedit

Type this Python code (credit to Lentin Joseph, author of Robot Operating System for Absolute Beginners).

28-move-turtleJPG

Save the file as move_turtle.py. Make sure to save it to your catkin_ws/src/hello_world/scripts folder.

The code above imports rospy (ROS library for Python), Twist (for us to work with the linear and angular velocity of the turtle), and sys (library that enables us to pass parameters via the Linux command line).

In a terminal window, type:

cd catkin_ws/src/hello_world/scripts

Make the node executable.

chmod +x move_turtle.py
chmod +x move_turtle.py

Open up a new terminal tab, launch ROS.

roscore

Open a new terminal tab, and launch the turtlesim node:

rosrun turtlesim turtlesim_node

Let’s get the turtle to move with a linear velocity of 3.0 m/s and an angular velocity of 1.5 radians/s. We need to pass those two values as arguments in the terminal. Open another terminal window and type:

rosrun hello_world move_turtle.py 3.0 1.5

You should see the turtle moving in circles, around and around.

29-turtle-moving-circlesJPG

Open a new terminal window, and let’s see the ROS computation graph. Type this command:

rqt_graph
30-computation-graphJPG-1

When you have had enough, stop the program by typing CTRL+C, and close all terminal windows.

Return to Table of Contents

Get the Turtle’s Position

Now that we know how to work with the velocity of the turtle, let’s take a look at how we can get the position of the robot. To do that, we need to work with the /turtle1/pose topic.

Launch ROS.

roscore

Start the turtlesim node by going to a new terminal window and typing:

rosrun turtlesim turtlesim_node

Let’s display the messages that are published to the /turtle1/pose topic.

rostopic echo /turtle1/pose

Here is the output to the screen. You can see the position and velocity information.

31-pose-outputJPG

We don’t want to have to type a command every time we want to get position and velocity information, so let’s modify move_turtle.py so that it subscribes to the /turtle1/pose topic. 

First, find out what the message type is of the /turtle1/pose topic.

rostopic type /turtle1/pose

Let’s also get the message definition:

rosmsg show turtlesim/Pose
32-ros-msg-show-poseJPG

Press CTRL+C to stop the processes. You can exit all terminal windows.

Let’s get the pose using an actual Python-based node. Open up a new terminal window and open the Linux text editor.

gedit

Type this Python code (credit to Lentin Joseph, author of Robot Operating System for Absolute Beginners).

Save it as move_turtle_get_pose_.py to your catkin_ws/src/hello_world/scripts folder. Here is the code: 

33-move-turtle-get-poseJPG

In a terminal window, type:

cd catkin_ws/src/hello_world/scripts

Make the node executable.

chmod +x move_turtle_get_pose_.py 
chmod +x move_turtle_get_pose_.py 

Open up a new terminal tab, launch ROS.

roscore

Open a new terminal tab, and launch the turtlesim node:

rosrun turtlesim turtlesim_node

Open a new terminal tab, and launch the move_turtle_get_pose node:

rosrun hello_world move_turtle_get_pose.py 1.0 0.5

You should see data output.

34-velocity-and-position-dataJPG

In a new terminal window, check out the computation graph:

rqt_graph
35-comp_graphJPG

You can see that the move_turtle node is publishing position data to the /turtle1/pose topic. This topic is subscribed by the /turtlesim node. Similarly, the turtlesim node is publishing velocity data to the /turtle1/cmd_vel topic. This topic is being subscribed by the move_turtle node.

Press CTRL+C on all windows, and close the terminal screens.

Return to Table of Contents

Move the Turtle a Specific Distance

Now let’s move the turtle a distance that we specify. 

Open up a new terminal window and open the Linux text editor.

gedit

Type this Python code (credit to Lentin Joseph, author of Robot Operating System for Absolute Beginners).

Save it as move_distance.py to your catkin_ws/src/hello_world/scripts folder. Here is the code: 

35b-robot-spec-distance-methodsJPG

In a terminal window, type:

cd catkin_ws/src/hello_world/scripts

Make the node executable. Type the command twice as sometimes you might get an error if you type it only once.

chmod +x move_distance.py 
chmod +x move_distance.py 

Open up a new terminal tab, launch ROS.

roscore

Open a new terminal tab, and launch the turtlesim node:

rosrun turtlesim turtlesim_node

Open a new terminal window, and launch the move_distance node. The arguments are linear velocity, angular velocity, and distance that you want the turtle to travel:

rosrun hello_world move_distance.py 0.4 0.0 7.0

Here is the data output:

36-robot-spec-distanceJPG

And here is what your simulation screen should look like:

37-visual-robot-move-spec-distanceJPG

Press CTRL+C on all windows, and close the terminal screens.

Return to Table of Contents

Work With ROS Services and ROS Parameters

Ros Services

Up until now, we have been using what is called the publish/subscribe model for inter-node communication. A node publishes to a topic, and nodes that need the data published to that topic have to subscribe to that topic. This one-way communication model is flexible, but it is inefficient when we want two-way communication between nodes … for example if one node requests data from another node and wants a reply from that node. 

Request / reply in ROS is done via what is known as a Service. A service is defined by a pair of messages: one for the request and one for the reply. If you want to know more details about ROS Services, check out this page on the ROS website.

Let’s check out a list of available ROS services in the turtlesim node. Open a new terminal window and type:

roscore

Start the turtlesim node by going to a new terminal tab and typing:

rosrun turtlesim turtlesim_node

Now in another terminal tab, type:

rosservice list
38-ros-service-listJPG

You should see this on your screen. We want to incorporate the reset service into our code. When the code calls the reset service, the workspace resets. Let’s find out the type of the reset service.

rosservice type /reset
39-ros-service-typeJPG

stdsrvs/Empty is the type. It is a built-in service type in ROS. Let’s display some information on this service type.

rossrv show std_srvs/Empty
40-ros-service-emptyJPG

You can see that the field is empty. This is what we expected because no actual data is exchanged during this service. All the /reset service does is reset the workspace. 

ROS Parameters

Before we implement the workspace reset service described above, let’s talk about what ROS parameters are.

Parameters are globally available values such as integers, floats, strings or booleans. We can also have parameters like background color.

Nodes (i.e. programs in C++/Python that exist inside ROS packages), can use parameters during runtime.

Parameters are stored inside the Parameter Server which is like a dictionary that contains the name of the parameter and the corresponding value of the parameter.

Let’s take a look at parameters in more detail now.

Open a new terminal tab and type the following command to retrieve a list of parameters:

rosparam list
41-ros-parameters-listJPG

Let’s get the value of the red background color parameter, for example:

rosparam get /background_b
42-ros-background-colorJPG

That’s how you retrieve the value of a parameter. The syntax is:

rosparam get <name_of_parameter>

If you would like to change the value of a parameter, you do that as follows:

rosparam set <name_of_parameter> <desired_value>

The topic of the background color parameter is /turtle1/color_sensor. Let’s see what this topic is all about by displaying some information on it:

rostopic echo /turtle1/color_sensor
43-rostopic-colorsJPG

Press CTRL+C on all windows, and close the terminal screens.

Return to Table of Contents

Change the Background Color and Reset the Workspace

Let’s use some Python code that modifies the parameter for the background color and resets the workspace by calling the /reset service.

Open up a new terminal window and open the Linux text editor.

gedit

Type this Python code (credit to Lentin Joseph, author of Robot Operating System for Absolute Beginners).

Save it as turtle_service_param.py  to your catkin_ws/src/hello_world/scripts folder.

In a terminal window, type:

cd catkin_ws/src/hello_world/scripts

Make the node executable. 

chmod +x turtle_service_param.py
chmod +x turtle_service_param.py

Open up a new terminal tab, launch ROS.

roscore

Open a new terminal tab, and launch the turtlesim node:

rosrun turtlesim turtlesim_node

Open a new terminal tab, and launch the code:

rosrun hello_world turtle_service_param.py

Here is what your screen should look like:

44-change-background-color-turtlesimJPG

Here is what the terminal outputs:

45-change-bg-color-2JPG

If you press CTRL+C on the same terminal window, and then rerun this command, you will see we get a different color:

rosrun hello_world turtle_service_param.py
46-diff-colorJPG

Each time you run the command above, you will get a message that the service has been executed.

47-executed-serviceJPG

When you are finished, press CTRL+C on all windows, and close the terminal screens.

Congratulations! You have completed the turtlesim tutorial. 

Return to Table of Contents

How to Visualize Nodes Using the RQt GUI Tool

The rqt tool in ROS enables us to visualize the node connections while a launch file is running. Let’s see what happens when we run the launch file we created in this tutorial. Open up a new terminal window.

Directions

Type:

roslaunch hello_world talker_listener.launch

Then in a new terminal window, type:

rqt_graph
24-talker-listenerJPG-1

You can see that the listener_node is subscribed to the /chatter topic. The talker_node is publishing to the /chatter topic. You might also see another node called /rosout (if you don’t see /rosout that is OK). This is where debug statements from nodes are going.