Skip to content

Commit b9246f0

Browse files
committed
Apply suggestions from code review and run precommit
1 parent b16132e commit b9246f0

File tree

7 files changed

+105
-70
lines changed

7 files changed

+105
-70
lines changed

controller_manager/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ if(BUILD_TESTING)
243243
${controller_manager_msgs_TARGETS}
244244
)
245245

246-
ament_add_gmock(test_controller_manager_with_resource_manager
246+
ament_add_gmock(test_controller_manager_with_resource_manager
247247
test/test_controller_manager_with_resource_manager.cpp
248248
)
249249
target_link_libraries(test_controller_manager_with_resource_manager

controller_manager/include/controller_manager/controller_manager.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,16 +243,15 @@ class ControllerManager : public rclcpp::Node
243243
rclcpp::Clock::SharedPtr get_trigger_clock() const;
244244

245245
/**
246-
* @brief Return the robot description timer.
247-
*
248-
* It can be used to determine whether the Controller Manager
249-
* is currently waiting for a robot description to be published.
250-
*
251-
* @return rclcpp::TimerBase::SharedPtr if the timer exists, nullptr otherwise
252-
*/
253-
rclcpp::TimerBase::SharedPtr get_robot_description_timer() const {
254-
return robot_description_notification_timer_;
246+
* @brief Returns true if we have a valid robot description, currently based on whether the timer
247+
* for waiting on description is still on.
248+
*/
249+
bool has_valid_robot_description() const
250+
{
251+
return robot_description_notification_timer_ &&
252+
!robot_description_notification_timer_->is_canceled();
255253
}
254+
256255
protected:
257256
void init_services();
258257

controller_manager/src/controller_manager.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -548,20 +548,26 @@ void ControllerManager::init_controller_manager()
548548

549549
if (!is_resource_manager_initialized())
550550
{
551-
// fallback state
552-
resource_manager_ = std::make_unique<hardware_interface::ResourceManager>(trigger_clock_, get_logger());
551+
// The RM failed to initialize after receiving the robot description, or no description was
552+
// received at all. This is a critical error. Don't finalize controller manager, instead keep
553+
// waiting for robot description - fallback state
554+
resource_manager_ =
555+
std::make_unique<hardware_interface::ResourceManager>(trigger_clock_, get_logger());
553556
if (!robot_description_notification_timer_)
554557
{
555558
robot_description_notification_timer_ = create_wall_timer(
556559
std::chrono::seconds(1),
557560
[&]()
558561
{
559-
RCLCPP_WARN(get_logger(), "Waiting for data on 'robot_description' topic to finish initialization");
562+
RCLCPP_WARN(
563+
get_logger(), "Waiting for data on 'robot_description' topic to finish initialization");
560564
});
561565
}
562-
}else
566+
}
567+
else
563568
{
564-
RCLCPP_INFO(get_logger(),
569+
RCLCPP_INFO(
570+
get_logger(),
565571
"Resource Manager successfully initialized. Starting Controller Manager services...");
566572
init_services();
567573
}
@@ -677,15 +683,15 @@ void ControllerManager::robot_description_callback(const std_msgs::msg::String &
677683
get_logger(),
678684
"ResourceManager has already loaded a urdf. Ignoring attempt to reload a robot description.");
679685
return;
680-
}
686+
}
681687

682688
init_resource_manager(robot_description_);
683689
if (!is_resource_manager_initialized())
684690
{
685-
// The RM failed to init AFTER we received the description - a critical error.
686-
// don't finalize controller manager, instead keep waiting for robot description - fallback state
687-
resource_manager_ = std::make_unique<hardware_interface::ResourceManager>(trigger_clock_, get_logger());
688-
} else
691+
resource_manager_ =
692+
std::make_unique<hardware_interface::ResourceManager>(trigger_clock_, get_logger());
693+
}
694+
else
689695
{
690696
RCLCPP_INFO(
691697
get_logger(),
@@ -707,7 +713,7 @@ void ControllerManager::init_resource_manager(const std::string & robot_descript
707713
resource_manager_ = std::make_unique<hardware_interface::ResourceManager>(params, false);
708714

709715
RCLCPP_INFO_EXPRESSION(
710-
get_logger(), params_->enforce_command_limits, "Enforcing command limits is enabled...");
716+
get_logger(), params_->enforce_command_limits, "Enforcing command limits is enabled...");
711717
if (params_->enforce_command_limits)
712718
{
713719
try
@@ -732,16 +738,16 @@ void ControllerManager::init_resource_manager(const std::string & robot_descript
732738
return;
733739
}
734740
}
735-
catch (const std::exception &e)
741+
catch (const std::exception & e)
736742
{
737743
// Other possible errors when loading components
738744
RCLCPP_ERROR(
739-
get_logger(),
740-
"Exception caught while loading and initializing components: %s", e.what());
745+
get_logger(), "Exception caught while loading and initializing components: %s", e.what());
741746
return;
742747
}
743-
resource_manager_->set_on_component_state_switch_callback(std::bind(&ControllerManager::publish_activity, this));
744-
748+
resource_manager_->set_on_component_state_switch_callback(
749+
std::bind(&ControllerManager::publish_activity, this));
750+
745751
// Get all components and if they are not defined in parameters activate them automatically
746752
auto components_to_activate = resource_manager_->get_components_status();
747753

controller_manager/test/test_controller_manager_with_resource_manager.cpp

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1+
// Copyright 2022 Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
#include "test_controller_manager_with_resource_manager.hpp"
216

317
std::shared_ptr<rclcpp::Node> ControllerManagerTest::node_ = nullptr;
4-
std::unique_ptr<hardware_interface::ResourceManager> ControllerManagerTest::test_resource_manager_ = nullptr;
5-
std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> ControllerManagerTest::executor_ = nullptr;
18+
std::unique_ptr<hardware_interface::ResourceManager> ControllerManagerTest::test_resource_manager_ =
19+
nullptr;
20+
std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> ControllerManagerTest::executor_ =
21+
nullptr;
622

723
using LifecycleCallbackReturn =
824
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;
925

1026
void ControllerManagerTest::SetUp()
1127
{
12-
if (!rclcpp::ok()) {
28+
if (!rclcpp::ok())
29+
{
1330
rclcpp::init(0, nullptr);
1431
}
1532

@@ -26,7 +43,8 @@ void ControllerManagerTest::TearDown()
2643
node_.reset();
2744
test_resource_manager_.reset();
2845
executor_.reset();
29-
if (rclcpp::ok()) {
46+
if (rclcpp::ok())
47+
{
3048
rclcpp::shutdown();
3149
}
3250
}
@@ -37,13 +55,12 @@ TEST_F(ControllerManagerTest, robot_description_callback_handles_urdf_without_ha
3755

3856
std_msgs::msg::String invalid_urdf_msg;
3957
invalid_urdf_msg.data = ros2_control_test_assets::invalid_urdf_without_hardware_plugin;
40-
58+
4159
cm.robot_description_callback(invalid_urdf_msg);
42-
43-
EXPECT_FALSE(cm.is_resource_manager_initialized());
4460

45-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
61+
EXPECT_FALSE(cm.is_resource_manager_initialized());
4662

63+
EXPECT_TRUE(cm.has_valid_robot_description());
4764
}
4865

4966
TEST_F(ControllerManagerTest, robot_description_callback_handles_invalid_urdf)
@@ -57,8 +74,7 @@ TEST_F(ControllerManagerTest, robot_description_callback_handles_invalid_urdf)
5774

5875
EXPECT_FALSE(cm.is_resource_manager_initialized());
5976

60-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
61-
77+
EXPECT_TRUE(cm.has_valid_robot_description());
6278
}
6379

6480
TEST_F(ControllerManagerTest, robot_description_callback_handles_empty_urdf)
@@ -72,7 +88,7 @@ TEST_F(ControllerManagerTest, robot_description_callback_handles_empty_urdf)
7288

7389
EXPECT_FALSE(cm.is_resource_manager_initialized());
7490

75-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
91+
EXPECT_TRUE(cm.has_valid_robot_description());
7692
}
7793

7894
TEST_F(ControllerManagerTest, robot_description_callback_handles_wrong_plugins)
@@ -81,12 +97,12 @@ TEST_F(ControllerManagerTest, robot_description_callback_handles_wrong_plugins)
8197

8298
std_msgs::msg::String invalid_urdf_msg;
8399
invalid_urdf_msg.data = ros2_control_test_assets::invalid_urdf_with_wrong_plugin;
84-
100+
85101
cm.robot_description_callback(invalid_urdf_msg);
86-
102+
87103
EXPECT_FALSE(cm.is_resource_manager_initialized());
88104

89-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
105+
EXPECT_TRUE(cm.has_valid_robot_description());
90106
}
91107

