@@ -403,7 +403,6 @@ void ControllerManager::configure_controller_manager(const controller_manager_ty
403403 case controller_manager_type::distributed_central_controller_manager:
404404 init_distributed_central_controller_manager ();
405405 break ;
406-
407406 case controller_manager_type::distributed_sub_controller_manager:
408407 init_distributed_sub_controller_manager ();
409408 break ;
@@ -419,7 +418,7 @@ void ControllerManager::configure_controller_manager(const controller_manager_ty
419418 }
420419}
421420
422- // TODO(Manuel) don't like this, this is for fast poc
421+ // TODO(Manuel): don't like this, this is for fast poc
423422// probably better to create factory and handle creation of correct controller manager type
424423// there. Since asynchronous control should be supported im the future as well and we don't
425424// want dozen of ifs.
@@ -447,12 +446,27 @@ ControllerManager::controller_manager_type ControllerManager::determine_controll
447446
448447void ControllerManager::init_distributed_sub_controller_manager ()
449448{
449+ // if only one node per sub controller manager is used
450450 if (!use_multiple_nodes ())
451451 {
452+ // create node for publishing/subscribing
452453 rclcpp::NodeOptions node_options;
453454 distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
454455 std::string (get_name ()) + " _pub_sub_node" , get_namespace (), node_options, false );
456+ // try to add to executor
457+ try
458+ {
459+ executor_->add_node (distributed_pub_sub_node_->get_node_base_interface ());
460+ }
461+ catch (const std::runtime_error & e)
462+ {
463+ RCLCPP_WARN_STREAM (
464+ get_logger (),
465+ " ControllerManager: can not add node for distributed publishing/subscribing to executor:"
466+ << e.what ());
467+ }
455468 }
469+
456470 create_hardware_state_publishers ();
457471 create_hardware_command_forwarders ();
458472 register_sub_controller_manager ();
@@ -465,6 +479,18 @@ void ControllerManager::init_distributed_central_controller_manager()
465479 rclcpp::NodeOptions node_options;
466480 distributed_pub_sub_node_ = std::make_shared<rclcpp_lifecycle::LifecycleNode>(
467481 std::string (get_name ()) + " _pub_sub_node" , get_namespace (), node_options, false );
482+ // try to add to executor
483+ try
484+ {
485+ executor_->add_node (distributed_pub_sub_node_->get_node_base_interface ());
486+ }
487+ catch (const std::runtime_error & e)
488+ {
489+ RCLCPP_WARN_STREAM (
490+ get_logger (),
491+ " ControllerManager: can not add node for distributed publishing/subscribing to executor:"
492+ << e.what ());
493+ }
468494 }
469495 init_distributed_central_controller_manager_services ();
470496}
@@ -499,54 +525,66 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
499525 std::vector<std::shared_ptr<hardware_interface::DistributedReadOnlyHandle>>
500526 distributed_state_interfaces;
501527 distributed_state_interfaces.reserve (sub_ctrl_mng_wrapper->get_state_publisher_count ());
528+ // create distributed state interface and import into resource storage.
502529 distributed_state_interfaces =
503530 resource_manager_->import_state_interfaces_of_sub_controller_manager (
504531 sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
505532
506- for (const auto & state_interface : distributed_state_interfaces)
533+ // register every node of state_interface at executor only if multiple nodes
534+ // are used. Otherwise the single nodes has already been added
535+ if (use_multiple_nodes ())
507536 {
508- try
509- {
510- executor_->add_node (state_interface->get_node ()->get_node_base_interface ());
511- }
512- catch (const std::runtime_error & e)
537+ for (const auto & state_interface : distributed_state_interfaces)
513538 {
514- response->ok = false ;
515- RCLCPP_WARN_STREAM (
516- get_logger (),
517- " ControllerManager: Caught exception while trying to register sub controller manager. "
518- " Exception:"
519- << e.what ());
539+ try
540+ {
541+ executor_->add_node (state_interface->get_node ()->get_node_base_interface ());
542+ }
543+ catch (const std::runtime_error & e)
544+ {
545+ response->ok = false ;
546+ RCLCPP_WARN_STREAM (
547+ get_logger (),
548+ " ControllerManager: Caught exception while trying to register node of distributed state "
549+ " interface of sub controller manager. Exception:"
550+ << e.what ());
551+ }
520552 }
521553 }
522554
523555 std::vector<std::shared_ptr<hardware_interface::DistributedReadWriteHandle>>
524556 distributed_command_interfaces;
525557 distributed_command_interfaces.reserve (sub_ctrl_mng_wrapper->get_command_forwarder_count ());
558+ // create distributed command interface and import into resource storage.
526559 distributed_command_interfaces =
527560 resource_manager_->import_command_interfaces_of_sub_controller_manager (
528561 sub_ctrl_mng_wrapper, get_namespace (), distributed_pub_sub_node_);
529562
530563 for (const auto & command_interface : distributed_command_interfaces)
531564 {
532- try
533- {
534- executor_->add_node (command_interface->get_node ()->get_node_base_interface ());
535- }
536- catch (const std::runtime_error & e)
565+ // register every node of command_interface at executor only if multiple nodes
566+ // are used. Otherwise the single nodes has already been added
567+ if (use_multiple_nodes ())
537568 {
538- response->ok = false ;
539- RCLCPP_WARN_STREAM (
540- get_logger (),
541- " ControllerManager: Caught exception while trying to register sub controller manager. "
542- " Exception:"
543- << e.what ());
569+ try
570+ {
571+ executor_->add_node (command_interface->get_node ()->get_node_base_interface ());
572+ }
573+ catch (const std::runtime_error & e)
574+ {
575+ response->ok = false ;
576+ RCLCPP_WARN_STREAM (
577+ get_logger (),
578+ " ControllerManager: Caught exception while trying to register node of distributed "
579+ " command_interface of sub controller manager. Exception:"
580+ << e.what ());
581+ }
544582 }
545583 auto msg = controller_manager_msgs::msg::PublisherDescription ();
546584 msg.ns = get_namespace ();
547585 msg.name .prefix_name = command_interface->get_prefix_name ();
548586 msg.name .interface_name = command_interface->get_interface_name ();
549- // TODO(Manuel) want topic name relative to namespace, but have to treat "root" namespace separate
587+ // TODO(Manuel): want topic name relative to namespace, but have to treat "root" namespace separate
550588 msg.publisher_topic = std::string (" /" ) + command_interface->forward_command_topic_name ();
551589 response->command_state_publishers .push_back (msg);
552590 }
@@ -559,52 +597,92 @@ void ControllerManager::register_sub_controller_manager_srv_cb(
559597
560598void ControllerManager::create_hardware_state_publishers ()
561599{
562- auto available_state_interfaces = resource_manager_-> available_state_interfaces ( );
563-
564- for ( const auto & state_interface : available_state_interfaces )
600+ std::vector<std::string> state_interfaces_to_export = std::vector<std::string>({} );
601+ // export every interface by default
602+ if (! get_parameter ( " export_state_interfaces " , state_interfaces_to_export) )
565603 {
566- auto state_publisher = std::make_shared<distributed_control::StatePublisher>(
567- std::move (std::make_unique<hardware_interface::LoanedStateInterface>(
568- resource_manager_->claim_state_interface (state_interface))),
569- get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_);
570-
571- resource_manager_->add_hardware_state_publishers (state_publisher);
604+ // get all available state interfaces
605+ state_interfaces_to_export = resource_manager_->available_state_interfaces ();
606+ }
572607
608+ for (const auto & state_interface : state_interfaces_to_export)
609+ {
610+ std::shared_ptr<distributed_control::StatePublisher> state_publisher;
573611 try
574612 {
575- executor_->add_node (state_publisher->get_node ()->get_node_base_interface ());
613+ state_publisher = std::make_shared<distributed_control::StatePublisher>(
614+ std::move (std::make_unique<hardware_interface::LoanedStateInterface>(
615+ resource_manager_->claim_state_interface (state_interface))),
616+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_);
576617 }
577- catch (const std::runtime_error & e)
618+ catch (const std::exception & e)
578619 {
579- RCLCPP_WARN_STREAM (
580- get_logger (), " ControllerManager: Can't create StatePublishers<"
581- << state_publisher->state_interface_name () << " >." << e.what ());
620+ RCLCPP_ERROR (
621+ get_logger (), " Can't create StatePublisher for state interface<'%s'>: %s" ,
622+ state_interface.c_str (), e.what ());
623+ continue ;
624+ }
625+
626+ resource_manager_->add_hardware_state_publishers (state_publisher);
627+
628+ if (use_multiple_nodes ())
629+ {
630+ try
631+ {
632+ executor_->add_node (state_publisher->get_node ()->get_node_base_interface ());
633+ }
634+ catch (const std::runtime_error & e)
635+ {
636+ RCLCPP_WARN_STREAM (
637+ get_logger (), " ControllerManager: Can't create StatePublishers<"
638+ << state_publisher->state_interface_name () << " >." << e.what ());
639+ }
582640 }
583641 }
584642}
585643
586644void ControllerManager::create_hardware_command_forwarders ()
587645{
588- auto available_command_interfaces = resource_manager_-> available_command_interfaces ( );
589-
590- for ( auto const & command_interface : available_command_interfaces )
646+ std::vector<std::string> command_interfaces_to_export = std::vector<std::string>({} );
647+ // export every interface by default
648+ if (! get_parameter ( " export_command_interfaces " , command_interfaces_to_export) )
591649 {
592- auto command_forwarder = std::make_shared<distributed_control::CommandForwarder>(
593- std::move (std::make_unique<hardware_interface::LoanedCommandInterface>(
594- resource_manager_->claim_command_interface (command_interface))),
595- get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_);
596-
597- resource_manager_->add_hardware_command_forwarders (command_forwarder);
650+ // get all available command interfaces
651+ command_interfaces_to_export = resource_manager_->available_command_interfaces ();
652+ }
598653
654+ for (auto const & command_interface : command_interfaces_to_export)
655+ {
656+ std::shared_ptr<distributed_control::CommandForwarder> command_forwarder;
599657 try
600658 {
601- executor_->add_node (command_forwarder->get_node ()->get_node_base_interface ());
659+ command_forwarder = std::make_shared<distributed_control::CommandForwarder>(
660+ std::move (std::make_unique<hardware_interface::LoanedCommandInterface>(
661+ resource_manager_->claim_command_interface (command_interface))),
662+ get_namespace (), distributed_interfaces_publish_period (), distributed_pub_sub_node_);
602663 }
603- catch (const std::runtime_error & e)
664+ catch (const std::exception & e)
604665 {
605- RCLCPP_WARN_STREAM (
606- get_logger (), " ControllerManager: Can't create CommandForwarder<"
607- << command_forwarder->command_interface_name () << " >." << e.what ());
666+ RCLCPP_ERROR (
667+ get_logger (), " Can't create CommandForwarder for command interface<'%s'>: %s" ,
668+ command_interface.c_str (), e.what ());
669+ continue ;
670+ }
671+
672+ resource_manager_->add_hardware_command_forwarders (command_forwarder);
673+
674+ if (use_multiple_nodes ())
675+ {
676+ try
677+ {
678+ executor_->add_node (command_forwarder->get_node ()->get_node_base_interface ());
679+ }
680+ catch (const std::runtime_error & e)
681+ {
682+ RCLCPP_WARN_STREAM (
683+ get_logger (), " ControllerManager: Can't create CommandForwarder<"
684+ << command_forwarder->command_interface_name () << " >." << e.what ());
685+ }
608686 }
609687 }
610688}
0 commit comments