Skip to content

Commit 6ae3950

Browse files
authored
[Feature] Hardware Components Grouping (ros-controls#1458)
1 parent 62b32af commit 6ae3950

File tree

18 files changed

+426
-9
lines changed

18 files changed

+426
-9
lines changed

hardware_interface/doc/hardware_interface_types_userdoc.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ The ``<gpio>`` tag can be used as a child of all three types of hardware compone
4141
Because ports implemented as ``<gpio>``-tag are typically very application-specific, there exists no generic publisher
4242
within the ros2_control framework. A custom gpio-controller has to be implemented for each application. As an example, see :ref:`the GPIO controller example <ros2_control_demos_example_10_userdoc>` as part of the demo repository.
4343

44+
Hardware Groups
45+
*****************************
46+
Hardware Component Groups serve as a critical organizational mechanism within complex systems, facilitating error handling and fault tolerance. By grouping related hardware components together, such as actuators within a manipulator, users can establish a unified framework for error detection and response.
47+
48+
Hardware Component Groups play a vital role in propagating errors across interconnected hardware components. For instance, in a manipulator system, grouping actuators together allows for error propagation. If one actuator fails within the group, the error can propagate to the other actuators, signaling a potential issue across the system. By default, the actuator errors are isolated to their own hardware component, allowing the rest to continue operation unaffected. In the provided ros2_control configuration, the ``<group>`` tag within each ``<ros2_control>`` block signifies the grouping of hardware components, enabling error propagation mechanisms within the system.
49+
4450
Examples
4551
*****************************
4652
The following examples show how to use the different hardware interface types in a ``ros2_control`` URDF.
@@ -152,3 +158,66 @@ They can be combined together within the different hardware component types (sys
152158
<state_interface name="calibration_matrix_nr"/>
153159
</gpio>
154160
</ros2_control>
161+
162+
4. Robot with multiple hardware components belonging to same group : ``Group1``
163+
164+
- RRBot System 1 and 2
165+
- Digital: Total 4 inputs and 2 outputs
166+
- Analog: Total 2 inputs and 1 output
167+
- Vacuum valve at the flange (on/off)
168+
- Group: Group1
169+
170+
.. code:: xml
171+
172+
<ros2_control name="RRBotSystem1" type="system">
173+
<hardware>
174+
<plugin>ros2_control_demo_hardware/RRBotSystemPositionOnlyHardware</plugin>
175+
<group>Group1</group>
176+
<param name="example_param_hw_start_duration_sec">2.0</param>
177+
<param name="example_param_hw_stop_duration_sec">3.0</param>
178+
<param name="example_param_hw_slowdown">2.0</param>
179+
</hardware>
180+
<joint name="joint1">
181+
<command_interface name="position">
182+
<param name="min">-1</param>
183+
<param name="max">1</param>
184+
</command_interface>
185+
<state_interface name="position"/>
186+
</joint>
187+
<gpio name="flange_analog_IOs">
188+
<command_interface name="analog_output1"/>
189+
<state_interface name="analog_output1"> <!-- Needed to know current state of the output -->
190+
<param name="initial_value">3.1</param> <!-- Optional initial value for mock_hardware -->
191+
</state_interface>
192+
<state_interface name="analog_input1"/>
193+
<state_interface name="analog_input2"/>
194+
</gpio>
195+
<gpio name="flange_vacuum">
196+
<command_interface name="vacuum"/>
197+
<state_interface name="vacuum"/> <!-- Needed to know current state of the output -->
198+
</gpio>
199+
</ros2_control>
200+
<ros2_control name="RRBotSystem2" type="system">
201+
<hardware>
202+
<plugin>ros2_control_demo_hardware/RRBotSystemPositionOnlyHardware</plugin>
203+
<group>Group1</group>
204+
<param name="example_param_hw_start_duration_sec">2.0</param>
205+
<param name="example_param_hw_stop_duration_sec">3.0</param>
206+
<param name="example_param_hw_slowdown">2.0</param>
207+
</hardware>
208+
<joint name="joint2">
209+
<command_interface name="position">
210+
<param name="min">-1</param>
211+
<param name="max">1</param>
212+
</command_interface>
213+
<state_interface name="position"/>
214+
</joint>
215+
<gpio name="flange_digital_IOs">
216+
<command_interface name="digital_output1"/>
217+
<state_interface name="digital_output1"/> <!-- Needed to know current state of the output -->
218+
<command_interface name="digital_output2"/>
219+
<state_interface name="digital_output2"/>
220+
<state_interface name="digital_input1"/>
221+
<state_interface name="digital_input2"/>
222+
</gpio>
223+
</ros2_control>

hardware_interface/include/hardware_interface/actuator.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class Actuator final
8383
HARDWARE_INTERFACE_PUBLIC
8484
std::string get_name() const;
8585

86+
HARDWARE_INTERFACE_PUBLIC
87+
std::string get_group_name() const;
88+
8689
HARDWARE_INTERFACE_PUBLIC
8790
const rclcpp_lifecycle::State & get_state() const;
8891

hardware_interface/include/hardware_interface/actuator_interface.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ class ActuatorInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNod
190190
*/
191191
virtual std::string get_name() const { return info_.name; }
192192

193+
/// Get name of the actuator hardware group to which it belongs to.
194+
/**
195+
* \return group name.
196+
*/
197+
virtual std::string get_group_name() const { return info_.group; }
198+
193199
/// Get life-cycle state of the actuator hardware.
194200
/**
195201
* \return state.

hardware_interface/include/hardware_interface/hardware_component_info.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ struct HardwareComponentInfo
3939
/// Component "classification": "actuator", "sensor" or "system"
4040
std::string type;
4141

42+
/// Component group
43+
std::string group;
44+
4245
/// Component pluginlib plugin name.
4346
std::string plugin_name;
4447

hardware_interface/include/hardware_interface/hardware_info.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ struct HardwareInfo
133133
std::string name;
134134
/// Type of the hardware: actuator, sensor or system.
135135
std::string type;
136+
/// Hardware group to which the hardware belongs.
137+
std::string group;
136138
/// Component is async
137139
bool is_async;
138140
/// Name of the pluginlib plugin of the hardware that will be loaded.

hardware_interface/include/hardware_interface/sensor.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class Sensor final
7171
HARDWARE_INTERFACE_PUBLIC
7272
std::string get_name() const;
7373

74+
HARDWARE_INTERFACE_PUBLIC
75+
std::string get_group_name() const;
76+
7477
HARDWARE_INTERFACE_PUBLIC
7578
const rclcpp_lifecycle::State & get_state() const;
7679

hardware_interface/include/hardware_interface/sensor_interface.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ class SensorInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI
129129
*/
130130
virtual std::string get_name() const { return info_.name; }
131131

132+
/// Get name of the actuator hardware group to which it belongs to.
133+
/**
134+
* \return group name.
135+
*/
136+
virtual std::string get_group_name() const { return info_.group; }
137+
132138
/// Get life-cycle state of the actuator hardware.
133139
/**
134140
* \return state.

hardware_interface/include/hardware_interface/system.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class System final
8484
HARDWARE_INTERFACE_PUBLIC
8585
std::string get_name() const;
8686

87+
HARDWARE_INTERFACE_PUBLIC
88+
std::string get_group_name() const;
89+
8790
HARDWARE_INTERFACE_PUBLIC
8891
const rclcpp_lifecycle::State & get_state() const;
8992

hardware_interface/include/hardware_interface/system_interface.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ class SystemInterface : public rclcpp_lifecycle::node_interfaces::LifecycleNodeI
191191
*/
192192
virtual std::string get_name() const { return info_.name; }
193193

194+
/// Get name of the actuator hardware group to which it belongs to.
195+
/**
196+
* \return group name.
197+
*/
198+
virtual std::string get_group_name() const { return info_.group; }
199+
194200
/// Get life-cycle state of the actuator hardware.
195201
/**
196202
* \return state.

hardware_interface/src/actuator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ return_type Actuator::perform_command_mode_switch(
214214

215215
std::string Actuator::get_name() const { return impl_->get_name(); }
216216

217+
std::string Actuator::get_group_name() const { return impl_->get_group_name(); }
218+
217219
const rclcpp_lifecycle::State & Actuator::get_state() const { return impl_->get_state(); }
218220

219221
return_type Actuator::read(const rclcpp::Time & time, const rclcpp::Duration & period)

0 commit comments

Comments
 (0)