FixTheRobot Explore Robotics / Systems Engineering / Engineering Guides / Module 07

Engineering Guides · Module 07

LiDAR deskewing

A spinning LiDAR takes time to sweep. Use the robot’s motion to bring every point to one instant.

  • Intermediate
  • Module 07: Sensor Time Synchronization & Latency Engineering
  • Written for ROS 2 Jazzy where ROS 2 is used
  • Sources checked 2026-11-06

Assumptions: Numbers in the examples are illustrative and the code is executed by the site’s tests. Facts taken from a cited source are marked; other statements are general engineering knowledge and must be confirmed on the datasheet of the part you use.

1. Engineering problem

A mechanical LiDAR fires its beams over the whole sweep period (0.1 s at 10 Hz). If the robot turns or moves during the sweep, points from the start and end of the sweep are measured from different poses, and walls look bent. Deskewing uses the measured motion to move each point to a single reference time.

2. When is this needed?

  • A robot turns or drives fast while mapping.
  • When walls look curved or doubled in the cloud.
  • Before scan matching on a moving platform.

3. Selection and design decisions

Deskewing needs a per-point (or per-beam) time and the robot’s motion during the sweep from an IMU or odometry. For each point: find the pose at the point’s time relative to the reference time, and transform the point by it. Many drivers publish a per-point time field in the PointCloud2; some SLAM packages deskew internally and expect it.

Overview
RequirementWhy
Per-point timestampsWithout them the correction cannot be applied per point
High-rate motion (IMU or odometry)Provides the pose between the first and last beam
Time offset between LiDAR and IMU calibratedAn offset applies the wrong motion to each point
Consistent frames and signA wrong sign doubles the distortion

4. Advantages and disadvantages

  • Constant-velocity model within a sweep is simple and usually enough; a full trajectory interpolation is more exact.
  • Deskewing in the driver vs in the SLAM front end: do it once.
  • Higher sweep rate shortens the sweep and reduces the distortion.

5. Requirements and constraints

  • Each point has a time relative to the reference.
  • The IMU or odometry covers the whole sweep period.
  • The reference time (start, middle or end of sweep) is stated and used by downstream code.

6. Architecture

points + per-point time ─▶ motion over the sweep (IMU / odometry) ─▶ transform each point to t_ref ─▶ deskewed cloud

7. Implementation

  1. Check the cloud fields for a per-point time.
  2. Estimate the motion over the sweep (rotation and translation) from the IMU or odometry.
  3. Transform each point to the reference time (below).
  4. Check with a flat wall while turning; it must be straight.
  5. Verify the sign and time offset by deliberately perturbing them.
import math
w = 2.0                                       # rad/s yaw rate during the sweep (a fast turn)
def rot(a, x, y):
    return x * math.cos(a) - y * math.sin(a), x * math.sin(a) + y * math.cos(a)
raw = []
for k in range(11):                           # flat wall at x = 5 m in the frame at t = 0, fired over 0.1 s
    t = k * 0.01
    y0 = -2 + 0.4 * k
    x, y = rot(-w * t, 5.0, y0)               # the sensor has turned by w*t when this beam fires
    raw.append((t, x, y))
def spread(points):
    xs = [p[-2] if len(p) == 3 else p[0] for p in points]
    return max(xs) - min(xs)
deskewed = [rot(w * t, x, y) for t, x, y in raw]  # rotate each point back into the frame at t = 0
print("wall x-spread raw: %.3f m" % spread(raw))
print("wall x-spread deskewed: %.3f m" % spread(deskewed))
wrong = [rot(-w * t, x, y) for t, x, y in raw]    # correction with the wrong sign
print("wall x-spread with the wrong sign: %.3f m" % spread(wrong))

Printed (checked by the site’s tests):

wall x-spread raw: 0.355 m
wall x-spread deskewed: 0.000 m
wall x-spread with the wrong sign: 0.516 m

Reading it: during a 2 rad/s turn a 0.1 s sweep of a flat wall 5 m away spreads the wall’s depth by 0.355 m; deskewing with the right sign brings the spread to 0 and the wrong sign makes it worse (0.516 m). The setup is synthetic: a real sensor adds noise and the motion estimate adds error.

8. Real examples

  • Indoor AMR turning in a corridor: deskewing straightens walls before scan matching.

9. Failure scenarios

  • Deskewing twice (driver and SLAM) over-corrects.
  • The correction sign inverted.
  • A 30 ms LiDAR–IMU offset that applies the wrong rotation to each point.

10. Troubleshooting

  1. Check straightness of a flat wall while turning.
  2. Perturb the time offset and sign and watch the spread.
  3. Check the time field units (seconds, nanoseconds, relative or absolute).

11. Validation

  • The example prints the lines shown (executed by the site tests).
  • A wall stays straight within the mapping tolerance at the maximum turn rate.

12. Engineering checklist

13. Further references

  • Check the documentation of your LiDAR driver and SLAM package for the per-point time field and its deskew options (see the LiDAR guide).

Related on FixTheRobot