Skip to content

Commit ecc2218

Browse files
committed
workaround for topic issues while testing
1 parent c338a94 commit ecc2218

File tree

5 files changed

+60
-66
lines changed

5 files changed

+60
-66
lines changed

controller_manager/include/controller_manager/controller_manager.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ class ControllerManager : public rclcpp::Node
8484
CONTROLLER_MANAGER_PUBLIC
8585
virtual ~ControllerManager() = default;
8686

87+
CONTROLLER_MANAGER_PUBLIC
88+
void subscribe_to_robot_description_topic();
89+
90+
CONTROLLER_MANAGER_PUBLIC
91+
void robot_description_callback(const std_msgs::msg::String & msg);
92+
8793
CONTROLLER_MANAGER_PUBLIC
8894
void init_resource_manager(const std::string & robot_description);
8995

@@ -307,9 +313,6 @@ class ControllerManager : public rclcpp::Node
307313
const std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Request> request,
308314
std::shared_ptr<controller_manager_msgs::srv::SetHardwareComponentState::Response> response);
309315

310-
CONTROLLER_MANAGER_PUBLIC
311-
void robot_description_callback(const std_msgs::msg::String & msg);
312-
313316
// Per controller update rate support
314317
unsigned int update_loop_counter_ = 0;
315318
unsigned int update_rate_ = 100;

