ROS2 Tutorial: Robotic Arm


Setting up Controllers

Controller nodes provide an interface to control the joints of a robot. We expose joints and then commands can be sent and they will translate the current state of these joints into a desired state.

Controller nodes can be separated into three groups: effort, velocity, and position. You have already seen some reference to those above, when we configured joints. Controller modifies the state according to its type.

Note: There are two ways we can make our robot move. Either we can expose the controller nodes and work with them manually, or use the Gazebo plugin that hides routine tasks from you.

Note: controller nodes interact with the interface that robot's hardware provides. It can be a "real" robot or a Gazebo simulation. That makes it easy to switch from simulated to real robot, you just need to provide interface similar to what simulation used.

Controllers are provided with the ros-control package.

First of all, we need to add the following dependencies to package.xml:


Then we need to install these dependencies (if you followed my Galactic installation instructions, you should already have it):

                        rosdep install --from-paths ./ -i -y --rosdistro galactic --ignore-src
                        apt-get install ros-galactic-ros2-control ros-galactic-ros2-controllers

Gazebo Controller

armA.gazebo_config_control.xacro contains code for Gazebo controller.


This was a standard XML header.


ROS2 needs to know which hardware plugin to use to access the robot, so here we are telling ROS2 that it is a Gazebo control.


Here we configure joints.

We need the gazebo-ros plugin to be configured by specifying robot's parameters, such as robot description topic, the namespace (for the robot), the name of the robot description node, and a link to the robot configuration file.


Controller config file

simple_controller.yaml contains additional configuartions for controllers.


In this file we specified the joint_trajectory_controller and granted it access to all joints.

Transmission Controller

armA.transmission.xacro contains code for Transmission controller. Depending on which interface (effort, velocity or position) you want this controller to use, you need to expose those by corresponding joint and provide tramsmission tags.


A transmission_interface/SimpleTransmission implementats a simple reducer transmission.

A hardware_interface/PositionJointInterface implements one of three ways to "access" the joint that I have already mentioned: effort, velocity or position.

An actuator in ROS2 implements 1 DOF actuator. Examples are conveyors or motors. In our case we use motor.

Internal Configuration Controller

armA.internal_config.xacro contains code to "explain" to Gazebo the properties of the links of our model.


When two objects collide in our simulation, the physics engine (see link to ODE in the links section below) has to detect the collision and do something about it. To make sure objects do not penetrate each other, the physics engine applies a corrective force (see Newton's 3rd law).

maxVel caps the resulting velocity such a corrective impulse can result in. For example, if you want your object to bounce, you need set a relatively high maxVel. On the other hand, if you want to reduce bouncing in your model, you might want to set maxVel to a relatively low value (0.5 [m/s] is a good start).

minDepth is how far one link can penetrate another before that corrective force is applied. This can be used to ensure continuous contact between surfaces. If you set a small minDepth (0.002 [m]), then small corrective forces will not push your foot link out of contact with the ground, allowing it to stay in contact and friction to work, etc.

Bumper Controller

armA.bumper_config.xacro contains code for the "contact sensor". A contact sensor detects collisions between two objects and reports the location of the contact associated forces. It will publish it on /gazebo/default/box/link_6/bumper_ctr_sensor topic. We can see these data using

                        gz topic -e /gazebo/default/box/link6/bumper_ctr_sensor

This code specifies parameters for the contact type sensor for the link6, the last segment of a robotic arm. The idea is to be able to detect collisions both with the robot and with the objects we will move around.

We use gazebo_ros_bumper_sensor plugin to handle this. In arm_01 project this sensor is not used.

(C), all rights reserved

Please read the disclaimer