Skip to content

feat: add unified dual-arm VR teleoperation - #3392

Merged
mustafab0 merged 24 commits into
mainfrom
cc/feat/dual-arm-teleop
Aug 25, 2026
Merged

feat: add unified dual-arm VR teleoperation#3392
mustafab0 merged 24 commits into
mainfrom
cc/feat/dual-arm-teleop

Conversation

@TomCC7

@TomCC7 TomCC7 commented Aug 7, 2026

Copy link
Copy Markdown
Member

Contribution path

  • Linked issue or discussion: closes DIM-1395

Problem

Quest arm teleoperation assumed one controller, one end-effector, and one IK task. OpenArm needs both controllers to drive one bimanual model in a single solve. The existing Cartesian, twist, and teleop paths also duplicated Pink setup and lacked a common streaming safety envelope for noisy, delayed hardware feedback.

Solution

  • Replace the legacy teleop task and duplicated Cartesian Pink controller with a shared PoseTargetIKTask core. CartesianIKTask, EEFTwistTask, and TeleopIKTask remain thin input-specific leaves.
  • Support one or two hand-to-frame bindings in TeleopIKTask, including optional gripper joints. A two-hand task captures both references together and requires both primary buttons; timeout, release, preemption, or E-stop clears the full session.
  • Keep a persistent command trajectory separate from measured feedback. Each Pink step is bounded by configured and URDF velocity limits, measured tracking error, joint limits, and a command margin, while feedback receives a small limit tolerance for sensor error.
  • Keep planning and control ownership separate: PinkIK exposes the planning API, PinkPoseTargetSolver owns streaming control state, and both use the private shared Pink solver core.
  • Allow each robot to inject a PinkPoseTargetSolver subclass. OpenArm tunes frame costs, posture weights, and per-arm manipulability tasks without replacing common solving or safety logic.
  • Add TeleopControlCoordinator for teleop-only pose and button ports while leaving the generic coordinator free of Quest streams. Existing A1Z, mixed-arm, OpenYam, Piper, and XArm Quest blueprints use the unified task configuration.
  • Add teleop-quest-openarm with one bimanual IK task and one OpenArm URDF. It uses fake hardware by default; specifying both CAN interfaces selects real hardware. The blueprint also includes the manipulation planner, Viser visualization, and a higher-priority dual-arm trajectory task.

How to Test

Run the complete feature with fake hardware:

uv run dimos run teleop-quest-openarm

To use real OpenArm hardware, specify both CAN interfaces:

uv run dimos run teleop-quest-openarm --left-can-port can0 --right-can-port can1

Run the focused control, Pink, routing, Quest, and OpenArm tests:

uv run pytest dimos/control/tasks/test_pose_target_ik.py dimos/control/tasks/cartesian_ik_task/test_cartesian_ik_task.py dimos/control/tasks/eef_twist_task/test_eef_twist_task.py dimos/control/tasks/teleop_ik_task/test_teleop_ik_task.py dimos/control/test_coordinator_routing.py dimos/manipulation/planning/kinematics/test_pink_ik.py dimos/robot/manipulators/openarm/test_openarm_teleop.py dimos/teleop/quest/test_blueprints.py dimos/teleop/quest/test_quest_teleop_module.py

Current result: 156 passed.

AI assistance

Codex with GPT-5 assisted substantially with architecture exploration, implementation, tests, documentation, and verification. The author developed and reviewed the changes interactively.

Checklist

  • I have read and approved the CLA.

@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

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

Files with missing lines Patch % Lines
dimos/control/tasks/pose_target_ik.py 84.01% 31 Missing and 28 partials ⚠️
...os/manipulation/planning/kinematics/pink_solver.py 75.89% 35 Missing and 12 partials ⚠️
...mos/control/tasks/teleop_ik_task/teleop_ik_task.py 91.41% 9 Missing and 8 partials ⚠️
...mos/control/tasks/eef_twist_task/eef_twist_task.py 79.22% 13 Missing and 3 partials ⚠️
dimos/robot/manipulators/openarm/teleop_ik.py 78.57% 3 Missing and 3 partials ⚠️
...ntrol/tasks/cartesian_ik_task/cartesian_ik_task.py 83.87% 4 Missing and 1 partial ⚠️
dimos/control/_control_test_helpers.py 60.00% 4 Missing ⚠️
dimos/hardware/whole_body/damiao/adapter.py 93.65% 2 Missing and 2 partials ⚠️
dimos/manipulation/test_roboplan.py 63.63% 4 Missing ⚠️
dimos/robot/manipulators/common/blueprints.py 69.23% 2 Missing and 2 partials ⚠️
... and 4 more
@@            Coverage Diff             @@
##             main    #3392      +/-   ##
==========================================
+ Coverage   77.29%   77.45%   +0.15%     
==========================================
  Files        1269     1274       +5     
  Lines      121027   121473     +446     
  Branches    10680    10686       +6     