controller_manager/src/controller_manager.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,7 @@ ControllerManager::ControllerManager(
154154
get_parameter("robot_description", robot_description);
155155
if (robot_description.empty())
156156
{
157-
// set QoS to transient local to get messages that have already been published
158-
// (if robot state publisher starts before controller manager)
159-
RCLCPP_INFO(
160-
get_logger(), "Subscribing to '~/robot_description' topic for robot description file.");
161-
robot_description_subscription_ = create_subscription<std_msgs::msg::String>(
162-
namespace_ + "/robot_description", rclcpp::QoS(1).transient_local(),
163-
std::bind(&ControllerManager::robot_description_callback, this, std::placeholders::_1));
157+
subscribe_to_robot_description_topic();
164158
}
165159
else
166160
{
@@ -196,19 +190,25 @@ ControllerManager::ControllerManager(
196190
RCLCPP_WARN(get_logger(), "'update_rate' parameter not set, using default value.");
197191
}
198192

199-
// set QoS to transient local to get messages that have already been published
200-
// (if robot state publisher starts before controller manager)
201-
RCLCPP_INFO(get_logger(), "Subscribing to ~/robot_description topic for robot description file.");
202-
robot_description_subscription_ = create_subscription<std_msgs::msg::String>(
203-
namespace_ + "/robot_description", rclcpp::QoS(1).transient_local(),
204-
std::bind(&ControllerManager::robot_description_callback, this, std::placeholders::_1));
193+
subscribe_to_robot_description_topic();
205194

206195
diagnostics_updater_.setHardwareID("ros2_control");
207196
diagnostics_updater_.add(
208197
"Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback);
209198
init_services();
210199
}
211200

201+
void ControllerManager::subscribe_to_robot_description_topic()
202+
{
203+
// set QoS to transient local to get messages that have already been published
204+
// (if robot state publisher starts before controller manager)
205+
RCLCPP_INFO_STREAM(
206+
get_logger(), "Subscribing to '~/robot_description' topic for robot description file.");
207+
robot_description_subscription_ = create_subscription<std_msgs::msg::String>(
208+
"~/robot_description", rclcpp::QoS(1).transient_local(),
209+
std::bind(&ControllerManager::robot_description_callback, this, std::placeholders::_1));
210+
}
211+
212212
void ControllerManager::robot_description_callback(const std_msgs::msg::String & robot_description)
213213
{
214214
RCLCPP_INFO(get_logger(), "Received robot description file.");

controller_manager/test/controller_manager_test_common.hpp

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,10 @@ template <typename CtrlMgr>
6565
class ControllerManagerFixture : public ::testing::Test
6666
{
6767
public:
68-
// TODO(Manuel): Maybe add parameter of which hardware is to be expected
6968
explicit ControllerManagerFixture(
7069
const std::string & robot_description = ros2_control_test_assets::minimal_robot_urdf,
71-
const std::string ns = "/", const bool & pass_urdf_as_parameter = false)
72-
: robot_description_(robot_description), ns_(ns), pass_urdf_as_parameter_(pass_urdf_as_parameter)
70+
const bool & pass_urdf_as_parameter = false)
71+
: robot_description_(robot_description), pass_urdf_as_parameter_(pass_urdf_as_parameter)
7372
{
7473
executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
7574
// We want to be able to create a ResourceManager where no urdf file has been passed to
@@ -90,37 +89,16 @@ class ControllerManagerFixture : public ::testing::Test
9089
}
9190
else
9291
{
93-
// First wie create a node and a publisher for publishing the passed robot description file
94-
urdf_publisher_node_ = std::make_shared<rclcpp::Node>("robot_description_publisher", ns_);
95-
description_pub_ = urdf_publisher_node_->create_publisher<std_msgs::msg::String>(
96-
"robot_description", rclcpp::QoS(1).transient_local());
97-
executor_->add_node(urdf_publisher_node_);
98-
publish_robot_description_file(robot_description_);
99-
// Then we create controller manager which subscribes to topic and receive
100-
// published robot description file. Publishing is transient_local so starting cm
101-
// later should not pose problem and is closer to real world applications
92+
// TODO(Manuel) : passing via topic not working in test setup, tested cm does
93+
// not receive msg. Have to check this...
94+
95+
// this is just a workaround to skip passing
10296
cm_ = std::make_shared<CtrlMgr>(
10397
std::make_unique<hardware_interface::ResourceManager>(), executor_, TEST_CM_NAME);
104-
executor_->add_node(cm_);
105-
// Now we have to wait for cm to process callback and initialize everything.
106-
// We have to wait here, otherwise controllers can not be initialized since
107-
// no hardware has been received.
108-
service_caller_node_ = std::make_shared<rclcpp::Node>("service_caller_node", ns_);
109-
executor_->add_node(service_caller_node_);
110-
auto client =
111-
service_caller_node_->create_client<controller_manager_msgs::srv::ListHardwareInterfaces>(
112-
"get_hw_interfaces");
113-
auto request =
114-
std::make_shared<controller_manager_msgs::srv::ListHardwareInterfaces::Request>();
115-
EXPECT_TRUE(client->wait_for_service(std::chrono::milliseconds(500)));
116-
auto future = client->async_send_request(request);
117-
EXPECT_EQ(
118-
executor_->spin_until_future_complete(future, std::chrono::milliseconds(1000)),
119-
rclcpp::FutureReturnCode::SUCCESS);
120-
auto res = future.get();
121-
auto command_interfaces = res->command_interfaces;
122-
auto state_interfaces = res->state_interfaces;
123-
// check for command-/stateinterfaces but spin_until_future_complete times out...
98+
// mimic topic call
99+
auto msg = std_msgs::msg::String();
100+
msg.data = robot_description_;
101+
cm_->robot_description_callback(msg);
124102
}
125103
}
126104
}
@@ -172,24 +150,13 @@ class ControllerManagerFixture : public ::testing::Test
172150
EXPECT_EQ(expected_return, switch_future.get());
173151
}
174152

175-
void publish_robot_description_file(const std::string & robot_description_file)
176-
{
177-
auto msg = std::make_unique<std_msgs::msg::String>();
178-
msg->data = robot_description_file;
179-
description_pub_->publish(std::move(msg));
180-
}
181-
182153
std::shared_ptr<rclcpp::Executor> executor_;
183154
std::shared_ptr<CtrlMgr> cm_;
184155

185156
std::thread updater_;
186157
bool run_updater_;
187158
const std::string robot_description_;
188-
const std::string ns_;
189159
const bool pass_urdf_as_parameter_;
190-
std::shared_ptr<rclcpp::Node> urdf_publisher_node_;
191-
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr description_pub_;
192-
std::shared_ptr<rclcpp::Node> service_caller_node_;
193160
};
194161

195162
class TestControllerManagerSrvs

controller_manager/test/test_controller_manager_urdf_passing.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,19 @@
2121
#include "controller_manager/controller_manager.hpp"
2222
#include "controller_manager_test_common.hpp"
2323

24+
#include "ros2_control_test_assets/descriptions.hpp"
25+
2426
class TestControllerManagerWithTestableCM;
2527

2628
class TestableControllerManager : public controller_manager::ControllerManager
2729
{
2830
friend TestControllerManagerWithTestableCM;
2931

30-
FRIEND_TEST(TestControllerManagerWithTestableCM, callback_gets_passed);
31-
FRIEND_TEST(TestControllerManagerWithTestableCM, initial_failing);
32+
FRIEND_TEST(TestControllerManagerWithTestableCM, initial_no_load_urdf_called);
33+
FRIEND_TEST(TestControllerManagerWithTestableCM, load_urdf_called_after_callback);
34+
FRIEND_TEST(TestControllerManagerWithTestableCM, load_urdf_called_after_invalid_urdf_passed);
35+
FRIEND_TEST(TestControllerManagerWithTestableCM, load_urdf_called_after_callback);
36+
FRIEND_TEST(TestControllerManagerWithTestableCM, load_urdf_called_after_callback);
3237

3338
public:
3439
TestableControllerManager(
@@ -46,16 +51,36 @@ class TestControllerManagerWithTestableCM
4651
: public ControllerManagerFixture<TestableControllerManager>,
4752
public testing::WithParamInterface<Strictness>
4853
{
54+
public:
55+
// create cm with no urdf
56+
TestControllerManagerWithTestableCM()
57+
: ControllerManagerFixture<TestableControllerManager>("", false)
58+
{
59+
}
4960
};
5061

51-
// only exemplary to test if working not a useful test yet
52-
TEST_P(TestControllerManagerWithTestableCM, callback_gets_passed)
62+
TEST_P(TestControllerManagerWithTestableCM, initial_no_load_urdf_called)
63+
{
64+
ASSERT_FALSE(cm_->resource_manager_->load_urdf_called());
65+
}
66+
67+
TEST_P(TestControllerManagerWithTestableCM, load_urdf_called_after_callback)
5368
{
5469
ASSERT_FALSE(cm_->resource_manager_->load_urdf_called());
70+
// mimic callback
71+
auto msg = std_msgs::msg::String();
72+
msg.data = ros2_control_test_assets::minimal_robot_urdf;
73+
cm_->robot_description_callback(msg);
74+
ASSERT_TRUE(cm_->resource_manager_->load_urdf_called());
5575
}
5676

57-
TEST_P(TestControllerManagerWithTestableCM, initial_failing)
77+
TEST_P(TestControllerManagerWithTestableCM, load_urdf_called_after_invalid_urdf_passed)
5878
{
79+
ASSERT_FALSE(cm_->resource_manager_->load_urdf_called());
80+
// mimic callback
81+
auto msg = std_msgs::msg::String();
82+
msg.data = ros2_control_test_assets::minimal_robot_missing_command_keys_urdf;
83+
cm_->robot_description_callback(msg);
5984
ASSERT_TRUE(cm_->resource_manager_->load_urdf_called());
6085
}
6186

hardware_interface/include/hardware_interface/resource_manager.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ class HARDWARE_INTERFACE_PUBLIC ResourceManager
6565
* "autostart_components" and "autoconfigure_components" instead.
6666
*/
6767
explicit ResourceManager(
68-
const std::string & urdf, bool validate_interfaces = true, bool activate_all = false,
69-
bool urdf_loaded = false);
68+
const std::string & urdf, bool validate_interfaces = true, bool activate_all = false);
7069

7170
ResourceManager(const ResourceManager &) = delete;
7271

0 commit comments

Comments
 (0)