How to use Arduino with Robot Operating System (ROS)

【How to use Arduino with Robot Operating System (ROS)】

  • 1 Introduction
  • 2. What is ROS?
  • 3. Communication between ROS and Arduino
  • 4. Set up the infrastructure
    • 4.1 Software Settings
    • 4.1 Hardware Setup
    • 4.3 Codes and instructions
    • 4.4 Explanation
    • 4.5 Program Execution

1. Introduction

Learn about ROS or Robot Operating System, a popular open source middleware for robotics!

Arduino boards are used to build small robots and have simple logic defined controls. But developers often cannot upgrade to more complex robots due to limited onboard computing power and software. Typically, as builders become more experienced, they look for robot-specific software, since the Arduino only provides partial control.

This tutorial introduces the Robot Operating System (ROS), a middleware software framework, and walks you through setting up and using ROS with an Arduino to create smarter robotic systems.

2. What is ROS?

Robot Operating System (ROS) is one of the most popular and widely used robotic middleware software frameworks. It is an open-source platform that helps manufacturers and developers get started with robotics software without reinventing the wheel. ROS provides a standard communication framework for seamlessly integrating, using, developing, and deploying different components of robotic systems, including control, perception, planning, and more. It is a language-independent platform that provides cross-platform communication support for different computers regardless of their deployment site.

Arduino is probably the most commonly used open-source microcontroller development board, offering an easy-to-use software-hardware interface and a growing user community. Arduino is mainly compatible with all digital and analog circuits and external devices that support serial communication interfaces such as SPI, I2C and UART.

The ROS-based software framework runs advanced algorithms and processes such as inference of robot models, filtering, motion policy generation, controller algorithms, and more. An Arduino controller mounted on the robot is used to perform low-level/embedded control and sensing. It includes any or all motor controls, temperature and ultrasonic sensors, IMUs and wheel encoders, among other devices.

Arduino _Robot_AK_MP_image1.png

ROS – Arduino Interaction Pipeline (Image source – original)

3. Communication between ROS and Arduino

The ROS communication module runs on a custom TCPROS protocol in two paradigms: the many-to-many publisher-subscriber approach and the point-to-point faster services approach. This tutorial uses a publisher/subscriber paradigm to communicate between an Arduino board running on a computer and ROS.

The rosserial ROS package communicates using Arduino’s Universal Asynchronous Receiver/Transmitter (UART) and turns the board into a ROS node that can publish ROS messages and subscribe to messages. An Arduino ROS Node Publisher can send data (from sensors or robot state) from a development board to a machine running ROS, and an Arduino ROS Node Subscriber can get instructions from a machine. The ros_lib Arduino library enables Arduino boards to communicate with ROS.

4. Set up infrastructure

4.1 Software Settings

  1. Install ROS on the machine (laptop/PC). Detailed steps are provided here.

NOTE: This works on ROS 1 running on a Linux machine

2. Install rosserial on the machine (distribution can be kinetic/indigo/melodic).

sudo apt-get install ros-<distro>-rosserial
sudo apt-get install ros-<distro>-rosserial-arduino
  1. Follow the instructions mentioned here to install Arduino IDE on your machine.

  2. Install the ros_lib package in the IDE.

one. The easiest way to install the package is from the Arduino IDE itself. Navigate to Sketch > Include Libraries > Manage Libraries in the IDE and search for the rosserial package

Arduino _Robot_AK_MP_image5.png

Dropdown menu to search for new Arduino packages

b. Arduino IDE stores all external libraries in ~/Arduino/libraries folder location. It loads these libraries into the development environment and can be seen in the IDE. Once installed, the Rosserial Arduino library can be seen in the dropdown list.

Arduino _Robot_AK_MP_image3.png

External libraries are shown in the list

c.c. After installation, the example sketches should also be visible in the IDE.

Arduino _Robot_AK_MP_image4.png

Example sketches in available libraries

4.1 Hardware Settings

We use a simple setup to use an Arduino board as a publisher and subscriber.

1. Publisher: A button connected to the Arduino board and toggles it to send a digital high/low signal to the machine via ROS. The message is displayed in the terminal on the computer.

  1. User: The LED is connected to the Arduino board and turned on/off using instructions obtained from the ROS user via the terminal.

Arduino _Robot_AK_MP_image6.png

Hardware Connections – (Image Source – Original)

4.3 Code and description

Arduino Code

#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/UInt16.h>

#define BUTTON 8
#define LED 13

ros::NodeHandle node_handle;

std_msgs::String button_msg;
std_msgs::UInt16 led_msg;

void subscriberCallback(const std_msgs::UInt16 & amp; led_msg) {<!-- -->
  if (led_msg.data == 1) {<!-- -->
    digitalWrite(LED, HIGH);
  } else {<!-- -->
    digitalWrite(LED, LOW);
  }
}

ros::Publisher button_publisher("button_press", & amp; button_msg);
ros::Subscriber<std_msgs::UInt16> led_subscriber("toggle_led", & amp;subscriberCallback);

void setup()
{<!-- -->
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT);
  
  node_handle.initNode();
  node_handle.advertise(button_publisher);
  node_handle. subscribe(led_subscriber);
}

void loop()
{<!-- -->
  if (digitalRead(BUTTON) == HIGH) {<!-- -->
    button_msg.data = "Pressed";
  } else {<!-- -->
    button_msg.data = "NOT pressed";
  }

  button_publisher. publish( & button_msg );
  node_handle. spinOnce();
  
  delay(100);
}

4.4 Explanation

The code imports std_msgs::String and std_msgs::UInt16 of the ros_lib library and standard ROS messages. Declare variables to store ROS data types and Arduino board pins.

The code declares a publisher named button_publisher that publishes the std_msgs::String data type button_msg to the button_press topic. Likewise, a subscriber named led_subscriber subscribes to the toggle_led topic, which gets a std_msgs::UInt6 datatype.

Declare the ROS node handle and initialize it in the setup() method. Node handles advertise publishers and subscribe to topics.

subscriberCallback() is the method called when data is received on the Arduino subscriber node. The callback method checks if the ROS topic data is HIGH and toggles the connected LED accordingly.

Finally, the loop() method runs an infinite loop, reading information from the button and posting it to ROS. The node handle calls spinOnce() to handle the communication.

4.5 Program Execution

Connect the Arduino Uno board to the laptop via the USB cable and verify that the board appears in the Arduino IDE’s list of available serial ports. Compile the code, select the board type and upload it to the board.

After uploading the code, execute the following command in the terminal of your computer.

  1. Start the ROS master – roscore
  2. Run the rosserial client on the machine – rosrun rosserial_python serial_node.py /dev/tty
  3. The serial port is determined at runtime as ttyUSB or ttyACM. The exact port number can be obtained from the Arduino IDE or using dmesg|grape_ti.
  4. Reads published data, returns whether a button on the Arduino board was pressed – rostopic echo button_press
  5. Publish data to toggle LED connected on Arduino – rostopic pub toggle_led std_msgs/UInt16 “Data: 0” Data is “0” to turn off the LED, “1” to turn on the LED.
    Arduino _Robot_AK_MP_image2.png

Use multiple terminal tabs to execute commands and watch responses in the same screen

rosserial provides a pretty standard platform that allows makers and developers to interface seamlessly between Arduino and ROS. It allows to explore new opportunities in robotics using two very well-known and useful techniques. This approach allows distributed computing, centralized control, control abstraction, and several other benefits of robotic systems at very low cost.