@@ -48,6 +48,17 @@ auto AdaptiveIntegralTerminalSlidingModeController::on_init() -> controller_inte
48
48
{
49
49
param_listener_ = std::make_shared<adaptive_integral_terminal_sliding_mode_controller::ParamListener>(get_node ());
50
50
params_ = param_listener_->get_params ();
51
+ logger_ = get_node ()->get_logger ();
52
+
53
+ RCLCPP_INFO (logger_, " Parsing hydrodynamic model from robot description" ); // NOLINT
54
+ const auto out = hydrodynamics::parse_model_from_xml (get_robot_description ());
55
+ if (!out.has_value ()) {
56
+ // NOLINTNEXTLINE
57
+ RCLCPP_ERROR (logger_, " Failed to parse hydrodynamic model from robot description: %s" , out.error ().c_str ());
58
+ return controller_interface::CallbackReturn::ERROR;
59
+ }
60
+ model_ = std::make_unique<hydrodynamics::Params>(out.value ());
61
+
51
62
return controller_interface::CallbackReturn::SUCCESS;
52
63
}
53
64
@@ -104,35 +115,15 @@ auto AdaptiveIntegralTerminalSlidingModeController::on_configure(const rclcpp_li
104
115
// reset the adaptive gain
105
116
k1_ = Eigen::Matrix6d::Identity ();
106
117
107
- RCLCPP_INFO (get_node ()->get_logger (), " Waiting for robot description to be received" ); // NOLINT
108
-
109
118
// NOLINTNEXTLINE(performance-unnecessary-value-param)
110
119
reference_sub_ = get_node ()->create_subscription <geometry_msgs::msg::Twist>(
111
120
" ~/reference" , rclcpp::SystemDefaultsQoS (), [this ](const std::shared_ptr<geometry_msgs::msg::Twist> msg) {
112
121
reference_.writeFromNonRT (*msg);
113
122
});
114
123
115
- const auto qos = rclcpp::QoS (rclcpp::KeepLast (10 )).transient_local ().reliable ();
116
- robot_description_sub_ = get_node ()->create_subscription <std_msgs::msg::String>(
117
- " robot_description" , qos, [this ](const std::shared_ptr<std_msgs::msg::String> msg) {
118
- if (model_initialized_ || msg->data .empty ()) {
119
- return ;
120
- }
121
- RCLCPP_INFO (get_node ()->get_logger (), " Parsing hydrodynamic model from robot description" ); // NOLINT
122
- const auto out = hydrodynamics::parse_model_from_xml (msg->data );
123
- if (!out.has_value ()) {
124
- RCLCPP_ERROR (
125
- get_node ()->get_logger (),
126
- std::format (" Failed to parse hydrodynamic model from robot description: {}" , out.error ()).c_str ());
127
- return ;
128
- }
129
- model_ = std::make_unique<hydrodynamics::Params>(out.value ());
130
- model_initialized_ = true ;
131
- });
132
-
133
124
// use the tf interface when we aren't getting the state from a topic
134
125
if (params_.use_external_measured_states ) {
135
- RCLCPP_INFO (get_node ()-> get_logger () , " Using external measured states" ); // NOLINT
126
+ RCLCPP_INFO (logger_ , " Using external measured states" ); // NOLINT
136
127
system_state_sub_ = get_node ()->create_subscription <nav_msgs::msg::Odometry>(
137
128
" ~/system_state" , rclcpp::SystemDefaultsQoS (), [this ](const std::shared_ptr<nav_msgs::msg::Odometry> msg) {
138
129
system_state_.writeFromNonRT (*msg);
@@ -228,9 +219,7 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_reference_from_subscr
228
219
auto * current_reference = reference_.readFromNonRT ();
229
220
const std::vector<double > reference = common::messages::to_vector (*current_reference);
230
221
for (auto && [interface, ref] : std::views::zip (reference_interfaces_, reference)) {
231
- if (!std::isnan (ref)) {
232
- interface = ref;
233
- }
222
+ interface = ref;
234
223
}
235
224
common::messages::reset_message (current_reference);
236
225
return controller_interface::return_type::OK;
@@ -241,60 +230,62 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_system_state_values()
241
230
{
242
231
if (params_.use_external_measured_states ) {
243
232
auto * current_state = system_state_.readFromNonRT ();
244
- const std::vector<double > state = common::messages::to_vector (current_state->twist .twist );
245
- system_state_values_.assign (state.begin (), state.end ());
233
+ std::ranges::copy (common::messages::to_vector (current_state->twist .twist ), system_state_values_.begin ());
246
234
tf2::fromMsg (current_state->pose .pose .orientation , *system_rotation_.readFromRT ());
247
235
} else {
248
- // read the velocity values from the state interfaces
249
- for (auto && [interface, dof, value] : std::views::zip (state_interfaces_, dofs_, system_state_values_)) {
250
- const auto val = interface.get_optional ();
251
- if (!val.has_value ()) {
252
- // NOLINTNEXTLINE
253
- RCLCPP_WARN (get_node ()->get_logger (), std::format (" Failed to get state value for joint {}" , dof).c_str ());
254
- return controller_interface::return_type::ERROR;
255
- }
256
- value = val.value ();
257
- }
236
+ std::ranges::transform (state_interfaces_, system_state_values_.begin (), [](const auto & interface) {
237
+ return interface.get_optional ().value_or (std::numeric_limits<double >::quiet_NaN ());
238
+ });
258
239
259
- // try getting the latest orientation of the vehicle in the inertial frame
260
- // if the transform is not available, use the last known orientation.
261
240
try {
262
- const geometry_msgs::msg::TransformStamped t =
263
- tf_buffer_->lookupTransform (params_.odom_frame_id , params_.vehicle_frame_id , tf2::TimePointZero);
241
+ const auto t = tf_buffer_->lookupTransform (params_.odom_frame_id , params_.vehicle_frame_id , tf2::TimePointZero);
264
242
tf2::fromMsg (t.transform .rotation , *system_rotation_.readFromRT ());
265
243
}
266
244
catch (const tf2::TransformException & e) {
267
- // NOLINTNEXTLINE
268
- RCLCPP_DEBUG (
269
- get_node ()->get_logger (),
270
- std::format (
271
- " Could not transform {} to {} using latest available transform. {}" ,
272
- params_.odom_frame_id ,
273
- params_.vehicle_frame_id ,
274
- e.what ())
245
+ RCLCPP_DEBUG ( // NOLINT
246
+ logger_,
247
+ std::format (" Could not transform {} to {}. {}" , params_.odom_frame_id , params_.vehicle_frame_id , e.what ())
275
248
.c_str ());
276
249
}
277
250
}
278
251
252
+ if (common::math::has_nan (system_state_values_)) {
253
+ RCLCPP_DEBUG (logger_, " Received system state with NaN value." ); // NOLINT
254
+ return controller_interface::return_type::ERROR;
255
+ }
256
+
257
+ return controller_interface::return_type::OK;
258
+ }
259
+
260
+ auto AdaptiveIntegralTerminalSlidingModeController::update_and_validate_interfaces ()
261
+ -> controller_interface::return_type
262
+ {
263
+ if (update_system_state_values () != controller_interface::return_type::OK) {
264
+ RCLCPP_DEBUG (logger_, " Failed to update system state values" ); // NOLINT
265
+ return controller_interface::return_type::ERROR;
266
+ }
267
+ if (common::math::has_nan (reference_interfaces_)) {
268
+ RCLCPP_DEBUG (logger_, " Received reference with NaN value." ); // NOLINT
269
+ return controller_interface::return_type::ERROR;
270
+ }
279
271
return controller_interface::return_type::OK;
280
272
}
281
273
282
274
auto AdaptiveIntegralTerminalSlidingModeController::update_and_write_commands (
283
275
const rclcpp::Time & time,
284
276
const rclcpp::Duration & period) -> controller_interface::return_type
285
277
{
286
- if (!model_initialized_) {
278
+ if (update_and_validate_interfaces () != controller_interface::return_type::OK) {
279
+ RCLCPP_DEBUG (logger_, " Skipping controller update. Failed to update and validate interfaces" ); // NOLINT
287
280
return controller_interface::return_type::OK;
288
281
}
289
282
290
283
configure_parameters ();
291
- update_system_state_values ();
292
284
293
285
// calculate the velocity error
294
286
const std::vector<double > error_values = common::math::calculate_error (reference_interfaces_, system_state_values_);
295
- if (std::ranges::all_of (error_values, [](double x) { return std::isnan (x); })) {
296
- // NOLINTNEXTLINE
297
- RCLCPP_DEBUG (get_node ()->get_logger (), " All velocity error values are NaN. Skipping control update." );
287
+ if (common::math::all_nan (error_values)) {
288
+ RCLCPP_DEBUG (logger_, " All velocity error values are NaN. Skipping control update." ); // NOLINT
298
289
return controller_interface::return_type::OK;
299
290
}
300
291
@@ -327,11 +318,7 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_and_write_commands(
327
318
328
319
for (auto && [command_interface, tau] : std::views::zip (command_interfaces_, t)) {
329
320
if (!command_interface.set_value (tau)) {
330
- // NOLINTNEXTLINE
331
- RCLCPP_WARN (
332
- get_node ()->get_logger (),
333
- std::format (" Failed to set command value for joint {}" , command_interface.get_name ()).c_str ());
334
- return controller_interface::return_type::ERROR;
321
+ RCLCPP_WARN (logger_, " Failed to set command for joint {}" , command_interface.get_name ().c_str ()); // NOLINT
335
322
};
336
323
}
337
324
0 commit comments