Skip to content

Fix FixedLagSmoother crash on first optimization cycle in auto-start mode - #434

Open
ikhann wants to merge 1 commit into
locusrobotics:rollingfrom
ikhann:fix/fixed-lag-autostart-clock-type
Open

Fix FixedLagSmoother crash on first optimization cycle in auto-start mode#434
ikhann wants to merge 1 commit into
locusrobotics:rollingfrom
ikhann:fix/fixed-lag-autostart-clock-type

Conversation

@ikhann

@ikhann ikhann commented Aug 15, 2026

Copy link
Copy Markdown

Problem

When the fixed-lag smoother is configured without any ignition sensors it auto-starts
("No ignition sensors were specified. Optimization will begin immediately."), and then aborts on
the very first sensor transaction:

[INFO] [...] [fixed_lag_node]: No ignition sensors were specified. Optimization will begin immediately.
terminate called after throwing an instance of 'std::runtime_error'
  what():  can't compare times with different time sources
[ros2run]: Aborted

Root cause

lag_expiration_ is default-constructed, which produces an rclcpp::Time with the
RCL_SYSTEM_TIME clock type. On the first optimization cycle it is passed to processQueue()
before ever being assigned, and compared against RCL_ROS_TIME sensor stamps
(if (min_stamp < lag_expiration)), which throws. The exception escapes the optimization thread,
so the whole node terminates.

Configurations with an ignition sensor return from processQueue() before reaching that
comparison, which is why this only manifests in auto-start mode. The existing
// TODO(CH3): We might have to make sure lag_expiration_ has been initialised at the
processQueue() call site, and the reset path (which already re-initializes lag_expiration_
with RCL_ROS_TIME), both point at this.

Reproduction (before this patch)

Any config with a sensor model but no ignition sensor, e.g. Unicycle2D + Odometry2D, then:

ros2 run fuse_optimizers fixed_lag_smoother_node --ros-args -r __node:=fixed_lag_node --params-file autostart.yaml
ros2 topic pub -r 2 /odom nav_msgs/msg/Odometry "{header: auto, pose: {pose: {position: {x: 1.0}}, covariance: [...]}}"

The node aborts on the first optimization cycle after the first message.

Fix

Initialize the member with the RCL_ROS_TIME clock type, mirroring the existing start_time_
member two declarations below it. The now-resolved TODO comment is removed.

…mode

The lag_expiration_ member was default-constructed, which produces an
rclcpp::Time with the RCL_SYSTEM_TIME clock type. On the first
optimization cycle it is passed to processQueue() before ever being
assigned, where it is compared against RCL_ROS_TIME sensor stamps.
rclcpp throws "can't compare times with different time sources" for
such comparisons, the exception escapes the optimization thread, and
the node aborts via std::terminate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant