Skip to content

Commit fe15642

Browse files
authored
Fix the same hardware component node naming issue with multiple controller managers setup (#2657) (#2666)
1 parent d9bef8e commit fe15642

File tree

7 files changed

+48
-10
lines changed

7 files changed

+48
-10
lines changed

controller_manager/src/controller_manager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ ControllerManager::ControllerManager(
421421
params.activate_all = activate_all_hw_components;
422422
params.update_rate = static_cast<unsigned int>(params_->update_rate);
423423
params.executor = executor_;
424+
params.node_namespace = node_namespace;
424425
params.allow_controller_activation_with_inactive_hardware =
425426
params_->defaults.allow_controller_activation_with_inactive_hardware;
426427
params.return_failed_hardware_names_on_return_deactivate_write_cycle_ =
@@ -650,6 +651,7 @@ void ControllerManager::init_resource_manager(const std::string & robot_descript
650651
params.clock = trigger_clock_;
651652
params.logger = this->get_logger();
652653
params.executor = executor_;
654+
params.node_namespace = this->get_namespace();
653655
params.update_rate = static_cast<unsigned int>(params_->update_rate);
654656
if (!resource_manager_->load_and_initialize_components(params))
655657
{

controller_manager/test/test_controller_manager_with_namespace.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@ class TestControllerManagerWithNamespace
3434
void SetUp()
3535
{
3636
executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
37+
hardware_interface::ResourceManagerParams params;
38+
params.update_rate = 100;
39+
params.clock = rm_node_->get_clock();
40+
params.logger = rm_node_->get_logger();
41+
params.executor = executor_;
42+
params.robot_description = ros2_control_test_assets::minimal_robot_urdf;
43+
params.node_namespace = TEST_NAMESPACE;
3744
cm_ = std::make_shared<controller_manager::ControllerManager>(
38-
std::make_unique<hardware_interface::ResourceManager>(
39-
ros2_control_test_assets::minimal_robot_urdf, rm_node_->get_node_clock_interface(),
40-
rm_node_->get_node_logging_interface(), true),
41-
executor_, TEST_CM_NAME, TEST_NAMESPACE);
45+
std::make_unique<hardware_interface::ResourceManager>(params, true), executor_, TEST_CM_NAME,
46+
TEST_NAMESPACE);
4247
run_updater_ = false;
4348
}
4449
};
@@ -56,6 +61,15 @@ TEST_P(TestControllerManagerWithNamespace, cm_and_controller_in_namespace)
5661
EXPECT_EQ(2u, cm_->get_loaded_controllers().size());
5762
EXPECT_EQ(2, test_controller.use_count());
5863

64+
const auto all_node_names = cm_->get_node_names();
65+
ASSERT_THAT(
66+
all_node_names,
67+
testing::UnorderedElementsAreArray(
68+
{"/test_namespace/test_controller_manager", "/test_namespace/test_controller_name",
69+
"/test_namespace/test_controller2_name", "/test_namespace/testactuatorhardware",
70+
"/test_namespace/testsensorhardware", "/test_namespace/testsystemhardware",
71+
"/ResourceManager"}));
72+
5973
// setup interface to claim from controllers
6074
controller_interface::InterfaceConfiguration cmd_itfs_cfg;
6175
cmd_itfs_cfg.type = controller_interface::interface_configuration_type::INDIVIDUAL;

controller_manager/test/test_spawner_unspawner.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,14 @@ TEST_F(TestLoadControllerWithNamespacedCM, multi_ctrls_test_type_in_param)
983983
EXPECT_EQ(
984984
call_spawner("ctrl_1 ctrl_2 -c test_controller_manager --ros-args -r __ns:=/foo_namespace"), 0);
985985

986+
const auto all_node_names = cm_->get_node_names();
987+
ASSERT_THAT(
988+
all_node_names,
989+
testing::UnorderedElementsAreArray(
990+
{"/foo_namespace/test_controller_manager", "/foo_namespace/ctrl_1", "/foo_namespace/ctrl_2",
991+
"/ResourceManager", "/foo_namespace/testactuatorhardware",
992+
"/foo_namespace/testsensorhardware", "/foo_namespace/testsystemhardware"}));
993+
986994
auto validate_loaded_controllers = [&]()
987995
{
988996
auto loaded_controllers = cm_->get_loaded_controllers();

hardware_interface/include/hardware_interface/hardware_component_interface.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,10 @@ class HardwareComponentInterface : public rclcpp_lifecycle::node_interfaces::Lif
204204

205205
if (auto locked_executor = params.executor.lock())
206206
{
207-
std::string node_name = params.hardware_info.name;
208-
std::transform(
209-
node_name.begin(), node_name.end(), node_name.begin(),
210-
[](unsigned char c) { return std::tolower(c); });
207+
std::string node_name = hardware_interface::to_lower_case(params.hardware_info.name);
211208
std::replace(node_name.begin(), node_name.end(), '/', '_');
212-
hardware_component_node_ =
213-
std::make_shared<rclcpp::Node>(node_name, get_hardware_component_node_options());
209+
hardware_component_node_ = std::make_shared<rclcpp::Node>(
210+
node_name, params.node_namespace, get_hardware_component_node_options());
214211
locked_executor->add_node(hardware_component_node_->get_node_base_interface());
215212
}
216213
else

hardware_interface/include/hardware_interface/types/hardware_component_params.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define HARDWARE_INTERFACE__TYPES__HARDWARE_COMPONENT_PARAMS_HPP_
1717

1818
#include <memory>
19+
#include <string>
1920
#include "hardware_interface/hardware_info.hpp"
2021
#include "rclcpp/rclcpp.hpp"
2122

@@ -49,6 +50,12 @@ struct HardwareComponentParams
4950
*/
5051
rclcpp::Clock::SharedPtr clock = nullptr;
5152

53+
/**
54+
* @brief The namespace used by the hardware component's internal node.
55+
* This is typically same as the controller manager's node namespace.
56+
*/
57+
std::string node_namespace = "";
58+
5259
/**
5360
* @brief Weak pointer to the rclcpp::Executor instance. Hardware components
5461
* can use this (after locking) to add their own internal ROS 2 nodes

hardware_interface/include/hardware_interface/types/resource_manager_params.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ struct ResourceManagerParams
4848
*/
4949
rclcpp::Logger logger = rclcpp::get_logger("resource_manager");
5050

51+
/**
52+
* @brief The namespace used by the ResourceManager and its components.
53+
* This is typically same as the controller manager's node namespace.
54+
*/
55+
std::string node_namespace = "";
56+
5157
/**
5258
* @brief Shared pointer to the rclcpp::Executor instance that the
5359
* ResourceManager and its components (including plugins that opt-in) will use.

hardware_interface/src/resource_manager.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class ResourceStorage
229229
component_params.clock = rm_clock_;
230230
component_params.logger = rm_logger_;
231231
component_params.executor = params.executor;
232+
component_params.node_namespace = params.node_namespace;
232233
RCLCPP_INFO(
233234
get_logger(), "Initialize hardware '%s' ", component_params.hardware_info.name.c_str());
234235

@@ -1298,6 +1299,7 @@ class ResourceStorage
12981299
rclcpp::Clock::SharedPtr rm_clock_;
12991300
rclcpp::Logger rm_logger_;
13001301
rclcpp::Executor::WeakPtr executor_;
1302+
std::string node_namespace_;
13011303

13021304
std::vector<Actuator> actuators_;
13031305
std::vector<Sensor> sensors_;
@@ -1479,6 +1481,7 @@ bool ResourceManager::load_and_initialize_components(
14791481
interface_params.executor = resource_storage_->executor_;
14801482
interface_params.clock = resource_storage_->rm_clock_;
14811483
interface_params.logger = resource_storage_->rm_logger_;
1484+
interface_params.node_namespace = resource_storage_->node_namespace_;
14821485

14831486
if (individual_hardware_info.type == actuator_type)
14841487
{
@@ -1535,6 +1538,7 @@ bool ResourceManager::load_and_initialize_components(
15351538
resource_storage_->robot_description_ = params.robot_description;
15361539
resource_storage_->cm_update_rate_ = params.update_rate;
15371540
resource_storage_->executor_ = params.executor;
1541+
resource_storage_->node_namespace_ = params.node_namespace;
15381542
#pragma GCC diagnostic push
15391543
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
15401544
return load_and_initialize_components(params.robot_description, params.update_rate);

0 commit comments

Comments
 (0)