Skip to content

Commit 82107d2

Browse files
authored
Merge branch 'master' into add/sw_joint_limiter
2 parents ece0933 + 0792a35 commit 82107d2

File tree

14 files changed

+292
-186
lines changed

14 files changed

+292
-186
lines changed

controller_interface/include/controller_interface/controller_interface_base.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,12 @@ class ControllerInterfaceBase : public rclcpp_lifecycle::node_interfaces::Lifecy
258258
protected:
259259
std::vector<hardware_interface::LoanedCommandInterface> command_interfaces_;
260260
std::vector<hardware_interface::LoanedStateInterface> state_interfaces_;
261-
unsigned int update_rate_ = 0;
262-
bool is_async_ = false;
263-
std::string urdf_ = "";
264261

265262
private:
266263
std::shared_ptr<rclcpp_lifecycle::LifecycleNode> node_;
264+
unsigned int update_rate_ = 0;
265+
bool is_async_ = false;
266+
std::string urdf_ = "";
267267
};
268268

269269
using ControllerInterfaceBaseSharedPtr = std::shared_ptr<ControllerInterfaceBase>;

controller_manager/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ if(BUILD_TESTING)
152152
)
153153
target_link_libraries(test_controller_manager_urdf_passing
154154
controller_manager
155+
test_controller
155156
ros2_control_test_assets::ros2_control_test_assets
156157
)
157158
ament_target_dependencies(test_controller_manager_urdf_passing

controller_manager/doc/userdoc.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jitter, using a lowlatency kernel can improve things a lot with being really eas
4848
Subscribers
4949
-----------
5050

51-
~/robot_description [std_msgs::msg::String]
51+
robot_description [std_msgs::msg::String]
5252
String with the URDF xml, e.g., from ``robot_state_publisher``.
5353
Reloading of the URDF is not supported yet.
5454
All joints defined in the ``<ros2_control>``-tag have to be present in the URDF.

controller_manager/include/controller_manager/controller_manager.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ class ControllerManager : public rclcpp::Node
356356
std::vector<std::string> get_controller_names();
357357
std::pair<std::string, std::string> split_command_interface(
358358
const std::string & command_interface);
359-
void subscribe_to_robot_description_topic();
359+
void init_controller_manager();
360360

361361
/**
362362
* Clear request lists used when switching controllers. The lists are shared between "callback"
@@ -585,6 +585,7 @@ class ControllerManager : public rclcpp::Node
585585

586586
std::string robot_description_;
587587
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr robot_description_subscription_;
588+
rclcpp::TimerBase::SharedPtr robot_description_notification_timer_;
588589

589590
struct SwitchParams
590591
{

controller_manager/src/controller_manager.cpp

Lines changed: 38 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -200,38 +200,7 @@ ControllerManager::ControllerManager(
200200
std::make_shared<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>(
201201
kControllerInterfaceNamespace, kChainableControllerInterfaceClassName))
202202
{
203-
if (!get_parameter("update_rate", update_rate_))
204-
{
205-
RCLCPP_WARN(
206-
get_logger(), "'update_rate' parameter not set, using default value of %d Hz.", update_rate_);
207-
}
208-
209-
robot_description_ = "";
210-
// TODO(destogl): remove support at the end of 2023
211-
get_parameter("robot_description", robot_description_);
212-
if (robot_description_.empty())
213-
{
214-
subscribe_to_robot_description_topic();
215-
}
216-
else
217-
{
218-
RCLCPP_WARN(
219-
get_logger(),
220-
"[Deprecated] Passing the robot description parameter directly to the control_manager node "
221-
"is deprecated. Use the 'robot_description' topic from 'robot_state_publisher' instead.");
222-
init_resource_manager(robot_description_);
223-
if (is_resource_manager_initialized())
224-
{
225-
RCLCPP_WARN(
226-
get_logger(),
227-
"You have to restart the framework when using robot description from parameter!");
228-
init_services();
229-
}
230-
}
231-
232-
diagnostics_updater_.setHardwareID("ros2_control");
233-
diagnostics_updater_.add(
234-
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback);
203+
init_controller_manager();
235204
}
236205

237206
ControllerManager::ControllerManager(
@@ -251,21 +220,7 @@ ControllerManager::ControllerManager(
251220
std::make_shared<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>(
252221
kControllerInterfaceNamespace, kChainableControllerInterfaceClassName))
253222
{
254-
if (!get_parameter("update_rate", update_rate_))
255-
{
256-
RCLCPP_WARN(
257-
get_logger(), "'update_rate' parameter not set, using default value of %d Hz.", update_rate_);
258-
}
259-
260-
if (is_resource_manager_initialized())
261-
{
262-
init_services();
263-
}
264-
subscribe_to_robot_description_topic();
265-
266-
diagnostics_updater_.setHardwareID("ros2_control");
267-
diagnostics_updater_.add(
268-
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback);
223+
init_controller_manager();
269224
}
270225

271226
ControllerManager::ControllerManager(
@@ -282,6 +237,12 @@ ControllerManager::ControllerManager(
282237
std::make_shared<pluginlib::ClassLoader<controller_interface::ChainableControllerInterface>>(
283238
kControllerInterfaceNamespace, kChainableControllerInterfaceClassName))
284239
{
240+
init_controller_manager();
241+
}
242+
243+
void ControllerManager::init_controller_manager()
244+
{
245+
// Get parameters needed for RT "update" loop to work
285246
if (!get_parameter("update_rate", update_rate_))
286247
{
287248
RCLCPP_WARN(
@@ -292,15 +253,17 @@ ControllerManager::ControllerManager(
292253
{
293254
init_services();
294255
}
295-
subscribe_to_robot_description_topic();
296-
297-
diagnostics_updater_.setHardwareID("ros2_control");
298-
diagnostics_updater_.add(
299-
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback);
300-
}
256+
else
257+
{
258+
robot_description_notification_timer_ = create_wall_timer(
259+
std::chrono::seconds(1),
260+
[&]()
261+
{
262+
RCLCPP_WARN(
263+
get_logger(), "Waiting for data on 'robot_description' topic to finish initialization");
264+
});
265+
}
301266

302-
void ControllerManager::subscribe_to_robot_description_topic()
303-
{
304267
// set QoS to transient local to get messages that have already been published
305268
// (if robot state publisher starts before controller manager)
306269
robot_description_subscription_ = create_subscription<std_msgs::msg::String>(
@@ -309,6 +272,11 @@ void ControllerManager::subscribe_to_robot_description_topic()
309272
RCLCPP_INFO(
310273
get_logger(), "Subscribing to '%s' topic for robot description.",
311274
robot_description_subscription_->get_topic_name());
275+
276+
// Setup diagnostics
277+
diagnostics_updater_.setHardwareID("ros2_control");
278+
diagnostics_updater_.add(
279+
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback);
312280
}
313281

314282
void ControllerManager::robot_description_callback(const std_msgs::msg::String & robot_description)
@@ -321,13 +289,16 @@ void ControllerManager::robot_description_callback(const std_msgs::msg::String &
321289
{
322290
RCLCPP_WARN(
323291
get_logger(),
324-
"ResourceManager has already loaded an urdf file. Ignoring attempt to reload a robot "
325-
"description file.");
292+
"ResourceManager has already loaded a urdf. Ignoring attempt to reload a robot description.");
326293
return;
327294
}
328295
init_resource_manager(robot_description_);
329296
if (is_resource_manager_initialized())
330297
{
298+
RCLCPP_INFO(
299+
get_logger(),
300+
"Resource Manager has been successfully initialized. Starting Controller Manager "
301+
"services...");
331302
init_services();
332303
}
333304
}
@@ -397,6 +368,7 @@ void ControllerManager::init_resource_manager(const std::string & robot_descript
397368
State::PRIMARY_STATE_ACTIVE, hardware_interface::lifecycle_state_names::ACTIVE);
398369
resource_manager_->set_component_state(component, active_state);
399370
}
371+
robot_description_notification_timer_->cancel();
400372
}
401373

402374
void ControllerManager::init_services()
@@ -898,6 +870,15 @@ controller_interface::return_type ControllerManager::switch_controller(
898870
const std::vector<std::string> & deactivate_controllers, int strictness, bool activate_asap,
899871
const rclcpp::Duration & timeout)
900872
{
873+
if (!is_resource_manager_initialized())
874+
{
875+
RCLCPP_ERROR(
876+
get_logger(),
877+
"Resource Manager is not initialized yet! Please provide robot description on "
878+
"'robot_description' topic before trying to switch controllers.");
879+
return controller_interface::return_type::ERROR;
880+
}
881+
901882
switch_params_ = SwitchParams();
902883

903884
if (!deactivate_request_.empty() || !activate_request_.empty())

controller_manager/test/controller_manager_test_common.hpp

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,46 +65,18 @@ class ControllerManagerFixture : public ::testing::Test
6565
{
6666
public:
6767
explicit ControllerManagerFixture(
68-
const std::string & robot_description = ros2_control_test_assets::minimal_robot_urdf,
69-
const bool & pass_urdf_as_parameter = false)
70-
: robot_description_(robot_description), pass_urdf_as_parameter_(pass_urdf_as_parameter)
68+
const std::string & robot_description = ros2_control_test_assets::minimal_robot_urdf)
69+
: robot_description_(robot_description)
7170
{
7271
executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
73-
// We want to be able to create a ResourceManager where no urdf file has been passed to
74-
if (robot_description_.empty())
72+
cm_ = std::make_shared<CtrlMgr>(
73+
std::make_unique<hardware_interface::ResourceManager>(
74+
rm_node_->get_node_clock_interface(), rm_node_->get_node_logging_interface()),
75+
executor_, TEST_CM_NAME);
76+
// We want to be able to not pass robot description immediately
77+
if (!robot_description_.empty())
7578
{
76-
cm_ = std::make_shared<CtrlMgr>(
77-
std::make_unique<hardware_interface::ResourceManager>(
78-
rm_node_->get_node_clock_interface(), rm_node_->get_node_logging_interface()),
79-
executor_, TEST_CM_NAME);
80-
}
81-
else
82-
{
83-
// can be removed later, needed if we want to have the deprecated way of passing the robot
84-
// description file to the controller manager covered by tests
85-
if (pass_urdf_as_parameter_)
86-
{
87-
cm_ = std::make_shared<CtrlMgr>(
88-
std::make_unique<hardware_interface::ResourceManager>(
89-
robot_description_, rm_node_->get_node_clock_interface(),
90-
rm_node_->get_node_logging_interface(), true, 100),
91-
executor_, TEST_CM_NAME);
92-
}
93-
else
94-
{
95-
// TODO(mamueluth) : passing via topic not working in test setup, tested cm does
96-
// not receive msg. Have to check this...
97-
98-
// this is just a workaround to skip passing
99-
cm_ = std::make_shared<CtrlMgr>(
100-
std::make_unique<hardware_interface::ResourceManager>(
101-
rm_node_->get_node_clock_interface(), rm_node_->get_node_logging_interface()),
102-
executor_, TEST_CM_NAME);
103-
// mimic topic call
104-
auto msg = std_msgs::msg::String();
105-
msg.data = robot_description_;
106-
cm_->robot_description_callback(msg);
107-
}
79+
pass_robot_description_to_cm_and_rm(robot_description_);
10880
}
10981
time_ = rclcpp::Time(0, 0, cm_->get_node_clock_interface()->get_clock()->get_clock_type());
11082
}
@@ -140,6 +112,17 @@ class ControllerManagerFixture : public ::testing::Test
140112
}
141113
}
142114

115+
void pass_robot_description_to_cm_and_rm(
116+
const std::string & robot_description = ros2_control_test_assets::minimal_robot_urdf)
117+
{
118+
// TODO(Manuel) : passing via topic not working in test setup, tested cm does
119+
// not receive msg. Have to check this...
120+
// this is just a workaround to skip passing - mimic topic call
121+
auto msg = std_msgs::msg::String();
122+
msg.data = robot_description;
123+
cm_->robot_description_callback(msg);
124+
}
125+
143126
void switch_test_controllers(
144127
const std::vector<std::string> & start_controllers,
145128
const std::vector<std::string> & stop_controllers, const int strictness,
@@ -162,7 +145,6 @@ class ControllerManagerFixture : public ::testing::Test
162145
std::thread updater_;
163146
bool run_updater_;
164147
const std::string robot_description_;
165-
const bool pass_urdf_as_parameter_;
166148
rclcpp::Time time_;
167149

168150
protected:

0 commit comments

Comments
 (0)