
A simpler illustration is as follows,

Application can be “we want the robot to move at 0.5 m/s linear velocity” so we give the topic /cmd_vel some command for the robot. The Controller transforms this cmd into velocity for each wheel - “rotate left wheel at some x rad/s and right wheel at -x rad/s”, and the HW interface is the connection between the controller and the driver. Then the HW Driver converts this command into something the robot can understand “eg. binary or encoder counts for speed or RPM”
For this tutorial, we shall be using a MOCK Component!

As we do not have a hardware with us, we will use this Mock Component (a perfect robot with no physics simulation) to test out ros2_control architecture.
Installing ros2_control packages
sudo apt install ros-humble-ros2-control ros-humble-ros2-controllers
(Optional) Install the my_robot_description package in ros2_ws/src folder
ros2 launch my_robot_description display.launch.xml
This will launch two nodes: robot_state_publisher and joint_state_publisher_gui
We want to add a ros2_control to this robot, even if its a fake node, we create a new file in the urdf/ directory called mobile_base.ros2_control.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="<http://www.ros.org/wiki/xacro>">
<ros2_control name="MobileBaseHardwareInterface" type="system">
<hardware>
<plugin>mock_components/GenericSystem</plugin>
<param name="calculate_dynamics">true</param>
</hardware>
<joint name="base_right_wheel_joint">
<command_interface name="velocity" /> <!--give-->
<state_interface name="position" /> <!--take-->
<state_interface name="velocity" /> <!--take-->
</joint>
<joint name="base_left_wheel_joint">
<command_interface name="velocity" />
<state_interface name="position" />
<state_interface name="velocity" />
</joint>
</ros2_control>
</robot>
Ofcourse, we need to add this file’s reference to urdf/my_robot.urdf.xacro file
For this, we create a new package