92108
TEST_F(ControllerManagerTest, robot_description_callback_handles_no_geometry)
@@ -95,28 +111,29 @@ TEST_F(ControllerManagerTest, robot_description_callback_handles_no_geometry)
95111

96112
std_msgs::msg::String invalid_urdf_msg;
97113
invalid_urdf_msg.data = ros2_control_test_assets::invalid_urdf_no_geometry;
98-
114+
99115
cm.robot_description_callback(invalid_urdf_msg);
100-
116+
101117
EXPECT_FALSE(cm.is_resource_manager_initialized());
102118

103-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
119+
EXPECT_TRUE(cm.has_valid_robot_description());
104120
}
105121

106122
TEST_F(ControllerManagerTest, init_controller_manager_with_invalid_urdf)
107123
{
108124
const std::string invalid_urdf = ros2_control_test_assets::invalid_urdf_with_wrong_plugin;
109125

110-
TestControllerManager cm(executor_, invalid_urdf, false, "test_controller_manager", "", rclcpp::NodeOptions{});
126+
TestControllerManager cm(
127+
executor_, invalid_urdf, false, "test_controller_manager", "", rclcpp::NodeOptions{});
111128

112129
EXPECT_FALSE(cm.is_resource_manager_initialized());
113130

114-
EXPECT_FALSE(cm.get_robot_description_timer()->is_canceled());
131+
EXPECT_TRUE(cm.has_valid_robot_description());
115132
}
116133

117134
int main(int argc, char ** argv)
118135
{
119136
::testing::InitGoogleTest(&argc, argv);
120137
int result = RUN_ALL_TESTS();
121138
return result;
122-
}
139+
}
Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
1-
#ifndef CONTROLLER_MANAGER_TEST_HPP_
2-
#define CONTROLLER_MANAGER_TEST_HPP_
1+
// Copyright 2022 Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef TEST_CONTROLLER_MANAGER_WITH_RESOURCE_MANAGER_HPP_
16+
#define TEST_CONTROLLER_MANAGER_WITH_RESOURCE_MANAGER_HPP_
317

418
#include <memory>
519
#include <string>
620

7-
#include "gtest/gtest.h"
8-
#include "rclcpp/node.hpp"
9-
#include "std_msgs/msg/string.hpp"
10-
#include "lifecycle_msgs/msg/state.hpp"
21+
#include <utility>
1122
#include "controller_manager/controller_manager.hpp"
23+
#include "gtest/gtest.h"
1224
#include "hardware_interface/resource_manager.hpp"
25+
#include "lifecycle_msgs/msg/state.hpp"
26+
#include "rclcpp/node.hpp"
1327
#include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp"
1428
#include "ros2_control_test_assets/descriptions.hpp"
29+
#include "std_msgs/msg/string.hpp"
1530

