Skip to content

Commit f1d6104

Browse files
committed
Add new build_controllers_topology_info method and move common information
1 parent c55262a commit f1d6104

File tree

2 files changed

+84
-27
lines changed

2 files changed

+84
-27
lines changed

controller_manager/include/controller_manager/controller_manager.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,14 @@ class ControllerManager : public rclcpp::Node
501501
const std::string & ctrl_name, std::vector<std::string>::iterator controller_iterator,
502502
bool append_to_controller);
503503

504+
/**
505+
* @brief Build the controller chain topology information based on the provided controllers.
506+
* This method constructs a directed graph representing the dependencies between controllers.
507+
* It analyzes the relationships between controllers, such as which controllers depend on others,
508+
* and builds a directed graph to represent these dependencies.
509+
*/
510+
void build_controllers_topology_info(const std::vector<ControllerSpec> & controllers);
511+
504512
/**
505513
* @brief Method to publish the state of the controller manager.
506514
* The state includes the list of controllers and the list of hardware interfaces along with

controller_manager/src/controller_manager.cpp

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,33 +1336,7 @@ controller_interface::return_type ControllerManager::configure_controller(
13361336
return controller_interface::return_type::ERROR;
13371337
}
13381338

1339-
for (const auto & cmd_itf : cmd_itfs)
1340-
{
1341-
controller_manager::ControllersListIterator ctrl_it;
1342-
if (is_interface_a_chained_interface(cmd_itf, controllers, ctrl_it))
1343-
{
1344-
ros2_control::add_item(
1345-
controller_chain_spec_[controller_name].following_controllers, ctrl_it->info.name);
1346-
ros2_control::add_item(
1347-
controller_chain_spec_[ctrl_it->info.name].preceding_controllers, controller_name);
1348-
ros2_control::add_item(
1349-
controller_chained_reference_interfaces_cache_[ctrl_it->info.name], controller_name);
1350-
}
1351-
}
1352-
// This is needed when we start exporting the state interfaces from the controllers
1353-
for (const auto & state_itf : state_itfs)
1354-
{
1355-
controller_manager::ControllersListIterator ctrl_it;
1356-
if (is_interface_a_chained_interface(state_itf, controllers, ctrl_it))
1357-
{
1358-
ros2_control::add_item(
1359-
controller_chain_spec_[controller_name].preceding_controllers, ctrl_it->info.name);
1360-
ros2_control::add_item(
1361-
controller_chain_spec_[ctrl_it->info.name].following_controllers, controller_name);
1362-
ros2_control::add_item(
1363-
controller_chained_state_interfaces_cache_[ctrl_it->info.name], controller_name);
1364-
}
1365-
}
1339+
build_controllers_topology_info(controllers);
13661340

13671341
// Now let's reorder the controllers
13681342
// lock controllers
@@ -4314,6 +4288,81 @@ void ControllerManager::update_list_with_controller_chain(
43144288
}
43154289
}
43164290

4291+
void ControllerManager::build_controllers_topology_info(
4292+
const std::vector<ControllerSpec> & controllers)
4293+
{
4294+
std::for_each(
4295+
controller_chain_spec_.begin(), controller_chain_spec_.end(),
4296+
[](auto & pair)
4297+
{
4298+
pair.second.following_controllers.clear();
4299+
pair.second.preceding_controllers.clear();
4300+
});
4301+
std::for_each(
4302+
controller_chained_reference_interfaces_cache_.begin(),
4303+
controller_chained_reference_interfaces_cache_.end(), [](auto & pair) { pair.second.clear(); });
4304+
std::for_each(
4305+
controller_chained_state_interfaces_cache_.begin(),
4306+
controller_chained_state_interfaces_cache_.end(), [](auto & pair) { pair.second.clear(); });
4307+
for (const auto & controller : controllers)
4308+
{
4309+
if (is_controller_unconfigured(*controller.c))
4310+
{
4311+
RCLCPP_DEBUG(
4312+
get_logger(), "Controller '%s' is unconfigured, skipping chain building.",
4313+
controller.info.name.c_str());
4314+
continue;
4315+
}
4316+
const auto cmd_itfs = controller.c->command_interface_configuration().names;
4317+
const auto state_itfs = controller.c->state_interface_configuration().names;
4318+
4319+
for (const auto & cmd_itf : cmd_itfs)
4320+
{
4321+
controller_manager::ControllersListIterator ctrl_it;
4322+
if (is_interface_a_chained_interface(cmd_itf, controllers, ctrl_it))
4323+
{
4324+
ros2_control::add_item(
4325+
controller_chain_spec_[controller.info.name].following_controllers, ctrl_it->info.name);
4326+
ros2_control::add_item(
4327+
controller_chain_spec_[ctrl_it->info.name].preceding_controllers, controller.info.name);
4328+
ros2_control::add_item(
4329+
controller_chained_reference_interfaces_cache_[ctrl_it->info.name], controller.info.name);
4330+
}
4331+
}
4332+
// This is needed when we start exporting the state interfaces from the controllers
4333+
for (const auto & state_itf : state_itfs)
4334+
{
4335+
controller_manager::ControllersListIterator ctrl_it;
4336+
if (is_interface_a_chained_interface(state_itf, controllers, ctrl_it))
4337+
{
4338+
ros2_control::add_item(
4339+
controller_chain_spec_[controller.info.name].preceding_controllers, ctrl_it->info.name);
4340+
ros2_control::add_item(
4341+
controller_chain_spec_[ctrl_it->info.name].following_controllers, controller.info.name);
4342+
ros2_control::add_item(
4343+
controller_chained_state_interfaces_cache_[ctrl_it->info.name], controller.info.name);
4344+
}
4345+
}
4346+
}
4347+
for (const auto & [controller_name, controller_chain] : controller_chain_spec_)
4348+
{
4349+
RCLCPP_INFO(
4350+
get_logger(), "Controller '%s' has %ld following controllers and %ld preceding controllers.",
4351+
controller_name.c_str(), controller_chain.following_controllers.size(),
4352+
controller_chain.preceding_controllers.size());
4353+
RCLCPP_INFO_EXPRESSION(
4354+
get_logger(), !controller_chain.following_controllers.empty(),
4355+
fmt::format(
4356+
"\tFollowing controllers are : {}", fmt::join(controller_chain.following_controllers, ", "))
4357+
.c_str());
4358+
RCLCPP_INFO_EXPRESSION(
4359+
get_logger(), !controller_chain.preceding_controllers.empty(),
4360+
fmt::format(
4361+
"\tPreceding controllers are : {}", fmt::join(controller_chain.preceding_controllers, ", "))
4362+
.c_str());
4363+
}
4364+
}
4365+
43174366
rclcpp::NodeOptions ControllerManager::determine_controller_node_options(
43184367
const ControllerSpec & controller) const
43194368
{

0 commit comments

Comments
 (0)