Skip to content

Commit 5f3d162

Browse files
committed
Add new build_controllers_topology_info method and move common information
1 parent b47c835 commit 5f3d162

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
@@ -4313,6 +4287,81 @@ void ControllerManager::update_list_with_controller_chain(
43134287
}
43144288
}
43154289

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

0 commit comments

Comments
 (0)