Please provide us feedback here
-
Clone the repository to your existing ROS 2 humble+ workspace. Either local or docker based workspace.
-
Import dependencies that need compilation from source using the command:
vcs import --input roscon2024_control_workshop/roscon2024_control_workshop.repos .
-
Build container
docker compose build
-
Compile the workspace using
colcon
, e.g.,colcon build
executed in the root of the workspace (wheresrc
folder is located).
This task shows how a controllers are chained with ros2_control.
Using PAL Tiago robot we want to reuse filtered data from the range sensor in the RangeSensorBroadcaster
and in DiffDriveController
.
We can of course filter those data separately in each controller, but than is is hard to make sure that filters' parameters are synchronized all the time.
Therefore, we introduce a ChainedFilter
controller that filters the data and provides state interfaces for other controllers to read those data.
Of course, the controllers using it has to have reference interfaces to be able to connect to other controllers. In this example DiffDriveController
is not chainable and we have to make it such.
Also, we want to process the velocity values from DiffDriveController
with PID before sending those the hardware.
Therefore, DiffDriveController
has to be enables to write to the interface with different prefix then reading from.
- In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup tiago_chaining.xml.launch
There is a new feature in ros2_control that support automatic replacement of a controller that might fail of throw exception during update
method.
Use of this feature is recommended on all robotic platforms that are inherently unstable, e.g., walking robots.
One other example is using of robotic arms in torque mode. To avoid sacking if something is not OK with the controller, we can now, for example, use JTC as fallback controller to our custom controller. The controllers from ros2_controllers repository are generally a good choice for fallback controllers as they are tested very well, but might have limited functionalities compared to your fancy controller.
As starting of fallback controllers might be disturbed by the configuration of other controllers, you HAVE TO always test fallback strategies before starting it on the hardware!
In this task we are running a Faulty JTC
that can "crash" on the next update()
call after a special service is called and it is replaced with the standard JTC.
This method for failure injection is used only for demonstration, but it is also useful to use similar or the same approach when testing fallback setup.
A variant of the Joint Trajectory Controller which has a service where one can trigger it to fault in the next update()
call. This failure injection method can be used for instance to demonstrate fallback controllers.
Make sure to understand the configuration of the fallback
controller in the fallback_controllers.yaml.
-
In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup tiago_fallback.launch.xml
-
Now list the controllers in another terminal also where your workspace is sourced:
ros2 control list_controllers
-
Call service to provoke error of the
Faulty JTC
:ros2 service call /faulty_arm_controller/set_fault example_interfaces/srv/SetBool "data: true"
-
Now list the controllers in another terminal also where your workspace is sourced:
ros2 control list_controllers
-
Activate again the
Faulty JTC
:ros2 control switch_controllers --activate faulty_arm_controller
Often time we have in our setup a controller that might require more time for calculation than our update rate allows. Until know we had to optimize such controller or create a separate thread for complex calculation within it. Now ros2_control can take are of it by using async controllers where you can with simple parameter set your controller to run in a separate thread and all the thread-safe data exchange is taken care for you!
In this task we are running the controllers as usual for Tiago robot. But we have also added a new sleepy controller that breaks update loop performance, by sleeping for random time. Using this controller as sync has influence on all other controller, therefore we should make it async to separate its "calculations" from the rest of the system.
-
In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup task3_async.launch.xml
-
Now list the controllers in another terminal also where your workspace is sourced:
ros2 control list_controllers
-
Echo
JointStateBroadcaster
'sjoint_states
messages to check the update frequency:ros2 topic hz /joint_states
-
Set the
SleepyController
to the SLOW mode:ros2 service call /sleepy_controller/set_slow_control_mode example_interfaces/srv/SetBool "data: true"
-
Now check the frequency again (make sense to restart the node):
ros2 topic hz /joint_states
-
Now make the controller Async by adding a parameter
is_async: true
under its namespace. -
Restart the scenario:
ros2 launch workshop_bringup async_controllers.launch.xml
This task demonstrates how to integrate multiple robots under different controller manager instances and how to handle parameters for better scalability of controller's configuration.
Using PAL TIAGo robot we are going to repeat the same controller chaining as in deploying on a fleet of robots. The idea is to make the setup work on different robots working on different namespaced controller_manager.
Make sure to understand the controller configuration present in the chaining_controllers_tiago1.yaml and chaining_controllers_generic.yaml.
-
In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup tiago_chaining.launch.launch.xml namespace:=tiago1
You should see that the different controllers are failing as the initial setup defined in the chaining_controllers.yaml is not enough to work with the different controller managers setup
-
In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup tiago_chaining.launch.launch.xml namespace:=tiago1 config_file:=chaining_controllers_tiago1
Now, launching the chaining_controllers_tiago1.yaml configuration file works because all the parameters are namespaced to the robot's serial number and it works. But!!!! you need to hardcode the namespacing in each and every robot's configuration file. If this works for you, then 👍. If not, the point 3 is for you!
ros2 launch workshop_bringup tiago_chaining.launch.launch.xml namespace:=tiago2 config_file:=chaining_controllers_tiago1
launching the above command should fail for you as it cannot find the corresponding parameters
-
In a terminal where your workspace is sourced start launch file:
ros2 launch workshop_bringup tiago_chaining.launch.launch.xml namespace:=tiago1 config_file:=chaining_controllers_generic
ros2 launch workshop_bringup tiago_chaining.launch.launch.xml namespace:=tiago2 config_file:=chaining_controllers_generic
-
Now list the controllers in another terminal also where your workspace is sourced:
ros2 control list_controllers --controller-manager /tiago1/controller_manager ros2 control list_controllers --controller-manager /tiago2/controller_manager
You should see the same set of the controllers loaded in both the controller managers
chaining_controllers_generic.yaml has the controller's parameters set with the wildcard entries and this makes it scalable when deploying on a fleet of robots