Skip to content

Commit 8549447

Browse files
committed
fix(ackermann): add NaN checks to library and safe open-loop update
- Refactored update_from_position/velocity to handle NaN checks internally per review. - Added try_update_open_loop to allow error prpagation without breaking ABI. - Updated Ackermann controller to use safe library methods.
1 parent 0c0ebb4 commit 8549447

File tree

5 files changed

+61
-87
lines changed

5 files changed

+61
-87
lines changed

ackermann_steering_controller/src/ackermann_steering_controller.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ bool AckermannSteeringController::update_odometry(const rclcpp::Duration & perio
5959

6060
if (params_.open_loop)
6161
{
62-
if (!odometry_.try_update_open_loop(
63-
last_linear_velocity_, last_angular_velocity_, period.seconds()))
64-
{
65-
return false;
66-
}
62+
if(!odometry_.try_update_open_loop(
63+
last_linear_velocity_, last_angular_velocity_, period.seconds()
64+
))return false;
6765
}
6866
else
6967
{
@@ -105,14 +103,14 @@ bool AckermannSteeringController::update_odometry(const rclcpp::Duration & perio
105103
if (params_.position_feedback)
106104
{
107105
// Estimate linear and angular velocity using joint information
108-
success = odometry_.try_update_from_position(
106+
success = odometry_.update_from_position(
109107
traction_right_wheel_value, traction_left_wheel_value, steering_right_position,
110108
steering_left_position, period.seconds());
111109
}
112110
else
113111
{
114112
// Estimate linear and angular velocity using joint information
115-
success = odometry_.try_update_from_velocity(
113+
success = odometry_.update_from_velocity(
116114
traction_right_wheel_value, traction_left_wheel_value, steering_right_position,
117115
steering_left_position, period.seconds());
118116
}

steering_controllers_library/include/steering_controllers_library/steering_kinematics.hpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,6 @@ class SteeringKinematics
141141

142142
bool try_update_open_loop(double linear, double angular, double delTime);
143143

144-
bool try_update_from_position(
145-
double right_traction, double left_traction, double right_steering, double left_steering,
146-
double delTime);
147-
148-
bool try_update_from_velocity(
149-
double right_traction, double left_traction, double right_steering, double left_steering,
150-
double delTime);
151-
152144
/**
153145
* \brief Set odometry type
154146
* \param type odometry type

steering_controllers_library/include/steering_controllers_library/steering_odometry.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,6 @@ class [[deprecated("Use steering_kinematics::SteeringKinematics instead")]] Stee
118118

119119
bool try_update_open_loop(double linear, double angular, double delTime);
120120

121-
bool try_update_from_position(double right_traction, double left_traction, double right_steering, double left_steering, double delTime);
122-
123-
bool try_update_from_velocity(double right_traction, double left_traction, double right_steering, double left_steering, double delTime);
124-
125121
private:
126122
steering_kinematics::SteeringKinematics sk_impl_;
127123
};

steering_controllers_library/src/steering_kinematics.cpp

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ bool SteeringKinematics::update_odometry(
7878
bool SteeringKinematics::update_from_position(
7979
const double traction_wheel_pos, const double steer_pos, const double dt)
8080
{
81+
82+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_wheel_pos) || !std::isfinite(steer_pos)) return false;
83+
8184
const double traction_wheel_est_pos_diff = traction_wheel_pos - traction_wheel_old_pos_;
8285

8386
/// Update old position with current:
@@ -90,6 +93,11 @@ bool SteeringKinematics::update_from_position(
9093
const double traction_right_wheel_pos, const double traction_left_wheel_pos,
9194
const double steer_pos, const double dt)
9295
{
96+
97+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_right_wheel_pos)
98+
|| !std::isfinite(traction_left_wheel_pos) || !std::isfinite(steer_pos))
99+
return false;
100+
93101
const double traction_right_wheel_est_pos_diff =
94102
traction_right_wheel_pos - traction_right_wheel_old_pos_;
95103
const double traction_left_wheel_est_pos_diff =
@@ -107,6 +115,11 @@ bool SteeringKinematics::update_from_position(
107115
const double traction_right_wheel_pos, const double traction_left_wheel_pos,
108116
const double right_steer_pos, const double left_steer_pos, const double dt)
109117
{
118+
119+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_right_wheel_pos)
120+
|| !std::isfinite(traction_left_wheel_pos) || !std::isfinite(right_steer_pos) || !std::isfinite(left_steer_pos))
121+
return false;
122+
110123
const double traction_right_wheel_est_pos_diff =
111124
traction_right_wheel_pos - traction_right_wheel_old_pos_;
112125
const double traction_left_wheel_est_pos_diff =
@@ -124,6 +137,9 @@ bool SteeringKinematics::update_from_position(
124137
bool SteeringKinematics::update_from_velocity(
125138
const double traction_wheel_vel, const double steer_pos, const double dt)
126139
{
140+
141+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_wheel_vel) || !std::isfinite(steer_pos)) return false;
142+
127143
steer_pos_ = steer_pos;
128144
double linear_velocity = traction_wheel_vel * wheel_radius_;
129145
const double angular_velocity = std::tan(steer_pos) * linear_velocity / wheel_base_;
@@ -156,6 +172,9 @@ bool SteeringKinematics::update_from_velocity(
156172
const double right_traction_wheel_vel, const double left_traction_wheel_vel,
157173
const double steer_pos, const double dt)
158174
{
175+
176+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(right_traction_wheel_vel) || !std::isfinite(left_traction_wheel_vel) || !std::isfinite(steer_pos)) return false;
177+
159178
steer_pos_ = steer_pos;
160179
double linear_velocity = get_linear_velocity_double_traction_axle(
161180
right_traction_wheel_vel, left_traction_wheel_vel, steer_pos_);
@@ -169,6 +188,11 @@ bool SteeringKinematics::update_from_velocity(
169188
const double right_traction_wheel_vel, const double left_traction_wheel_vel,
170189
const double right_steer_pos, const double left_steer_pos, const double dt)
171190
{
191+
192+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(right_traction_wheel_vel) ||
193+
!std::isfinite(left_traction_wheel_vel) || !std::isfinite(right_steer_pos) || !std::isfinite(left_steer_pos)) return false;
194+
195+
172196
// overdetermined, we take the average
173197
const double right_steer_pos_est = std::atan(
174198
wheel_base_ * std::tan(right_steer_pos) /
@@ -187,14 +211,29 @@ bool SteeringKinematics::update_from_velocity(
187211

188212
void SteeringKinematics::update_open_loop(const double v_bx, const double omega_bz, const double dt)
189213
{
214+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(v_bx) || !std::isfinite(omega_bz)) return;
190215
/// Save last linear and angular velocity:
191216
linear_ = v_bx;
217+
192218
angular_ = omega_bz;
193219

194220
/// Integrate odometry:
195221
integrate_fk(v_bx, omega_bz, dt);
196222
}
197223

224+
bool SteeringKinematics::try_update_open_loop(const double v_bx, const double omega_bz, const double dt)
225+
{
226+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(v_bx) || !std::isfinite(omega_bz)) return false;
227+
/// Save last linear and angular velocity:
228+
linear_ = v_bx;
229+
230+
angular_ = omega_bz;
231+
232+
/// Integrate odometry:
233+
integrate_fk(v_bx, omega_bz, dt);
234+
return true;
235+
}
236+
198237
void SteeringKinematics::set_wheel_params(
199238
double wheel_radius, double wheel_base, double wheel_track)
200239
{
@@ -393,38 +432,4 @@ void SteeringKinematics::reset_accumulators()
393432
linear_acc_ = RollingMeanAccumulator(velocity_rolling_window_size_);
394433
angular_acc_ = RollingMeanAccumulator(velocity_rolling_window_size_);
395434
}
396-
397-
bool SteeringKinematics::try_update_open_loop(double linear, double angular, double delTime)
398-
{
399-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
400-
update_open_loop(linear, angular, delTime);
401-
return true;
402-
}
403-
404-
bool SteeringKinematics::try_update_from_position(
405-
double right_traction, double left_traction, double right_steering, double left_steering,
406-
double delTime)
407-
{
408-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
409-
if (
410-
!std::isfinite(right_traction) || !std::isfinite(left_traction) ||
411-
!std::isfinite(right_steering) || !std::isfinite(left_steering))
412-
return false;
413-
update_from_position(right_traction, left_traction, right_steering, left_steering, delTime);
414-
return true;
415-
}
416-
417-
bool SteeringKinematics::try_update_from_velocity(
418-
double right_traction, double left_traction, double right_steering, double left_steering,
419-
double delTime)
420-
{
421-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
422-
if (
423-
!std::isfinite(right_traction) || !std::isfinite(left_traction) ||
424-
!std::isfinite(right_steering) || !std::isfinite(left_steering))
425-
return false;
426-
update_from_velocity(right_traction, left_traction, right_steering, left_steering, delTime);
427-
return true;
428-
}
429-
430435
} // namespace steering_kinematics

steering_controllers_library/src/steering_odometry.cpp

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ void SteeringOdometry::init(const rclcpp::Time & time) { sk_impl_.init(time); }
3333
bool SteeringOdometry::update_from_position(
3434
const double traction_wheel_pos, const double steer_pos, const double dt)
3535
{
36+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_wheel_pos) || !std::isfinite(steer_pos)) return false;
3637
return sk_impl_.update_from_position(traction_wheel_pos, steer_pos, dt);
3738
}
3839

3940
bool SteeringOdometry::update_from_position(
4041
const double traction_right_wheel_pos, const double traction_left_wheel_pos,
4142
const double steer_pos, const double dt)
4243
{
44+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_right_wheel_pos) ||
45+
!std::isfinite(traction_left_wheel_pos) || !std::isfinite(steer_pos)) return false;
4346
return sk_impl_.update_from_position(
4447
traction_right_wheel_pos, traction_left_wheel_pos, steer_pos, dt);
4548
}
@@ -48,20 +51,25 @@ bool SteeringOdometry::update_from_position(
4851
const double traction_right_wheel_pos, const double traction_left_wheel_pos,
4952
const double right_steer_pos, const double left_steer_pos, const double dt)
5053
{
54+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_right_wheel_pos) ||
55+
!std::isfinite(traction_left_wheel_pos) || !std::isfinite(right_steer_pos) || !std::isfinite(left_steer_pos)) return false;
5156
return sk_impl_.update_from_position(
5257
traction_right_wheel_pos, traction_left_wheel_pos, right_steer_pos, left_steer_pos, dt);
5358
}
5459

5560
bool SteeringOdometry::update_from_velocity(
5661
const double traction_wheel_vel, const double steer_pos, const double dt)
5762
{
63+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(traction_wheel_vel) || !std::isfinite(steer_pos)) return false;
5864
return sk_impl_.update_from_velocity(traction_wheel_vel, steer_pos, dt);
5965
}
6066

6167
bool SteeringOdometry::update_from_velocity(
6268
const double right_traction_wheel_vel, const double left_traction_wheel_vel,
6369
const double steer_pos, const double dt)
6470
{
71+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(right_traction_wheel_vel) ||
72+
!std::isfinite(left_traction_wheel_vel) || !std::isfinite(steer_pos)) return false;
6573
return sk_impl_.update_from_velocity(
6674
right_traction_wheel_vel, left_traction_wheel_vel, steer_pos, dt);
6775
}
@@ -70,15 +78,24 @@ bool SteeringOdometry::update_from_velocity(
7078
const double right_traction_wheel_vel, const double left_traction_wheel_vel,
7179
const double right_steer_pos, const double left_steer_pos, const double dt)
7280
{
81+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(right_traction_wheel_vel) ||
82+
!std::isfinite(left_traction_wheel_vel) || !std::isfinite(right_steer_pos) || !std::isfinite(left_steer_pos)) return false;
7383
return sk_impl_.update_from_velocity(
7484
right_traction_wheel_vel, left_traction_wheel_vel, right_steer_pos, left_steer_pos, dt);
7585
}
7686

7787
void SteeringOdometry::update_open_loop(const double v_bx, const double omega_bz, const double dt)
7888
{
89+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(v_bx) || !std::isfinite(omega_bz)) return;
7990
sk_impl_.update_open_loop(v_bx, omega_bz, dt);
8091
}
8192

93+
bool SteeringOdometry::try_update_open_loop(const double v_bx, const double omega_bz, const double dt){
94+
if(std::fabs(dt) < std::numeric_limits<double>::epsilon() || !std::isfinite(v_bx) || !std::isfinite(omega_bz)) return false;
95+
sk_impl_.try_update_open_loop(v_bx, omega_bz, dt);
96+
return true;
97+
}
98+
8299
void SteeringOdometry::set_wheel_params(double wheel_radius, double wheel_base, double wheel_track)
83100
{
84101
sk_impl_.set_wheel_params(wheel_radius, wheel_base, wheel_track);
@@ -109,38 +126,4 @@ std::tuple<std::vector<double>, std::vector<double>> SteeringOdometry::get_comma
109126
}
110127

111128
void SteeringOdometry::reset_odometry() { sk_impl_.reset_odometry(); }
112-
113-
bool SteeringOdometry::try_update_open_loop(double linear, double angular, double delTime)
114-
{
115-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
116-
update_open_loop(linear, angular, delTime);
117-
return true;
118-
}
119-
120-
bool SteeringOdometry::try_update_from_position(
121-
double right_traction, double left_traction, double right_steering, double left_steering,
122-
double delTime)
123-
{
124-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
125-
if (
126-
!std::isfinite(right_traction) || !std::isfinite(left_traction) ||
127-
!std::isfinite(right_steering) || !std::isfinite(left_steering))
128-
return false;
129-
update_from_position(right_traction, left_traction, right_steering, left_steering, delTime);
130-
return true;
131-
}
132-
133-
bool SteeringOdometry::try_update_from_velocity(
134-
double right_traction, double left_traction, double right_steering, double left_steering,
135-
double delTime)
136-
{
137-
if (std::fabs(delTime) < std::numeric_limits<double>::epsilon()) return false;
138-
if (
139-
!std::isfinite(right_traction) || !std::isfinite(left_traction) ||
140-
!std::isfinite(right_steering) || !std::isfinite(left_steering))
141-
return false;
142-
update_from_velocity(right_traction, left_traction, right_steering, left_steering, delTime);
143-
return true;
144-
}
145-
146129
} // namespace steering_odometry

0 commit comments

Comments
 (0)