@@ -181,7 +181,9 @@ ControllerManager::ControllerManager(
181181 diagnostics_updater_.add (
182182 " Controllers Activity" , this , &ControllerManager::controller_activity_diagnostic_callback);
183183 init_services ();
184- configure_controller_manager ();
184+ get_and_initialize_distributed_parameters ();
185+ auto cm_type = determine_controller_manager_type ();
186+ configure_controller_manager (cm_type);
185187}
186188
187189ControllerManager::ControllerManager (
@@ -209,7 +211,9 @@ ControllerManager::ControllerManager(
209211 diagnostics_updater_.add (
210212 " Controllers Activity" , this , &ControllerManager::controller_activity_diagnostic_callback);
211213 init_services ();
212- configure_controller_manager ();
214+ get_and_initialize_distributed_parameters ();
215+ auto cm_type = determine_controller_manager_type ();
216+ configure_controller_manager (cm_type);
213217}
214218
215219void ControllerManager::subscribe_to_robot_description_topic ()
@@ -354,11 +358,7 @@ void ControllerManager::init_services()
354358 qos_services, best_effort_callback_group_);
355359}
356360
357- // TODO(Manuel) don't like this, this is for fast poc
358- // probably better to create factory and handle creation of correct controller manager type
359- // there. Since asynchronous control should be supported im the future as well and we don't
360- // want dozen of ifs.
361- void ControllerManager::configure_controller_manager ()
361+ void ControllerManager::get_and_initialize_distributed_parameters ()
362362{
363363 if (!get_parameter (" distributed" , distributed_))
364364 {
@@ -374,50 +374,102 @@ void ControllerManager::configure_controller_manager()
374374 sub_controller_manager_ ? " true" : " false" );
375375 }
376376
377+ int64_t distributed_interfaces_publish_period;
378+ if (get_parameter (" distributed_interfaces_publish_period" , distributed_interfaces_publish_period))
379+ {
380+ distributed_interfaces_publish_period_ =
381+ std::chrono::milliseconds (distributed_interfaces_publish_period);
382+ }
383+
384+ else
385+ {
386+ RCLCPP_WARN (
387+ get_logger (),
388+ " 'distributed_interfaces_publish_period' parameter not set, using default value." );
389+ }
390+
391+ if (!get_parameter (" use_multiple_nodes" , use_multiple_nodes_))
392+ {
393+ RCLCPP_WARN (
394+ get_logger (), " 'use_multiple_nodes' parameter not set, using default value:%s" ,
395+ use_multiple_nodes_ ? " true" : " false" );
396+ }
397+ }
398+
399+ void ControllerManager::configure_controller_manager (const controller_manager_type & cm_type)
400+ {
401+ switch (cm_type)
402+ {
403+ case controller_manager_type::distributed_central_controller_manager:
404+ init_distributed_central_controller_manager ();
405+ break ;
406+
407+ case controller_manager_type::distributed_sub_controller_manager:
408+ init_distributed_sub_controller_manager ();
409+ break ;
410+ case controller_manager_type::standard_controller_manager:
411+ // nothing special to configure
412+ break ;
413+ default :
414+ throw std::logic_error (
415+ " Controller manager configuration not possible. Not a known controller manager type."
416+ " Did you maybe set `distributed:false` and `sub_controller_manager:true`?"
417+ " Note:Only distributed controller manager can be a sub controller manager." );
418+ break ;
419+ }
420+ }
421+
422+ // TODO(Manuel) don't like this, this is for fast poc
423+ // probably better to create factory and handle creation of correct controller manager type
424+ // there. Since asynchronous control should be supported im the future as well and we don't
425+ // want dozen of ifs.
426+ ControllerManager::controller_manager_type ControllerManager::determine_controller_manager_type ()
427+ {
377428 bool std_controller_manager = !distributed_ && !sub_controller_manager_;
378429 bool distributed_sub_controller_manager = distributed_ && sub_controller_manager_;
379430 bool central_controller_manager = distributed_ && !sub_controller_manager_;
380431 if (distributed_sub_controller_manager)
381432 {
382- init_distributed_sub_controller_manager () ;
433+ return controller_manager_type::distributed_sub_controller_manager ;
383434 }
384435 // This means we are the central controller manager
385436 else if (central_controller_manager)
386437 {
387- init_distributed_main_controller_services () ;
438+ return controller_manager_type::distributed_central_controller_manager ;
388439 }
389440 // std controller manager or error. std controller manager needs no special setup.
390- else
441+ else if (std_controller_manager)
391442 {
392- if (!std_controller_manager)
393- {
394- throw std::logic_error (
395- " Controller manager configured with: distributed:false and sub_controller_manager:true. "
396- " Only distributed controller manager can be a sub controller manager." );
397- }
443+ return controller_manager_type::standard_controller_manager;
398444 }
445+ return controller_manager_type::unkown_type;
399446}
400447
401448void ControllerManager::init_distributed_sub_controller_manager ()
402449{
403- int64_t distributed_interfaces_publish_period;
404- if (get_parameter (" distributed_interfaces_publish_period" , distributed_interfaces_publish_period))
405- {
406- distributed_interfaces_publish_period_ =
407- std::chrono::milliseconds (distributed_interfaces_publish_period);
408- }
409- else
450+ if (!use_multiple_nodes ())
410451 {
411- RCLCPP_WARN (
412- get_logger (),
413- " 'distributed_interfaces_publish_period' parameter not set, using default value. " );
452+ rclcpp::NodeOptions node_options;
453+ distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
454+ std::string ( get_name ()) + " _pub_sub_node " , get_namespace (), node_options, false );
414455 }
415456 add_hardware_state_publishers ();
416457 add_hardware_command_forwarders ();
417458 register_sub_controller_manager ();
418459}
419460
420- void ControllerManager::init_distributed_main_controller_services ()
461+ void ControllerManager::init_distributed_central_controller_manager ()
462+ {
463+ if (!use_multiple_nodes ())
464+ {
465+ rclcpp::NodeOptions node_options;
466+ distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
467+ std::string (get_name ()) + " _pub_sub_node" , get_namespace (), node_options, false );
468+ }
469+ init_distributed_central_controller_manager_services ();
470+ }
471+
472+ void ControllerManager::init_distributed_central_controller_manager_services ()
421473{
422474 distributed_system_srv_callback_group_ =
423475 create_callback_group (rclcpp::CallbackGroupType::MutuallyExclusive);
@@ -448,7 +500,8 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
448500 distributed_state_interfaces;
449501 distributed_state_interfaces.reserve (sub_ctrl_mng_wrapper->get_state_publisher_count ());
450502 distributed_state_interfaces =
451- resource_manager_->import_state_interfaces_of_sub_controller_manager (sub_ctrl_mng_wrapper);
503+ resource_manager_->import_state_interfaces_of_sub_controller_manager (
504+ sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
452505
453506 for (const auto & state_interface : distributed_state_interfaces)
454507 {
@@ -471,7 +524,8 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
471524 distributed_command_interfaces;
472525 distributed_command_interfaces.reserve (sub_ctrl_mng_wrapper->get_command_forwarder_count ());
473526 distributed_command_interfaces =
474- resource_manager_->import_command_interfaces_of_sub_controller_manager (sub_ctrl_mng_wrapper);
527+ resource_manager_->import_command_interfaces_of_sub_controller_manager (
528+ sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
475529
476530 for (const auto & command_interface : distributed_command_interfaces)
477531 {
@@ -508,7 +562,7 @@ void ControllerManager::add_hardware_state_publishers()
508562 std::vector<std::shared_ptr<distributed_control::StatePublisher>> state_publishers_vec;
509563 state_publishers_vec.reserve (resource_manager_->available_state_interfaces ().size ());
510564 state_publishers_vec = resource_manager_->create_hardware_state_publishers (
511- get_namespace (), distributed_interfaces_publish_period ());
565+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_ );
512566
513567 for (auto const & state_publisher : state_publishers_vec)
514568 {
@@ -530,7 +584,7 @@ void ControllerManager::add_hardware_command_forwarders()
530584 std::vector<std::shared_ptr<distributed_control::CommandForwarder>> command_forwarder_vec;
531585 command_forwarder_vec.reserve (resource_manager_->available_command_interfaces ().size ());
532586 command_forwarder_vec = resource_manager_->create_hardware_command_forwarders (
533- get_namespace (), distributed_interfaces_publish_period ());
587+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_ );
534588
535589 for (auto const & command_forwarder : command_forwarder_vec)
536590 {
@@ -2254,6 +2308,8 @@ std::pair<std::string, std::string> ControllerManager::split_command_interface(
22542308
22552309unsigned int ControllerManager::get_update_rate () const { return update_rate_; }
22562310
2311+ bool ControllerManager::use_multiple_nodes () const { return use_multiple_nodes_; }
2312+
22572313std::chrono::milliseconds ControllerManager::distributed_interfaces_publish_period () const
22582314{
22592315 return distributed_interfaces_publish_period_;
0 commit comments