Skip to content

Add viam.spatialmath: FFI bindings for rust-utils orientation math#1233

Open
Nick Hehr (HipsterBrown) wants to merge 15 commits into
mainfrom
nhehr/spatialmath-ffi
Open

Add viam.spatialmath: FFI bindings for rust-utils orientation math#1233
Nick Hehr (HipsterBrown) wants to merge 15 commits into
mainfrom
nhehr/spatialmath-ffi

Conversation

@HipsterBrown

Copy link
Copy Markdown
Member

Summary

Adds a new viam.spatialmath package: Pythonic, object-oriented wrappers over the shared rust-utils (libviam_rust_utils) spatial-math FFI, exposing orientation conversions whose results match Go rdk/spatialmath.

  • Six wrapper classesQuaternion, Vector3, OrientationVector, EulerAngles, AxisAngle, RotationMatrix — each owning an opaque FFI handle freed deterministically via weakref.finalize, with conversions between every representation.
  • Proto bridges to viam.proto.commonOrientationVector/Vector3 from_proto/to_proto and Quaternion.from_pose/to_pose. Classes are radians-native; the proto bridges convert to/from the Viam protos' degrees convention at the boundary.
  • Shared native loader — extracted the libviam_rust_utils ctypes loading from rpc/dial.py into viam/_native.py so both the dialer and spatialmath load one cached CDLL.
  • No packaging change — the spatialmath symbols already ship in the bundled libviam_rust_utils, and hatchling already bundles the lib and picks up the new sub-package.

Conventions (matched to Go rdk/spatialmath)

  • All angles are radians (Euler order Z-Y'-X" / yaw-pitch-roll); proto bridges convert deg↔rad.
  • RotationMatrix.elements is row-major, matching rdk's convention.
  • Zero-rotation AxisAngle returns the canonical axis (0, 0, 1), matching rdk.

Test Plan

  • Golden paritytests/spatialmath/fixtures/golden.json is generated from canonical Go rdk/spatialmath (generator in etc/spatialmath_golden/); a parametrized test asserts all conversions (orientation-vector, Euler, axis-angle, rotation-matrix) match within 1e-9 across identity / 90°-X / 180°-Y / tumble cases.
  • Unit tests for each wrapper, proto bridges, and degrees/radians boundary behavior.
  • Lifetime/leak — 10k-iteration churn + repeated component-read tests confirm no double-free/segfault; null-pointer input raises ValueError.
  • ruff check and pyright clean on the new modules; dial.py refactor verified against existing dial tests.

🤖 Generated with Claude Code

Nick Hehr (HipsterBrown) and others added 14 commits June 19, 2026 16:59
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RotationMatrix now exposes the rdk rotation-matrix convention (the nalgebra
column-major storage read directly), and AxisAngle returns the canonical
(0,0,1) axis for zero rotation. Adds the golden-vector parity test asserting
all conversions match Go rdk/spatialmath.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ridges

Viam Pose/Orientation protos express theta in degrees, while the spatialmath
classes are radians-native (matching the FFI and Go rdk). The proto bridges now
convert at the boundary instead of passing degrees through as radians.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread etc/spatialmath_golden/README.md Outdated
Comment thread etc/spatialmath_golden/README.md Outdated
@HipsterBrown

Copy link
Copy Markdown
Member Author

Ethan (@stuqdog) I've removed that Go module responsible for generating the golden.json test fixture and added a note to the JSON to mention how it was created. I can work on a follow up in the rust-utils library to upstream the parity test, so other consumers of the spatialmath utils benefit from those changes.

@stuqdog Ethan (stuqdog) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't personally test everything but given that tests are passing, assuming golden.json came from RDK this all seems good to me!

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.

2 participants