# Damiao Motors y CAN Bus

Esta guía cubre la configuración y el uso de los motores Damiao con LeRobot mediante comunicación por bus CAN.

Actualmente, solo se admite Linux, ya que el adaptador CAN de OpenArms solo tiene controladores para Linux.

## Configuración de CAN en Linux

Antes de usar los motores Damiao, debe configurar la interfaz CAN en su sistema Linux.

### Instalar CAN Utilities

```bash
sudo apt-get install can-utils
```

### Configurar la interfaz CAN (manual)

Para CAN FD estándar (recomendado para OpenArms):

```bash
sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up
```

Para CAN estándar (sin FD):

```bash
sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
```

### Configurar la interfaz CAN (usando LeRobot)

LeRobot proporciona un script de utilidad para configurar y probar interfaces CAN:

```bash
# Setup multiple interfaces (e.g., OpenArms Followers with 2 CAN buses)
lerobot-setup-can --mode=setup --interfaces=can0,can1
```

## Depuración de la comunicación CAN

Use las herramientas de depuración integradas para probar la comunicación del motor:

```bash
# Test motors on all interfaces
lerobot-setup-can --mode=test --interfaces=can0,can1

# Run speed/latency test
lerobot-setup-can --mode=speed --interfaces=can0
```

El modo de prueba buscará motores (IDs 0x01-0x08) e informará cuáles responden. Salida de ejemplo:

```
can0: UP (CAN FD)
  Motor 0x01 (joint_1): ✓ FOUND
    → Response 0x11 [FD]: 00112233...
  Motor 0x02 (joint_2): ✓ FOUND
  Motor 0x03 (joint_3): ✗ No response
  ...
  Summary: 2/8 motors found
```

## Uso

### Configuración básica

```python
from lerobot.motors import Motor
from lerobot.motors.damiao import DamiaoMotorsBus

# Define your motors with send/receive CAN IDs
motors = {
    "joint_1": Motor(id=0x01, motor_type_str="dm8009", recv_id=0x11),
    "joint_2": Motor(id=0x02, motor_type_str="dm4340", recv_id=0x12),
    "joint_3": Motor(id=0x03, motor_type_str="dm4310", recv_id=0x13),
}

# Create the bus
bus = DamiaoMotorsBus(
    port="can0",  # Linux socketcan interface
    motors=motors,
)

# Connect
bus.connect()
```

### Lectura de estados del motor

```python
# Read single motor position (degrees)
position = bus.read("Present_Position", "joint_1")

# Read from multiple motors
positions = bus.sync_read("Present_Position")  # All motors
positions = bus.sync_read("Present_Position", ["joint_1", "joint_2"])

# Read all states at once (position, velocity, torque)
states = bus.sync_read_all_states()
# Returns: {'joint_1': {'position': 45.2, 'velocity': 1.3, 'torque': 0.5}, ...}
```

### Escribir comandos de motor

```python
# Enable torque
bus.enable_torque()

# Set goal position (degrees)
bus.write("Goal_Position", "joint_1", 45.0)

# Set positions for multiple motors
bus.sync_write("Goal_Position", {
    "joint_1": 45.0,
    "joint_2": -30.0,
    "joint_3": 90.0,
})

# Disable torque
bus.disable_torque()
```

## Opciones de configuración

| Parámetro      | Predeterminado   | Descripción                                                 |
| -------------- | --------- | ----------------------------------------------------------- |
| `port`         | -         | Interfaz CAN (`can0`) o puerto serie (`/dev/cu.usbmodem*`) |
| `use_can_fd`   | `True`    | Habilitar CAN FD para tasas de datos más altas                         |
| `bitrate`      | `1000000` | Tasa de bits nominal (1 Mbps)                                    |
| `data_bitrate` | `5000000` | Tasa de bits de datos CAN FD (5 Mbps)                                |

## Configuración del motor

Cada motor requiere:

- `id`: ID de CAN para enviar comandos
- `motor_type`: Uno de los tipos de motor admitidos (p. ej., `"dm8009"`, `"dm4340"`)
- `recv_id`: ID de CAN para recibir respuestas

Los IDs predeterminados de OpenArms siguen el patrón: ID de envío `0x0N`, ID de recepción `0x1N`, donde N es el número de la articulación.

## Solución de problemas

### Sin respuesta de los motores

1. **Comprobar el suministro de energía**
2. **Verify CAN wiring**: Check CAN-H, CAN-L, and GND connections
3. **Comprobar los IDs de los motores**: Utilice las herramientas de depuración de Damiao para verificar/configurar los IDs
4. **Probar la interfaz CAN**: Ejecuta `candump can0` para ver si se están recibiendo mensajes
5. **Ejecutar diagnósticos**: `lerobot-setup-can --mode=test --interfaces=can0`

### Parámetro de tiempo de espera del motor

Si los motores se configuraron con timeout=0, no responderán a los comandos. Utilice las herramientas de depuración de Damiao para establecer un valor de timeout distinto de cero.

### Verificar el estado de CAN FD

```bash
ip -d link show can0 | grep fd
```

