Skip to content

feat: rust transform support - #2816

Merged
aclauer merged 46 commits into
mainfrom
andrew/feat/rust-transform-get
Aug 3, 2026
Merged

feat: rust transform support#2816
aclauer merged 46 commits into
mainfrom
andrew/feat/rust-transform-get

Conversation

@aclauer

@aclauer aclauer commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Problem

We need transforms with Rust

Closes DIM-XXX

Solution

Add #[tf] attribute to subscribe a module to the transform topic
get_latest() -> get the latest transform between two frames
.at() to set source time for a transform
.tolerance() for max allowed gap between time set by .at()
.within() for how long to wait for a valid transform on the topic before just returning None

Other

  • add IO ports
  • ensure 1:1 mapping of topics between python wrapper and what rust expects
  • add toggle to turn off base_link tf from go2 for when we are setting base_link from mid360 or other source

Transforms are collected in a hash map and inter-frame transforms are built on demand

How to Test

uv run python examples/native-modules/rust_tf.py

Contributor License Agreement

  • I have read and approved the CLA.

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.62651% with 14 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/navigation/basic_path_follower/module.py 70.58% 4 Missing and 1 partial ⚠️
dimos/navigation/nav_3d/mls_planner/goal_relay.py 91.89% 1 Missing and 2 partials ⚠️
dimos/navigation/tf_pose.py 93.02% 1 Missing and 2 partials ⚠️
...s/robot/unitree/go2/blueprints/test_tf_topology.py 93.75% 1 Missing and 1 partial ⚠️
.../robot/unitree/go2/go2_mid360_static_transforms.py 75.00% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main    #2816      +/-   ##
==========================================
+ Coverage   75.37%   75.46%   +0.08%     
==========================================
  Files        1153     1157       +4     
  Lines      110948   111276     +328     
  Branches    10047    10073      +26     
