Skip to content

feat(openarm): OpenArm Mini leader teleop and collection on the leader module - #5182

Draft
KrishnaH96 wants to merge 6 commits into
krishna/feat/leader-teleop-modulefrom
krishna/feat/openarm-mini-leader-on-module
Draft

KrishnaH96 wants to merge 6 commits into
krishna/feat/leader-teleop-modulefrom
krishna/feat/openarm-mini-leader-on-module

Conversation

@KrishnaH96

Copy link
Copy Markdown
Contributor

Why

#4326 drives the bimanual OpenArm from two Feetech leaders with an OpenArm-specific module. #5177 made that module generic. This PR is the OpenArm half: the robot folder carries only the mapping, limits, velocity profile and blueprints. Supersedes #4326 together with #5177.

What

dimos/robot/manipulators/openarm/blueprints/

  • mini_teleop.py: MAPPINGS (leader joint N drives arm/openarm_<side>_jointN inside the URDF limits, trigger servo closes the jaw), velocity profile 3/3/3/3/6/6/6 rad/s, 6 Hz leader filter, 10 ms leader tick. Blueprints teleop-openarm-mini (one machine), -leader (operator laptop, zenoh client) and -follower (robot, dials the router). --simulation swaps in the mock connection.
  • mini_collection.py: openarm-mini-collection and openarm-mini-follower-collection add the recorder (coordinator_joint_state, arm_position_command, 16 joints each) and three 640x480 webcams.
  • Tests for the mapping against the loaded URDF, task wiring, port selection, split deployment and the collection schema.
  • Docs: docs/capabilities/manipulation/openarm_mini_teleop.md, linked from the OpenArm integration page.

No change under dimos/teleop/leader/ or dimos/control/.

How to test

uv sync --extra leader-teleop --extra manipulation
uv run pytest dimos/robot/manipulators/openarm/blueprints dimos/teleop/leader
dimos --simulation run teleop-openarm-mini --leaderteleopmodule.reader mock

With the leaders and the OpenArm (calibration files in ~/.local/state/dimos/teleop/leader/<side>/, trigger included):

dimos hardware feetech-leader joint-tui --side left --port /dev/serial/by-id/<left>
dimos run teleop-openarm-mini --leaderteleopmodule.port-left /dev/serial/by-id/<left> \
  --leaderteleopmodule.port-right /dev/serial/by-id/<right> --left-can-port can1 --right-can-port can2

Checks

  • pytest (openarm blueprints + leader): 81 passed; codebase checks: 167 passed; ruff, mypy, deptry clean.
  • Simulation: four modules deploy, joint_trajectory executes the mock leader at 50 Hz, both gripper tasks bound.
  • Hardware, Alfred 2026-11-10, leaders on a laptop and follower on the Jetson: both arms and jaws follow; three episodes recorded with openarm-mini-follower-collection and prepared into a LeRobot v3 dataset (2,432 frames at 30 Hz, 16-dim state and action, three videos).
  • Smoothness, from command-vs-state analysis of the recordings: the coordinator sharing a Python process with cameras and Viser lost a quarter of its 100 Hz ticks; with its own worker (feat(teleop): generic Feetech leader teleop module and coordinator port #5177) it runs at 100.0/s, wrist roughness halves and tracking error drops a third. The 6 Hz filter halves wrist roughness again for ~10 ms of lag; the 10 ms tick takes ~10 ms off wrist lag. cc's fix(damiao): consume the latest target on one SDK-owning thread #5180 was A/B tested on this rig and is independent of this PR.
  • Known: the recorder's strict quality mode rejects an episode on a single dropped camera frame; the dataset above was prepared with the schema's quality mode set to fill. Raised with cc.

Checklist

  • I have read and approved the CLA.

…r module

Blueprints teleop-openarm-mini, -leader and -follower drive both OpenArm
arms and jaws from Feetech leaders through LeaderTeleopModule and
LeaderCoordinator; the OpenArm folder supplies only the per-side mapping,
limits and velocity profile. openarm-mini-collection and
openarm-mini-follower-collection add the recorder and three cameras.
Measured on the OpenArm 2.0: without it the wrists step at the target
rate (high-frequency velocity power 10-17 percent), with it 5-7 percent
for about 10 ms of lag.
A target every coordinator tick halves each ramp the trajectory task
runs; wrist lag drops by about 10 ms and the feel on the arm is the best
measured.

@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: 269b2df Previous: 14c62ab Ratio
peak memory 1794.664 MB 1762.355 MB 1.02
peak threads 368 threads 385 threads 0.96
network (transport) 2731.097 MB 2731.013 MB 1.00
disk write 1.84 MB 1.605 MB 1.15
instructions 138.728 G 138.791 G 1.00

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

@codecov

codecov Bot commented Nov 11, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
8173 1 8172 55
View the top 1 failed test(s) by shortest run time
experimental.gateway.tests.test_config::test_every_registered_blueprint_is_annotated
Stack Traces | 0.162s run time
def test_every_registered_blueprint_is_annotated() -> None:
        source = annotation_file.load()
        annotated = {name for robot in source["robots"].values() for name in robot["blueprints"]}
        missing = sorted(
            name
            for name in all_blueprints
            if name not in annotated and not annotation_file.HIDDEN_NAME.search(name)
        )
>       assert not missing, f"add these to experimental/gateway/annotations.yaml: {', '.join(missing)}"
E       AssertionError: add these to experimental/gateway/annotations.yaml: openarm-mini-collection, openarm-mini-follower-collection, teleop-openarm-mini, teleop-openarm-mini-follower, teleop-openarm-mini-leader
E       assert not ['openarm-mini-collection', 'openarm-mini-follower-collection', 'teleop-openarm-mini', 'teleop-openarm-mini-follower', 'teleop-openarm-mini-leader']

annotated  = {'a1z-planner-coordinator', 'alfred-keyboard-teleop', 'alfred-mls-nav', 'alfred-mls-nav-lidar', 'alfred-nav', 'coordinator-a1z', ...}
missing    = ['openarm-mini-collection', 'openarm-mini-follower-collection', 'teleop-openarm-mini', 'teleop-openarm-mini-follower', 'teleop-openarm-mini-leader']
source     = {'robots': {'a1z': {'blueprints': {'a1z-planner-coordinator': {'description': 'Motion planning and execution for a Gal...': {'label': 'Arms'}, 'dog': {'label': 'Dogs'}, 'drone': {'label': 'Drones'}, 'humanoid': {'label': 'Humanoids'}, ...}}

.../gateway/tests/test_config.py:255: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

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