Skip to content

Commit 437533c

Browse files
committed
separate offset update logic from callibration logic
- check if offset update topic needs to be published for control - when offset update is published, right new published value to log file - separate calibration logic to right offset to calibration file when triggered - remove unnecessary output topic steer_offset_error (since its same as steering offset value itself) Signed-off-by: Mohammad <alqudah.mohammad@tier4.jp>
1 parent a9693d8 commit 437533c

File tree

6 files changed

+110
-83
lines changed

6 files changed

+110
-83
lines changed

control/autoware_mpc_lateral_controller/src/mpc_lateral_controller.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ MpcLateralController::MpcLateralController(
117117

118118
/* steering offset compensation */
119119
{
120-
const auto steer_offset_param_name =
121-
node.declare_parameter<std::string>("steer_offset_param_name");
122-
m_steering_offset_ = node.declare_parameter<double>(steer_offset_param_name);
123120
enable_auto_steering_offset_removal_ =
124121
dp_bool("steering_offset.enable_auto_steering_offset_removal");
125122
if (enable_auto_steering_offset_removal_) {

control/autoware_trajectory_follower_node/param/lateral/mpc.param.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,6 @@
6969
# steer offset
7070
steering_offset:
7171
enable_auto_steering_offset_removal: true
72-
steer_offset_filter_cutoff_hz: 0.5 # cutoff frequency of lowpass filter for steering offset [Hz]
72+
steer_offset_filter_cutoff_hz: 0.3 # cutoff frequency of lowpass filter for steering offset [Hz]
7373

7474
publish_debug_trajectories: true # flag to publish predicted trajectory and resampled reference trajectory for debug purpose

vehicle/autoware_steer_offset_estimator/include/autoware/steer_offset_estimator/structs.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ struct SteerOffsetCalibrationParameters
7373
double warning_offset_th{0.005};
7474
std::string steer_offset_param_path;
7575
std::string steer_offset_param_name;
76+
std::string calibration_file_path;
77+
std::string calibration_param_name;
7678

7779
static inline const std::unordered_map<std::string, CalibrationMode> mode_map{
7880
{"off", CalibrationMode::OFF},

vehicle/autoware_steer_offset_estimator/launch/steer_offset_estimator.launch.xml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
<launch>
22
<!-- Parameter -->
33
<arg name="config_file" default="$(find-pkg-share autoware_steer_offset_estimator)/config/steer_offset_estimator.param.yaml"/>
4-
<arg name="initial_steer_offset_param_path" default="$(find-pkg-share autoware_steer_offset_estimator)/config/steer_offset.param.yaml"/>
5-
<arg name="initial_steer_offset_param_name" default="steer_offset"/>
4+
<arg name="steer_offset_log_file_path" default="$(find-pkg-share autoware_steer_offset_estimator)/config/steer_offset.param.yaml"/>
5+
<arg name="steer_offset_log_param_name" default="steer_offset"/>
6+
<arg name="steer_offset_calibration_file_path" default="$(find-pkg-share autoware_steer_offset_estimator)/config/steer_offset.param.yaml"/>
7+
<arg name="steer_offset_calibration_param_name" default="residual_steering_offset"/>
68
<!-- get wheel base from vehicle info -->
79
<include file="$(find-pkg-share autoware_global_parameter_loader)/launch/global_params.launch.py"/>
810

911
<!-- steer offset estimator -->
1012
<node pkg="autoware_steer_offset_estimator" exec="steer_offset_estimator_node" name="steer_offset_estimator" output="screen">
1113
<param from="$(var config_file)"/>
12-
<param from="$(var initial_steer_offset_param_path)"/>
13-
<param name="steer_offset_param_path" value="$(var initial_steer_offset_param_path)"/>
14-
<param name="steer_offset_param_name" value="$(var initial_steer_offset_param_name)"/>
14+
<param from="$(var steer_offset_log_file_path)"/>
15+
<param name="steer_offset_param_path" value="$(var steer_offset_log_file_path)"/>
16+
<param name="steer_offset_param_name" value="$(var steer_offset_log_param_name)"/>
17+
<param name="calibration_file_path" value="$(var steer_offset_calibration_file_path)"/>
18+
<param name="calibration_param_name" value="$(var steer_offset_calibration_param_name)"/>
1519
<remap from="~/input/pose" to="/localization/pose_estimator/pose"/>
1620
<remap from="~/input/steer" to="/vehicle/status/steering_status"/>
1721
<remap from="~/output/steering_offset" to="~/steering_offset"/>
1822
<remap from="~/output/steering_offset_covariance" to="~/steering_offset_covariance"/>
19-
<remap from="~/output/steering_offset_error" to="~/steering_offset_error"/>
2023
<remap from="~/output/debug_info" to="~/debug_info"/>
2124
<remap from="~/output/steering_offset_update" to="~/steering_offset_update"/>
2225
</node>

vehicle/autoware_steer_offset_estimator/src/node.cpp

Lines changed: 76 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,12 @@ SteerOffsetEstimatorNode::SteerOffsetEstimatorNode(const rclcpp::NodeOptions & n
6565
pub_steer_offset_ = this->create_publisher<Float32Stamped>("~/output/steering_offset", 1);
6666
pub_steer_offset_covariance_ =
6767
this->create_publisher<Float32Stamped>("~/output/steering_offset_covariance", 1);
68-
pub_steer_offset_error_ =
69-
this->create_publisher<Float32Stamped>("~/output/steering_offset_error", 1);
7068
pub_debug_info_ = this->create_publisher<StringStamped>("~/output/debug_info", 1);
7169
pub_steer_offset_update_ = this->create_publisher<Float32Stamped>(
7270
"~/output/steering_offset_update", rclcpp::QoS{1}.transient_local());
7371

7472
set_calibration_parameters();
7573

76-
// get current registered steering offset
77-
current_steering_offset_ =
78-
this->declare_parameter<double>(calibration_params_.steer_offset_param_name);
79-
8074
// Create timer
8175
auto update_hz = this->declare_parameter<double>("update_hz", 10.0);
8276
const auto period = rclcpp::Rate(update_hz).period();
@@ -92,9 +86,12 @@ SteerOffsetEstimatorNode::SteerOffsetEstimatorNode(const rclcpp::NodeOptions & n
9286
SteerOffsetCalibrationParameters::mode_to_str_map.at(calibration_params_.mode).c_str());
9387

9488
// publish initial steer offset value
89+
// get current registered steering offset
90+
last_offset_update_ =
91+
this->declare_parameter<double>(calibration_params_.steer_offset_param_name);
9592
auto initial_msg = std::make_unique<autoware_internal_debug_msgs::msg::Float32Stamped>();
9693
initial_msg->stamp = this->now();
97-
initial_msg->data = static_cast<float>(current_steering_offset_);
94+
initial_msg->data = static_cast<float>(last_offset_update_);
9895
pub_steer_offset_update_->publish(std::move(initial_msg));
9996

10097
last_calibration_time_ = this->now();
@@ -128,6 +125,10 @@ void SteerOffsetEstimatorNode::set_calibration_parameters()
128125
this->declare_parameter<std::string>("steer_offset_param_path");
129126
calibration_params_.steer_offset_param_name =
130127
this->declare_parameter<std::string>("steer_offset_param_name");
128+
calibration_params_.calibration_file_path =
129+
this->declare_parameter<std::string>("calibration_file_path");
130+
calibration_params_.calibration_param_name =
131+
this->declare_parameter<std::string>("calibration_param_name");
131132
}
132133

133134
void SteerOffsetEstimatorNode::on_timer()
@@ -149,7 +150,7 @@ void SteerOffsetEstimatorNode::on_timer()
149150

150151
auto result = estimator_.update(poses, steers);
151152
if (result) {
152-
latest_result_ = result.value();
153+
set_latest_reliable_result(result.value());
153154
publish_data(result.value());
154155
check_auto_calibration();
155156
} else {
@@ -165,6 +166,21 @@ void SteerOffsetEstimatorNode::on_timer()
165166
}
166167
}
167168

169+
void SteerOffsetEstimatorNode::set_latest_reliable_result(
170+
const SteerOffsetEstimationUpdated & result)
171+
{
172+
if (result.covariance > calibration_params_.covariance_th) {
173+
return;
174+
}
175+
176+
const auto now = this->now();
177+
if ((now - last_no_result_time_).seconds() < calibration_params_.min_steady_duration) {
178+
return;
179+
}
180+
181+
latest_reliable_result_ = result;
182+
}
183+
168184
void SteerOffsetEstimatorNode::publish_data(const SteerOffsetEstimationUpdated & result)
169185
{
170186
auto pub_float = [this](const auto & publisher, const double value) {
@@ -177,12 +193,10 @@ void SteerOffsetEstimatorNode::publish_data(const SteerOffsetEstimationUpdated &
177193
pub_float(pub_steer_offset_, result.offset);
178194
pub_float(pub_steer_offset_covariance_, result.covariance);
179195

180-
const double offset_error = result.offset - current_steering_offset_;
181-
pub_float(pub_steer_offset_error_, offset_error);
182-
183196
if (is_publish_update(result)) {
184197
pub_float(pub_steer_offset_update_, result.offset);
185198
last_offset_update_ = result.offset;
199+
log_offset_update(result);
186200
}
187201

188202
autoware_internal_debug_msgs::msg::StringStamped debug_info;
@@ -204,44 +218,46 @@ bool SteerOffsetEstimatorNode::is_publish_update(const SteerOffsetEstimationUpda
204218
result.covariance < calibration_params_.covariance_th;
205219
}
206220

221+
void SteerOffsetEstimatorNode::log_offset_update(const SteerOffsetEstimationUpdated & result) const
222+
{
223+
const auto & param_path = calibration_params_.steer_offset_param_path;
224+
const auto & param_name = calibration_params_.steer_offset_param_name;
225+
226+
auto write_result = write_to_yaml(param_path, param_name, result.offset);
227+
if (!write_result) {
228+
RCLCPP_ERROR(
229+
this->get_logger(), "Failed to write steer offset to YAML: %s", write_result.error().c_str());
230+
}
231+
}
232+
207233
void SteerOffsetEstimatorNode::check_auto_calibration()
208234
{
209-
if (!latest_result_) return;
235+
if (!latest_reliable_result_) return;
210236

211237
if (calibration_params_.mode != CalibrationMode::AUTO) {
212238
if (
213-
std::abs(latest_result_->offset) > calibration_params_.warning_offset_th &&
214-
latest_result_->covariance < calibration_params_.covariance_th) {
239+
std::abs(latest_reliable_result_->offset) > calibration_params_.warning_offset_th &&
240+
latest_reliable_result_->covariance < calibration_params_.covariance_th) {
215241
RCLCPP_WARN_THROTTLE(
216242
this->get_logger(), *get_clock(), 1000,
217243
"Estimated steering offset %.4f exceeds warning threshold %.4f. Consider calibrating the "
218244
"steering offset.",
219-
latest_result_->offset, calibration_params_.warning_offset_th);
245+
latest_reliable_result_->offset, calibration_params_.warning_offset_th);
220246
}
221247
return;
222248
}
223249

224250
const auto now = this->now();
225251
if (
226252
(now - last_calibration_time_).seconds() < calibration_params_.min_update_interval ||
227-
(now - last_no_result_time_).seconds() < calibration_params_.min_steady_duration) {
228-
return;
229-
}
230-
231-
if (std::abs(latest_result_->offset) < calibration_params_.update_offset_th) {
232-
return;
233-
}
234-
235-
if (
236-
latest_result_->covariance > calibration_params_.covariance_th ||
237-
std::abs(latest_result_->offset) > calibration_params_.max_offset_limit) {
253+
std::abs(latest_reliable_result_->offset) < calibration_params_.update_offset_th ||
254+
std::abs(latest_reliable_result_->offset) > calibration_params_.max_offset_limit) {
238255
return;
239256
}
240257

241-
if (execute_calibration_update(latest_result_->offset)) {
258+
if (execute_calibration_update(latest_reliable_result_->offset)) {
242259
last_calibration_time_ = now;
243-
RCLCPP_INFO(
244-
this->get_logger(), "Auto calibration updated offset to %.4f rad.", latest_result_->offset);
260+
RCLCPP_INFO(this->get_logger(), "Auto calibration updated offset successfully.");
245261
} else {
246262
RCLCPP_ERROR(this->get_logger(), "Auto calibration failed to write to YAML path.");
247263
}
@@ -260,24 +276,22 @@ void SteerOffsetEstimatorNode::on_update_offset_request(
260276
if (calibration_params_.mode == CalibrationMode::OFF)
261277
return reject("Rejected: calibration is in OFF mode");
262278

263-
if (!latest_result_) return reject("Rejected: estimation result not available");
279+
if (!latest_reliable_result_) return reject("Rejected: latest reliable result not available");
264280

265-
if (latest_result_->covariance > calibration_params_.covariance_th)
281+
if (std::abs(latest_reliable_result_->offset) > calibration_params_.max_offset_limit)
266282
return reject(
267-
"Rejected: High uncertainty. Covariance: " + std::to_string(latest_result_->covariance));
283+
"Rejected: Offset value exceeds limit. Offset: " +
284+
std::to_string(latest_reliable_result_->offset));
268285

269-
if (std::abs(latest_result_->offset) > calibration_params_.max_offset_limit)
270-
return reject(
271-
"Rejected: Offset value exceeds limit. Offset: " + std::to_string(latest_result_->offset));
272-
273-
if (execute_calibration_update(latest_result_->offset)) {
286+
const auto calibration_result = execute_calibration_update(latest_reliable_result_->offset);
287+
if (calibration_result) {
274288
response->success = true;
275289
response->message =
276-
"Success: Offset updated to " + std::to_string(latest_result_->offset) + " rad.";
290+
"Success: Offset updated to " + std::to_string(calibration_result.value()) + " rad.";
277291
last_calibration_time_ = this->now();
278292
} else {
279293
response->success = false;
280-
response->message = "Error: Failed to write to YAML path.";
294+
response->message = "Error: " + calibration_result.error();
281295
}
282296
}
283297

@@ -290,26 +304,34 @@ std::string get_timestamp_string()
290304
return ss.str();
291305
}
292306

293-
bool SteerOffsetEstimatorNode::execute_calibration_update(const double steer_offset)
307+
tl::expected<double, std::string> SteerOffsetEstimatorNode::execute_calibration_update(
308+
const double steer_offset)
294309
{
295-
const auto & param_path = calibration_params_.steer_offset_param_path;
296-
const auto & param_name = calibration_params_.steer_offset_param_name;
310+
const auto & param_path = calibration_params_.calibration_file_path;
311+
const auto & param_name = calibration_params_.calibration_param_name;
312+
313+
return write_to_yaml(param_path, param_name, steer_offset, true);
314+
}
297315

316+
tl::expected<double, std::string> SteerOffsetEstimatorNode::write_to_yaml(
317+
const std::string & file_path, const std::string & param_name, double value,
318+
const bool accumulate) const
319+
{
298320
try {
299-
YAML::Node config = YAML::LoadFile(param_path);
321+
YAML::Node config = YAML::LoadFile(file_path);
300322
auto node = config["/**"]["ros__parameters"];
301323

302-
if (node) {
303-
node[param_name] = steer_offset;
304-
} else {
305-
RCLCPP_ERROR(this->get_logger(), "Could not find 'ros__parameters' key in YAML.");
306-
return false;
324+
if (!node) {
325+
return tl::make_unexpected("Could not find 'ros__parameters' key in YAML.");
307326
}
308327

309-
std::ofstream fout(param_path);
328+
auto write_value =
329+
accumulate ? value + (node[param_name] ? node[param_name].as<double>() : 0.0) : value;
330+
node[param_name] = write_value;
331+
332+
std::ofstream fout(file_path);
310333
if (!fout.is_open()) {
311-
RCLCPP_ERROR(this->get_logger(), "Failed to open file for writing: %s", param_path.c_str());
312-
return false;
334+
return tl::make_unexpected(fmt::format("Failed to open file for writing: {}", file_path));
313335
}
314336

315337
fout << "# " << param_name << " was AUTOMATICALLY SET BY steer_offset_estimator at "
@@ -318,13 +340,12 @@ bool SteerOffsetEstimatorNode::execute_calibration_update(const double steer_off
318340
fout.close();
319341

320342
RCLCPP_INFO(
321-
this->get_logger(), "Saved %.4f to %s as '%s'", steer_offset, param_path.c_str(),
343+
this->get_logger(), "Saved %.4f to %s as '%s'", write_value, file_path.c_str(),
322344
param_name.c_str());
323345

324-
return true;
346+
return write_value;
325347
} catch (const std::exception & e) {
326-
RCLCPP_ERROR(this->get_logger(), "YAML update exception: %s", e.what());
327-
return false;
348+
return tl::make_unexpected(fmt::format("YAML update exception: {}", e.what()));
328349
}
329350
}
330351

0 commit comments

Comments
 (0)