Skip to content

feat: add dual MakerMods Metal manipulation setup - #4881

Closed
TomCC7 wants to merge 9 commits into
codex/feat/robot-model-compositionfrom
codex/feat/dual-makermods-metal
Closed

TomCC7 wants to merge 9 commits into
codex/feat/robot-model-compositionfrom
codex/feat/dual-makermods-metal

Conversation

@TomCC7

@TomCC7 TomCC7 commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Two Metal arms need a shared collision world and one synchronized 12-joint planner while retaining separate CAN buses. Add the dual Metal coordinator, declarative model configuration, ManipulationModule/Viser blueprint, and gateway catalog entry.

Stack

Parent: #4919 (RobotModel fixed-attachment API), which builds on single-arm #4865. B601-DM #4858 remains independent. Review this diff against codex/feat/robot-model-composition.

Model and control

Create dual_metal_base in memory with RobotModel.from_root_link("dual_metal_base", name="dual_makermods_metal"), then call with_attached_model() twice to weld the pinned official single-arm Metal tree onto it. Each fixed joint has a left/right prefix and configurable mount transform. The RobotModel load pipeline owns attachment and resource resolution; source_path is None for the in-memory base. No base.urdf file is needed; each child resolves its own assets. No generated URDF, independent cache, public composition helper, or PathLike class is used. The model has left_arm/right_arm planning groups and a shared collision scene. One trajectory task controls all 12 angular joints; per-arm gripper tasks and streams remain independent.

Do not modify ManipulationModule or RobotModelConfig to add gripper bindings. That interface belongs to #4747. Until it lands, the gripper tasks are available on the coordinator but are unbound in ManipulationModule/Viser. Future bindings are left_arm -> left_arm_gripper and right_arm -> right_arm_gripper.

Without CAN selectors both arms use mocks. Physical startup requires both distinct left/right selectors; it enables both arms and calibrates their grippers. Reuse the released can-motor-control>=0.0.11 driver, fixed increasing_position direction, and 0.1 current ratio.

Geometry provenance

The official ROS and Lab descriptions reviewed provide single-arm URDFs. The official two-arm controller configuration starts two controllers but supplies no shared mounting transform. The vendor's 90 x 90 mm four-M5 pattern is one arm's mounting pattern, not dual-arm spacing.

Default bases at (0, 0.3, 0) and (0, -0.3, 0) meters with the same orientation are an example layout only. Physical planning requires actual measured mount positions/orientations. Both planning tips remain gripper mount frames, not calibrated fingertip TCPs.

Validation

CI follow-up: guard Alfred's file-backed URDF invariant after source_path became optional. The unrelated peek timeout test now waits for Rx subscription disposal before asserting cleanup, avoiding a race between timeout notification and asynchronous disposal. All 13 stream-peek tests pass locally. Full mypy with CI version 1.19.0 and Linux platform passes across 1,268 source files.

161 focused regression tests passed, covering source-less roots, real Viser mesh loading, planning-group discovery, the fixed-attachment API, existing model/source behavior, configuration round trips, single/dual hardware setup, gateway annotations, and blueprint registry. Targeted mypy and changed-file pre-commit passed.

Actual RoboPlan/Viser mock runtime: 12-joint model loaded, initial state collision-valid, both planning groups discovered, synchronized two-group trajectory succeeded (two waypoints, 0.632 s), HTTP 200, and independent coordinator gripper tasks accepted commands. The excluded existing Viser cleanup KeyError still occurs on shutdown; this PR does not fix it. No physical dual-arm hardware was controlled.

Run

uv run dimos run dual-makermods-metal-planner-coordinator

Open http://127.0.0.1:8095. Physical selectors remain --left-can-port and --right-can-port; configure measured mounts with --left-base-xyz, --right-base-xyz, --left-base-rpy, and --right-base-rpy (JSON triples, meters/radians). See docs/capabilities/manipulation/makermods_metal_integration.md#dual-arm-setup.

  • I have read and approved the CLA.

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

go2 replay realtime (arm64)

Details
Benchmark suite Current: 7df037f Previous: ebe17bd Ratio
peak memory 1783.844 MB 1730.012 MB 1.03
peak threads 365 threads 370 threads 0.99
network (transport) 2730.983 MB 2730.98 MB 1.00
disk write 1.691 MB 1.785 MB 0.95
instructions 137.633 G 137.843 G 1.00

This comment was automatically generated by workflow using github-action-benchmark.

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

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

Files with missing lines Patch % Lines
...ipulators/dual_makermods_metal/blueprints/basic.py 88.88% 2 Missing ⚠️
@@                          Coverage Diff                           @@
##           codex/feat/robot-model-composition    #4881      +/-   ##
======================================================================
+ Coverage                               83.10%   83.12%   +0.01%     
======================================================================
  Files                                    1743     1748       +5     
  Lines                                  166808   166952     +144     
  Branches                                13799    13805       +6     
