We are processing mobile mapping data from an Ouster OS1-071 Rev 7.1, 64-channel sensor, firmware 3.2, with synchronized IMU. Data is recorded to OSF and processed with Ouster SDK 1.0.1.
We have an Ouster SLAM trajectory that is visually clean and preserves the local LiDAR geometry well. We also have an independent, timestamped XYZ trajectory in a projected metric coordinate system that we need to use for horizontal placement and vertical authority.
Our goal is to georeference the Ouster result while preserving the original SLAM geometry, scan-to-scan shape, and Ouster orientation behavior.
What we have tested:
- PoseOptimizer with sparse
AbsolutePoseConstraintXYZ controls.
We created sparse absolute XYZ constraints and used the initial Ouster trajectory rotation in each constraint pose. The external trajectory supplied the XYZ translation. Although the numerical position residuals looked reasonable, the resulting point cloud showed visible geometric distortion: curves appeared stretched or folded, and vertical objects no longer held their expected shape.
- Direct per-column vertical translation.
We retained rigid XY placement and original Ouster rotations, then replaced the Z translation of each valid body_to_world pose from the external vertical authority. This caused visible vertical warping of the roadway and corridor.
- Single rigid left-side transform.
We applied one constant rigid transform to every source pose:
T_output = T_alignment @ T_source
This produces visually clean LiDAR geometry. Road shape, poles, wires, and trees remain coherent. However, we still need a supported method to bring the result into the correct external horizontal and vertical reference frame without introducing a non-rigid deformation.
We are writing the modified trajectory to OSF with the SDK Writer and preserving the original scan fields and timestamps.
Questions:
- Must external XYZ controls be transformed into the existing Ouster SLAM world frame before constructing
AbsolutePoseConstraintobjects? - Does
AbsolutePoseConstraint.poserepresent the LiDAR sensor/body-to-world pose, or another pose convention? - When preserving local LiDAR geometry is the primary requirement, is a rigid registration the recommended approach instead of forcing sparse external position constraints to zero residual?
- What is the recommended Ouster SDK workflow for applying sparse vertical control from an external surveyed elevation source without changing roll, pitch, yaw, or causing vertical road-surface warping?
- Is there an official example or recommended pattern for applying a smooth, low-frequency vertical correction to an Ouster SLAM trajectory while retaining the original local geometry?
We would appreciate any guidance, documentation, or example code showing the correct frame convention and recommended workflow.
After More Testing Follow-up:
Follow-up: we have now isolated a separate upstream failure inside stock Ouster SLAM before any external georeferencing, trajectory modification, Writer operation, or PoseOptimizer step.
Hardware and software:
-
Ouster OS1-071 Rev 7.1, 64-channel
-
Firmware 3.2
-
Synchronized IMU
-
Ouster SDK / CLI 1.0.1
-
10 Hz LiDAR, ACCEL32_GYRO32_NMEA IMU profile
We isolated one 53-second PCAP segment containing the worst failure. The raw capture is intact:
-
530 continuous LiDAR frames
-
33,920 LiDAR packets
-
4,240 IMU packets
-
No missing LiDAR frame IDs
-
No missing columns in the affected frames
-
Continuous individual IMU measurement timestamps at approximately 640 Hz
-
No abnormal raw gyro or accelerometer event
We also compared the Ouster IMU against an independent, time-aligned GNSS/INS IMU through the exact failed interval. Both systems show ordinary continuous vehicle motion. The vehicle remained near 18 m/s (about 40 mph); there was no stop, impact, major rotation spike, or missing IMU event.
However, when processing this raw PCAP with stock Ouster CLI using:
slam --deskew-method imu_deskew
the final Ouster per-column trajectory begins reducing forward translation. Normal within-frame travel is about 1.8 m per 100 ms LiDAR frame. During the failure it falls to approximately 0.24 m per frame for about five seconds, then later recovers.
Using constant_velocity on the same PCAP avoids the main sustained translation collapse. It retains approximately normal forward travel after a short transition. none fails much more broadly.
We inspected the SDK 1.0.1 C++ API and understand that InertialIntegrationImuDeskewMethod maintains internal feedback state, including previous corrected SLAM pose(s), solved world-frame linear velocity, IMU integration anchor, gravity estimate, and IMU biases. Its API includes:
set_last_pose(...)
finalize_after_registration(...)
solve_initial_velocity(...)
calc_poses_with_motion_model(...)
calc_corrected_poses_with_motion_model(...)
This suggests a possible feedback mechanism:
Registration returns an underestimated forward pose
->
IMU deskew receives a low corrected velocity / pose prior
->
the next scan is under-deskewed in translation
->
registration becomes less reliable
->
the low velocity persists for subsequent frames
The Python SDK binding exposes only final map-aligned poses and does not expose the pre-registration prediction, solved initial/ending velocity, registration residual, convergence status, or the set_last_pose / finalize_after_registration feedback calls.
Could you please advise:
-
Is the above feedback interpretation consistent with how
InertialIntegrationImuDeskewMethodand the LIO backend operate in SDK 1.0.1? -
Can
imu_deskewlose its estimated forward velocity while raw IMU data remains normal, particularly during steady-speed vehicle travel where the accelerometer does not independently measure absolute forward speed? -
Is there a supported way to log or expose, per frame:
-
pre-registration predicted anchor pose;
-
initial and ending world-frame velocity;
-
post-registration corrected anchor pose;
-
ICP residual / correspondence count / convergence status;
-
whether the velocity solve succeeded or fell back?
-
-
Are
set_last_pose()andfinalize_after_registration()intentionally unavailable in the Python binding? Is there a supported C++ example or diagnostic build path for observing this state? -
Is there any known issue or recommended configuration for cases where
imu_deskewenters a sustained low-translation state whileconstant_velocitycontinues to produce a materially better trajectory from the same synchronized firmware-3.2 data?
We can provide the isolated PCAP, metadata JSON, frame IDs, and per-frame trajectory comparison if that would help reproduce the issue.
Failure area:
Rest of the PACP results are clean as the sample below:
Thank you.


