Skip to content

Task: OpenArm Integration with DimOS#1897

Open
mustafab0 wants to merge 30 commits intodevfrom
task/mustafa/open-arm-integration
Open

Task: OpenArm Integration with DimOS#1897
mustafab0 wants to merge 30 commits intodevfrom
task/mustafa/open-arm-integration

Conversation

@mustafab0
Copy link
Copy Markdown
Contributor

Problem

OpenArm is a bimanual 7-DOF research arm built from Damiao DM-J motors. Unlike every other arm in dimos, it ships no Python SDK — only raw CAN. Need a from-scratch driver + adapter + blueprints to run it.

Closes DIM-386

Solution

From-scratch Damiao MIT-mode CAN driver (ported from enactic/openarm_can) + ManipulatorAdapter wrapper with Pinocchio gravity-comp feedforward + bimanual blueprints. Auto-writes CTRL_MODE=MIT on connect. Per-side URDFs avoid phantom-arm Drake collisions. Generic reachability tool added to dimos.utils since it works on any URDF.

Added:

  • dimos/hardware/manipulators/openarm/{driver,adapter,test_driver}.py
  • dimos/robot/catalog/openarm.py
  • dimos/robot/manipulators/openarm/blueprints.py
  • dimos/robot/manipulators/openarm/scripts/{openarm_can_up.sh, openarm_can_probe.py, openarm_set_mit_mode.py}
  • dimos/utils/workspace.py
  • docs/capabilities/manipulation/openarm_integration.md

Modified: dimos/robot/all_blueprints.py

Breaking Changes

None.

How to Test

Unit tests (no hardware):

.venv/bin/python -m pytest dimos/hardware/manipulators/openarm/ -v

Mock (no hardware, Drake viz):

dimos run openarm-mock-planner-coordinator

Real hardware:

sudo ./dimos/robot/manipulators/openarm/scripts/openarm_can_up.sh can0 can1
python ./dimos/robot/manipulators/openarm/scripts/openarm_can_probe.py --channel can0     # expect 8/8
dimos run openarm-planner-coordinator
# then in another terminal: python -i -m dimos.manipulation.planning.examples.manipulation_client

Full guide: openarm_integration.md.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 22, 2026

Greptile Summary

This PR introduces a complete from-scratch OpenArm v10 integration: a Damiao MIT-mode CAN driver (driver.py), a ManipulatorAdapter with Pinocchio gravity-compensation feedforward (adapter.py), bimanual and single-arm blueprints, hardware bring-up scripts, and a generic workspace reachability tool. All previously flagged issues (velocity-mode gravity feedforward, ENOBUFS errno detection, --classical CLI flag) have been addressed. The remaining findings are P2 quality issues only.

Confidence Score: 5/5

Safe to merge — no P0 or P1 issues; all findings are minor style or robustness P2s.

No blocking issues found. The driver, adapter, and tests are well-structured. Previous P1 comments have been addressed. Remaining findings (duplicate import, weak bounds check in a rarely-triggered branch, unclosed file handles in CLI scripts, potential NaN in workspace sampling for unlimited joints) are all P2 and do not affect correctness on the target hardware.

dimos/perception/detection/type/imageDetections.py (duplicate import), dimos/utils/workspace.py (unbounded joint sampling), dimos/robot/manipulators/openarm/scripts/openarm_set_mit_mode.py (struct bounds check)

Important Files Changed

Filename Overview
dimos/hardware/manipulators/openarm/driver.py New Damiao MIT-mode CAN driver: frame packing/unpacking, background RX thread with state cache, ENOBUFS retry now using errno directly — clean and well-structured.
dimos/hardware/manipulators/openarm/adapter.py ManipulatorAdapter wrapping the CAN driver; gravity feedforward now applied in all three write paths (position, velocity, stop) — no issues found.
dimos/hardware/manipulators/openarm/test_driver.py Good unit-test coverage via virtual CAN loopback: frame packing roundtrips, RX thread state cache, enable/disable, send_mit_many fan-out — all hardware-free.
dimos/perception/detection/type/imageDetections.py Duplicate Self import block added — appears to be a merge artifact; harmless at runtime but should be removed.
dimos/utils/workspace.py New reachability + manipulability workspace tool; sampling loop is correct for bounded joints but will silently produce NaN for infinite-limit joints (e.g. continuous revolute or free-floating base).
dimos/robot/manipulators/openarm/scripts/openarm_set_mit_mode.py Hardware bring-up script; bounds check before struct.unpack is too weak (>=4 instead of >=8) and file handle is unclosed.
dimos/robot/manipulators/openarm/scripts/openarm_can_probe.py Hardware probe script; uses open() without context manager for sysfs flags read — minor resource leak identical to the pattern in set_mit_mode.py.
dimos/robot/catalog/openarm.py Clean catalog definitions for single-arm and bimanual configs with proper adapter_kwargs merging; no issues found.
dimos/robot/manipulators/openarm/blueprints.py Bimanual and single-arm blueprints covering mock, left-only, right-only, and planner+coordinator combos; CAN channel assignment clearly documented.
dimos/robot/all_blueprints.py Adds eight new OpenArm blueprint entries in alphabetical order — clean registration.

Sequence Diagram

sequenceDiagram
    participant App as Application / Blueprint
    participant Adapter as OpenArmAdapter
    participant Bus as OpenArmBus
    participant RX as RX Thread (daemon)
    participant HW as Damiao Motors (CAN)

    App->>Adapter: connect()
    Adapter->>Bus: open() → start RX thread
    Bus->>RX: spawn thread
    Adapter->>Bus: write_ctrl_mode(MIT) × 7
    Bus->>HW: 0x7FF param-write frame
    Adapter->>Bus: enable_all()
    Bus->>HW: ENABLE frame × 7
    HW-->>RX: state reply frames
    RX->>Bus: _states[recv_id] = MotorState
    Adapter->>Bus: wait_all_states(0.5s)
    Adapter->>Adapter: load Pinocchio model (gravity comp)

    loop Control tick
        App->>Adapter: write_joint_positions(q)
        Adapter->>Bus: get_states() [read lock]
        Adapter->>Adapter: _compute_gravity_torques(q_current)
        Adapter->>Bus: send_mit_many(commands)
        Bus->>HW: MIT frame × 7 (inter-frame 0.5ms)
        HW-->>RX: state replies → cache update
    end

    App->>Adapter: disconnect()
    Adapter->>Bus: disable_all()
    Adapter->>Bus: close() → stop RX thread
Loading

Reviews (4): Last reviewed commit: "converted relateive paths to absolute pa..." | Re-trigger Greptile

Comment thread dimos/hardware/manipulators/openarm/adapter.py
Comment thread dimos/robot/manipulators/openarm/scripts/openarm_set_mit_mode.py Outdated
Comment thread dimos/hardware/manipulators/openarm/driver.py
@mustafab0 mustafab0 marked this pull request as draft April 22, 2026 01:56
@mustafab0 mustafab0 marked this pull request as ready for review April 29, 2026 02:23
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.

6 participants