==========================================
+ Hits        83631    83972     +341     
+ Misses      24462    24416      -46     
- Partials     2855     2888      +33     
Flag Coverage Δ
OS-ubuntu-24.04-arm 69.46% <96.62%> (+0.12%) ⬆️
OS-ubuntu-latest 71.51% <96.62%> (+0.11%) ⬆️
Py-3.10 71.50% <96.62%> (+0.11%) ⬆️
Py-3.11 71.51% <96.62%> (+0.11%) ⬆️
Py-3.12 71.50% <96.62%> (+0.11%) ⬆️
Py-3.13 71.50% <96.62%> (+0.11%) ⬆️
Py-3.14 71.51% <96.62%> (+0.11%) ⬆️
Py-3.14t 71.50% <96.62%> (+0.11%) ⬆️
SelfHosted-Large 29.60% <33.09%> (+0.23%) ⬆️
SelfHosted-Linux 35.93% <33.09%> (+0.11%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dimos/core/native_module.py 72.11% <100.00%> (+3.18%) ⬆️
dimos/core/test_native_module.py 97.02% <100.00%> (+0.64%) ⬆️
...imos/navigation/basic_path_follower/test_module.py 100.00% <100.00%> (ø)
...avigation/nav_3d/mls_planner/mls_planner_native.py 100.00% <100.00%> (ø)
...s/navigation/nav_3d/mls_planner/test_goal_relay.py 100.00% <100.00%> (ø)
dimos/navigation/test_tf_pose.py 100.00% <100.00%> (ø)
dimos/robot/all_blueprints.py 100.00% <ø> (ø)
.../go2/blueprints/basic/unitree_go2_mid360_record.py 78.78% <ø> (ø)
...e/go2/blueprints/navigation/unitree_go2_mls_htc.py 83.33% <ø> (ø)
...ee/go2/blueprints/navigation/unitree_go2_nav_3d.py 79.03% <100.00%> (-0.66%) ⬇️
... and 10 more

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aclauer aclauer changed the title Andrew/feat/rust transform feat: rust transform get Jul 9, 2026
@aclauer aclauer changed the title feat: rust transform get feat: rust get transform Jul 9, 2026
@aclauer aclauer linked an issue Jul 9, 2026 that may be closed by this pull request
@aclauer
aclauer marked this pull request as ready for review July 9, 2026 20:43
@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds transform (tf) support for Rust native modules, mirroring the existing Python tf API. It introduces #[tf] derive support that gives Rust modules a Tf handle with get() / get_latest() for nearest-sample BFS lookups, backed by a per-edge time-sorted ring buffer. On the Python side, it consolidates pose resolution into a shared OdomBasePose helper and eliminates the now-redundant OdomBodyFrame module.

  • Rust tf crate (native/rust/dimos-module/src/tf.rs): New 759-line file implementing TBuffer, MultiTBuffer, BFS path composition, LCM encode/decode, and a comprehensive test suite covering direct/reverse/multi-hop edges, tolerance filtering, time ordering, and publish round-trips.
  • Python tf helpers (dimos/navigation/tf_pose.py): New OdomBasePose class that resolves sensor-frame odometry into base-frame poses by looking up the static mount leg once, then reusing it. GoalRelay and BasicPathFollower are updated to use this instead of the deleted OdomBodyFrame.
  • Blueprint cleanup (dimos/robot/unitree/go2/zenoh/blueprints.py): Removes OdomBodyFrame from nav stack; GoalRelay now receives lidar_height from the physical ROBOT_HEIGHT constant and handles the ground projection internally via OdomBasePose.

Confidence Score: 5/5

Safe to merge; the transform graph, BFS composition, and Python pose-resolution logic are all well-tested and the previously-raised concerns are confirmed resolved.

The Rust tf crate has comprehensive unit and async tests covering direct/reverse/multi-hop edges, tie-breaking, tolerance filtering, out-of-order insertion, publish round-trips, and decode errors. The Python OdomBasePose helper is similarly well-covered. The BFS visited-before-edge-check issue flagged in a previous review is confirmed fixed in the current diff. No data-loss or incorrect-behavior paths were found after tracing the -leg inversion math, the stamp encoding overflow guard, and the lazy tf handle construction.

No files require special attention.

Important Files Changed

Filename Overview
native/rust/dimos-module/src/tf.rs New 759-line tf transform crate with BFS graph traversal, time-sorted ring buffers, and thorough test coverage; previously-flagged BFS visited-before-edge-check issue is confirmed fixed.
dimos/navigation/tf_pose.py New OdomBasePose helper caches the static mount leg from tf once and reuses it per message; throttled retry on missing leg, well-tested.
dimos/navigation/nav_3d/mls_planner/goal_relay.py Updated to use OdomBasePose and _resolve_base_height; the -leg inversion correctly converts sensor→base to base→sensor before calling base_height_above_ground.
dimos/navigation/basic_path_follower/module.py Switches from raw Odometry to OdomBasePose-resolved PoseStamped, simplifying the control loop and removing the OdomBodyFrame dependency.
dimos/core/native_module.py Adds the tf channel to every NativeModule's stdin config unconditionally; modules without #[tf] simply ignore it.
native/rust/dimos-module/src/module.rs Builder.tf() lazily initialises one shared TBuffer+route pair; repeated calls return the same Tf clone; tested.
dimos/core/transport_factory.py Adds tf_channel() that returns the correct wire channel name for both Zenoh and LCM backends.
dimos/robot/unitree/go2/zenoh/blueprints.py Removes OdomBodyFrame from all nav blueprints; GoalRelay now receives lidar_height=ROBOT_HEIGHT and handles the ground projection itself.

Sequence Diagram

sequenceDiagram
    participant P as Python TfProducer
    participant T as /tf topic
    participant R as Rust TfRoute (TfRoute.try_dispatch)
    participant B as MultiTBuffer (BFS graph)
    participant M as Rust Module (#[tf] Tf handle)
    participant G as GoalRelay (OdomBasePose)

    P->>T: publish Transform (a→b, b→c)
    T->>R: LCM TFMessage bytes
    R->>B: buffer.receive(parent, child, ts, iso)

    Note over B: TBuffer.add() inserts sorted,<br/>prunes outside window_secs

    M->>B: tf.get_latest("a","d")
    B->>B: BFS over edge graph
    B-->>M: composed Transform (a→d)

    Note over G: OdomBasePose.resolve(odometry)
    G->>B: tf.get("mid360_link","base_link")
    B-->>G: cached static leg (once)
    G->>G: odom + leg → base_link PoseStamped
    G->>G: "start.position.z -= base_height_above_ground"
    G-->>G: publish start_pose
Loading

Reviews (12): Last reviewed commit: "Merge branch 'andrew/feat/rust-transform..." | Re-trigger Greptile

Comment thread native/rust/dimos-module/src/tf.rs
Comment thread dimos/core/native_module.py Outdated
@aclauer aclauer changed the title feat: rust get transform feat: rust transform support (get only) Jul 9, 2026
@jeff-hykin
jeff-hykin enabled auto-merge (squash) July 13, 2026 02:45
@jeff-hykin
jeff-hykin disabled auto-merge July 13, 2026 02:46
@aclauer aclauer changed the title feat: rust transform support (get only) feat: rust transform support Jul 31, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jul 31, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jul 31, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jul 31, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jul 31, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Aug 1, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Aug 3, 2026
@leshy
leshy enabled auto-merge August 3, 2026 14:56
@leshy
leshy added this pull request to the merge queue Aug 3, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Aug 3, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 3, 2026
@aclauer
aclauer added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 0f9b161 Aug 3, 2026
52 of 54 checks passed
@aclauer
aclauer deleted the andrew/feat/rust-transform-get branch August 3, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rust modules tf publish Rust Native Modules transforms

3 participants