mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-14 16:19:45 +00:00
329 lines
9.3 KiB
Plaintext
329 lines
9.3 KiB
Plaintext
# OpenArms Robot
|
|
|
|
OpenArms is a 7 DOF robotic arm with a gripper, designed by [Enactic, Inc.](https://www.enactic.com/) It uses Damiao motors controlled via CAN bus communication and MIT control mode for smooth, precise motion.
|
|
|
|
## Hardware Overview
|
|
|
|
- **7 DOF per arm** (14 DOF total for dual arm setup)
|
|
- **1 gripper per arm** (2 grippers total)
|
|
- **Damiao motors** with 4 different types:
|
|
- **DM8009** (DM-J8009P-2EC) for shoulders (J1, J2) - high torque
|
|
- **DM4340** for shoulder rotation and elbow (J3, J4)
|
|
- **DM4310** (DM-J4310-2EC V1.1) for wrist (J5, J6, J7) and gripper (J8)
|
|
- **24V power supply** required
|
|
- **CAN interface device**:
|
|
- **Linux**: Any SocketCAN-compatible adapter
|
|
- **macOS**: CANable, PEAK PCAN-USB, or Kvaser USBcan
|
|
- Proper CAN wiring (CANH, CANL, 120Ω termination)
|
|
|
|
|
|
## Motor Configuration
|
|
|
|
Each arm has the following motor configuration based on the [OpenArm setup guide](https://docs.openarm.dev/software/setup/):
|
|
|
|
| Joint | Motor | Motor Type | Sender CAN ID | Receiver ID | Description |
|
|
|-------|-------|------------|---------------|-------------|-------------|
|
|
| J1 | joint_1 | DM8009 | 0x01 | 0x11 | Shoulder pan |
|
|
| J2 | joint_2 | DM8009 | 0x02 | 0x12 | Shoulder lift |
|
|
| J3 | joint_3 | DM4340 | 0x03 | 0x13 | Shoulder rotation |
|
|
| J4 | joint_4 | DM4340 | 0x04 | 0x14 | Elbow flex |
|
|
| J5 | joint_5 | DM4310 | 0x05 | 0x15 | Wrist roll |
|
|
| J6 | joint_6 | DM4310 | 0x06 | 0x16 | Wrist pitch |
|
|
| J7 | joint_7 | DM4310 | 0x07 | 0x17 | Wrist rotation |
|
|
| J8 | gripper | DM4310 | 0x08 | 0x18 | Gripper |
|
|
|
|
For dual arm setups, the left arm uses IDs 0x09-0x10 for joints 1-8 with the same motor types.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Install system dependencies
|
|
sudo apt install can-utils iproute2
|
|
|
|
# Install LeRobot with OpenArms support
|
|
pip install -e ".[openarms]"
|
|
```
|
|
|
|
## Setup Guide
|
|
|
|
### Step 1: Motor ID Configuration
|
|
|
|
**IMPORTANT**: Before using the robot, motors must be configured with the correct CAN IDs.
|
|
|
|
Refer to the [OpenArm Motor ID Configuration Guide](https://docs.openarm.dev/software/setup/motor-id) for detailed instructions using the Damiao Debugging Tools on Windows.
|
|
|
|
Key points:
|
|
- Each motor needs a unique **Sender CAN ID** (0x01-0x08)
|
|
- Each motor needs a unique **Receiver/Master ID** (0x11-0x18)
|
|
- Use the Damiao Debugging Tools to set these IDs
|
|
|
|
### Step 2: Setup CAN Interface
|
|
|
|
Configure your CAN interface as described in the [OpenArm CAN Setup Guide](https://docs.openarm.dev/software/setup/can-setup):
|
|
|
|
#### Linux (SocketCAN)
|
|
|
|
```bash
|
|
# Find your CAN interface
|
|
ip link show
|
|
|
|
# Configure can0, 1, 2, 3
|
|
sudo ip link set can0 down
|
|
sudo ip link set can0 type can bitrate 1000000
|
|
sudo ip link set can0 up
|
|
|
|
sudo ip link set can1 down
|
|
sudo ip link set can1 type can bitrate 1000000
|
|
sudo ip link set can1 up
|
|
|
|
sudo ip link set can2 down
|
|
sudo ip link set can2 type can bitrate 1000000
|
|
sudo ip link set can2 up
|
|
|
|
sudo ip link set can3 down
|
|
sudo ip link set can3 type can bitrate 1000000
|
|
sudo ip link set can3 up
|
|
|
|
# Verify configuration
|
|
ip link show can0
|
|
```
|
|
|
|
or run:
|
|
|
|
`examples/openarms/setup_can.sh`
|
|
|
|
### Testing canbus and motor connection
|
|
|
|
Please run this script to check if all motors can be found and to find your can-fd speed: `python examples/openarms/debug_can_communication.py`
|
|
|
|
## Usage
|
|
|
|
### Basic Setup
|
|
|
|
|
|
```python
|
|
from lerobot.robots.openarms import OpenArmsFollower
|
|
from lerobot.robots.openarms.config_openarms_follower import OpenArmsFollowerConfig
|
|
|
|
# Configure for dual arm setup
|
|
config = OpenArmsFollowerConfig(
|
|
port="can0",
|
|
can_interface="socketcan", # Or "auto" for auto-detection
|
|
id="openarms_dual",
|
|
is_dual_arm=True,
|
|
)
|
|
|
|
robot = OpenArmsFollower(config)
|
|
robot.connect()
|
|
```
|
|
|
|
### Calibration
|
|
|
|
On first use, you'll need to calibrate the robot:
|
|
|
|
```python
|
|
robot.calibrate()
|
|
```
|
|
|
|
The calibration process will:
|
|
1. Disable torque on all motors
|
|
2. Ask you to position arms in **hanging position with grippers closed**
|
|
3. Set this as the zero position
|
|
4. Ask you to move each joint through its full range
|
|
5. Record min/max positions for each joint
|
|
6. Save calibration to file
|
|
|
|
### Reading Observations
|
|
|
|
The robot provides comprehensive state information:
|
|
|
|
```python
|
|
observation = robot.get_observation()
|
|
|
|
# Observation includes for each motor:
|
|
# - {motor_name}.pos: Position in degrees
|
|
# - {motor_name}.vel: Velocity in degrees/second
|
|
# - {motor_name}.torque: Motor torque
|
|
# - {camera_name}: Camera images (if configured)
|
|
|
|
print(f"Right arm joint 1 position: {observation['right_joint_1.pos']:.1f}°")
|
|
print(f"Right arm joint 1 velocity: {observation['right_joint_1.vel']:.1f}°/s")
|
|
print(f"Right arm joint 1 torque: {observation['right_joint_1.torque']:.3f} N·m")
|
|
```
|
|
|
|
### Sending Actions
|
|
|
|
```python
|
|
# Send target positions (in degrees)
|
|
action = {
|
|
"right_joint_1.pos": 45.0,
|
|
"right_joint_2.pos": -30.0,
|
|
# ... all joints
|
|
"right_gripper.pos": 45.0, # Half-closed
|
|
}
|
|
|
|
actual_action = robot.send_action(action)
|
|
```
|
|
|
|
### Gripper Control
|
|
|
|
```python
|
|
# Open gripper
|
|
robot.open_gripper(arm="right")
|
|
|
|
# Close gripper
|
|
robot.close_gripper(arm="right")
|
|
```
|
|
|
|
## Safety Features
|
|
|
|
### 1. Maximum Relative Target
|
|
|
|
Limits how far a joint can move in a single command to prevent sudden movements:
|
|
|
|
```python
|
|
config = OpenArmsFollowerConfig(
|
|
port="can0",
|
|
# Limit all joints to 10 degrees per command
|
|
max_relative_target=10.0,
|
|
|
|
# Or set per-motor limits
|
|
max_relative_target={
|
|
"right_joint_1": 15.0, # Slower moving joint
|
|
"right_joint_2": 10.0,
|
|
"right_gripper": 5.0, # Very slow gripper
|
|
}
|
|
)
|
|
```
|
|
|
|
**How it works**: If current position is 50° and you command 80°, with `max_relative_target=10.0`, the robot will only move to 60° in that step.
|
|
|
|
### 2. Torque Limits
|
|
|
|
Control maximum torque output, especially important for grippers and teleoperation:
|
|
|
|
```python
|
|
config = OpenArmsFollowerConfig(
|
|
port="can0",
|
|
# Gripper torque limit (fraction of motor's max torque)
|
|
gripper_torque_limit=0.5, # 50% of max torque
|
|
)
|
|
```
|
|
|
|
Lower torque limits prevent damage when gripping delicate objects.
|
|
|
|
### 3. MIT Control Gains
|
|
|
|
Control responsiveness and stability via PID-like gains:
|
|
|
|
```python
|
|
config = OpenArmsFollowerConfig(
|
|
port="can0",
|
|
position_kp=10.0, # Position gain (higher = more responsive)
|
|
position_kd=0.5, # Velocity damping (higher = more damped)
|
|
)
|
|
```
|
|
|
|
**Guidelines**:
|
|
- **For following (robot)**: Higher gains for responsiveness
|
|
- `position_kp=10.0`, `position_kd=0.5`
|
|
- **For teleoperation (leader)**: Lower gains or disable torque for manual movement
|
|
- `manual_control=True` (torque disabled)
|
|
|
|
### 4. Velocity Limits
|
|
|
|
Velocity limits are enforced by the Damiao motors based on motor type. For DM4310:
|
|
- Max velocity: 30 rad/s ≈ 1718°/s
|
|
|
|
The motors will automatically limit velocity to safe values.
|
|
|
|
## Teleoperation
|
|
|
|
### Leader Arm Setup
|
|
|
|
The leader arm is moved manually (torque disabled) to generate commands:
|
|
|
|
```python
|
|
from lerobot.teleoperators.openarms import OpenArmsLeader
|
|
from lerobot.teleoperators.openarms.config_openarms_leader import OpenArmsLeaderConfig
|
|
|
|
config = OpenArmsLeaderConfig(
|
|
port="can1", # Separate CAN interface for leader
|
|
id="openarms_leader",
|
|
manual_control=True, # Torque disabled for manual movement
|
|
is_dual_arm=True,
|
|
)
|
|
|
|
leader = OpenArmsLeader(config)
|
|
leader.connect()
|
|
|
|
# Read current position as action
|
|
action = leader.get_action()
|
|
# action contains positions for all joints in degrees
|
|
```
|
|
|
|
### Safety Considerations for Teleoperation
|
|
|
|
1. **Use separate CAN interfaces** for leader and follower to avoid conflicts
|
|
2. **Enable max_relative_target** on follower to smooth abrupt movements
|
|
3. **Lower torque limits** on follower to prevent damage from tracking errors
|
|
4. **Test with one arm** before enabling dual arm teleoperation
|
|
5. **Have emergency stop** ready (power switch or CAN disable)
|
|
|
|
```python
|
|
# Recommended follower config for teleoperation
|
|
follower_config = OpenArmsFollowerConfig(
|
|
port="can0",
|
|
max_relative_target=5.0, # Small steps for smooth following
|
|
gripper_torque_limit=0.3, # Low torque for safety
|
|
position_kp=5.0, # Lower gains for gentler following
|
|
position_kd=0.3,
|
|
)
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Motor Shaking/Unstable
|
|
|
|
- **Lower control gains**: Reduce `position_kp` and `position_kd`
|
|
- **Check calibration**: Re-run calibration procedure
|
|
- **Verify power**: Insufficient current can cause instability
|
|
- **Check mechanical**: Loose connections, binding, or damaged components
|
|
|
|
### CAN Bus Errors
|
|
|
|
```bash
|
|
# Check for errors
|
|
ip -s link show can0
|
|
|
|
# Reset CAN interface
|
|
sudo ip link set can0 down
|
|
sudo ip link set can0 up
|
|
```
|
|
|
|
### Control Mode
|
|
|
|
OpenArms uses **MIT control mode** which allows simultaneous control of:
|
|
- Position (degrees)
|
|
- Velocity (degrees/second)
|
|
- Torque (N·m)
|
|
- Position gain (Kp)
|
|
- Velocity damping (Kd)
|
|
|
|
### Communication
|
|
|
|
- **Protocol**: CAN 2.0 at 1 Mbps (or CAN-FD at 5 Mbps)
|
|
- **Frame format**: Standard 11-bit IDs
|
|
- **Update rate**: Typically 50-100 Hz depending on motor count
|
|
- **Latency**: ~10-20ms per motor command
|
|
|
|
## References
|
|
|
|
- [OpenArm Official Documentation](https://docs.openarm.dev/)
|
|
- [OpenArm Setup Guide](https://docs.openarm.dev/software/setup/)
|
|
- [Motor ID Configuration](https://docs.openarm.dev/software/setup/motor-id)
|
|
- [CAN Interface Setup](https://docs.openarm.dev/software/setup/can-setup)
|
|
- [Motor Communication Test](https://docs.openarm.dev/software/setup/configure-test)
|
|
- [Damiao Motor Documentation](https://wiki.seeedstudio.com/damiao_series/)
|
|
- [Enactic GitHub](https://github.com/enactic/openarm_can)
|