@@ -101,6 +101,8 @@ class ResourceStorage
101101 component_info.class_type = hardware_info.hardware_class_type ;
102102
103103 hardware_info_map_.insert (std::make_pair (component_info.name , component_info));
104+ hardware_used_by_controllers_.insert (
105+ std::make_pair (component_info.name , std::vector<std::string>()));
104106 }
105107
106108 template <class HardwareT >
@@ -195,6 +197,58 @@ class ResourceStorage
195197 return result;
196198 }
197199
200+ void remove_all_hardware_interfaces_from_available_list (const std::string & hardware_name)
201+ {
202+ // remove all command interfaces from available list
203+ for (const auto & interface : hardware_info_map_[hardware_name].command_interfaces )
204+ {
205+ auto found_it = std::find (
206+ available_command_interfaces_.begin (), available_command_interfaces_.end (), interface);
207+
208+ if (found_it != available_command_interfaces_.end ())
209+ {
210+ available_command_interfaces_.erase (found_it);
211+ RCUTILS_LOG_DEBUG_NAMED (
212+ " resource_manager" , " (hardware '%s'): '%s' command interface removed from available list" ,
213+ hardware_name.c_str (), interface.c_str ());
214+ }
215+ else
216+ {
217+ // TODO(destogl): do here error management if interfaces are only partially added into
218+ // "available" list - this should never be the case!
219+ RCUTILS_LOG_WARN_NAMED (
220+ " resource_manager" ,
221+ " (hardware '%s'): '%s' command interface not in available list. "
222+ " This should not happen (hint: multiple cleanup calls)." ,
223+ hardware_name.c_str (), interface.c_str ());
224+ }
225+ }
226+ // remove all state interfaces from available list
227+ for (const auto & interface : hardware_info_map_[hardware_name].state_interfaces )
228+ {
229+ auto found_it = std::find (
230+ available_state_interfaces_.begin (), available_state_interfaces_.end (), interface);
231+
232+ if (found_it != available_state_interfaces_.end ())
233+ {
234+ available_state_interfaces_.erase (found_it);
235+ RCUTILS_LOG_DEBUG_NAMED (
236+ " resource_manager" , " (hardware '%s'): '%s' state interface removed from available list" ,
237+ hardware_name.c_str (), interface.c_str ());
238+ }
239+ else
240+ {
241+ // TODO(destogl): do here error management if interfaces are only partially added into
242+ // "available" list - this should never be the case!
243+ RCUTILS_LOG_WARN_NAMED (
244+ " resource_manager" ,
245+ " (hardware '%s'): '%s' state interface not in available list. "
246+ " This should not happen (hint: multiple cleanup calls)." ,
247+ hardware_name.c_str (), interface.c_str ());
248+ }
249+ }
250+ }
251+
198252 template <class HardwareT >
199253 bool cleanup_hardware (HardwareT & hardware)
200254 {
@@ -204,55 +258,7 @@ class ResourceStorage
204258
205259 if (result)
206260 {
207- // remove all command interfaces from available list
208- for (const auto & interface : hardware_info_map_[hardware.get_name ()].command_interfaces )
209- {
210- auto found_it = std::find (
211- available_command_interfaces_.begin (), available_command_interfaces_.end (), interface);
212-
213- if (found_it != available_command_interfaces_.end ())
214- {
215- available_command_interfaces_.erase (found_it);
216- RCUTILS_LOG_DEBUG_NAMED (
217- " resource_manager" ,
218- " (hardware '%s'): '%s' command interface removed from available list" ,
219- hardware.get_name ().c_str (), interface.c_str ());
220- }
221- else
222- {
223- // TODO(destogl): do here error management if interfaces are only partially added into
224- // "available" list - this should never be the case!
225- RCUTILS_LOG_WARN_NAMED (
226- " resource_manager" ,
227- " (hardware '%s'): '%s' command interface not in available list."
228- " This can happen due to multiple calls to 'cleanup'" ,
229- hardware.get_name ().c_str (), interface.c_str ());
230- }
231- }
232- // remove all state interfaces from available list
233- for (const auto & interface : hardware_info_map_[hardware.get_name ()].state_interfaces )
234- {
235- auto found_it = std::find (
236- available_state_interfaces_.begin (), available_state_interfaces_.end (), interface);
237-
238- if (found_it != available_state_interfaces_.end ())
239- {
240- available_state_interfaces_.erase (found_it);
241- RCUTILS_LOG_DEBUG_NAMED (
242- " resource_manager" , " (hardware '%s'): '%s' state interface removed from available list" ,
243- hardware.get_name ().c_str (), interface.c_str ());
244- }
245- else
246- {
247- // TODO(destogl): do here error management if interfaces are only partially added into
248- // "available" list - this should never be the case!
249- RCUTILS_LOG_WARN_NAMED (
250- " resource_manager" ,
251- " (hardware '%s'): '%s' state interface not in available list. "
252- " This can happen due to multiple calls to 'cleanup'" ,
253- hardware.get_name ().c_str (), interface.c_str ());
254- }
255- }
261+ remove_all_hardware_interfaces_from_available_list (hardware.get_name ());
256262 }
257263 return result;
258264 }
@@ -629,6 +635,10 @@ class ResourceStorage
629635
630636 std::unordered_map<std::string, HardwareComponentInfo> hardware_info_map_;
631637
638+ // / Mapping between hardware and controllers that are using it (accessing data from it)
639+ std::unordered_map<std::string, std::vector<std::string>> hardware_used_by_controllers_;
640+
641+ // / Mapping between controllers and list of reference interfaces they are using
632642 std::unordered_map<std::string, std::vector<std::string>> controllers_reference_interfaces_map_;
633643
634644 // / Storage of all available state interfaces
@@ -699,6 +709,11 @@ void ResourceManager::load_urdf(const std::string & urdf, bool validate_interfac
699709 {
700710 validate_storage (hardware_info);
701711 }
712+
713+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
714+ read_write_status.failed_hardware_names .reserve (
715+ resource_storage_->actuators_ .size () + resource_storage_->sensors_ .size () +
716+ resource_storage_->systems_ .size ());
702717}
703718
704719bool ResourceManager::is_urdf_already_loaded () const { return is_urdf_loaded__; }
@@ -807,6 +822,51 @@ void ResourceManager::remove_controller_reference_interfaces(const std::string &
807822 resource_storage_->remove_command_interfaces (interface_names);
808823}
809824
825+ void ResourceManager::cache_controller_to_hardware (
826+ const std::string & controller_name, const std::vector<std::string> & interfaces)
827+ {
828+ for (const auto & interface : interfaces)
829+ {
830+ bool found = false ;
831+ for (const auto & [hw_name, hw_info] : resource_storage_->hardware_info_map_ )
832+ {
833+ auto cmd_itf_it =
834+ std::find (hw_info.command_interfaces .begin (), hw_info.command_interfaces .end (), interface);
835+ if (cmd_itf_it != hw_info.command_interfaces .end ())
836+ {
837+ found = true ;
838+ }
839+ auto state_itf_it =
840+ std::find (hw_info.state_interfaces .begin (), hw_info.state_interfaces .end (), interface);
841+ if (state_itf_it != hw_info.state_interfaces .end ())
842+ {
843+ found = true ;
844+ }
845+
846+ if (found)
847+ {
848+ // check if controller exist already in the list and if not add it
849+ auto controllers = resource_storage_->hardware_used_by_controllers_ [hw_name];
850+ auto ctrl_it = std::find (controllers.begin (), controllers.end (), controller_name);
851+ if (ctrl_it == controllers.end ())
852+ {
853+ // add because it does not exist
854+ controllers.reserve (controllers.size () + 1 );
855+ controllers.push_back (controller_name);
856+ }
857+ resource_storage_->hardware_used_by_controllers_ [hw_name] = controllers;
858+ break ;
859+ }
860+ }
861+ }
862+ }
863+
864+ std::vector<std::string> ResourceManager::get_cached_controllers_to_hardware (
865+ const std::string & hardware_name)
866+ {
867+ return resource_storage_->hardware_used_by_controllers_ [hardware_name];
868+ }
869+
810870// CM API: Called in "update"-thread
811871bool ResourceManager::command_interface_is_claimed (const std::string & key) const
812872{
@@ -895,19 +955,31 @@ size_t ResourceManager::sensor_components_size() const
895955void ResourceManager::import_component (
896956 std::unique_ptr<ActuatorInterface> actuator, const HardwareInfo & hardware_info)
897957{
958+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
898959 resource_storage_->initialize_actuator (std::move (actuator), hardware_info);
960+ read_write_status.failed_hardware_names .reserve (
961+ resource_storage_->actuators_ .size () + resource_storage_->sensors_ .size () +
962+ resource_storage_->systems_ .size ());
899963}
900964
901965void ResourceManager::import_component (
902966 std::unique_ptr<SensorInterface> sensor, const HardwareInfo & hardware_info)
903967{
968+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
904969 resource_storage_->initialize_sensor (std::move (sensor), hardware_info);
970+ read_write_status.failed_hardware_names .reserve (
971+ resource_storage_->actuators_ .size () + resource_storage_->sensors_ .size () +
972+ resource_storage_->systems_ .size ());
905973}
906974
907975void ResourceManager::import_component (
908976 std::unique_ptr<SystemInterface> system, const HardwareInfo & hardware_info)
909977{
978+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
910979 resource_storage_->initialize_system (std::move (system), hardware_info);
980+ read_write_status.failed_hardware_names .reserve (
981+ resource_storage_->actuators_ .size () + resource_storage_->sensors_ .size () +
982+ resource_storage_->systems_ .size ());
911983}
912984
913985size_t ResourceManager::system_components_size () const
@@ -1089,32 +1161,57 @@ return_type ResourceManager::set_component_state(
10891161 return result;
10901162}
10911163
1092- void ResourceManager::read (const rclcpp::Time & time, const rclcpp::Duration & period)
1164+ HardwareReadWriteStatus ResourceManager::read (
1165+ const rclcpp::Time & time, const rclcpp::Duration & period)
10931166{
1094- for (auto & component : resource_storage_->actuators_ )
1095- {
1096- component.read (time, period);
1097- }
1098- for (auto & component : resource_storage_->sensors_ )
1099- {
1100- component.read (time, period);
1101- }
1102- for (auto & component : resource_storage_->systems_ )
1167+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
1168+ read_write_status.ok = true ;
1169+ read_write_status.failed_hardware_names .clear ();
1170+
1171+ auto read_components = [&](auto & components)
11031172 {
1104- component.read (time, period);
1105- }
1173+ for (auto & component : components)
1174+ {
1175+ if (component.read (time, period) != return_type::OK)
1176+ {
1177+ read_write_status.ok = false ;
1178+ read_write_status.failed_hardware_names .push_back (component.get_name ());
1179+ resource_storage_->remove_all_hardware_interfaces_from_available_list (component.get_name ());
1180+ }
1181+ }
1182+ };
1183+
1184+ read_components (resource_storage_->actuators_ );
1185+ read_components (resource_storage_->sensors_ );
1186+ read_components (resource_storage_->systems_ );
1187+
1188+ return read_write_status;
11061189}
11071190
1108- void ResourceManager::write (const rclcpp::Time & time, const rclcpp::Duration & period)
1191+ HardwareReadWriteStatus ResourceManager::write (
1192+ const rclcpp::Time & time, const rclcpp::Duration & period)
11091193{
1110- for ( auto & component : resource_storage_-> actuators_ )
1111- {
1112- component. write (time, period );
1113- }
1114- for (auto & component : resource_storage_-> systems_ )
1194+ std::lock_guard<std::recursive_mutex> guard (resources_lock_);
1195+ read_write_status. ok = true ;
1196+ read_write_status. failed_hardware_names . clear ( );
1197+
1198+ auto write_components = [&] (auto & components )
11151199 {
1116- component.write (time, period);
1117- }
1200+ for (auto & component : components)
1201+ {
1202+ if (component.write (time, period) != return_type::OK)
1203+ {
1204+ read_write_status.ok = false ;
1205+ read_write_status.failed_hardware_names .push_back (component.get_name ());
1206+ resource_storage_->remove_all_hardware_interfaces_from_available_list (component.get_name ());
1207+ }
1208+ }
1209+ };
1210+
1211+ write_components (resource_storage_->actuators_ );
1212+ write_components (resource_storage_->systems_ );
1213+
1214+ return read_write_status;
11181215}
11191216
11201217void ResourceManager::validate_storage (
0 commit comments