@@ -174,7 +174,9 @@ ControllerManager::ControllerManager(
174174 diagnostics_updater_.add (
175175 " Controllers Activity" , this , &ControllerManager::controller_activity_diagnostic_callback);
176176 init_services ();
177- configure_controller_manager ();
177+ get_and_initialize_distributed_parameters ();
178+ auto cm_type = determine_controller_manager_type ();
179+ configure_controller_manager (cm_type);
178180}
179181
180182ControllerManager::ControllerManager (
@@ -199,7 +201,9 @@ ControllerManager::ControllerManager(
199201 diagnostics_updater_.add (
200202 " Controllers Activity" , this , &ControllerManager::controller_activity_diagnostic_callback);
201203 init_services ();
202- configure_controller_manager ();
204+ get_and_initialize_distributed_parameters ();
205+ auto cm_type = determine_controller_manager_type ();
206+ configure_controller_manager (cm_type);
203207}
204208
205209void ControllerManager::init_resource_manager (const std::string & robot_description)
@@ -304,11 +308,7 @@ void ControllerManager::init_services()
304308 qos_services, best_effort_callback_group_);
305309}
306310
307- // TODO(Manuel) don't like this, this is for fast poc
308- // probably better to create factory and handle creation of correct controller manager type
309- // there. Since asynchronous control should be supported im the future as well and we don't
310- // want dozen of ifs.
311- void ControllerManager::configure_controller_manager ()
311+ void ControllerManager::get_and_initialize_distributed_parameters ()
312312{
313313 if (!get_parameter (" distributed" , distributed_))
314314 {
@@ -324,50 +324,102 @@ void ControllerManager::configure_controller_manager()
324324 sub_controller_manager_ ? " true" : " false" );
325325 }
326326
327+ int64_t distributed_interfaces_publish_period;
328+ if (get_parameter (" distributed_interfaces_publish_period" , distributed_interfaces_publish_period))
329+ {
330+ distributed_interfaces_publish_period_ =
331+ std::chrono::milliseconds (distributed_interfaces_publish_period);
332+ }
333+
334+ else
335+ {
336+ RCLCPP_WARN (
337+ get_logger (),
338+ " 'distributed_interfaces_publish_period' parameter not set, using default value." );
339+ }
340+
341+ if (!get_parameter (" use_multiple_nodes" , use_multiple_nodes_))
342+ {
343+ RCLCPP_WARN (
344+ get_logger (), " 'use_multiple_nodes' parameter not set, using default value:%s" ,
345+ use_multiple_nodes_ ? " true" : " false" );
346+ }
347+ }
348+
349+ void ControllerManager::configure_controller_manager (const controller_manager_type & cm_type)
350+ {
351+ switch (cm_type)
352+ {
353+ case controller_manager_type::distributed_central_controller_manager:
354+ init_distributed_central_controller_manager ();
355+ break ;
356+
357+ case controller_manager_type::distributed_sub_controller_manager:
358+ init_distributed_sub_controller_manager ();
359+ break ;
360+ case controller_manager_type::standard_controller_manager:
361+ // nothing special to configure
362+ break ;
363+ default :
364+ throw std::logic_error (
365+ " Controller manager configuration not possible. Not a known controller manager type."
366+ " Did you maybe set `distributed:false` and `sub_controller_manager:true`?"
367+ " Note:Only distributed controller manager can be a sub controller manager." );
368+ break ;
369+ }
370+ }
371+
372+ // TODO(Manuel) don't like this, this is for fast poc
373+ // probably better to create factory and handle creation of correct controller manager type
374+ // there. Since asynchronous control should be supported im the future as well and we don't
375+ // want dozen of ifs.
376+ ControllerManager::controller_manager_type ControllerManager::determine_controller_manager_type ()
377+ {
327378 bool std_controller_manager = !distributed_ && !sub_controller_manager_;
328379 bool distributed_sub_controller_manager = distributed_ && sub_controller_manager_;
329380 bool central_controller_manager = distributed_ && !sub_controller_manager_;
330381 if (distributed_sub_controller_manager)
331382 {
332- init_distributed_sub_controller_manager () ;
383+ return controller_manager_type::distributed_sub_controller_manager ;
333384 }
334385 // This means we are the central controller manager
335386 else if (central_controller_manager)
336387 {
337- init_distributed_main_controller_services () ;
388+ return controller_manager_type::distributed_central_controller_manager ;
338389 }
339390 // std controller manager or error. std controller manager needs no special setup.
340- else
391+ else if (std_controller_manager)
341392 {
342- if (!std_controller_manager)
343- {
344- throw std::logic_error (
345- " Controller manager configured with: distributed:false and sub_controller_manager:true. "
346- " Only distributed controller manager can be a sub controller manager." );
347- }
393+ return controller_manager_type::standard_controller_manager;
348394 }
395+ return controller_manager_type::unkown_type;
349396}
350397
351398void ControllerManager::init_distributed_sub_controller_manager ()
352399{
353- int64_t distributed_interfaces_publish_period;
354- if (get_parameter (" distributed_interfaces_publish_period" , distributed_interfaces_publish_period))
355- {
356- distributed_interfaces_publish_period_ =
357- std::chrono::milliseconds (distributed_interfaces_publish_period);
358- }
359- else
400+ if (!use_multiple_nodes ())
360401 {
361- RCLCPP_WARN (
362- get_logger (),
363- " 'distributed_interfaces_publish_period' parameter not set, using default value. " );
402+ rclcpp::NodeOptions node_options;
403+ distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
404+ std::string ( get_name ()) + " _pub_sub_node " , get_namespace (), node_options, false );
364405 }
365406 add_hardware_state_publishers ();
366407 add_hardware_command_forwarders ();
367408 register_sub_controller_manager ();
368409}
369410
370- void ControllerManager::init_distributed_main_controller_services ()
411+ void ControllerManager::init_distributed_central_controller_manager ()
412+ {
413+ if (!use_multiple_nodes ())
414+ {
415+ rclcpp::NodeOptions node_options;
416+ distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
417+ std::string (get_name ()) + " _pub_sub_node" , get_namespace (), node_options, false );
418+ }
419+ init_distributed_central_controller_manager_services ();
420+ }
421+
422+ void ControllerManager::init_distributed_central_controller_manager_services ()
371423{
372424 distributed_system_srv_callback_group_ =
373425 create_callback_group (rclcpp::CallbackGroupType::MutuallyExclusive);
@@ -398,7 +450,8 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
398450 distributed_state_interfaces;
399451 distributed_state_interfaces.reserve (sub_ctrl_mng_wrapper->get_state_publisher_count ());
400452 distributed_state_interfaces =
401- resource_manager_->import_state_interfaces_of_sub_controller_manager (sub_ctrl_mng_wrapper);
453+ resource_manager_->import_state_interfaces_of_sub_controller_manager (
454+ sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
402455
403456 for (const auto & state_interface : distributed_state_interfaces)
404457 {
@@ -421,7 +474,8 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
421474 distributed_command_interfaces;
422475 distributed_command_interfaces.reserve (sub_ctrl_mng_wrapper->get_command_forwarder_count ());
423476 distributed_command_interfaces =
424- resource_manager_->import_command_interfaces_of_sub_controller_manager (sub_ctrl_mng_wrapper);
477+ resource_manager_->import_command_interfaces_of_sub_controller_manager (
478+ sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
425479
426480 for (const auto & command_interface : distributed_command_interfaces)
427481 {
@@ -458,7 +512,7 @@ void ControllerManager::add_hardware_state_publishers()
458512 std::vector<std::shared_ptr<distributed_control::StatePublisher>> state_publishers_vec;
459513 state_publishers_vec.reserve (resource_manager_->available_state_interfaces ().size ());
460514 state_publishers_vec = resource_manager_->create_hardware_state_publishers (
461- get_namespace (), distributed_interfaces_publish_period ());
515+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_ );
462516
463517 for (auto const & state_publisher : state_publishers_vec)
464518 {
@@ -480,7 +534,7 @@ void ControllerManager::add_hardware_command_forwarders()
480534 std::vector<std::shared_ptr<distributed_control::CommandForwarder>> command_forwarder_vec;
481535 command_forwarder_vec.reserve (resource_manager_->available_command_interfaces ().size ());
482536 command_forwarder_vec = resource_manager_->create_hardware_command_forwarders (
483- get_namespace (), distributed_interfaces_publish_period ());
537+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_ );
484538
485539 for (auto const & command_forwarder : command_forwarder_vec)
486540 {
@@ -2204,6 +2258,8 @@ std::pair<std::string, std::string> ControllerManager::split_command_interface(
22042258
22052259unsigned int ControllerManager::get_update_rate () const { return update_rate_; }
22062260
2261+ bool ControllerManager::use_multiple_nodes () const { return use_multiple_nodes_; }
2262+
22072263std::chrono::milliseconds ControllerManager::distributed_interfaces_publish_period () const
22082264{
22092265 return distributed_interfaces_publish_period_;
0 commit comments