Skip to content

Commit 69efebb

Browse files
committed
Add controllers chain dependency graph to know the successors and predecessors
1 parent 56fc052 commit 69efebb

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

controller_manager/include/controller_manager/controller_manager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ class ControllerManager : public rclcpp::Node
635635
std::unique_ptr<rclcpp::PreShutdownCallbackHandle> preshutdown_cb_handle_{nullptr};
636636
RTControllerListWrapper rt_controllers_wrapper_;
637637
std::unordered_map<std::string, ControllerChainSpec> controller_chain_spec_;
638+
ControllerChainDependencyGraph controller_chain_dependency_graph_;
638639
std::vector<std::string> ordered_controllers_names_;
639640
/// mutex copied from ROS1 Control, protects service callbacks
640641
/// not needed if we're guaranteed that the callbacks don't come from multiple threads

controller_manager/include/controller_manager/controller_spec.hpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
#ifndef CONTROLLER_MANAGER__CONTROLLER_SPEC_HPP_
2020
#define CONTROLLER_MANAGER__CONTROLLER_SPEC_HPP_
2121

22+
#include <algorithm>
2223
#include <memory>
2324
#include <string>
25+
#include <unordered_map>
26+
#include <unordered_set>
2427
#include <vector>
28+
2529
#include "controller_interface/controller_interface_base.hpp"
2630
#include "hardware_interface/controller_info.hpp"
31+
#include "hardware_interface/helpers.hpp"
2732
#include "hardware_interface/types/statistics_types.hpp"
2833

2934
namespace controller_manager
@@ -57,5 +62,79 @@ struct ControllerChainSpec
5762
std::vector<std::string> following_controllers;
5863
std::vector<std::string> preceding_controllers;
5964
};
65+
66+
class ControllerChainDependencyGraph
67+
{
68+
public:
69+
void add_dependency(const std::string & predecessor, const std::string & successor)
70+
{
71+
if (predecessors.count(predecessor) == 0)
72+
{
73+
predecessors[predecessor] = {};
74+
}
75+
if (successors.count(successor) == 0)
76+
{
77+
successors[successor] = {};
78+
}
79+
80+
ros2_control::add_item(predecessors[successor], predecessor);
81+
ros2_control::add_item(successors[predecessor], successor);
82+
}
83+
84+
void remove_controller(const std::string & controller_name)
85+
{
86+
predecessors.erase(controller_name);
87+
successors.erase(controller_name);
88+
for (auto & [_, succ] : predecessors)
89+
{
90+
succ.erase(std::remove(succ.begin(), succ.end(), controller_name), succ.end());
91+
}
92+
for (auto & [_, preds] : successors)
93+
{
94+
preds.erase(std::remove(preds.begin(), preds.end(), controller_name), preds.end());
95+
}
96+
}
97+
98+
void depth_first_search(
99+
const std::string & controller_name, std::unordered_set<std::string> & visited,
100+
std::unordered_map<std::string, std::vector<std::string>> & graph)
101+
{
102+
if (visited.find(controller_name) != visited.end())
103+
{
104+
return;
105+
}
106+
visited.insert(controller_name);
107+
for (const auto & neighbor : graph[controller_name])
108+
{
109+
if (visited.find(neighbor) == visited.end())
110+
{
111+
depth_first_search(neighbor, visited, graph);
112+
}
113+
}
114+
}
115+
116+
std::vector<std::string> get_all_predecessors(const std::string & controller_name)
117+
{
118+
std::unordered_set<std::string> visited;
119+
depth_first_search(controller_name, visited, predecessors);
120+
std::vector<std::string> predecessors_list;
121+
std::copy(visited.begin(), visited.end(), std::back_inserter(predecessors_list));
122+
return predecessors_list;
123+
}
124+
125+
std::vector<std::string> get_all_successors(const std::string & controller_name)
126+
{
127+
std::unordered_set<std::string> visited;
128+
depth_first_search(controller_name, visited, successors);
129+
std::vector<std::string> successors_list;
130+
std::copy(visited.begin(), visited.end(), std::back_inserter(successors_list));
131+
return successors_list;
132+
}
133+
134+
private:
135+
std::unordered_map<std::string, std::vector<std::string>> predecessors = {};
136+
std::unordered_map<std::string, std::vector<std::string>> successors = {};
137+
};
138+
60139
} // namespace controller_manager
61140
#endif // CONTROLLER_MANAGER__CONTROLLER_SPEC_HPP_

controller_manager/src/controller_manager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ controller_interface::return_type ControllerManager::configure_controller(
13411341
controller_manager::ControllersListIterator ctrl_it;
13421342
if (is_interface_a_chained_interface(cmd_itf, controllers, ctrl_it))
13431343
{
1344+
controller_chain_dependency_graph_.add_dependency(controller_name, ctrl_it->info.name);
13441345
ros2_control::add_item(
13451346
controller_chain_spec_[controller_name].following_controllers, ctrl_it->info.name);
13461347
ros2_control::add_item(
@@ -1355,6 +1356,7 @@ controller_interface::return_type ControllerManager::configure_controller(
13551356
controller_manager::ControllersListIterator ctrl_it;
13561357
if (is_interface_a_chained_interface(state_itf, controllers, ctrl_it))
13571358
{
1359+
controller_chain_dependency_graph_.add_dependency(ctrl_it->info.name, controller_name);
13581360
ros2_control::add_item(
13591361
controller_chain_spec_[controller_name].preceding_controllers, ctrl_it->info.name);
13601362
ros2_control::add_item(

0 commit comments

Comments
 (0)