Skip to content

refactor(geometry)!: typed pose interpolator and a result type for motion decompensation - #260

Open
janickm wants to merge 1 commit into
stack/v20-rc-cleanup/03-sensorsfrom
stack/v20-rc-cleanup/04-geometry-cleanup
Open

janickm wants to merge 1 commit into
stack/v20-rc-cleanup/03-sensorsfrom
stack/v20-rc-cleanup/04-geometry-cleanup

Conversation

@janickm

@janickm janickm commented Nov 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Small cleanup of the motion compensation and pose interpolation classes in ncore.geometry before the 20.0 freeze. The free functions (se3_inverse, transform_point_cloud, bbox_pose, ...) are unchanged.

Stack (merge from the top to land all six at once):

  1. Keyword-only parameters and public exports
  2. Storage contract and Group / Array API
  3. Sensor models
  4. Geometry cleanup (this PR)
  5. Loaders, V4 components, and ValueError for user-facing validation
  6. Converter default, wheel requirements, tools and docs (upgrading guide)

Changes

  • MotionCompensator.motion_decompensate_points returns a MotionCompensator.MotionDecompensationResult (the decompensated points xyz_pointtime plus the reference frame, reference timestamp and anchor frame), mirroring motion_compensate_points. It is a separate type because the compensation result holds a start / end point pair, while decompensation yields one point set. Both result types are documented field by field. The in-repo converters read the points from the result.
  • MotionCompensator(pose_graph, *, parameters), and reference_timestamp_us / anchor_frame_id of both (de)compensation methods are keyword-only, like the optional parameters of the other public APIs.
  • PoseInterpolator takes typed array-like poses and timestamps (in_range too) and documents the time domain. Its scipy interpolants and homogeneous row are private (_slerp, _f_t, _last_row).
  • An empty decompensation records the resolved reference timestamp (the frame end) instead of None.

Testing

  • A test runs the converters' frame alignment with a real MotionCompensator, covering the converter-facing path (the dataset converter tests need datasets).
  • Breaking a change on purpose makes its test fail: returning the bare array again (frame alignment and transformation tests), a public slerp (True is not false : slerp), recording the unresolved reference timestamp.
  • bazel test //... --config=no-gpu green on all four interpreters, bazel build //... (ty), docs with warnings as errors, bazel run //:format.check clean.

Upgrading

  • xyz = mc.motion_decompensate_points(...) -> xyz = mc.motion_decompensate_points(...).xyz_pointtime.
  • MotionCompensator(pose_graph, params) -> MotionCompensator(pose_graph, parameters=params); pass reference_timestamp_us / anchor_frame_id by keyword.
  • PoseInterpolator.slerp, f_t and last_row are private: use interpolate_to_timestamps / extrapolate_to_timestamps.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)

Checklist

  • I have read the Contributing Guidelines
  • My commits follow Conventional Commits format
  • My commits are GPG-signed
  • I have added tests that prove my fix is effective or my feature works
  • New and existing tests pass locally (bazel test //...)
  • Code is formatted (bazel run //:format)
  • I have updated documentation as needed
  • My changes include SPDX license headers on all new files

@janickm
janickm added this pull request to stack #263 November 14, 2026 06:56
…tion decompensation

PoseInterpolator takes typed array-like poses and timestamps (in_range as
well), documents the timestamps as microseconds, and keeps its scipy
interpolants and the homogeneous row private.

The parameters of MotionCompensator and the reference timestamp and anchor
frame of its (de)compensation methods are keyword-only, like the optional
parameters of the other public APIs.

MotionCompensator.motion_decompensate_points returns a
MotionCompensator.MotionDecompensationResult that records the decompensated
points together with the reference frame, reference timestamp and anchor
frame, mirroring motion_compensate_points. The compensation result keeps its
start/end point pair, so decompensation gets its own type rather than reusing
it. Both result types are documented field by field. The in-repo converters
read the points from the result.

BREAKING CHANGE: MotionCompensator.motion_decompensate_points returns a
MotionCompensator.MotionDecompensationResult instead of an array; read the
points from its xyz_pointtime field. PoseInterpolator.slerp, f_t and last_row
are private (_slerp, _f_t, _last_row); use interpolate_to_timestamps or
extrapolate_to_timestamps instead.
MotionCompensator(pose_graph, *, parameters) takes its parameters by
keyword, and the reference_timestamp_us and anchor_frame_id arguments of
motion_compensate_points and motion_decompensate_points are keyword-only.
@janickm
janickm force-pushed the stack/v20-rc-cleanup/04-geometry-cleanup branch from c55590a to e2ca57a Compare November 15, 2026 13:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant