1. Overview

BlankChalkboard

ROS, the Robot Operating System, is the platform of choice for robot development. However, the breadth and depth of existing documentation can be daunting for the ROS beginner. This tutorial presents a solid foundation before digging deeper into a robotics specialty of your choosing.

What you’ll learn

This tutorial will introduce you to the basic concepts of ROS robots using simulated robots. The concepts introduced here give you the necessary foundation to use ROS products and begin developing your own robots. This is a companion guide to the ROS 2 tutorials.

Sample commands are based on the ROS 2 Foxy distribution. Although the basic concepts do not change between ROS 1 and ROS 2, many of the commands differ and the underlying architecture is quite different.

What you’ll need

No programming experience is required to complete this tutorial!

If you plan on following along with the examples, you should either have a ROS 2 Foxy installation of either turtlesim or the Robotis TurtleBot3.

How will you use this tutorial?

What is your current level of experience with ROS?


2. Prerequisites

If you plan to follow along with the turtlesim simulator, start it with the command:

ros2 run turtlesim turtlesim_node

Similarly if you’re using the TurtleBot WafflePi simulator, use the command:

ros2 launch turtlebot3_gazebo empty_world.launch.py

Keep the simulator running throughout the tutorial.


3. Nodes

The software of a ROS-based robot conceptually builds up a graph of connected endpoints. The endpoints within ROS are called “Nodes”. They’re the primary software building block, the process that anchors all parts of the robot software design.

A node will control hardware like wheel motors, or a node may gather sensor data from a laser range finder.

Use the command ros2 node list to show which nodes are running in your simulator. For turtlesim you should see the following:

/turtlesim

The turtlebot publishes multiple nodes to handle the different functions available on the robot:

/camera_driver
/gazebo
/robot_state_publisher
/turtlebot3_diff_drive
/turtlebot3_imu
/turtlebot3_joint_state
/turtlebot3_laserscan

Nodes can dynamically be added to a ROS robot as additional programs are launched. While turtlesim continues to run, launch a keyboard controller for it with the following command:

ros2 run turtlesim turtle_teleop_key

Now the node list contains both /teleop_turtle and /turtlesim. The controller is a separate node because it may or may not be needed depending on how you want to control the turtle.


4. Topics

If ROS nodes are endpoints, the endpoints need some way to communicate with each other. There are a few different ways ROS can accomplish this, the primary being through topics. While nodes handle computation for the robot, topics can broker data communications between nodes.

Topics work on flexible Pub/Sub (publish / subscribe) asynchronous messaging protocol. A node will listen (subscribe) to a topic, or it will publish data on a topic. Topics allow for a many-to-many relationship: multiple nodes can listen on the same topic, and each node can publish data on multiple topics.

For the turtlesim robot, the command ros2 topic list returns the following topics:

/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

See how the topic list changes after starting the turtle_teleop_key node:

/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

Did you notice the topics are identical? That’s because turtle_teleop_key does not create any new topics; instead, it simply publishes on the existing /turtle1/cmd_vel topic.

The following topics exist in the turtlebot simulator. These represent all the data both produced and consumed by the turtlebot:

/camera/camera_info
/camera/image_raw
/clock
/cmd_vel
/imu
/joint_states
/odom
/parameter_events
/robot_description
/rosout
/scan
/tf
/tf_static

Use the ros2 topic echo command to show the raw data published on a particular topic.


5. Messages

A node can publish data on a topic, and it can subscribe to a topic to receive the data, but how is the data itself formatted?

All data exchange in a ROS message follows a specific message structure. This structure contains fields which define the data interface used to connect nodes. ROS supports a number of built-in field types such as numbers, strings, booleans and arrays. Standard message templates combine these fields; for instance, a “point” message contains three float64 values for x, y and z coordinates. Although many common message templates exist within the ROS standard libraries, you can also program custom message types.

ROS message formats are pre-defined at compile time. Although a distributed ROS system may run across different computers connected to multiple networks, all endpoints must have the same message definitions installed in order to properly encode and decode message data.

In order to see the type of message for a topic, simply use the -t flag. For turtlesim, the command

ros2 topic list -t

returns the following:

/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]

Similarly on the turtlebot, the command returns a different set of message types:

/camera/camera_info [sensor_msgs/msg/CameraInfo]
/camera/image_raw [sensor_msgs/msg/Image]
/clock [rosgraph_msgs/msg/Clock]
/cmd_vel [geometry_msgs/msg/Twist]
/imu [sensor_msgs/msg/Imu]
/joint_states [sensor_msgs/msg/JointState]
/odom [nav_msgs/msg/Odometry]
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/robot_description [std_msgs/msg/String]
/rosout [rcl_interfaces/msg/Log]
/scan [sensor_msgs/msg/LaserScan]
/tf [tf2_msgs/msg/TFMessage]
/tf_static [tf2_msgs/msg/TFMessage]

6. Parameters

Each parameter defines a name-value pair–an attribute or a configuration setting–for a specific node. Topics do not have parameters, only nodes. Parameters must be one of the built-in types, they do not support complex message types.

To show the parameters for a running robot, use the command ros2 param list. The single node in turtlesim publishes the following parameters:

/turtlesim:
  background_b
  background_g
  background_r
  use_sim_time

The turtlebot running in gazebo has the following parameters, many of which are related to the simulator itself and not the robot:

/camera_driver:
  update_rate
  use_sim_time
/gazebo:
  publish_rate
  use_sim_time
/robot_state_publisher:
  ignore_timestamp
  publish_frequency
  robot_description
  use_sim_time
  use_tf_static
/turtlebot3_diff_drive:
  use_sim_time
/turtlebot3_imu:
  use_sim_time
/turtlebot3_joint_state:
  use_sim_time
/turtlebot3_laserscan:
  use_sim_time

Use the command ros2 param get [node] [parameter name] to view the value of a parameter.

ROS Eloquent and later added the option to set parameters on startup using the --ros-args -p command. In order to set the red background color when starting the turtlesim simulator, use the following command:

ros2 run turtlesim turtlesim_node --ros-args -p background_r:=255

7. Services

Now let’s suppose we want the robot to do something specific. Something that’s synchronous and guaranteed. That’s a service call.

Similar to the other ROS commands we’ve used, there’s a ros2 service list command to show which services are available. The following services are available for the turtlesim:

/clear
/kill
/reset
/spawn
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically

The turtlebot service list is much longer and most service are parameter-related services. In ROS 2, parameters are implemented through services and lengthen the list:

/camera_driver/describe_parameters
/camera_driver/get_parameter_types
...
/gazebo/set_parameters
/gazebo/set_parameters_atomically
/pause_physics
/reset_simulation
/reset_world
/robot_state_publisher/describe_parameters
...
/turtlebot3_laserscan/set_parameters
/turtlebot3_laserscan/set_parameters_atomically
/unpause_physics

Calling a service in ROS 2 requires three arguments: the service, the service type and the message data to send to the service. After retrieving the list of service names, the ros2 service type [service] command shows the service type. By examining the turtlesim \spawn that’s used to add a new turtle to the simulator, we find the service type is turtlesim/srv/Spawn.

The message data is defined by the service interface. Use the command

ros2 interface show turtlesim/srv/Spawn

to display the message format required to make the service call:

float32 x
float32 y
float32 theta
string name # Optional.  A unique name will be created and returned if this is empty
---
string name

This output follows the ROS .srv file format. This format allows for comments using the # sign, and sections are delimited with three hyphens, ---. The first section is the format used to call the service, and the second section shows the message type returned after the service has been called. Calling the Spawn service requires two floats for the turtle position, the orientation of the turtle in radians, and an optional name for the new turtle; it returns the name of the new turtle.

Call the service by specifying the service name, service type, and the message data in yaml format:

ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.0, name: 'tortise'}"

The service returns the name of the turtle that was added to the playfield.

Explore the /kill service within turtlesim to remove the newly created turtle!


8. Actions

Action calls are similar in many ways to service calls, but actions happen asynchronously. Actions represent a goal-driven request that may take a while to complete, and the action server periodically issues status updates to the requester until the goal succeeds or fails.

Looking at turtlesim, use the ros2 action list -t command to show the single available action. The -t switch displays both the action name and type; both will be used to call the action.

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

The rotate_absolute service turns the turtle to a specific direction in radians. Unlike the ‘teleport’ services that happen instantly, this service requires time to complete. Similar to services, use the ros2 interface show turtlesim/action/RotateAbsolute to describe details of the action interface:

# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining

The result is similar to service interfaces, although actions have three sections: the format of the initial goal, the format of the response from the action server when the goal is requested, and the periodic updates from the service.

Send an action from the command line to rotate the turtle 180 degrees using the following command:

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 3.14}"

This seems to behave similar to a service. However, by adding the --feedback option, you can see the feedback in progress:

Waiting for an action server to become available...
Sending goal:
     theta: 0.0

Feedback:
    remaining: -3.1200034618377686

Goal accepted with ID: fdab52e23f214c70b0f946308c20cbfd

Feedback:
    remaining: -3.104003429412842

Feedback:
    remaining: -3.088003396987915

...

9. Conclusion

Hopefully now you’re somewhat familiar with the basic ROS building blocks: nodes, topics, service, actions and parameters. You should also begin to form many unanswered questions on how to properly design a robot. That’s a great place to be! Start exploring the many open source ROS projects to see how to tackle common design problems.

Whether you’re working with an airborne drone, a robot quadruped, a self-driving vehicle or any of the many, many robots, it can all be done with nodes, parameters, topics, services and actions!

For more details about ROS, be sure to check out the ROS 2 tutorials tutorials. You can also find a video version of this tutorial on the Ubuntu Robotics YouTube channel. If you’re building a robot and Ubuntu and want to talk to our engineers, reach out to the Ubuntu Robotics team!