This package is a demonstration of Chaining Controller
in ros2_control
.
Tested on: ROS2 Humble
gazebo_ros2_control
repository was used for the Hardware Interface setup of this repository. It was a good starting point to understand and create hardware interfaces for classic-gazebo simultation.
Here is the ink to gazebo_ros2_control repository: https://github.com/ros-controls/gazebo_ros2_control/tree/master
For the Hardware Interface we have used gazebo_ros2_control
package which contains:
1. Gazebo System Interface
2. Gazebo Model Plugin
3. System Interface Implementation
In this demo, we will be using effort controller. There are two controllers in total:
1. Chaining Controller (At Lower Level)
2. Effort Controller (At Higher Level)
The chaining controller is exports certain command interfaces by acting as a hardware interface to the higher level controllers which is Effort Controller in our case.
The Chainable Controller Interface has reference interfaces
which are to be exported to the higher level controller as a command interface
. There are two key things to note while setting the export of reference interfaces:
-
The
prefix name
of thereference interfaces
will be the name of of the chaining controller itself as this name would be used by the higher level controllers to form chain to the chaining controller (Refer to Controller Manager to know more about this). -
The
reference interfaces
arecommand interfaces
which have to be populated by the higher level controllers, therefore don't forget to resize this container (probably in youron_init
method)
This is how chaining happens in the controllers and this doesn't require
any change in the configuration file.
Ps: Note that, the chaining controller should be running before you run the higher level controllers as the higher level controllers would be looking for them in their command interfaces to claim.
The chaining controller will clip the effort values from Higher Level Controller and send it as command interface to the hardware interface through the resource manager.
Here is the link to the API of Chaining Controller for reference: https://control.ros.org/humble/doc/api/classcontroller__interface_1_1ChainableControllerInterface.html
The effort controller which is at the higher level has 3 state interfaces
and 1 command interface
which is an exported reference interface
by the chaining controller.
The effort controller claims the reference interfaces and then they can be populated by your code. No altercations are required here.
The effort controller's objective is to set random values to the command interfaces received from the chaining controller and update it.
These values will be clipped by the chaining controller.
Clone the repository in your colcon workspace. In your home directory:
mkdir -p chaining_demo_ws/src && cd chaining_demo_ws/src
Clone the repository here and then go back to chaining_demo_ws. Run:
colcon build
source install/local_setup.zsh
PS: depending on your shell you can change the extension (bash, sh, zsh).
Now run:
ros2 launch chaining_controller cart_example_effort.launch.py
In a new tab source the workspace and run:
ros2 topic echo /joint_states
You can see the efforts getting clipped by the chaining controller and being sent as a final command to the resource manager. These values are published by the joint state broadcaster over this topic.
To inspect the working of controllers, you can run:
ros2 control list_controllers # To see the current state of the controllers
ros2 control list_hardware_interfaces # To see the hardware interfaces
You can look at the claimed resources in list_hardware_interfaces
as it will show you the chaining_controller/effort
resource being (available) [claimed]
. This is what you should be looking for when creating your chaining controllers as well.
This command interface will ONLY show up when the state of chaining controller is ACTIVE where it would be (unavailable) [unclaimed]
. After making the higher level controller active as well, you would see the desired output, i.e (available) [claimed]
.