@@ -831,16 +831,21 @@ void ControllerManager::clear_requests()
831
{
831
{
832
deactivate_request_.clear ();
832
deactivate_request_.clear ();
833
activate_request_.clear ();
833
activate_request_.clear ();
834
- // Set these interfaces as unavailable when clearing requests to avoid leaving them in available
834
+ clear_chained_mode_requests ();
835
- // state without the controller being in active state
835
+ activate_command_interface_request_.clear ();
836
+ deactivate_command_interface_request_.clear ();
837
+ }
838
+
839
+ void ControllerManager::clear_chained_mode_requests ()
840
+ {
841
+ // Set these interfaces as unavailable when clearing requests to avoid leaving them in
842
+ // available state without the controller being in active state
836
for (const auto & controller_name : to_chained_mode_request_)
843
for (const auto & controller_name : to_chained_mode_request_)
837
{
844
{
838
resource_manager_->make_controller_reference_interfaces_unavailable (controller_name);
845
resource_manager_->make_controller_reference_interfaces_unavailable (controller_name);
839
}
846
}
840
to_chained_mode_request_.clear ();
847
to_chained_mode_request_.clear ();
841
from_chained_mode_request_.clear ();
848
from_chained_mode_request_.clear ();
842
- activate_command_interface_request_.clear ();
843
- deactivate_command_interface_request_.clear ();
844
}
849
}
845
850
846
controller_interface::return_type ControllerManager::switch_controller (
851
controller_interface::return_type ControllerManager::switch_controller (
@@ -963,136 +968,25 @@ controller_interface::return_type ControllerManager::switch_controller(
963
968
964
const std::vector<ControllerSpec> & controllers = rt_controllers_wrapper_.get_updated_list (guard);
969
const std::vector<ControllerSpec> & controllers = rt_controllers_wrapper_.get_updated_list (guard);
965
970
966
- enum class CreateRequestResult
967
- {
968
- OK,
969
- ERROR,
970
- RETRY
971
- };
972
-
973
const auto check_de_activate_request_and_create_chained_mode_request =
971
const auto check_de_activate_request_and_create_chained_mode_request =
974
- [this , &strictness, &controllers]() -> CreateRequestResult
972
+ [this , &strictness, &controllers]() -> CheckDeActivateRequestResult
975
- {
976
- const auto clear_chained_mode_requests = [this ]()
977
{
973
{
978
- // Set these interfaces as unavailable when clearing requests to avoid leaving them in
979
- // available state without the controller being in active state
980
- for (const auto & controller_name : to_chained_mode_request_)
981
- {
982
- resource_manager_->make_controller_reference_interfaces_unavailable (controller_name);
983
- }
984
- to_chained_mode_request_.clear ();
985
- from_chained_mode_request_.clear ();
986
- };
987
-
988
// if a preceding controller is deactivated, all first-level controllers should be switched
974
// if a preceding controller is deactivated, all first-level controllers should be switched
989
// 'from' chained mode
975
// 'from' chained mode
990
propagate_deactivation_of_chained_mode (controllers);
976
propagate_deactivation_of_chained_mode (controllers);
991
977
992
- // check if controllers should be switched 'to' chained mode when controllers are activated
978
+ if (const auto result = check_activate_requests (controllers, strictness);
993
- for (auto ctrl_it = activate_request_.begin (); ctrl_it != activate_request_.end (); ++ctrl_it)
979
+ result != CheckDeActivateRequestResult::OK)
994
- {
995
- auto controller_it = std::find_if (
996
- controllers.begin (), controllers.end (),
997
- std::bind (controller_name_compare, std::placeholders::_1, *ctrl_it));
998
- controller_interface::return_type status = controller_interface::return_type::OK;
999
-
1000
- // if controller is not inactive then do not do any following-controllers checks
1001
- if (!is_controller_inactive (controller_it->c ))
1002
- {
1003
- RCLCPP_WARN (
1004
- get_logger (),
1005
- " Controller with name '%s' is not inactive so its following "
1006
- " controllers do not have to be checked, because it cannot be activated." ,
1007
- controller_it->info .name .c_str ());
1008
- status = controller_interface::return_type::ERROR;
1009
- }
1010
- else
1011
- {
1012
- status = check_following_controllers_for_activate (controllers, strictness, controller_it);
1013
- }
1014
-
1015
- if (status != controller_interface::return_type::OK)
1016
- {
1017
- RCLCPP_WARN (
1018
- get_logger (),
1019
- " Could not activate controller with name '%s'. Check above warnings for more details. "
1020
- " Check the state of the controllers and their required interfaces using "
1021
- " `ros2 control list_controllers -v` CLI to get more information." ,
1022
- (*ctrl_it).c_str ());
1023
- if (strictness == controller_manager_msgs::srv::SwitchController::Request::BEST_EFFORT)
1024
- {
1025
- // TODO(destogl): automatic manipulation of the chain:
1026
- // || strictness ==
1027
- // controller_manager_msgs::srv::SwitchController::Request::MANIPULATE_CONTROLLERS_CHAIN);
1028
- // remove controller that can not be activated from the activation request and step-back
1029
- // iterator to correctly step to the next element in the list in the loop
1030
- activate_request_.erase (ctrl_it);
1031
- // reset chained mode request lists and will retry the creation of the request
1032
- clear_chained_mode_requests ();
1033
- return CreateRequestResult::RETRY;
1034
- }
1035
- if (strictness == controller_manager_msgs::srv::SwitchController::Request::STRICT)
1036
- {
1037
- RCLCPP_ERROR (get_logger (), " Aborting, no controller is switched! (::STRICT switch)" );
1038
- // reset all lists
1039
- clear_requests ();
1040
- return CreateRequestResult::ERROR;
1041
- }
1042
- }
1043
- }
1044
-
1045
- // check if controllers should be deactivated if used in chained mode
1046
- for (auto ctrl_it = deactivate_request_.begin (); ctrl_it != deactivate_request_.end ();
1047
- ++ctrl_it)
1048
- {
1049
- auto controller_it = std::find_if (
1050
- controllers.begin (), controllers.end (),
1051
- std::bind (controller_name_compare, std::placeholders::_1, *ctrl_it));
1052
- controller_interface::return_type status = controller_interface::return_type::OK;
1053
-
1054
- // if controller is not active then skip preceding-controllers checks
1055
- if (!is_controller_active (controller_it->c ))
1056
{
980
{
1057
- RCLCPP_WARN (
981
+ return result;
1058
- get_logger (), " Controller with name '%s' can not be deactivated since it is not active." ,
1059
- controller_it->info .name .c_str ());
1060
- status = controller_interface::return_type::ERROR;
1061
}
982
}
1062
- else
983
+ if (const auto result = check_deactivate_requests (controllers, strictness);
984
+ result != CheckDeActivateRequestResult::OK)
1063
{
985
{
1064
- status =
986
+ return result;
1065
- check_preceeding_controllers_for_deactivate (controllers, strictness, controller_it);
1066
}
987
}
1067
988
1068
- if (status != controller_interface::return_type::OK)
989
+ return CheckDeActivateRequestResult::OK;
1069
- {
1070
- RCLCPP_WARN (
1071
- get_logger (),
1072
- " Could not deactivate controller with name '%s'. Check above warnings for more details. "
1073
- " Check the state of the controllers and their required interfaces using "
1074
- " `ros2 control list_controllers -v` CLI to get more information." ,
1075
- (*ctrl_it).c_str ());
1076
- if (strictness == controller_manager_msgs::srv::SwitchController::Request::BEST_EFFORT)
1077
- {
1078
- // remove controller that can not be activated from the activation request and step-back
1079
- // iterator to correctly step to the next element in the list in the loop
1080
- deactivate_request_.erase (ctrl_it);
1081
- // reset chained mode request lists and will retry the creation of the request
1082
- clear_chained_mode_requests ();
1083
- return CreateRequestResult::RETRY;
1084
- }
1085
- if (strictness == controller_manager_msgs::srv::SwitchController::Request::STRICT)
1086
- {
1087
- RCLCPP_ERROR (get_logger (), " Aborting, no controller is switched! (::STRICT switch)" );
1088
- // reset all lists
1089
- clear_requests ();
1090
- return CreateRequestResult::ERROR;
1091
- }
1092
- }
1093
- }
1094
-
1095
- return CreateRequestResult::OK;
1096
};
990
};
1097
991
1098
// Validate the (de)activate request and create from/to chained mode requests as needed.
992
// Validate the (de)activate request and create from/to chained mode requests as needed.
@@ -1104,15 +998,15 @@ controller_interface::return_type ControllerManager::switch_controller(
1104
while (true )
998
while (true )
1105
{
999
{
1106
const auto result = check_de_activate_request_and_create_chained_mode_request ();
1000
const auto result = check_de_activate_request_and_create_chained_mode_request ();
1107
- if (result == CreateRequestResult ::RETRY)
1001
+ if (result == CheckDeActivateRequestResult ::RETRY)
1108
{
1002
{
1109
continue ;
1003
continue ;
1110
}
1004
}
1111
- if (result == CreateRequestResult ::ERROR)
1005
+ if (result == CheckDeActivateRequestResult ::ERROR)
1112
{
1006
{
1113
return controller_interface::return_type::ERROR;
1007
return controller_interface::return_type::ERROR;
1114
}
1008
}
1115
- // if result == CreateRequestResult ::OK -> break the loop
1009
+ // if result == CheckDeActivateRequestResult ::OK -> break the loop
1116
break ;
1010
break ;
1117
}
1011
}
1118
1012
@@ -2550,6 +2444,68 @@ controller_interface::return_type ControllerManager::check_following_controllers
2550
return controller_interface::return_type::OK;
2444
return controller_interface::return_type::OK;
2551
};
2445
};
2552
2446
2447
+ ControllerManager::CheckDeActivateRequestResult ControllerManager::check_activate_requests (
2448
+ const std::vector<ControllerSpec> & controllers, int strictness)
2449
+ {
2450
+ // check if controllers should be switched 'to' chained mode when controllers are activated
2451
+ for (auto ctrl_it = activate_request_.begin (); ctrl_it != activate_request_.end (); ++ctrl_it)
2452
+ {
2453
+ auto controller_it = std::find_if (
2454
+ controllers.begin (), controllers.end (),
2455
+ std::bind (controller_name_compare, std::placeholders::_1, *ctrl_it));
2456
+ controller_interface::return_type status = controller_interface::return_type::OK;
2457
+
2458
+ // if controller is not inactive then do not do any following-controllers checks
2459
+ if (
2460
+ !is_controller_inactive (controller_it->c ) &&
2461
+ std::find (deactivate_request_.begin (), deactivate_request_.end (), *ctrl_it) ==
2462
+ deactivate_request_.end ())
2463
+ {
2464
+ RCLCPP_WARN (
2465
+ get_logger (),
2466
+ " Controller with name '%s' is not inactive so its following "
2467
+ " controllers do not have to be checked, because it cannot be activated." ,
2468
+ controller_it->info .name .c_str ());
2469
+ status = controller_interface::return_type::ERROR;
2470
+ }
2471
+ else
2472
+ {
2473
+ status = check_following_controllers_for_activate (controllers, strictness, controller_it);
2474
+ }
2475
+
2476
+ if (status != controller_interface::return_type::OK)
2477
+ {
2478
+ RCLCPP_WARN (
2479
+ get_logger (),
2480
+ " Could not activate controller with name '%s'. Check above warnings for more details. "
2481
+ " Check the state of the controllers and their required interfaces using "
2482
+ " `ros2 control list_controllers -v` CLI to get more information." ,
2483
+ (*ctrl_it).c_str ());
2484
+ if (strictness == controller_manager_msgs::srv::SwitchController::Request::BEST_EFFORT)
2485
+ {
2486
+ // TODO(destogl): automatic manipulation of the chain:
2487
+ // || strictness ==
2488
+ // controller_manager_msgs::srv::SwitchController::Request::MANIPULATE_CONTROLLERS_CHAIN);
2489
+ // remove controller that can not be activated from the activation request and step-back
2490
+ // iterator to correctly step to the next element in the list in the loop
2491
+ activate_request_.erase (ctrl_it);
2492
+ // reset chained mode request lists and will retry the creation of the request
2493
+ clear_chained_mode_requests ();
2494
+ return CheckDeActivateRequestResult::RETRY;
2495
+ }
2496
+ if (strictness == controller_manager_msgs::srv::SwitchController::Request::STRICT)
2497
+ {
2498
+ RCLCPP_ERROR (get_logger (), " Aborting, no controller is switched! (::STRICT switch)" );
2499
+ // reset all lists
2500
+ clear_requests ();
2501
+ return CheckDeActivateRequestResult::ERROR;
2502
+ }
2503
+ }
2504
+ }
2505
+
2506
+ return CheckDeActivateRequestResult::OK;
2507
+ }
2508
+
2553
controller_interface::return_type ControllerManager::check_preceeding_controllers_for_deactivate (
2509
controller_interface::return_type ControllerManager::check_preceeding_controllers_for_deactivate (
2554
const std::vector<ControllerSpec> & controllers, int /* strictness*/ ,
2510
const std::vector<ControllerSpec> & controllers, int /* strictness*/ ,
2555
const ControllersListIterator controller_it)
2511
const ControllersListIterator controller_it)
@@ -2636,6 +2592,60 @@ controller_interface::return_type ControllerManager::check_preceeding_controller
2636
return controller_interface::return_type::OK;
2592
return controller_interface::return_type::OK;
2637
}
2593
}
2638
2594
2595
+ ControllerManager::CheckDeActivateRequestResult ControllerManager::check_deactivate_requests (
2596
+ const std::vector<ControllerSpec> & controllers, int strictness)
2597
+ {
2598
+ // check if controllers should be deactivated if used in chained mode
2599
+ for (auto ctrl_it = deactivate_request_.begin (); ctrl_it != deactivate_request_.end (); ++ctrl_it)
2600
+ {
2601
+ auto controller_it = std::find_if (
2602
+ controllers.begin (), controllers.end (),
2603
+ std::bind (controller_name_compare, std::placeholders::_1, *ctrl_it));
2604
+ controller_interface::return_type status = controller_interface::return_type::OK;
2605
+
2606
+ // if controller is not active then skip preceding-controllers checks
2607
+ if (!is_controller_active (controller_it->c ))
2608
+ {
2609
+ RCLCPP_WARN (
2610
+ get_logger (), " Controller with name '%s' can not be deactivated since it is not active." ,
2611
+ controller_it->info .name .c_str ());
2612
+ status = controller_interface::return_type::ERROR;
2613
+ }
2614
+ else
2615
+ {
2616
+ status = check_preceeding_controllers_for_deactivate (controllers, strictness, controller_it);
2617
+ }
2618
+
2619
+ if (status != controller_interface::return_type::OK)
2620
+ {
2621
+ RCLCPP_WARN (
2622
+ get_logger (),
2623
+ " Could not deactivate controller with name '%s'. Check above warnings for more details. "
2624
+ " Check the state of the controllers and their required interfaces using "
2625
+ " `ros2 control list_controllers -v` CLI to get more information." ,
2626
+ (*ctrl_it).c_str ());
2627
+ if (strictness == controller_manager_msgs::srv::SwitchController::Request::BEST_EFFORT)
2628
+ {
2629
+ // remove controller that can not be activated from the activation request and step-back
2630
+ // iterator to correctly step to the next element in the list in the loop
2631
+ deactivate_request_.erase (ctrl_it);
2632
+ // reset chained mode request lists and will retry the creation of the request
2633
+ clear_chained_mode_requests ();
2634
+ return CheckDeActivateRequestResult::RETRY;
2635
+ }
2636
+ if (strictness == controller_manager_msgs::srv::SwitchController::Request::STRICT)
2637
+ {
2638
+ RCLCPP_ERROR (get_logger (), " Aborting, no controller is switched! (::STRICT switch)" );
2639
+ // reset all lists
2640
+ clear_requests ();
2641
+ return CheckDeActivateRequestResult::ERROR;
2642
+ }
2643
+ }
2644
+ }
2645
+
2646
+ return CheckDeActivateRequestResult::OK;
2647
+ }
2648
+
2639
void ControllerManager::controller_activity_diagnostic_callback (
2649
void ControllerManager::controller_activity_diagnostic_callback (
2640
diagnostic_updater::DiagnosticStatusWrapper & stat)
2650
diagnostic_updater::DiagnosticStatusWrapper & stat)
2641
{
2651
{
0 commit comments