Skip to content

Commit 01580bd

Browse files
authored
Redesign graceful controller dynamic parameters patterns (#5600)
Signed-off-by: mini-1235 <mauricepurnawan@gmail.com>
1 parent b91eda5 commit 01580bd

File tree

4 files changed

+97
-33
lines changed

4 files changed

+97
-33
lines changed

nav2_graceful_controller/include/nav2_graceful_controller/parameter_handler.hpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,28 @@ class ParameterHandler
8383
nav2::LifecycleNode::WeakPtr node_;
8484

8585
/**
86-
* @brief Callback executed when a parameter change is detected
87-
* @param event ParameterEvent message
86+
* @brief Validate incoming parameter updates before applying them.
87+
* This callback is triggered when one or more parameters are about to be updated.
88+
* It checks the validity of parameter values and rejects updates that would lead
89+
* to invalid or inconsistent configurations
90+
* @param parameters List of parameters that are being updated.
91+
* @return rcl_interfaces::msg::SetParametersResult Result indicating whether the update is accepted.
8892
*/
89-
rcl_interfaces::msg::SetParametersResult
90-
dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters);
93+
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(
94+
std::vector<rclcpp::Parameter> parameters);
95+
96+
/**
97+
* @brief Apply parameter updates after validation
98+
* This callback is executed when parameters have been successfully updated.
99+
* It updates the internal configuration of the node with the new parameter values.
100+
* @param parameters List of parameters that have been updated.
101+
*/
102+
void updateParametersCallback(std::vector<rclcpp::Parameter> parameters);
91103

92104
// Dynamic parameters handler
93105
std::mutex mutex_;
94-
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr dyn_params_handler_;
106+
rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr post_set_params_handler_;
107+
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr on_set_params_handler_;
95108
Parameters params_;
96109
std::string plugin_name_;
97110
rclcpp::Logger logger_ {rclcpp::get_logger("GracefulMotionController")};

nav2_graceful_controller/src/parameter_handler.cpp

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -115,31 +115,77 @@ ParameterHandler::ParameterHandler(
115115
params_.allow_backward = false;
116116
}
117117

118-
dyn_params_handler_ = node->add_on_set_parameters_callback(
119-
std::bind(&ParameterHandler::dynamicParametersCallback, this, std::placeholders::_1));
118+
post_set_params_handler_ = node->add_post_set_parameters_callback(
119+
std::bind(
120+
&ParameterHandler::updateParametersCallback,
121+
this, std::placeholders::_1));
122+
on_set_params_handler_ = node->add_on_set_parameters_callback(
123+
std::bind(
124+
&ParameterHandler::validateParameterUpdatesCallback,
125+
this, std::placeholders::_1));
120126
}
121127

122128
ParameterHandler::~ParameterHandler()
123129
{
124130
auto node = node_.lock();
125-
if (dyn_params_handler_ && node) {
126-
node->remove_on_set_parameters_callback(dyn_params_handler_.get());
131+
if (post_set_params_handler_ && node) {
132+
node->remove_post_set_parameters_callback(post_set_params_handler_.get());
127133
}
128-
dyn_params_handler_.reset();
134+
post_set_params_handler_.reset();
135+
if (on_set_params_handler_ && node) {
136+
node->remove_on_set_parameters_callback(on_set_params_handler_.get());
137+
}
138+
on_set_params_handler_.reset();
129139
}
130140

131-
rcl_interfaces::msg::SetParametersResult
132-
ParameterHandler::dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters)
141+
rcl_interfaces::msg::SetParametersResult ParameterHandler::validateParameterUpdatesCallback(
142+
std::vector<rclcpp::Parameter> parameters)
133143
{
134144
rcl_interfaces::msg::SetParametersResult result;
135-
std::lock_guard<std::mutex> lock_reinit(mutex_);
136-
145+
result.successful = true;
137146
for (auto parameter : parameters) {
138147
const auto & param_type = parameter.get_type();
139148
const auto & param_name = parameter.get_name();
140149
if (param_name.find(plugin_name_ + ".") != 0) {
141150
continue;
142151
}
152+
if (param_type == ParameterType::PARAMETER_DOUBLE) {
153+
if (parameter.as_double() < 0.0) {
154+
RCLCPP_WARN(
155+
logger_, "The value of parameter '%s' is incorrectly set to %f, "
156+
"it should be >=0. Ignoring parameter update.",
157+
param_name.c_str(), parameter.as_double());
158+
result.successful = false;
159+
}
160+
} else if (param_type == ParameterType::PARAMETER_BOOL) {
161+
if (param_name == plugin_name_ + ".allow_backward") {
162+
if (params_.initial_rotation && parameter.as_bool()) {
163+
RCLCPP_WARN(
164+
logger_, "Initial rotation and allow backward parameters are both true, "
165+
"rejecting parameter change.");
166+
result.successful = false;
167+
}
168+
} else if(param_name == plugin_name_ + ".initial_rotation") {
169+
if (parameter.as_bool() && params_.allow_backward) {
170+
RCLCPP_WARN(
171+
logger_, "Initial rotation and allow backward parameters are both true, "
172+
"rejecting parameter change.");
173+
result.successful = false;
174+
}
175+
}
176+
}
177+
}
178+
return result;
179+
}
180+
void
181+
ParameterHandler::updateParametersCallback(
182+
std::vector<rclcpp::Parameter> parameters)
183+
{
184+
std::lock_guard<std::mutex> lock_reinit(mutex_);
185+
186+
for (const auto & parameter : parameters) {
187+
const auto & param_type = parameter.get_type();
188+
const auto & param_name = parameter.get_name();
143189

144190
if (param_type == ParameterType::PARAMETER_DOUBLE) {
145191
if (param_name == plugin_name_ + ".transform_tolerance") {
@@ -177,31 +223,16 @@ ParameterHandler::dynamicParametersCallback(std::vector<rclcpp::Parameter> param
177223
}
178224
} else if (param_type == ParameterType::PARAMETER_BOOL) {
179225
if (param_name == plugin_name_ + ".initial_rotation") {
180-
if (parameter.as_bool() && params_.allow_backward) {
181-
RCLCPP_WARN(
182-
logger_, "Initial rotation and allow backward parameters are both true, "
183-
"rejecting parameter change.");
184-
continue;
185-
}
186226
params_.initial_rotation = parameter.as_bool();
187227
} else if (param_name == plugin_name_ + ".prefer_final_rotation") {
188228
params_.prefer_final_rotation = parameter.as_bool();
189229
} else if (param_name == plugin_name_ + ".allow_backward") {
190-
if (params_.initial_rotation && parameter.as_bool()) {
191-
RCLCPP_WARN(
192-
logger_, "Initial rotation and allow backward parameters are both true, "
193-
"rejecting parameter change.");
194-
continue;
195-
}
196230
params_.allow_backward = parameter.as_bool();
197231
} else if (param_name == plugin_name_ + ".use_collision_detection") {
198232
params_.use_collision_detection = parameter.as_bool();
199233
}
200234
}
201235
}
202-
203-
result.successful = true;
204-
return result;
205236
}
206237

207238
} // namespace nav2_graceful_controller

