feat: xarm manipulator adapter improvement#2425
Conversation
- Fix _XARM6/7_INITIAL_JOINTS to use degrees instead of radians - Add motion_enable(False) before set_state(4) in stop() - Update custom arm docs with activate/deactivate lifecycle methods - Ignore .omo/ directory
Remove unnecessary getattr/callable/hasattr guards since ManipulatorAdapter Protocol guarantees these methods exist.
- Guard activate()/deactivate() calls in the coordinator so adapters without lifecycle methods (twist bases, whole-body) no longer raise AttributeError; restore the write_enable(True) fallback on setup - Implement activate()/deactivate() in MockAdapter and ShmMujocoAdapter to satisfy the extended ManipulatorAdapter protocol - Log and set the stop event when keyboard teleop fails to read the initial joint state instead of exiting the thread silently - Remove unused home_pose computation in keyboard teleop - Add coordinator test covering adapters without lifecycle methods Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR introduces
Confidence Score: 4/5Safe to merge with awareness of the open keyboard-teleop threading issues raised in earlier review rounds The coordinator lifecycle wiring and adapter implementations are correct. The xarm adapter's _prepare_for_position_motion discards SDK return codes (flagged previously), and the keyboard teleop thread can outlive stop() when the initial joint-state read is still blocked — both are open items from earlier rounds. The changes are otherwise well-tested and the new lifecycle path is straightforward. dimos/teleop/keyboard/keyboard_teleop_module.py (thread-lifetime window when initial_state_timeout > DEFAULT_THREAD_JOIN_TIMEOUT) and dimos/hardware/manipulators/xarm/adapter.py (_prepare_for_position_motion return-code handling) Important Files Changed
Sequence DiagramsequenceDiagram
participant CC as ControlCoordinator
participant XA as XArmAdapter
participant KT as KeyboardTeleopModule
CC->>XA: connect()
Note over XA: TCP connect, set servo mode
CC->>XA: activate()
XA->>XA: _prepare_for_position_motion()
Note over XA: clean errors, enable motion, set mode=0
XA->>XA: "_move_to_initial_pose(wait=True)"
Note over XA: set_servo_angle to default pose
XA->>XA: set_control_mode(SERVO_POSITION)
XA-->>CC: True
CC->>CC: add_hardware() → start publishing JointState
KT->>KT: "_read_joint_positions(timeout=5s)"
CC-->>KT: JointState message
KT->>KT: JogState.from_fk(initial_joints)
loop Teleop loop
KT->>CC: cartesian_command.publish(PoseStamped)
KT->>KT: SPACE → _read_joint_positions(0.1s) → sync pose
end
CC->>XA: deactivate()
XA->>XA: _prepare_for_position_motion()
XA->>XA: "_move_to_initial_pose(wait=True)"
XA->>XA: motion_enable(False) + set_state(4)
XA-->>CC: True
CC->>XA: disconnect()
Reviews (4): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
❌ 1 Tests Failed:
View the full list of 1 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
Internal version of #2353 , closing the original pr.
Closes #1183
Solution
This PR resolves the following issues observed on teleoperating xarm:
KeyboardTeleopModule initial position sync
Wire robot joint states to the keyboard teleop module so that it initialize target to the robot startup position. A more proper fix in my mind should be to refactor keyboard teleop module to only output relative cartesian motion and wire that to some relative cartesian task so that the teleop module is decoupled from the actual robot state.
XArm graceful start/stop
Added two lifecycle methods in manipulator adapter activate/deactivate to execute functions required before robot starts/stop movement. The semantic is different from connect/disconnect in that sometime you might want to only pause robot commanding while still keeping the connection. Now the xarm will move to the default position on start/stop.
How to Test
# connects to a real robot for testing dimos --xarm6-ip=192.168.1.210 run keyboard-teleop-xarm6Contributor License Agreement
I have read and approved the CLA.