@@ -91,6 +91,22 @@ std::string interfaces_to_string(
91
91
return ss.str ();
92
92
};
93
93
94
+ void get_hardware_related_interfaces (
95
+ const std::vector<std::string> & hw_command_itfs,
96
+ const std::vector<std::string> & start_stop_interfaces_list,
97
+ std::vector<std::string> & hw_interfaces)
98
+ {
99
+ hw_interfaces.clear ();
100
+ for (const auto & interface : start_stop_interfaces_list)
101
+ {
102
+ if (
103
+ std::find (hw_command_itfs.begin (), hw_command_itfs.end (), interface) != hw_command_itfs.end ())
104
+ {
105
+ hw_interfaces.push_back (interface);
106
+ }
107
+ }
108
+ }
109
+
94
110
class ResourceStorage
95
111
{
96
112
static constexpr const char * pkg_name = " hardware_interface" ;
@@ -672,6 +688,8 @@ class ResourceStorage
672
688
auto interfaces = hardware.export_command_interfaces ();
673
689
hardware_info_map_[hardware.get_name ()].command_interfaces =
674
690
add_command_interfaces (interfaces);
691
+ start_interfaces_buffer_.reserve (start_interfaces_buffer_.capacity () + interfaces.size ());
692
+ stop_interfaces_buffer_.reserve (stop_interfaces_buffer_.capacity () + interfaces.size ());
675
693
// TODO(Manuel) END: for backward compatibility
676
694
}
677
695
catch (const std::exception & ex)
@@ -1306,6 +1324,10 @@ class ResourceStorage
1306
1324
// / The callback to be called when a component state is switched
1307
1325
std::function<void ()> on_component_state_switch_callback_ = nullptr ;
1308
1326
1327
+ // To be used with the prepare and perform command switch for the hardware components
1328
+ std::vector<std::string> start_interfaces_buffer_;
1329
+ std::vector<std::string> stop_interfaces_buffer_;
1330
+
1309
1331
// Update rate of the controller manager, and the clock interface of its node
1310
1332
// Used by async components.
1311
1333
unsigned int cm_update_rate_ = 100 ;
@@ -1902,12 +1924,24 @@ bool ResourceManager::prepare_command_mode_switch(
1902
1924
return false ;
1903
1925
}
1904
1926
1927
+ const auto & hardware_info_map = resource_storage_->hardware_info_map_ ;
1905
1928
auto call_prepare_mode_switch =
1906
- [&start_interfaces, &stop_interfaces, logger = get_logger ()](auto & components)
1929
+ [&start_interfaces, &stop_interfaces, &hardware_info_map, logger = get_logger ()](
1930
+ auto & components, auto & start_interfaces_buffer, auto & stop_interfaces_buffer)
1907
1931
{
1908
1932
bool ret = true ;
1909
1933
for (auto & component : components)
1910
1934
{
1935
+ const auto & hw_command_itfs = hardware_info_map.at (component.get_name ()).command_interfaces ;
1936
+ get_hardware_related_interfaces (hw_command_itfs, start_interfaces, start_interfaces_buffer);
1937
+ get_hardware_related_interfaces (hw_command_itfs, stop_interfaces, stop_interfaces_buffer);
1938
+ if (start_interfaces_buffer.empty () && stop_interfaces_buffer.empty ())
1939
+ {
1940
+ RCLCPP_DEBUG (
1941
+ logger, " Component '%s' after filtering has no command interfaces to switch" ,
1942
+ component.get_name ().c_str ());
1943
+ continue ;
1944
+ }
1911
1945
if (
1912
1946
component.get_lifecycle_state ().id () ==
1913
1947
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE ||
@@ -1917,12 +1951,12 @@ bool ResourceManager::prepare_command_mode_switch(
1917
1951
{
1918
1952
if (
1919
1953
return_type::OK !=
1920
- component.prepare_command_mode_switch (start_interfaces, stop_interfaces ))
1954
+ component.prepare_command_mode_switch (start_interfaces_buffer, stop_interfaces_buffer ))
1921
1955
{
1922
1956
RCLCPP_ERROR (
1923
1957
logger, " Component '%s' did not accept command interfaces combination: \n %s" ,
1924
1958
component.get_name ().c_str (),
1925
- interfaces_to_string (start_interfaces, stop_interfaces ).c_str ());
1959
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer ).c_str ());
1926
1960
ret = false ;
1927
1961
}
1928
1962
}
@@ -1933,7 +1967,8 @@ bool ResourceManager::prepare_command_mode_switch(
1933
1967
" Exception of type : %s occurred while preparing command mode switch for component "
1934
1968
" '%s' for the interfaces: \n %s : %s" ,
1935
1969
typeid (e).name (), component.get_name ().c_str (),
1936
- interfaces_to_string (start_interfaces, stop_interfaces).c_str (), e.what ());
1970
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer).c_str (),
1971
+ e.what ());
1937
1972
ret = false ;
1938
1973
}
1939
1974
catch (...)
@@ -1943,16 +1978,27 @@ bool ResourceManager::prepare_command_mode_switch(
1943
1978
" Unknown exception occurred while preparing command mode switch for component '%s' for "
1944
1979
" the interfaces: \n %s" ,
1945
1980
component.get_name ().c_str (),
1946
- interfaces_to_string (start_interfaces, stop_interfaces ).c_str ());
1981
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer ).c_str ());
1947
1982
ret = false ;
1948
1983
}
1949
1984
}
1985
+ else
1986
+ {
1987
+ RCLCPP_WARN (
1988
+ logger, " Component '%s' is not in INACTIVE or ACTIVE state, skipping the prepare switch" ,
1989
+ component.get_name ().c_str ());
1990
+ ret = false ;
1991
+ }
1950
1992
}
1951
1993
return ret;
1952
1994
};
1953
1995
1954
- const bool actuators_result = call_prepare_mode_switch (resource_storage_->actuators_ );
1955
- const bool systems_result = call_prepare_mode_switch (resource_storage_->systems_ );
1996
+ const bool actuators_result = call_prepare_mode_switch (
1997
+ resource_storage_->actuators_ , resource_storage_->start_interfaces_buffer_ ,
1998
+ resource_storage_->stop_interfaces_buffer_ );
1999
+ const bool systems_result = call_prepare_mode_switch (
2000
+ resource_storage_->systems_ , resource_storage_->start_interfaces_buffer_ ,
2001
+ resource_storage_->stop_interfaces_buffer_ );
1956
2002
1957
2003
return actuators_result && systems_result;
1958
2004
}
@@ -1968,12 +2014,24 @@ bool ResourceManager::perform_command_mode_switch(
1968
2014
return true ;
1969
2015
}
1970
2016
2017
+ const auto & hardware_info_map = resource_storage_->hardware_info_map_ ;
1971
2018
auto call_perform_mode_switch =
1972
- [&start_interfaces, &stop_interfaces, logger = get_logger ()](auto & components)
2019
+ [&start_interfaces, &stop_interfaces, &hardware_info_map, logger = get_logger ()](
2020
+ auto & components, auto & start_interfaces_buffer, auto & stop_interfaces_buffer)
1973
2021
{
1974
2022
bool ret = true ;
1975
2023
for (auto & component : components)
1976
2024
{
2025
+ const auto & hw_command_itfs = hardware_info_map.at (component.get_name ()).command_interfaces ;
2026
+ get_hardware_related_interfaces (hw_command_itfs, start_interfaces, start_interfaces_buffer);
2027
+ get_hardware_related_interfaces (hw_command_itfs, stop_interfaces, stop_interfaces_buffer);
2028
+ if (start_interfaces_buffer.empty () && stop_interfaces_buffer.empty ())
2029
+ {
2030
+ RCLCPP_DEBUG (
2031
+ logger, " Component '%s' after filtering has no command interfaces to perform switch" ,
2032
+ component.get_name ().c_str ());
2033
+ continue ;
2034
+ }
1977
2035
if (
1978
2036
component.get_lifecycle_state ().id () ==
1979
2037
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE ||
@@ -1983,10 +2041,12 @@ bool ResourceManager::perform_command_mode_switch(
1983
2041
{
1984
2042
if (
1985
2043
return_type::OK !=
1986
- component.perform_command_mode_switch (start_interfaces, stop_interfaces ))
2044
+ component.perform_command_mode_switch (start_interfaces_buffer, stop_interfaces_buffer ))
1987
2045
{
1988
2046
RCLCPP_ERROR (
1989
- logger, " Component '%s' could not perform switch" , component.get_name ().c_str ());
2047
+ logger, " Component '%s' could not perform switch for the command interfaces: \n %s" ,
2048
+ component.get_name ().c_str (),
2049
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer).c_str ());
1990
2050
ret = false ;
1991
2051
}
1992
2052
}
@@ -1997,7 +2057,8 @@ bool ResourceManager::perform_command_mode_switch(
1997
2057
" Exception of type : %s occurred while performing command mode switch for component "
1998
2058
" '%s' for the interfaces: \n %s : %s" ,
1999
2059
typeid (e).name (), component.get_name ().c_str (),
2000
- interfaces_to_string (start_interfaces, stop_interfaces).c_str (), e.what ());
2060
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer).c_str (),
2061
+ e.what ());
2001
2062
ret = false ;
2002
2063
}
2003
2064
catch (...)
@@ -2008,16 +2069,27 @@ bool ResourceManager::perform_command_mode_switch(
2008
2069
" for "
2009
2070
" the interfaces: \n %s" ,
2010
2071
component.get_name ().c_str (),
2011
- interfaces_to_string (start_interfaces, stop_interfaces ).c_str ());
2072
+ interfaces_to_string (start_interfaces_buffer, stop_interfaces_buffer ).c_str ());
2012
2073
ret = false ;
2013
2074
}
2014
2075
}
2076
+ else
2077
+ {
2078
+ RCLCPP_WARN (
2079
+ logger, " Component '%s' is not in INACTIVE or ACTIVE state, skipping the perform switch" ,
2080
+ component.get_name ().c_str ());
2081
+ ret = false ;
2082
+ }
2015
2083
}
2016
2084
return ret;
2017
2085
};
2018
2086
2019
- const bool actuators_result = call_perform_mode_switch (resource_storage_->actuators_ );
2020
- const bool systems_result = call_perform_mode_switch (resource_storage_->systems_ );
2087
+ const bool actuators_result = call_perform_mode_switch (
2088
+ resource_storage_->actuators_ , resource_storage_->start_interfaces_buffer_ ,
2089
+ resource_storage_->stop_interfaces_buffer_ );
2090
+ const bool systems_result = call_perform_mode_switch (
2091
+ resource_storage_->systems_ , resource_storage_->start_interfaces_buffer_ ,
2092
+ resource_storage_->stop_interfaces_buffer_ );
2021
2093
2022
2094
if (actuators_result && systems_result)
2023
2095
{
0 commit comments