@@ -445,6 +445,13 @@ struct ControllerPeerInfo
445
445
// All predecessors of the controller should be deactivated except the state interface ones
446
446
for (const auto & predecessor : predecessors)
447
447
{
448
+ if (ros2_control::has_item (controllers_to_deactivate, predecessor->name ))
449
+ {
450
+ RCLCPP_ERROR_STREAM (
451
+ rclcpp::get_logger (" controller_manager" ),
452
+ " The predecessor: " << predecessor->name << " is already in the deactivation list." );
453
+ continue ;
454
+ }
448
455
ros2_control::add_item (controllers_to_deactivate, predecessor->name );
449
456
std::for_each (
450
457
state_interfaces.begin (), state_interfaces.end (),
@@ -461,11 +468,48 @@ struct ControllerPeerInfo
461
468
// All successors of controller with no command interfaces should be deactivated
462
469
for (const auto & successor : successors)
463
470
{
471
+ if (ros2_control::has_item (controllers_to_deactivate, successor->name ))
472
+ {
473
+ RCLCPP_ERROR_STREAM (
474
+ rclcpp::get_logger (" controller_manager" ),
475
+ " The successor: " << successor->name << " is already in the deactivation list." );
476
+ continue ;
477
+ }
478
+ RCLCPP_INFO (
479
+ rclcpp::get_logger (" controller_manager" ),
480
+ fmt::format (
481
+ " The controllers to deactivate list is {}" , fmt::join (controllers_to_deactivate, " , " ))
482
+ .c_str ());
483
+
484
+ // Check if the successor is an individual exclusive group, if so, then return
485
+ if (std::any_of (
486
+ mutually_exclusive_successor_groups.begin (), mutually_exclusive_successor_groups.end (),
487
+ [&successor](const std::unordered_set<std::string> & group)
488
+ { return group.find (successor->name ) != group.end () && group.size () == 1 ; }))
489
+ {
490
+ RCLCPP_INFO_STREAM (
491
+ rclcpp::get_logger (" controller_manager" ),
492
+ " The successor: " << successor->name
493
+ << " is in a mutually exclusive group, skipping further deactivation." );
494
+ continue ;
495
+ }
496
+
464
497
if (successor->command_interfaces .empty ())
465
498
{
466
499
ros2_control::add_item (controllers_to_deactivate, successor->name );
467
- successor->get_controllers_to_deactivate (controllers_to_deactivate);
500
+ RCLCPP_INFO_STREAM (
501
+ rclcpp::get_logger (" controller_manager" ),
502
+ " Adding successor: " << successor->name
503
+ << " to the deactivation list, as it has no command interfaces." );
504
+ }
505
+ else
506
+ {
507
+ RCLCPP_ERROR (
508
+ rclcpp::get_logger (" controller_manager" ),
509
+ " Controller %s has a successor %s who has command interfaces. This is not supported now." ,
510
+ name.c_str (), successor->name .c_str ());
468
511
}
512
+ successor->get_controllers_to_deactivate (controllers_to_deactivate);
469
513
}
470
514
}
471
515
};
0 commit comments