==========================================
+ Hits        93551    94084     +533     
+ Misses      24407    24317      -90     
- Partials     3069     3072       +3     
Flag Coverage Δ
OS-ubuntu-24.04-arm 72.33% <88.71%> (+0.10%) ⬆️
OS-ubuntu-latest 74.21% <88.71%> (+0.10%) ⬆️
Py-3.10 74.21% <88.71%> (+0.10%) ⬆️
Py-3.11 74.21% <88.71%> (+0.09%) ⬆️
Py-3.12 74.21% <88.71%> (+0.10%) ⬆️
Py-3.13 74.21% <88.71%> (+0.10%) ⬆️
Py-3.14 74.21% <88.71%> (+0.10%) ⬆️
Py-3.14t 74.21% <88.71%> (+0.10%) ⬆️
SelfHosted-Large 30.03% <28.85%> (+0.02%) ⬆️
SelfHosted-Linux 35.37% <40.90%> (+0.26%) ⬆️

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

Files with missing lines Coverage Δ
dimos/control/coordinator.py 82.60% <ø> (+1.11%) ⬆️
.../tasks/cartesian_ik_task/test_cartesian_ik_task.py 100.00% <100.00%> (ø)
...ontrol/tasks/eef_twist_task/test_eef_twist_task.py 100.00% <100.00%> (ø)
dimos/control/tasks/teleop_ik_task/_registry.py 100.00% <ø> (ø)
...ontrol/tasks/teleop_ik_task/test_teleop_ik_task.py 100.00% <100.00%> (ø)
dimos/control/tasks/test_registry.py 88.17% <ø> (ø)
dimos/control/teleop_coordinator.py 100.00% <100.00%> (ø)
dimos/control/test_coordinator_routing.py 99.41% <100.00%> (+<0.01%) ⬆️
dimos/core/coordination/module_coordinator.py 86.56% <100.00%> (ø)
dimos/core/coordination/test_module_coordinator.py 98.37% <100.00%> (+<0.01%) ⬆️
... and 40 more

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

