Keynotes for creating a custom hardware interface and controllers.
When using the ROS2 Control the following tag must be used in the robot description:
<ros2_control name="name" type="system">
.....
</ros2_control>
There are 3 types of interfaces available to use:
Sensors
Joints
Joints need to have at least one command_interface and one state_interface. Those can be: velocity, position or effort.
GPIO
GPIO can have command_interface or state_interface or both, the initial value must be double.
Plugins
In the Xacro file it is possible to include 3 types of control plugins:
1. ign_ros2_control/IgnitionSystem: For simulation.
2. mock_components/GenericSystem: For testing hardware without real hardware (including GPIO).
3. custom_hardware_interfaces/Custom: Custom hardware interfaces, created as a plugin.
Custom Hardware Interface
To access each hardware interface the member info_ is used. All the information contained in this variable is extracted from URDF file, thus it might contain the following type of interfaces:
joints
gpios
sensors
transmissions
These interfaces are contained in info_ as an std::vector<ComponentInfo>, except for transmissions that is a std::vector<TransmissionInfo>.
The ComponentInfo class contains 4 members of interest:
name (std::string)
type (std::string)
state_interfaces (std::vector<InterfaceInfo>)*
command_interfaces (std::vector<InterfaceInfo>)*
*The order of the interfaces is given by the order in the URDF file.
For example to print the name of each state interface contained in the "platform" interface of type GPIO, first we iterate in the info_.gpio interfaces until we find the "platform" one. Then we print each state interface name.
Exporting a state interface or command interface:
state_interfaces.emplace_back(hardware_interface::StateInterface("name", TYPE, &variable_to_export*));
*variable_to_export must be type: double even for GPIO, then it can be casted.
When creating a custom controller or broadcaster all the information comes from the YAML parameter file NOT from the URDF, thus the order of the state interfaces and command interfaces in the yaml must match the URDF order.
For example, the following yaml file:
It is important to follow the structure <name/interface_name>: platform/power. "commands" and "states" are just the name of the string and can be anything.
In the controller, the class hardware_interface::LoanedCommandInterface and hardware_interface::LoanedStateInterface are mostly used. Also, the members states_interfaces_ and command_interfaces_ are available.
Thus, we can get the name and prefix to create state and commands handlers, as follow: