Skip to content

Commit db75dea

Browse files
committed
reset odom service removed
- changes in diff drive PR (#2096) mirrored - manual state transition added for testing - docs updated
1 parent 6ef95b3 commit db75dea

File tree

8 files changed

+44
-66
lines changed

8 files changed

+44
-66
lines changed

doc/release_notes.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ diff_drive_controller
2121

2222
mecanum_drive_controller
2323
*****************************
24-
* Parameter ``tf_frame_prefix_enable`` got deprecated and will be removed in a future release (`#1997 <https://github.com/ros-controls/ros2_controllers/pull/1997>`_).
25-
* Now any tilde ("~") character in ``tf_frame_prefix`` is substituted with node namespace. (`#1997 <https://github.com/ros-controls/ros2_controllers/pull/1997>`_).
24+
* Parameter ``tf_frame_prefix_enable`` got deprecated and will be removed in a future release (`#2063 <https://github.com/ros-controls/ros2_controllers/pull/2063>`_).
25+
* Now any tilde ("~") character in ``tf_frame_prefix`` is substituted with node namespace. (`#2063 <https://github.com/ros-controls/ros2_controllers/pull/2063>`_).
26+
* Set odometry service added to be used at runtime. (`#2110 <https://github.com/ros-controls/ros2_controllers/pull/2110>`_).
2627

2728
joint_state_broadcaster
2829
************************

mecanum_drive_controller/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ target_link_libraries(mecanum_drive_controller PUBLIC
5454
${tf2_geometry_msgs_TARGETS}
5555
${tf2_msgs_TARGETS}
5656
${nav_msgs_TARGETS}
57-
${std_srvs_TARGETS})
57+
${control_msgs_TARGETS})
5858

5959
pluginlib_export_plugin_description_file(
6060
controller_interface mecanum_drive_controller.xml)

mecanum_drive_controller/doc/userdoc.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ Publishers
6060
- ``<controller_name>/tf_odometry`` [``tf2_msgs/msg/TFMessage``]
6161
- ``<controller_name>/controller_state`` [``control_msgs/msg/MecanumDriveControllerState``]
6262

63+
Services
64+
,,,,,,,,,,,
65+
~/set_odometry [control_msgs::srv::SetOdometry]
66+
This service can be used to set the current odometry of the robot to desired values.
67+
6368
Parameters
6469
,,,,,,,,,,,
6570

mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
#include "rclcpp_lifecycle/state.hpp"
3434
#include "realtime_tools/realtime_publisher.hpp"
3535
#include "realtime_tools/realtime_thread_safe_box.hpp"
36-
#include "std_srvs/srv/empty.hpp"
37-
#include "std_srvs/srv/set_bool.hpp"
3836
#include "tf2_msgs/msg/tf_message.hpp"
3937

4038
#include "mecanum_drive_controller/mecanum_drive_controller_parameters.hpp"
@@ -80,10 +78,6 @@ class MecanumDriveController : public controller_interface::ChainableControllerI
8078
const std::shared_ptr<rmw_request_id_t> request_header,
8179
const std::shared_ptr<control_msgs::srv::SetOdometry::Request> req,
8280
std::shared_ptr<control_msgs::srv::SetOdometry::Response> res);
83-
void reset_odometry(
84-
const std::shared_ptr<rmw_request_id_t> request_header,
85-
const std::shared_ptr<std_srvs::srv::Empty::Request> req,
86-
std::shared_ptr<std_srvs::srv::Empty::Response> res);
8781

8882
using ControllerReferenceMsg = geometry_msgs::msg::TwistStamped;
8983
using OdomStateMsg = nav_msgs::msg::Odometry;
@@ -153,12 +147,9 @@ class MecanumDriveController : public controller_interface::ChainableControllerI
153147

154148
Odometry odometry_;
155149
rclcpp::Service<control_msgs::srv::SetOdometry>::SharedPtr set_odom_service_;
156-
rclcpp::Service<std_srvs::srv::Empty>::SharedPtr reset_odom_service_;
157-
std::atomic<bool> set_odom_request_{false}, reset_odom_request_{false};
158-
struct
159-
{
160-
double x, y, yaw;
161-
} requested_odom_params_;
150+
std::atomic<bool> set_odom_requested_{false};
151+
realtime_tools::RealtimeThreadSafeBox<control_msgs::srv::SetOdometry::Request>
152+
requested_odom_params_;
162153

