@@ -186,12 +186,8 @@ AmclNode::AmclNode(const rclcpp::NodeOptions& options) : BaseAMCLNode{"amcl", ""
186186
187187 {
188188 auto descriptor = rcl_interfaces::msg::ParameterDescriptor ();
189- descriptor.description = " Frequency in Hz for increased propagation rate. Set to 0 to disable." ;
190- descriptor.floating_point_range .resize (1 );
191- descriptor.floating_point_range [0 ].from_value = 0.0 ;
192- descriptor.floating_point_range [0 ].to_value = 100.0 ;
193- descriptor.floating_point_range [0 ].step = 0.0 ;
194- declare_parameter (" propagation_rate" , rclcpp::ParameterValue (0.0 ), descriptor);
189+ descriptor.description = " Set true to enable increased propagation, and set false to disable it." ;
190+ declare_parameter (" propagation_rate" , rclcpp::ParameterValue (false ), descriptor);
195191 }
196192}
197193
@@ -262,15 +258,14 @@ void AmclNode::do_activate(const rclcpp_lifecycle::State&) {
262258 common_service_qos, common_callback_group_);
263259 RCLCPP_INFO (get_logger (), " Created request_nomotion_update service" );
264260
265- // Setup increased propagation timer if enabled
266261 {
267- const double propagation_freq = get_parameter ( " propagation_rate " ). as_double ();
268- if (propagation_freq > 0.0 ) {
269- auto period = std::chrono::duration< double >( 1.0 / propagation_freq);
270- propagation_timer_ =
271- create_wall_timer (period, std::bind (&AmclNode::propagation_timer_callback , this ), common_callback_group_ );
272- RCLCPP_INFO ( get_logger (), " Created propagation timer at %.1f Hz " , propagation_freq);
273- // Initialize odometry motion buffer
262+ // Subscribe to odometry topic to buffer odometry motions
263+ if (get_parameter ( " propagation_rate " ). as_bool () ) {
264+ odom_sub_ = create_subscription<nav_msgs::msg::Odometry>(
265+ get_parameter ( " odom_topic " ). as_string (), rclcpp::SensorDataQoS (),
266+ std::bind (&AmclNode::odometry_callback , this , std::placeholders::_1 ), common_subscription_options_ );
267+
268+ RCLCPP_INFO ( get_logger (), " Subscribed to odom_topic: %s " , odom_sub_-> get_topic_name ());
274269 odometry_motion_buffer_.clear ();
275270 }
276271 }
@@ -282,7 +277,7 @@ void AmclNode::do_deactivate(const rclcpp_lifecycle::State&) {
282277 laser_scan_filter_.reset ();
283278 laser_scan_sub_.reset ();
284279 global_localization_server_.reset ();
285- propagation_timer_ .reset ();
280+ odom_sub_ .reset ();
286281 if (likelihood_field_pub_) {
287282 likelihood_field_pub_->on_deactivate ();
288283 }
@@ -491,38 +486,18 @@ void AmclNode::do_periodic_timer_callback() {
491486 }
492487}
493488
494- auto AmclNode::get_base_pose_in_odom (const tf2::TimePoint& time) const -> std::optional<Sophus::SE2d> {
495- auto base_pose_in_odom = Sophus::SE2d{};
496- try {
497- tf2::convert (
498- tf_buffer_
499- ->lookupTransform (
500- get_parameter (" odom_frame_id" ).as_string (), get_parameter (" base_frame_id" ).as_string (), time)
501- .transform ,
502- base_pose_in_odom);
503- return base_pose_in_odom;
504- } catch (const tf2::TransformException& error) {
505- RCLCPP_ERROR (get_logger (), " Could not transform from odom to base: %s" , error.what ());
506- return std::nullopt ;
507- }
508- }
509-
510- void AmclNode::propagation_timer_callback () {
489+ void AmclNode::odometry_callback (nav_msgs::msg::Odometry::ConstSharedPtr odom) {
511490 if (!particle_filter_) {
512491 RCLCPP_WARN_THROTTLE (
513- get_logger (), *get_clock (), 2000 , " Ignoring propagation because the particle filter has not been initialized" );
514- return ;
515- }
516-
517- const auto base_pose_in_odom = get_base_pose_in_odom (tf2::TimePointZero);
518- if (!base_pose_in_odom.has_value ()) {
492+ get_logger (), *get_clock (), 2000 ,
493+ " Ignoring odometry data because the particle filter has not been initialized" );
519494 return ;
520495 }
521-
522- const auto now = this -> now ( );
523- const auto time = tf2_ros::fromMsg (now) ;
524- // Queue odometry motion (timestamp, pose) for later processing in laser_callback
525- odometry_motion_buffer_.emplace_back (time, base_pose_in_odom. value () );
496+ // Use the odometry message timestamp and pose
497+ const auto time = tf2_ros::fromMsg (odom-> header . stamp );
498+ auto base_pose_in_odom = Sophus::SE2d{} ;
499+ tf2::convert (odom-> pose . pose , base_pose_in_odom);
500+ odometry_motion_buffer_.emplace_back (time, base_pose_in_odom);
526501}
527502
528503void AmclNode::laser_callback (sensor_msgs::msg::LaserScan::ConstSharedPtr laser_scan) {
@@ -533,21 +508,23 @@ void AmclNode::laser_callback(sensor_msgs::msg::LaserScan::ConstSharedPtr laser_
533508 }
534509
535510 // If propagation_rate is enabled, process odometry buffer up to lidar timestamp
536- if (get_parameter (" propagation_rate" ).as_double () > 0.0 ) {
511+ if (get_parameter (" propagation_rate" ).as_bool () ) {
537512 const auto laser_scan_stamp = tf2_ros::fromMsg (laser_scan->header .stamp );
538- while (!odometry_motion_buffer_.empty ()) {
539- const auto & [odom_time, odom_pose] = odometry_motion_buffer_.front ();
540- if (odom_time >= laser_scan_stamp) {
541- break ;
542- }
543- particle_filter_->update (odom_pose);
544- odometry_motion_buffer_.pop_front ();
545- }
513+ particle_filter_->process_buffered_odometry_until (odometry_motion_buffer_, laser_scan_stamp);
546514 }
547515
548516 // Get base pose in odom frame at laser scan timestamp
549- const auto base_pose_in_odom = get_base_pose_in_odom (tf2_ros::fromMsg (laser_scan->header .stamp ));
550- if (!base_pose_in_odom.has_value ()) {
517+ auto base_pose_in_odom = Sophus::SE2d{};
518+ try {
519+ tf2::convert (
520+ tf_buffer_
521+ ->lookupTransform (
522+ get_parameter (" odom_frame_id" ).as_string (), get_parameter (" base_frame_id" ).as_string (),
523+ tf2_ros::fromMsg (laser_scan->header .stamp ))
524+ .transform ,
525+ base_pose_in_odom);
526+ } catch (const tf2::TransformException& error) {
527+ RCLCPP_ERROR (get_logger (), " Could not transform from odom to base: %s" , error.what ());
551528 return ;
552529 }
553530
@@ -567,7 +544,7 @@ void AmclNode::laser_callback(sensor_msgs::msg::LaserScan::ConstSharedPtr laser_
567544
568545 const auto update_start_time = std::chrono::high_resolution_clock::now ();
569546 const auto new_estimate = particle_filter_->update (
570- base_pose_in_odom. value () , //
547+ base_pose_in_odom, //
571548 beluga_ros::LaserScan{
572549 laser_scan,
573550 laser_pose_in_base,
@@ -580,7 +557,7 @@ void AmclNode::laser_callback(sensor_msgs::msg::LaserScan::ConstSharedPtr laser_
580557
581558 if (new_estimate.has_value ()) {
582559 const auto & [base_pose_in_map, _] = new_estimate.value ();
583- last_known_odom_transform_in_map_ = base_pose_in_map * base_pose_in_odom.value (). inverse ();
560+ last_known_odom_transform_in_map_ = base_pose_in_map * base_pose_in_odom.inverse ();
584561 last_known_estimate_ = new_estimate;
585562
586563 RCLCPP_INFO (
0 commit comments