[codex] Reconstruct rerun TF trees in the bridge#1881
[codex] Reconstruct rerun TF trees in the bridge#1881skorinko wants to merge 2 commits intodimensionalOS:mainfrom
Conversation
Greptile SummaryThis PR teaches
Confidence Score: 4/5Safe to merge after fixing the subscriber list mutation bug; the remaining findings are minor style or edge-case concerns. One P1 bug exists: mutating self._subscribers during iteration in receive_transform can silently drop callbacks when any subscriber unsubscribes itself during dispatch. The root_frame mismatch in entity_path_for_frame is a P2 edge case for non-world-rooted trees. All other findings are style or test-fragility concerns. dimos/protocol/tf/tf.py — receive_transform subscriber iteration and entity_path_for_frame root-frame stripping logic. Important Files Changed
Sequence DiagramsequenceDiagram
participant PubSub
participant Bridge as RerunBridgeModule
participant TFBuf as MultiTBuffer
participant Rerun
PubSub->>Bridge: _on_message(TFMessage, "/tf")
Bridge->>Bridge: _is_tf_message() → true
Bridge->>TFBuf: receive_tfmessage(msg)
loop for each Transform in TFMessage
TFBuf->>TFBuf: store in buffers[parent, child]
TFBuf->>Bridge: _log_tf_transform(transform) [subscriber]
Bridge->>TFBuf: entity_path_for_frame(child_frame_id)
TFBuf->>TFBuf: get_frame_chain() [BFS up parents]
TFBuf-->>Bridge: "world/tf/robot/camera"
Bridge->>Rerun: rr.log("world/tf/robot/camera", transform.to_rerun())
end
Reviews (1): Last reviewed commit: "Reconstruct rerun TF trees in bridge" | Re-trigger Greptile |
- MultiTBuffer.receive_transform: snapshot subscribers before dispatch so a callback that unsubscribes itself doesn't skip the next subscriber. - RerunBridgeModule.start: treat _tf_buffer as an injection point — skip creation and subscription when it's already set, so tests that preinstall it aren't silently clobbered if start() is ever invoked. - MultiTBuffer.entity_path_for_frame: when root_frame is set, strip the topmost frame unconditionally. It's either the matched root_frame or the tree's actual root; either way it's represented by `prefix`. Prevents paths like world/tf/map/robot when the tree isn't rooted at "world". - Add regression tests for all three behaviors.
Summary
MultiTBufferto publish transform updates and reconstruct hierarchical frame chainsRerunBridgeModuleown a TF buffer and log/tfmessages at reconstructed Rerun entity pathsWhy
Standalone
rerun-bridgewas logging TF updates as flat child-frame paths, so the viewer could not reconstruct the real TF tree unless a blueprint hardcoded extra TF-specific visualization setup.Impact
rerun-bridgenow reconstructs TF entity paths internally from the buffered transform graph, which makes standalone visualization behave more like the rest of the TF stack and removes the need for callers to rely on partial TF message layout.Validation
ruff check dimos/protocol/tf/tf.py dimos/protocol/tf/test_tf.py dimos/visualization/rerun/bridge.py dimos/visualization/rerun/test_bridge_tf.pyCloses #1627