1631
class TestControllerManager : public controller_manager::ControllerManager
1732
{
@@ -22,10 +37,10 @@ class TestControllerManager : public controller_manager::ControllerManager
2237
using ControllerManager::robot_description_callback;
2338

2439
using ControllerManager::is_resource_manager_initialized;
25-
40+
2641
using ControllerManager::resource_manager_;
2742

28-
using ControllerManager::get_robot_description_timer;
43+
using ControllerManager::has_valid_robot_description;
2944
};
3045

3146
class ControllerManagerTest : public ::testing::Test
@@ -38,4 +53,4 @@ class ControllerManagerTest : public ::testing::Test
3853
virtual void TearDown();
3954
};
4055

41-
#endif
56+
#endif // TEST_CONTROLLER_MANAGER_WITH_RESOURCE_MANAGER_HPP_

hardware_interface/src/resource_manager.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,16 +1420,16 @@ ResourceManager::ResourceManager(
14201420
params.allow_controller_activation_with_inactive_hardware;
14211421
return_failed_hardware_names_on_return_deactivate_write_cycle_ =
14221422
params.return_failed_hardware_names_on_return_deactivate_write_cycle_;
1423-
1424-
try
1423+
1424+
try
14251425
{
14261426
if (load && !load_and_initialize_components(params))
14271427
{
14281428
RCLCPP_WARN(
14291429
get_logger(),
14301430
"Could not load and initialize hardware. Please check previous output for more details. "
14311431
"After you have corrected your URDF, try to publish robot description again.");
1432-
return;
1432+
throw std::runtime_error("Failed to load and initialize components");
14331433
}
14341434
if (params.activate_all)
14351435
{
@@ -1441,14 +1441,12 @@ ResourceManager::ResourceManager(
14411441
}
14421442
}
14431443
}
1444-
catch (const std::exception &e)
1444+
catch (const std::exception & e)
14451445
{
14461446
// Other possible errors when loading components
14471447
RCLCPP_ERROR(
1448-
get_logger(),
1449-
"Exception caught while loading and initializing components: %s", e.what());
1450-
return;
1451-
}
1448+
get_logger(), "Exception caught while loading and initializing components: %s", e.what());
1449+
}
14521450
}
14531451

14541452
bool ResourceManager::shutdown_components()

ros2_control_test_assets/include/ros2_control_test_assets/descriptions.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,7 +2171,7 @@ const auto diff_drive_robot_sdf =
21712171
</sdf>
21722172
)";
21732173

2174-
const auto invalid_urdf_without_hardware_plugin =
2174+
const auto invalid_urdf_without_hardware_plugin =
21752175
R"(
21762176
<robot name="minimal_robot">
21772177
<link name="base_link"/>
@@ -2188,8 +2188,8 @@ const auto invalid_urdf_without_hardware_plugin =
21882188
</robot>
21892189
)";
21902190

2191-
const auto invalid_urdf_with_wrong_plugin =
2192-
R"(
2191+
const auto invalid_urdf_with_wrong_plugin =
2192+
R"(
21932193
<robot name="minimal_robot">
21942194
<link name="base_link"/>
21952195
<joint name="joint1" type="revolute">
@@ -2202,18 +2202,18 @@ const auto invalid_urdf_with_wrong_plugin =
22022202
<link name="link1"/>
22032203
<ros2_control name="default" type="system">
22042204
<hardware>
2205-
<plugin>mock_components/NonExistentSystem</plugin>
2205+
<plugin>mock_components/NonExistentSystem</plugin>
22062206
</hardware>
22072207
</ros2_control>
22082208
</robot>
22092209
)";
22102210

2211-
const auto invalid_urdf_no_geometry =
2212-
R"(
2211+
const auto invalid_urdf_no_geometry =
2212+
R"(
22132213
<robot name="minimal_robot">
22142214
<ros2_control name="default" type="system">
22152215
<hardware>
2216-
<plugin>mock_components/NonExistentSystem</plugin>
2216+
<plugin>mock_components/NonExistentSystem</plugin>
22172217
</hardware>
22182218
</ros2_control>
22192219
</robot>

0 commit comments

Comments
 (0)