@@ -1298,6 +1298,7 @@ controller_interface::return_type ControllerManager::configure_controller(
1298
1298
void ControllerManager::clear_requests ()
1299
1299
{
1300
1300
switch_params_.do_switch = false ;
1301
+ switch_params_.activate_asap = false ;
1301
1302
switch_params_.deactivate_request .clear ();
1302
1303
switch_params_.activate_request .clear ();
1303
1304
// Set these interfaces as unavailable when clearing requests to avoid leaving them in available
@@ -1871,17 +1872,27 @@ controller_interface::return_type ControllerManager::switch_controller_cb(
1871
1872
switch_params_.do_switch = true ;
1872
1873
1873
1874
// wait until switch is finished
1874
- RCLCPP_DEBUG (get_logger (), " Requested atomic controller switch from realtime loop" );
1875
- std::unique_lock<std::mutex> switch_params_guard (switch_params_.mutex );
1876
- if (!switch_params_.cv .wait_for (
1877
- switch_params_guard, switch_params_.timeout , [this ] { return !switch_params_.do_switch ; }))
1878
- {
1879
- message = fmt::format (
1880
- FMT_COMPILE (" Switch controller timed out after {} seconds!" ),
1881
- static_cast <double >(switch_params_.timeout .count ()) / 1e9 );
1882
- RCLCPP_ERROR (get_logger (), " %s" , message.c_str ());
1883
- clear_requests ();
1884
- return controller_interface::return_type::ERROR;
1875
+ if (switch_params_.activate_asap )
1876
+ {
1877
+ RCLCPP_DEBUG (get_logger (), " Requested atomic controller switch from realtime loop" );
1878
+ std::unique_lock<std::mutex> switch_params_guard (switch_params_.mutex );
1879
+ if (!switch_params_.cv .wait_for (
1880
+ switch_params_guard, switch_params_.timeout ,
1881
+ [this ] { return !switch_params_.do_switch ; }))
1882
+ {
1883
+ message = fmt::format (
1884
+ FMT_COMPILE (" Switch controller timed out after {} seconds!" ),
1885
+ static_cast <double >(switch_params_.timeout .count ()) / 1e9 );
1886
+ RCLCPP_ERROR (get_logger (), " %s" , message.c_str ());
1887
+ clear_requests ();
1888
+ return controller_interface::return_type::ERROR;
1889
+ }
1890
+ }
1891
+ else
1892
+ {
1893
+ RCLCPP_INFO (get_logger (), " Requested controller switch from non-realtime loop" );
1894
+ // This should work as the realtime thread operation is read-only operation
1895
+ manage_switch ();
1885
1896
}
1886
1897
1887
1898
// copy the controllers spec from the used to the unused list
@@ -1983,7 +1994,7 @@ controller_interface::ControllerInterfaceBaseSharedPtr ControllerManager::add_co
1983
1994
1984
1995
void ControllerManager::deactivate_controllers (
1985
1996
const std::vector<ControllerSpec> & rt_controller_list,
1986
- const std::vector<std::string> controllers_to_deactivate)
1997
+ const std::vector<std::string> & controllers_to_deactivate)
1987
1998
{
1988
1999
// deactivate controllers
1989
2000
for (const auto & controller_name : controllers_to_deactivate)
@@ -2087,7 +2098,7 @@ void ControllerManager::switch_chained_mode(
2087
2098
2088
2099
void ControllerManager::activate_controllers (
2089
2100
const std::vector<ControllerSpec> & rt_controller_list,
2090
- const std::vector<std::string> controllers_to_activate)
2101
+ const std::vector<std::string> & controllers_to_activate)
2091
2102
{
2092
2103
for (const auto & controller_name : controllers_to_activate)
2093
2104
{
@@ -2239,14 +2250,6 @@ void ControllerManager::activate_controllers(
2239
2250
}
2240
2251
}
2241
2252
2242
- void ControllerManager::activate_controllers_asap (
2243
- const std::vector<ControllerSpec> & rt_controller_list,
2244
- const std::vector<std::string> controllers_to_activate)
2245
- {
2246
- // https://github.com/ros-controls/ros2_control/issues/263
2247
- activate_controllers (rt_controller_list, controllers_to_activate);
2248
- }
2249
-
2250
2253
void ControllerManager::list_controllers_srv_cb (
2251
2254
const std::shared_ptr<controller_manager_msgs::srv::ListControllers::Request>,
2252
2255
std::shared_ptr<controller_manager_msgs::srv::ListControllers::Response> response)
@@ -2788,6 +2791,15 @@ controller_interface::return_type ControllerManager::update(
2788
2791
rt_buffer_.deactivate_controllers_list .clear ();
2789
2792
for (const auto & loaded_controller : rt_controller_list)
2790
2793
{
2794
+ if (
2795
+ switch_params_.do_switch && !switch_params_.activate_asap &&
2796
+ switch_params_.skip_cycle (loaded_controller))
2797
+ {
2798
+ RCLCPP_DEBUG (
2799
+ get_logger (), " Skipping update for controller '%s' as it is being switched" ,
2800
+ loaded_controller.info .name .c_str ());
2801
+ continue ;
2802
+ }
2791
2803
// TODO(v-lopez) we could cache this information
2792
2804
// https://github.com/ros-controls/ros2_control/issues/153
2793
2805
if (is_controller_active (*loaded_controller.c ))
@@ -2944,7 +2956,7 @@ controller_interface::return_type ControllerManager::update(
2944
2956
resource_manager_->enforce_command_limits (period);
2945
2957
2946
2958
// there are controllers to (de)activate
2947
- if (switch_params_.do_switch )
2959
+ if (switch_params_.do_switch && switch_params_. activate_asap )
2948
2960
{
2949
2961
manage_switch ();
2950
2962
}
0 commit comments