@@ -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
133134void 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+
168184void 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+
207233void 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