163154
private:
164155
// callback for topic interface

mecanum_drive_controller/package.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
<depend>rclcpp_lifecycle</depend>
3737
<depend>realtime_tools</depend>
3838
<depend>rcpputils</depend>
39-
<depend>std_srvs</depend>
4039
<depend>tf2</depend>
4140
<depend>tf2_geometry_msgs</depend>
4241
<depend>tf2_msgs</depend>

mecanum_drive_controller/src/mecanum_drive_controller.cpp

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ void reset_controller_reference_msg(
4646
}
4747

4848
constexpr auto DEFAULT_SET_ODOM_SERVICE = "~/set_odometry";
49-
constexpr auto DEFAULT_RESET_ODOM_SERVICE = "~/reset_odometry";
5049
} // namespace
5150

5251
namespace mecanum_drive_controller
@@ -250,17 +249,11 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure(
250249

251250
try
252251
{
253-
// Create odometry set & reset services
254252
set_odom_service_ = get_node()->create_service<control_msgs::srv::SetOdometry>(
255253
DEFAULT_SET_ODOM_SERVICE,
256254
std::bind(
257255
&MecanumDriveController::set_odometry, this, std::placeholders::_1, std::placeholders::_2,
258256
std::placeholders::_3));
259-
reset_odom_service_ = get_node()->create_service<std_srvs::srv::Empty>(
260-
DEFAULT_RESET_ODOM_SERVICE,
261-
std::bind(
262-
&MecanumDriveController::reset_odometry, this, std::placeholders::_1, std::placeholders::_2,
263-
std::placeholders::_3));
264257
}
265258
catch (const std::exception & e)
266259
{
@@ -372,7 +365,6 @@ controller_interface::CallbackReturn MecanumDriveController::on_activate(
372365
ControllerReferenceMsg emtpy_msg;
373366
reset_controller_reference_msg(emtpy_msg, get_node());
374367
input_ref_.try_set(emtpy_msg);
375-
376368
return controller_interface::CallbackReturn::SUCCESS;
377369
}
378370

@@ -476,16 +468,15 @@ controller_interface::return_type MecanumDriveController::update_and_write_comma
476468
const double wheel_rear_left_state_vel = wheel_rear_left_state_vel_op.value();
477469

478470
// check if odometry set or reset was requested by non-RT thread
479-
if (set_odom_request_.load())
480-
{
481-
odometry_.setOdometry(
482-
requested_odom_params_.x, requested_odom_params_.y, requested_odom_params_.yaw);
483-
set_odom_request_.store(false);
484-
}
485-
else if (reset_odom_request_.load())
471+
if (set_odom_requested_.load())
486472
{
487-
odometry_.resetOdometry();
488-
reset_odom_request_.store(false);
473+
auto param_op = requested_odom_params_.try_get();
474+
if (param_op.has_value())
475+
{
476+
auto params = param_op.value();
477+
odometry_.setOdometry(params.x, params.y, params.yaw);
478+
set_odom_requested_.store(false);
479+
}
489480
}
490481
else
491482
{
@@ -630,23 +621,21 @@ void MecanumDriveController::set_odometry(
630621
const std::shared_ptr<control_msgs::srv::SetOdometry::Request> req,
631622
std::shared_ptr<control_msgs::srv::SetOdometry::Response> res)
632623
{
624+
if (get_node()->get_current_state().id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE)
625+
{
626+
res->success = false;
627+
res->message = "Controller is not active";
628+
return;
629+
}
630+
631+
// put requested odom params into RealtimeThreadSafeBox
632+
requested_odom_params_.set(*req);
633+
633634
// flip the flag for thread-safe odom set in the control loop
634-
set_odom_request_.store(true);
635-
requested_odom_params_.x = req->x;
636-
requested_odom_params_.y = req->y;
637-
requested_odom_params_.yaw = req->yaw;
638-
res->success = true;
639-
res->message = "Odometry set requested";
640-
}
635+
set_odom_requested_.store(true);
641636

642-
void MecanumDriveController::reset_odometry(
643-
const std::shared_ptr<rmw_request_id_t> /*request_header*/,
644-
const std::shared_ptr<std_srvs::srv::Empty::Request> /*req*/,
645-
std::shared_ptr<std_srvs::srv::Empty::Response> /*res*/)
646-
{
647-
// flip the flag for thread-safe odom reset in the control loop
648-
reset_odom_request_.store(true);
649-
RCLCPP_INFO(get_node()->get_logger(), "Odometry reset requested");
637+
res->success = true;
638+
res->message = "Odometry set request accepted";
650639
}
651640

652641
} // namespace mecanum_drive_controller

mecanum_drive_controller/test/test_mecanum_drive_controller.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -810,9 +810,16 @@ TEST_F(MecanumDriveControllerTest, odometry_set_reset_services)
810810
// 0. Initialize and activate
811811
SetUpController();
812812
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
813+
controller_->get_node()->trigger_transition(
814+
rclcpp_lifecycle::Transition(lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE));
813815

814816
controller_->set_chained_mode(true);
815817
ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);
818+
controller_->get_node()->trigger_transition(
819+
rclcpp_lifecycle::Transition(lifecycle_msgs::msg::Transition::TRANSITION_ACTIVATE));
820+
ASSERT_EQ(
821+
controller_->get_node()->get_current_state().id(),
822+
lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE);
816823

817824
const double dt = 0.02; // 50Hz
818825
rclcpp::Time test_time = controller_->get_node()->now();
@@ -843,23 +850,7 @@ TEST_F(MecanumDriveControllerTest, odometry_set_reset_services)
843850
for (int i = 0; i < 10; ++i) move_robot(1.0, 0.0, 0.0);
844851
ASSERT_GT(controller_->odometry_.getX(), 0.0);
845852

846-
// 2. Call Odometry Reset Service
847-
auto reset_request = std::make_shared<std_srvs::srv::Empty::Request>();
848-
auto reset_response = std::make_shared<std_srvs::srv::Empty::Response>();
849-
controller_->reset_odometry(nullptr, reset_request, reset_response);
850-
851-
// One update to propagate the internal reset
852-
controller_->update(test_time, period);
853-
854-
EXPECT_NEAR(controller_->odometry_.getX(), 0.0, 1e-6);
855-
EXPECT_NEAR(controller_->odometry_.getY(), 0.0, 1e-6);
856-
EXPECT_NEAR(controller_->odometry_.getRz(), 0.0, 1e-6);
857-
858-
// 3. Move again to ensure it still works
859-
for (int i = 0; i < 10; ++i) move_robot(1.0, 0.0, 0.0);
860-
ASSERT_GT(controller_->odometry_.getX(), 0.0);
861-
862-
// 4. Call Set Odometry Service
853+
// 2. Call Set Odometry Service
863854
auto set_request = std::make_shared<control_msgs::srv::SetOdometry::Request>();
864855
auto set_response = std::make_shared<control_msgs::srv::SetOdometry::Response>();
865856
set_request->x = 5.0;
@@ -875,7 +866,7 @@ TEST_F(MecanumDriveControllerTest, odometry_set_reset_services)
875866
EXPECT_NEAR(controller_->odometry_.getY(), -2.0, 1e-6);
876867
EXPECT_NEAR(controller_->odometry_.getRz(), 1.57079632679, 1e-5);
877868

878-
// 5. Move forward again to verify
869+
// 3. Move forward again to verify
879870
double start_y = controller_->odometry_.getY();
880871
for (int i = 0; i < 10; ++i) move_robot(1.0, 0.0, 0.0); // we are facing +Y now
881872
EXPECT_GT(controller_->odometry_.getY(), start_y);

mecanum_drive_controller/test/test_mecanum_drive_controller.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "hardware_interface/loaned_state_interface.hpp"
2929
#include "hardware_interface/types/hardware_interface_return_values.hpp"
3030
#include "hardware_interface/types/hardware_interface_type_values.hpp"
31+
#include "lifecycle_msgs/msg/state.hpp"
32+
#include "lifecycle_msgs/msg/transition.hpp"
3133
#include "mecanum_drive_controller/mecanum_drive_controller.hpp"
3234
#include "rclcpp/executor.hpp"
3335
#include "rclcpp/executors.hpp"

0 commit comments

Comments
 (0)