nav2_graceful_controller/test/test_graceful_controller.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ TEST(GracefulControllerTest, dynamicParameters) {
283283
rclcpp::Parameter("test.initial_rotation_tolerance", 12.0),
284284
rclcpp::Parameter("test.prefer_final_rotation", false),
285285
rclcpp::Parameter("test.rotation_scaling_factor", 13.0),
286-
rclcpp::Parameter("test.allow_backward", true),
286+
rclcpp::Parameter("test.allow_backward", false),
287287
rclcpp::Parameter("test.use_collision_detection", false),
288288
rclcpp::Parameter("test.in_place_collision_resolution", 15.0)});
289289

@@ -307,10 +307,17 @@ TEST(GracefulControllerTest, dynamicParameters) {
307307
EXPECT_EQ(node->get_parameter("test.initial_rotation_tolerance").as_double(), 12.0);
308308
EXPECT_EQ(node->get_parameter("test.prefer_final_rotation").as_bool(), false);
309309
EXPECT_EQ(node->get_parameter("test.rotation_scaling_factor").as_double(), 13.0);
310-
EXPECT_EQ(node->get_parameter("test.allow_backward").as_bool(), true);
310+
EXPECT_EQ(node->get_parameter("test.allow_backward").as_bool(), false);
311311
EXPECT_EQ(node->get_parameter("test.use_collision_detection").as_bool(), false);
312312
EXPECT_EQ(node->get_parameter("test.in_place_collision_resolution").as_double(), 15.0);
313313

314+
// Set allow backward to true
315+
results = params->set_parameters_atomically(
316+
{rclcpp::Parameter("test.allow_backward", true)});
317+
rclcpp::spin_until_future_complete(node->get_node_base_interface(), results);
318+
EXPECT_EQ(controller->getInitialRotation(), false);
319+
EXPECT_EQ(controller->getAllowBackward(), true);
320+
314321
// Set initial rotation to true
315322
results = params->set_parameters_atomically(
316323
{rclcpp::Parameter("test.initial_rotation", true)});

nav2_regulated_pure_pursuit_controller/include/nav2_regulated_pure_pursuit_controller/parameter_handler.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,27 @@ class ParameterHandler
9191

9292
protected:
9393
nav2::LifecycleNode::WeakPtr node_;
94+
9495
/**
95-
* @brief Callback executed when a parameter change is detected
96-
* @param event ParameterEvent message
96+
* @brief Apply parameter updates after validation
97+
* This callback is executed when parameters have been successfully updated.
98+
* It updates the internal configuration of the node with the new parameter values.
99+
* @param parameters List of parameters that have been updated.
97100
*/
98101
void
99102
updateParametersCallback(std::vector<rclcpp::Parameter> parameters);
103+
104+
/**
105+
* @brief Validate incoming parameter updates before applying them.
106+
* This callback is triggered when one or more parameters are about to be updated.
107+
* It checks the validity of parameter values and rejects updates that would lead
108+
* to invalid or inconsistent configurations
109+
* @param parameters List of parameters that are being updated.
110+
* @return rcl_interfaces::msg::SetParametersResult Result indicating whether the update is accepted.
111+
*/
100112
rcl_interfaces::msg::SetParametersResult
101113
validateParameterUpdatesCallback(std::vector<rclcpp::Parameter> parameters);
114+
102115
// Dynamic parameters handler
103116
std::mutex mutex_;
104117
rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr post_set_params_handler_;

0 commit comments

Comments
 (0)