Skip to content

Commit b7dac3a

Browse files
committed
cleanup
1 parent ccd1b90 commit b7dac3a

File tree

7 files changed

+126
-138
lines changed

7 files changed

+126
-138
lines changed

controller_common/include/controller_common/common.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ namespace math
6060

6161
auto calculate_error(const std::vector<double> & reference, const std::vector<double> & state) -> std::vector<double>;
6262

63+
auto has_nan(const std::vector<double> & vec) -> bool;
64+
65+
auto all_nan(const std::vector<double> & vec) -> bool;
66+
6367
} // namespace math
6468

6569
} // namespace common

controller_common/src/common.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ auto calculate_error(const std::vector<double> & reference, const std::vector<do
161161
return error;
162162
}
163163

164+
auto has_nan(const std::vector<double> & vec) -> bool
165+
{
166+
return std::ranges::any_of(vec, [](double x) { return std::isnan(x); });
167+
}
168+
169+
auto all_nan(const std::vector<double> & vec) -> bool
170+
{
171+
return std::ranges::all_of(vec, [](double x) { return std::isnan(x); });
172+
}
173+
164174
} // namespace math
165175

166176
} // namespace common

velocity_controllers/include/velocity_controllers/adaptive_integral_terminal_sliding_mode_controller.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class AdaptiveIntegralTerminalSlidingModeController : public controller_interfac
7373

7474
auto configure_parameters() -> controller_interface::CallbackReturn;
7575

76+
auto update_and_validate_interfaces() -> controller_interface::return_type;
77+
7678
// provide an interface for setting reference commands from a topic
7779
// this allows us to use tools like the keyboard teleop node
7880
realtime_tools::RealtimeBuffer<geometry_msgs::msg::Twist> reference_;
@@ -87,9 +89,6 @@ class AdaptiveIntegralTerminalSlidingModeController : public controller_interfac
8789
bool first_update_{true};
8890
Eigen::Vector6d integral_error_;
8991

90-
std::shared_ptr<rclcpp::Subscription<std_msgs::msg::String>> robot_description_sub_;
91-
bool model_initialized_{false};
92-
9392
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
9493
std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
9594

@@ -114,6 +113,8 @@ class AdaptiveIntegralTerminalSlidingModeController : public controller_interfac
114113
Eigen::Matrix6d alpha_, k1_, k2_;
115114

116115
std::unique_ptr<hydrodynamics::Params> model_;
116+
117+
rclcpp::Logger logger_{rclcpp::get_logger("adaptive_integral_terminal_sliding_mode_controller")};
117118
};
118119

119120
} // namespace velocity_controllers

velocity_controllers/include/velocity_controllers/integral_sliding_mode_controller.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,15 @@ class IntegralSlidingModeController : public controller_interface::ChainableCont
7878

7979
auto configure_parameters() -> controller_interface::CallbackReturn;
8080

81+
auto update_and_validate_interfaces() -> controller_interface::return_type;
82+
8183
realtime_tools::RealtimeBuffer<geometry_msgs::msg::Twist> reference_;
8284
std::shared_ptr<rclcpp::Subscription<geometry_msgs::msg::Twist>> reference_sub_;
8385

8486
realtime_tools::RealtimeBuffer<nav_msgs::msg::Odometry> system_state_;
8587
std::shared_ptr<rclcpp::Subscription<nav_msgs::msg::Odometry>> system_state_sub_;
8688
std::vector<double> system_state_values_;
8789

88-
std::shared_ptr<rclcpp::Subscription<std_msgs::msg::String>> robot_description_sub_;
89-
bool model_initialized_{false};
90-
9190
// we need the system rotation from the inertial frame to the vehicle frame for the hydrodynamic model
9291
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
9392
std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
@@ -114,6 +113,8 @@ class IntegralSlidingModeController : public controller_interface::ChainableCont
114113
Eigen::Vector6d init_error_, total_error_;
115114

116115
std::unique_ptr<hydrodynamics::Params> model_;
116+
117+
rclcpp::Logger logger_{rclcpp::get_logger("integral_sliding_mode_controller")};
117118
};
118119

119120
} // namespace velocity_controllers

velocity_controllers/src/adaptive_integral_terminal_sliding_mode_controller.cpp

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ auto AdaptiveIntegralTerminalSlidingModeController::on_init() -> controller_inte
4848
{
4949
param_listener_ = std::make_shared<adaptive_integral_terminal_sliding_mode_controller::ParamListener>(get_node());
5050
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+
5162
return controller_interface::CallbackReturn::SUCCESS;
5263
}
5364

@@ -104,35 +115,15 @@ auto AdaptiveIntegralTerminalSlidingModeController::on_configure(const rclcpp_li
104115
// reset the adaptive gain
105116
k1_ = Eigen::Matrix6d::Identity();
106117

107-
RCLCPP_INFO(get_node()->get_logger(), "Waiting for robot description to be received"); // NOLINT
108-
109118
// NOLINTNEXTLINE(performance-unnecessary-value-param)
110119
reference_sub_ = get_node()->create_subscription<geometry_msgs::msg::Twist>(
111120
"~/reference", rclcpp::SystemDefaultsQoS(), [this](const std::shared_ptr<geometry_msgs::msg::Twist> msg) {
112121
reference_.writeFromNonRT(*msg);
113122
});
114123

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-
133124
// use the tf interface when we aren't getting the state from a topic
134125
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
136127
system_state_sub_ = get_node()->create_subscription<nav_msgs::msg::Odometry>(
137128
"~/system_state", rclcpp::SystemDefaultsQoS(), [this](const std::shared_ptr<nav_msgs::msg::Odometry> msg) {
138129
system_state_.writeFromNonRT(*msg);
@@ -228,9 +219,7 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_reference_from_subscr
228219
auto * current_reference = reference_.readFromNonRT();
229220
const std::vector<double> reference = common::messages::to_vector(*current_reference);
230221
for (auto && [interface, ref] : std::views::zip(reference_interfaces_, reference)) {
231-
if (!std::isnan(ref)) {
232-
interface = ref;
233-
}
222+
interface = ref;
234223
}
235224
common::messages::reset_message(current_reference);
236225
return controller_interface::return_type::OK;
@@ -241,60 +230,62 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_system_state_values()
241230
{
242231
if (params_.use_external_measured_states) {
243232
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());
246234
tf2::fromMsg(current_state->pose.pose.orientation, *system_rotation_.readFromRT());
247235
} 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+
});
258239

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.
261240
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);
264242
tf2::fromMsg(t.transform.rotation, *system_rotation_.readFromRT());
265243
}
266244
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())
275248
.c_str());
276249
}
277250
}
278251

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+
}
279271
return controller_interface::return_type::OK;
280272
}
281273

282274
auto AdaptiveIntegralTerminalSlidingModeController::update_and_write_commands(
283275
const rclcpp::Time & time,
284276
const rclcpp::Duration & period) -> controller_interface::return_type
285277
{
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
287280
return controller_interface::return_type::OK;
288281
}
289282

290283
configure_parameters();
291-
update_system_state_values();
292284

293285
// calculate the velocity error
294286
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
298289
return controller_interface::return_type::OK;
299290
}
300291

@@ -327,11 +318,7 @@ auto AdaptiveIntegralTerminalSlidingModeController::update_and_write_commands(
327318

328319
for (auto && [command_interface, tau] : std::views::zip(command_interfaces_, t)) {
329320
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
335322
};
336323
}
337324

0 commit comments

Comments
 (0)