======================================================================
+ Hits                                   138629   138774     +145     
- Misses                                  24411    24415       +4     
+ Partials                                 3768     3763       -5     
Components Coverage Δ
Tests 97.20% <100.00%> (+<0.01%) ⬆️
Flag Coverage Δ
OS-macos-latest 77.23% <98.61%> (+0.01%) ⬆️
OS-ubuntu-24.04-arm 76.99% <98.61%> (+0.01%) ⬆️
OS-ubuntu-latest 77.39% <98.61%> (+0.02%) ⬆️
Py-3.10 77.39% <98.61%> (+0.02%) ⬆️
Py-3.11 77.37% <98.61%> (+0.02%) ⬆️
Py-3.12 77.39% <98.61%> (+0.01%) ⬆️
SelfHosted-Large 32.01% <50.69%> (+0.01%) ⬆️
SelfHosted-Linux 40.46% <50.69%> (+<0.01%) ⬆️
SelfHosted-macOS 40.71% <50.69%> (+0.01%) ⬆️

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

Files with missing lines Coverage Δ
dimos/core/test_module_peek_stream.py 100.00% <100.00%> (ø)
dimos/robot/all_blueprints.py 100.00% <ø> (ø)
.../robot/manipulators/dual_makermods_metal/config.py 100.00% <100.00%> (ø)
...t/manipulators/dual_makermods_metal/coordinator.py 100.00% <100.00%> (ø)
...s/robot/manipulators/dual_makermods_metal/model.py 100.00% <100.00%> (ø)
...ot/manipulators/dual_makermods_metal/test_setup.py 100.00% <100.00%> (ø)
...ipulators/dual_makermods_metal/blueprints/basic.py 88.88% <88.88%> (ø)

... 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.

@TomCC7
TomCC7 added this pull request to stack #4872 October 28, 2026 02:55
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from d6485cd to 03d9308 Compare October 28, 2026 20:52
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from 03d9308 to 1cc5ef1 Compare October 28, 2026 21:03
@TomCC7
TomCC7 removed this pull request from stack #4872 October 28, 2026 21:07
@TomCC7
TomCC7 added this pull request to stack #4889 October 28, 2026 21:07
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from 1cc5ef1 to 83f3d67 Compare October 28, 2026 21:21
@TomCC7
TomCC7 removed this pull request from stack #4889 October 29, 2026 18:25
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from 83f3d67 to 725c1a6 Compare October 29, 2026 18:25
@TomCC7
TomCC7 changed the base branch from codex/feat/makermods-metal-stacked to codex/feat/robot-model-composition October 29, 2026 18:25
@TomCC7
TomCC7 added this pull request to stack #4920 October 29, 2026 18:25
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch 2 times, most recently from 06816f7 to 0c14ad8 Compare October 29, 2026 20:02
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from 0c14ad8 to 8743e55 Compare October 29, 2026 20:16
@TomCC7
TomCC7 force-pushed the codex/feat/dual-makermods-metal branch from 8719fe4 to c5fe19a Compare October 29, 2026 22:56
@TomCC7
TomCC7 marked this pull request as ready for review October 29, 2026 22:57
@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] No merge-blocking issues were identified. Real-asset planning and mock control execution support merging the reviewed changes; physical commissioning still requires measured geometry and hardware checks.

Summary

Adds two Metal arms to one shared planning world while keeping their CAN connections separate.

  • Two Metal arms share one planning world and move together.
  • The stream timeout test waits for subscription cleanup before checking it.

Runtime checks successfully loaded the real arm assets, verified default and configured mount transforms, and exercised both arms in the same collision scene. Synchronized two-arm planning succeeded, with every generated trajectory sample passing collision checks. Mock coordinator execution confirmed correct twelve-joint routing and independent gripper task and stream commands. Invalid CAN selector combinations were rejected before adapter connection.

Acknowledged scope:

  • TomCC7 explicitly defers ManipulationModule/Viser gripper bindings to PR fix(manipulation): bind gripper tasks per planning group #4747; coordinator gripper tasks remain available independently.
  • TomCC7 identifies the default mounts as an example layout only. Physical planning requires measured mount transforms, and the planning tips remain gripper mount frames rather than calibrated fingertip TCPs.
  • TomCC7 acknowledges the existing Viser shutdown KeyError as out of scope; this PR does not fix it.

No actionable issues were found in the reviewed changes. No physical hardware was controlled.

Reviews (1) · Last reviewed commit: "test: wait for asynchronous peek subscri..." · Reviewed by Greptile

@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Oct 30, 2026
@TomCC7 TomCC7 closed this Nov 3, 2026
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.

1 participant