Comment thread dimos/manipulation/planning/kinematics/pink_ik.py
Comment thread dimos/control/coordinator.py Outdated
Comment thread dimos/control/tasks/pose_target_ik.py
Comment thread dimos/control/tasks/teleop_ik_task/teleop_ik_task.py
Comment thread dimos/core/global_config.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_ik.py
Comment thread dimos/robot/manipulators/openarm/teleop_ik.py Outdated
Comment thread dimos/robot/manipulators/piper/cli.py Outdated
Comment thread dimos/teleop/quest/quest_extensions.py Outdated
@TomCC7
TomCC7 marked this pull request as ready for review August 8, 2026 06:34
Comment thread dimos/control/tasks/pose_target_ik.py Outdated
Comment thread dimos/control/tasks/cartesian_ik_task/cartesian_ik_task.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
Comment thread docs/capabilities/manipulation/openarm_integration.md
Comment thread docs/capabilities/manipulation/adding_a_custom_arm.md Outdated
Comment thread dimos/utils/data.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Aug 8, 2026
@TomCC7 TomCC7 changed the title feat: add unified dual-arm Quest teleoperation feat: add unified dual-arm VR teleoperation Aug 8, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Aug 9, 2026
Comment thread dimos/control/tasks/eef_twist_task/eef_twist_task.py Outdated
Comment thread dimos/control/tasks/eef_twist_task/eef_twist_task.py Outdated
Comment thread dimos/control/tasks/eef_twist_task/eef_twist_task.py Outdated
Comment thread dimos/control/tasks/eef_twist_task/eef_twist_task.py Outdated
Comment thread dimos/control/tasks/teleop_ik_task/teleop_ik_task.py Outdated
Comment thread dimos/hardware/whole_body/openarm_damiao/adapter.py Outdated
Comment thread dimos/hardware/whole_body/openarm_damiao/adapter.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
@TomCC7
TomCC7 force-pushed the cc/feat/dual-arm-teleop branch from 0a253c6 to 94a3bd4 Compare August 10, 2026 23:36
@TomCC7
TomCC7 force-pushed the cc/feat/dual-arm-teleop branch 2 times, most recently from 8b7239a to cac9e77 Compare August 11, 2026 03:07
Comment thread dimos/robot/manipulators/openarm/teleop_ik.py Outdated
@TomCC7
TomCC7 force-pushed the cc/feat/dual-arm-teleop branch 2 times, most recently from 5812922 to 93300a9 Compare August 14, 2026 21:40
@TomCC7
TomCC7 force-pushed the cc/feat/dual-arm-teleop branch from f9b4a25 to d30ed33 Compare August 21, 2026 05:15
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This update unifies Cartesian, twist, and Quest teleoperation around bounded Pink IK control, adds coordinated one- and two-hand deadman handling, and introduces an OpenArm teleoperation blueprint with mock hardware by default. The current deadman implementation stops active motion after button input becomes stale even when controller poses continue arriving.

Confidence Score: 5/5

No blocking failure remains.

The focused teleoperation checks exercised stale and refreshed deadman input for single-arm and bimanual control; stale button input halted motion and refreshed input continued the active stream.

T-Rex T-Rex Logs

What T-Rex did

  • Executed the stale-deadman test for single-arm and bimanual flows; both tests passed, confirming fresh controller poses cannot extend a stale button stream.
  • Executed the refreshed-deadman test; it passed, confirming a fresh button update permits continued pose control.
  • Executed the focused teleoperation IK test module; all 17 tests passed.
  • Cross-validated the before/after and focused teleop IK test suite captures against the published reports, confirming the captured results align with the test outcomes.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (7): Last reviewed commit: "docs: replace Pink tuning frontmatter he..." | Re-trigger Greptile

Comment thread dimos/control/tasks/teleop_ik_task/teleop_ik_task.py
@TomCC7
TomCC7 force-pushed the cc/feat/dual-arm-teleop branch from db170b3 to 42c367c Compare August 21, 2026 06:51
Base automatically changed from krishna/feat/openarm-damiao to main August 21, 2026 18:52
# Conflicts:
#	dimos/hardware/whole_body/damiao/adapter.py
#	dimos/hardware/whole_body/damiao/test_adapter.py
#	dimos/hardware/whole_body/openarm_damiao/adapter.py
#	dimos/hardware/whole_body/openarm_damiao/test_adapter.py
#	dimos/hardware/whole_body/openyam_damiao/adapter.py
#	dimos/manipulation/test_roboplan.py
#	dimos/robot/manipulators/openarm/blueprints/basic.py
#	dimos/robot/manipulators/openarm/blueprints/teleop.py
#	dimos/robot/manipulators/openarm/config.py
#	dimos/robot/manipulators/openarm/test_config.py
#	docs/capabilities/manipulation/openarm_integration.md
@mintlify

mintlify Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
dimensional 🟢 Ready View Preview Aug 21, 2026, 8:25 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread dimos/control/tasks/teleop_ik_task/teleop_ik_task.py
@Nabla7

Nabla7 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

pls approve someone

mustafab0
mustafab0 previously approved these changes Aug 21, 2026
Comment thread dimos/manipulation/planning/kinematics/pink_solver.py Outdated
@mustafab0 mustafab0 added the backport:skip Skip creating a backport to any release branches label Aug 22, 2026
@mustafab0
mustafab0 added this pull request to the merge queue Aug 25, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Aug 25, 2026
Merged via the queue into main with commit e67485d Aug 25, 2026
31 of 32 checks passed
@mustafab0
mustafab0 deleted the cc/feat/dual-arm-teleop branch August 25, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip Skip creating a backport to any release branches ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants