Skip to content

Commit c913a8a

Browse files
feat(control_validator)!: add acceleration check (#10326)
Signed-off-by: yuki-takagi-66 <yuki.takagi@tier4.jp>
1 parent 2338eef commit c913a8a

File tree

7 files changed

+110
-15
lines changed

7 files changed

+110
-15
lines changed

control/autoware_control_validator/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,5 @@ The input trajectory is detected as invalid if the index exceeds the following t
6464
| `thresholds.over_velocity_offset` | double | threshold velocity offset to valid the vehicle velocity [m/s] | 2.0 |
6565
| `thresholds.over_velocity_ratio` | double | threshold ratio to valid the vehicle velocity [*] | 0.2 |
6666
| `thresholds.overrun_stop_point_dist` | double | threshold distance to overrun stop point [m] | 0.8 |
67+
| `thresholds.acc_error_offset` | double | threshold ratio to valid the vehicle acceleration [*] | 0.8 |
68+
| `thresholds.acc_error_scale` | double | threshold acceleration to valid the vehicle acceleration [m] | 0.2 |
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
/**:
22
ros__parameters:
3-
# If the number of consecutive invalid trajectory exceeds this threshold, the Diag will be set to ERROR.
4-
# (For example, threshold = 1 means, even if the trajectory is invalid, Diag will not be ERROR if
5-
# the next trajectory is valid.)
3+
# If the number of consecutive invalid predicted_path exceeds this threshold, the Diag will be set to ERROR.
4+
# (For example, threshold = 1 means, even if the predicted_path is invalid, Diag will not be ERROR if
5+
# the next predicted_path is valid.)
66
diag_error_count_threshold: 0
77

88
display_on_terminal: false # show error msg on terminal
99

1010
thresholds:
1111
max_distance_deviation: 1.0
12+
acc_error_offset: 0.8
13+
acc_error_scale: 0.2
1214
rolling_back_velocity: 0.5
1315
over_velocity_offset: 2.0
1416
over_velocity_ratio: 0.2
1517
overrun_stop_point_dist: 0.8
1618
nominal_latency: 0.01
1719

20+
acc_lpf_gain: 0.97 # Time constant 1.11s
1821
vel_lpf_gain: 0.9 # Time constant 0.33
1922
hold_velocity_error_until_stop: true

control/autoware_control_validator/include/autoware/control_validator/control_validator.hpp

+40-1
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222

2323
#include <autoware/signal_processing/lowpass_filter_1d.hpp>
2424
#include <autoware_control_validator/msg/control_validator_status.hpp>
25+
#include <autoware_utils/ros/parameter.hpp>
2526
#include <autoware_utils/system/stop_watch.hpp>
2627
#include <rclcpp/rclcpp.hpp>
2728

2829
#include <autoware_control_msgs/msg/control.hpp>
2930
#include <autoware_internal_debug_msgs/msg/float64_stamped.hpp>
3031
#include <autoware_planning_msgs/msg/trajectory.hpp>
3132
#include <diagnostic_msgs/msg/diagnostic_array.hpp>
33+
#include <geometry_msgs/msg/accel_with_covariance_stamped.hpp>
3234
#include <nav_msgs/msg/odometry.hpp>
3335

3436
#include <cstdint>
@@ -45,6 +47,7 @@ using autoware_planning_msgs::msg::Trajectory;
4547
using autoware_planning_msgs::msg::TrajectoryPoint;
4648
using diagnostic_updater::DiagnosticStatusWrapper;
4749
using diagnostic_updater::Updater;
50+
using geometry_msgs::msg::AccelWithCovarianceStamped;
4851
using nav_msgs::msg::Odometry;
4952

5053
struct ValidationParams
@@ -57,6 +60,35 @@ struct ValidationParams
5760
double nominal_latency_threshold;
5861
};
5962

63+
/**
64+
* @class AccelerationValidator
65+
* @brief Validates deviation between output acceleration and measured acceleration.
66+
*/
67+
class AccelerationValidator
68+
{
69+
public:
70+
explicit AccelerationValidator(rclcpp::Node & node)
71+
{
72+
e_offset =
73+
autoware_utils::get_or_declare_parameter<double>(node, "thresholds.acc_error_offset");
74+
e_scale = autoware_utils::get_or_declare_parameter<double>(node, "thresholds.acc_error_scale");
75+
const double acc_lpf_gain =
76+
autoware_utils::get_or_declare_parameter<double>(node, "acc_lpf_gain");
77+
desired_acc_lpf.setGain(acc_lpf_gain);
78+
measured_acc_lpf.setGain(acc_lpf_gain);
79+
};
80+
81+
void validate(
82+
ControlValidatorStatus & res, const Odometry & kinematic_state, const Control & control_cmd,
83+
const AccelWithCovarianceStamped & loc_acc);
84+
85+
private:
86+
double e_offset;
87+
double e_scale;
88+
autoware::signal_processing::LowpassFilter1d desired_acc_lpf{0.0};
89+
autoware::signal_processing::LowpassFilter1d measured_acc_lpf{0.0};
90+
};
91+
6092
/**
6193
* @class ControlValidator
6294
* @brief Validates control commands by comparing predicted trajectories against reference
@@ -130,7 +162,8 @@ class ControlValidator : public rclcpp::Node
130162
*/
131163
void validate(
132164
const Trajectory & predicted_trajectory, const Trajectory & reference_trajectory,
133-
const Odometry & kinematics);
165+
const Odometry & kinematics, const Control & control_cmd,
166+
const AccelWithCovarianceStamped & measured_acc);
134167

135168
/**
136169
* @brief Publish debug information
@@ -156,6 +189,8 @@ class ControlValidator : public rclcpp::Node
156189
rclcpp::Subscription<Trajectory>::SharedPtr sub_predicted_traj_;
157190
autoware_utils::InterProcessPollingSubscriber<Odometry>::SharedPtr sub_kinematics_;
158191
autoware_utils::InterProcessPollingSubscriber<Trajectory>::SharedPtr sub_reference_traj_;
192+
autoware_utils::InterProcessPollingSubscriber<AccelWithCovarianceStamped>::SharedPtr
193+
sub_measured_acc_;
159194
rclcpp::Publisher<ControlValidatorStatus>::SharedPtr pub_status_;
160195
rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr pub_markers_;
161196
rclcpp::Publisher<autoware_internal_debug_msgs::msg::Float64Stamped>::SharedPtr
@@ -171,6 +206,8 @@ class ControlValidator : public rclcpp::Node
171206
ValidationParams validation_params_; // for thresholds
172207
autoware::signal_processing::LowpassFilter1d vehicle_vel_{0.0};
173208
autoware::signal_processing::LowpassFilter1d target_vel_{0.0};
209+
AccelerationValidator acceleration_validator{*this};
210+
174211
bool hold_velocity_error_until_stop_{false};
175212

176213
vehicle_info_utils::VehicleInfo vehicle_info_;
@@ -186,6 +223,8 @@ class ControlValidator : public rclcpp::Node
186223
Trajectory::ConstSharedPtr current_predicted_trajectory_;
187224

188225
Odometry::ConstSharedPtr current_kinematics_;
226+
AccelWithCovarianceStamped::ConstSharedPtr acceleration_msg_;
227+
Control::ConstSharedPtr control_cmd_msg_;
189228

190229
autoware_utils::StopWatch<std::chrono::milliseconds> stop_watch;
191230

control/autoware_control_validator/launch/control_validator.launch.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
<param from="$(var control_validator_param_path)"/>
99

1010
<!-- remap topic name -->
11+
<remap from="~/input/control_cmd" to="/control/command/control_cmd"/>
12+
<remap from="~/input/kinematics" to="/localization/kinematic_state"/>
13+
<remap from="~/input/measured_acceleration" to="/localization/acceleration"/>
1114
<remap from="~/input/reference_trajectory" to="$(var input_reference_trajectory)"/>
1215
<remap from="~/input/predicted_trajectory" to="$(var input_predicted_trajectory)"/>
13-
<remap from="~/input/kinematics" to="/localization/kinematic_state"/>
1416
<remap from="~/output/validation_status" to="~/validation_status"/>
1517
</node>
1618
</launch>

control/autoware_control_validator/msg/ControlValidatorStatus.msg

+3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ builtin_interfaces/Time stamp
22

33
# states
44
bool is_valid_max_distance_deviation
5+
bool is_valid_acc
56
bool is_rolling_back
67
bool is_over_velocity
78
bool has_overrun_stop_point
89
bool is_valid_latency
910

1011
# values
1112
float64 max_distance_deviation
13+
float64 desired_acc
14+
float64 measured_acc
1215
float64 target_vel
1316
float64 vehicle_vel
1417
float64 dist_to_stop

control/autoware_control_validator/src/control_validator.cpp

+55-10
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
#include "autoware/motion_utils/trajectory/trajectory.hpp"
2020
#include "autoware_vehicle_info_utils/vehicle_info_utils.hpp"
2121

22-
#include <nav_msgs/msg/odometry.hpp>
23-
2422
#include <algorithm>
2523
#include <cstdint>
2624
#include <memory>
@@ -31,6 +29,31 @@ namespace autoware::control_validator
3129
{
3230
using diagnostic_msgs::msg::DiagnosticStatus;
3331

32+
void AccelerationValidator::validate(
33+
ControlValidatorStatus & res, const Odometry & kinematic_state, const Control & control_cmd,
34+
const AccelWithCovarianceStamped & loc_acc)
35+
{
36+
desired_acc_lpf.filter(
37+
control_cmd.longitudinal.acceleration +
38+
9.8 * autoware_utils::get_rpy(kinematic_state.pose.pose).y);
39+
measured_acc_lpf.filter(loc_acc.accel.accel.linear.x);
40+
if (std::abs(kinematic_state.twist.twist.linear.x) < 1e-3) {
41+
desired_acc_lpf.reset(0.0);
42+
measured_acc_lpf.reset(0.0);
43+
}
44+
45+
res.desired_acc = desired_acc_lpf.getValue().value();
46+
res.measured_acc = measured_acc_lpf.getValue().value();
47+
res.is_valid_acc = [this]() {
48+
const double des = desired_acc_lpf.getValue().value();
49+
const double mes = measured_acc_lpf.getValue().value();
50+
const int8_t des_sign = std::signbit(des) ? 1 : -1;
51+
52+
return mes <= des * (1 + des_sign * e_scale) + e_offset &&
53+
mes >= des * (1 - des_sign * e_scale) + e_offset;
54+
}();
55+
}
56+
3457
ControlValidator::ControlValidator(const rclcpp::NodeOptions & options)
3558
: Node("control_validator", options), validation_params_(), vehicle_info_()
3659
{
@@ -47,6 +70,9 @@ ControlValidator::ControlValidator(const rclcpp::NodeOptions & options)
4770
sub_reference_traj_ =
4871
autoware_utils::InterProcessPollingSubscriber<Trajectory>::create_subscription(
4972
this, "~/input/reference_trajectory", 1);
73+
sub_measured_acc_ =
74+
autoware_utils::InterProcessPollingSubscriber<AccelWithCovarianceStamped>::create_subscription(
75+
this, "~/input/measured_acceleration", 1);
5076

5177
pub_status_ = create_publisher<ControlValidatorStatus>("~/output/validation_status", 1);
5278

@@ -77,9 +103,10 @@ void ControlValidator::setup_parameters()
77103
p.overrun_stop_point_dist = declare_parameter<double>(t + "overrun_stop_point_dist");
78104
p.nominal_latency_threshold = declare_parameter<double>(t + "nominal_latency");
79105
}
80-
const auto lpf_gain = declare_parameter<double>("vel_lpf_gain");
81-
vehicle_vel_.setGain(lpf_gain);
82-
target_vel_.setGain(lpf_gain);
106+
107+
const auto vel_lpf_gain = declare_parameter<double>("vel_lpf_gain");
108+
vehicle_vel_.setGain(vel_lpf_gain);
109+
target_vel_.setGain(vel_lpf_gain);
83110

84111
hold_velocity_error_until_stop_ = declare_parameter<bool>("hold_velocity_error_until_stop");
85112

@@ -122,6 +149,11 @@ void ControlValidator::setup_diag()
122149
stat, validation_status_.is_valid_max_distance_deviation,
123150
"control output is deviated from trajectory");
124151
});
152+
d.add(ns + "acceleration_error", [&](auto & stat) {
153+
set_status(
154+
stat, validation_status_.is_valid_acc,
155+
"Measured acceleration and desired acceleration is deviated");
156+
});
125157
d.add(ns + "rolling_back", [&](auto & stat) {
126158
set_status(
127159
stat, !validation_status_.is_rolling_back,
@@ -159,14 +191,23 @@ bool ControlValidator::is_data_ready()
159191
if (!current_predicted_trajectory_) {
160192
return waiting(sub_predicted_traj_->get_topic_name());
161193
}
194+
if (!acceleration_msg_) {
195+
return waiting(sub_measured_acc_->subscriber()->get_topic_name());
196+
}
197+
if (!control_cmd_msg_) {
198+
return waiting(sub_control_cmd_->get_topic_name());
199+
}
162200
return true;
163201
}
164202

165203
void ControlValidator::on_control_cmd(const Control::ConstSharedPtr msg)
166204
{
205+
control_cmd_msg_ = msg;
206+
167207
validation_status_.latency = (this->now() - msg->stamp).seconds();
168208
validation_status_.is_valid_latency =
169209
validation_status_.latency < validation_params_.nominal_latency_threshold;
210+
170211
validation_status_.invalid_count =
171212
is_all_valid(validation_status_) ? 0 : validation_status_.invalid_count + 1;
172213
}
@@ -178,12 +219,15 @@ void ControlValidator::on_predicted_trajectory(const Trajectory::ConstSharedPtr
178219
current_predicted_trajectory_ = msg;
179220
current_reference_trajectory_ = sub_reference_traj_->take_data();
180221
current_kinematics_ = sub_kinematics_->take_data();
222+
acceleration_msg_ = sub_measured_acc_->take_data();
181223

182224
if (!is_data_ready()) return;
183225

184226
debug_pose_publisher_->clear_markers();
185227

186-
validate(*current_predicted_trajectory_, *current_reference_trajectory_, *current_kinematics_);
228+
validate(
229+
*current_predicted_trajectory_, *current_reference_trajectory_, *current_kinematics_,
230+
*control_cmd_msg_, *acceleration_msg_);
187231

188232
diag_updater_.force_update();
189233

@@ -213,7 +257,8 @@ void ControlValidator::publish_debug_info()
213257

214258
void ControlValidator::validate(
215259
const Trajectory & predicted_trajectory, const Trajectory & reference_trajectory,
216-
const Odometry & kinematics)
260+
const Odometry & kinematics, const Control & control_cmd,
261+
const AccelWithCovarianceStamped & measured_acc)
217262
{
218263
if (predicted_trajectory.points.size() < 2) {
219264
RCLCPP_DEBUG(get_logger(), "predicted_trajectory size is less than 2. Cannot validate.");
@@ -232,7 +277,7 @@ void ControlValidator::validate(
232277
std::tie(
233278
validation_status_.max_distance_deviation, validation_status_.is_valid_max_distance_deviation) =
234279
calc_lateral_deviation_status(predicted_trajectory, *current_reference_trajectory_);
235-
280+
acceleration_validator.validate(validation_status_, kinematics, control_cmd, measured_acc);
236281
calc_velocity_deviation_status(*current_reference_trajectory_, kinematics);
237282
calc_stop_point_overrun_status(*current_reference_trajectory_, kinematics);
238283

@@ -310,8 +355,8 @@ void ControlValidator::calc_stop_point_overrun_status(
310355

311356
bool ControlValidator::is_all_valid(const ControlValidatorStatus & s)
312357
{
313-
return s.is_valid_max_distance_deviation && !s.is_rolling_back && !s.is_over_velocity &&
314-
!s.has_overrun_stop_point;
358+
return s.is_valid_max_distance_deviation && s.is_valid_acc && !s.is_rolling_back &&
359+
!s.is_over_velocity && !s.has_overrun_stop_point;
315360
}
316361

317362
void ControlValidator::display_status()

launch/tier4_control_launch/launch/control.launch.xml

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
<composable_node pkg="autoware_control_validator" plugin="autoware::control_validator::ControlValidator" name="control_validator">
204204
<remap from="~/input/control_cmd" to="/control/command/control_cmd"/>
205205
<remap from="~/input/kinematics" to="/localization/kinematic_state"/>
206+
<remap from="~/input/measured_acceleration" to="/localization/acceleration"/>
206207
<remap from="~/input/reference_trajectory" to="/planning/scenario_planning/trajectory"/>
207208
<remap from="~/input/predicted_trajectory" to="/control/trajectory_follower/lateral/predicted_trajectory"/>
208209
<remap from="~/output/validation_status" to="~/validation_status"/>

0 commit comments

Comments
 (0)