Saltar al contenido principal

Control de Posición MIT del reBot Arm B601-RS

reBot Arm B601-RS

License: MITPython VersionPlatformMIT Mode

6+1 DOF · RobStride · CAN @ 1 Mbps · Control de Posición MIT · Protección de Temperatura · Retorno Seguro a Cero · API de Python de código abierto

MotorBridge es un SDK CAN en Python para motores RobStride / Damiao. rebot_control lo envuelve con una API de control de posición MIT para el reBot Arm B601-RS: configuración YAML, límites de velocidad por articulación, protección de temperatura MOS de tres niveles y retorno suave a cero mediante Esc / Ctrl+C / stop().

Este tutorial te guía a través de: configuración del entorno → configuración de CAN → ejecución de ejemplos → uso del paquete como biblioteca.

Aviso Importante de Seguridad
  • Este proyecto solo proporciona APIs de control — sin límites de articulación por software ni límites de espacio de trabajo. Los ángulos objetivo que configures se envían directamente a los motores.
  • Mantén el brazo dentro de aproximadamente el 70% de su espacio de trabajo. Permanecer más allá del espacio de trabajo durante períodos prolongados puede activar la protección contra bloqueo en la articulación 2 y el brazo puede caer.
  • En el primer uso, haz pruebas con ángulos pequeños y bajas velocidades, y mantén el espacio de trabajo libre de personas y obstáculos.

Características​

  1. Control de posición MIT
    Comandos de posición MIT por defecto a 200 Hz; límites de velocidad por articulación con suavizado en el bucle de control.

  2. 6+1 motores
    J1–J6 son articulaciones del brazo; J7 (ID CAN 7) es el gripper del efector final, controlado mediante set_joint_angles / set_joint_angle.

  3. Protección de temperatura de tres niveles
    Monitorización en tiempo real de la temperatura MOS: alarma y continuar → sobretemperatura con retorno lento a cero y luego deshabilitar → deshabilitado de emergencia (sin retorno a cero).

  4. Salida segura y retorno a cero
    Esc / Ctrl+C / arm.stop() activan un retorno a cero suave tipo smoothstep; un segundo Ctrl+C durante el retorno a cero aborta inmediatamente y deshabilita los motores.

  5. Configuración basada en YAML
    Canal CAN, umbrales de temperatura, parámetros de retorno a cero y kp/kd del motor se encuentran en config/rebotarm_rs.yaml — ajusta sin cambiar código.

  6. Lista para usar como biblioteca
    Capas claras (config / API / ejemplos); importa con from rebot import ReBotRSMITController.


Especificaciones​

El hardware para este tutorial es proporcionado por Seeed Studio.

ParámetroEspecificación
Modelo de brazoreBot Arm B601-RS Kit ensamblado con gripper
DOF6+1 (incluyendo gripper)
Radio de trabajo754.7 mm (con gripper) / 587.5 mm (sin gripper)
Carga útilNominal 2.5 kg / Máx 5 kg
Rango de articulacionesJ1: ±150° / J2: 220° ~ 0° / J3: 220° ~ 0° / J4: ±90° / J5: ±90° / J6: ±180° / Gripper: 345° ~ 0°
Repetibilidad0.1 mm
Peso6.7 kg
ServomotoresRobStride 06 × 3 / RobStride 00 × 4 (incluyendo gripper)
ComunicaciónBus CAN @ 1 Mbps
Tensión de alimentaciónDC 48V
Fuente de alimentaciónDC 48V 15A
Temperatura de funcionamiento-20°C ~ 50°C
ControlPC

Asignación de motores en este proyecto​

ArticulaciónID CANModeloNotas
J11RS06Base
J22RS06
J33RS06
J44RS00
J55RS00
J66RS00Muñeca
J77RS00Gripper del efector final

Capacidades de software (este repositorio)​

CapacidadEstado
Control de posición MIT✅
Límites de velocidad por articulación✅
Control del gripper (ID CAN 7)✅
Monitorización de temperatura MOS y protección de tres niveles✅
Retorno seguro a cero / deshabilitado de emergencia✅
Configuración YAML✅
API de biblioteca en Python✅
Cinemática directa / inversa (Pinocchio)❌ (ver reBotArm_control_py)
Simulación MeshCat❌ (ver repositorio anterior)

Parámetros de los motores de las articulaciones​

ParámetroRobStride 00RobStride 06
Tensión nominal48V48V
Corriente nominal4.7 Apk ± 10%14.3 Apk ± 10%
Corriente pico15.5 Apk ± 10%57 Apk ± 10%
Par nominal5 N.m11 N.m
Par pico14 N.m36 N.m
Velocidad nominal100 rpm ± 10%100 rpm ± 10%
Velocidad máxima en vacío315 rpm ± 10%480 rpm ± 10%
Relación de reducción10 : 19 : 1
Interfaz de controlCAN @ 1 MbpsCAN @ 1 Mbps
Modos de controlMIT / Velocidad / Posición / ParMIT / Velocidad / Posición / Par

Lista de materiales (BOM)​

ÍtemCantidadIncluido
reBot Arm B601-RS1✅
Adaptador CAN (CANABLE / PCAN-USB, etc.)1✅
Fuente de alimentación (DC 48V 15A)1✅
Cable USB-C1✅
Gripper1✅

Requisitos​

ÍtemRequisito
Python3.10+
SOUbuntu 22.04+ (recomendado)
Interfaz CANcan0 por defecto
AlimentaciónDC 48V 15A
Dependenciasmotorbridge, pyyaml; opcional pynput (tecla Esc)

Instalación​

Paso 1. Clonar el repositorio​

git clone https://github.com/LAN-GER/rebot_control.git
cd rebot_control

Paso 2. Instalar dependencias​

pip install motorbridge pynput pyyaml
tip

pynput habilita la escucha de la tecla Esc. Sin él, solo Esc queda deshabilitada; Ctrl+C y arm.stop() siguen funcionando.

Paso 3. Configurar la interfaz CAN​

# List interfaces (PCAN-USB, etc.)
sudo modprobe peak_usb # if using a PEAK adapter
ip -br link

# Set can0 to 1 Mbps (RobStride default)
sudo ip link set can0 down 2>/dev/null
sudo ip link set can0 up type can bitrate 1000000
precaución

Después de desconectar y volver a conectar un adaptador CAN USB, normalmente necesitas ejecutar de nuevo los comandos ip link.

Paso 4. (Opcional) Editar el archivo de configuración​

Edita config/rebotarm_rs.yaml:

ClaveDescripciónValor por defecto
can.channelNombre de la interfaz CANcan0
can.host_idID del host0xFD
control.control_hzFrecuencia de comandos MIT (no velocidad de movimiento)200 Hz
control.telemetry_hzFrecuencia de lectura de temperatura2 Hz
temperatures.alarm_cUmbral de alarma de temperatura80°C
temperatures.return_zero_cUmbral de retorno a cero por sobretemperatura125°C
temperatures.disconnect_cUmbral de deshabilitado de emergencia140°C
return_zero.max_speed_deg_sVelocidad pico normal de retorno a cero30°/s
return_zero.thermal_max_speed_deg_sVelocidad pico térmica de retorno a cero30°/s
return_zero.min_time_sDuración mínima de retorno a cero3.0 s
return_zero.settle_time_sTiempo de mantenimiento en cero después del retorno0.30 s
motorsID / modelo del motor / MIT kp / kdVer YAML

Las claves que faltan usan valores por defecto en el código; las claves desconocidas generan un error para detectar errores tipográficos.


Estructura del código​

rebot_control/
├── config/
│ └── rebotarm_rs.yaml # CAN / motors / temperature / return-to-zero
├── rebot/
│ ├── __init__.py # Public API
│ ├── config.py # Config loading and validation
│ └── controller.py # ReBotRSMITController
└── examples/
├── _bootstrap.py # Path setup + wait-for-target helpers
├── quick_start.py # Tutorial 1: quick start
├── custom_config.py # Tutorial 2: custom config
├── monitor_status.py # Tutorial 3: monitor status
├── single_joint_adjust.py # Tutorial 4: single joint + gripper
├── read_joint_angles.py # Tutorial 5: read actual positions
├── stop_options.py # Tutorial 6: stop options
├── recommended_structure.py # Tutorial 7: recommended structure
└── mit_position_control.py # Full editable demo

Capas:

  • Archivo de configuración: única fuente de parámetros ajustables.
  • Capa de configuración: load_config() → ControllerConfig.
  • Capa de API: lógica de control sin valores de demostración codificados.
  • Capa de ejemplos: ángulos objetivo, velocidades y flujo de ejecución.

Cómo funciona​

Control MIT y suavizado de velocidad​

  • control_hz (200 Hz por defecto) establece solo la frecuencia de envío de comandos.
  • La velocidad real de movimiento proviene de set_max_speeds([...]) (deg/s).
  • set_joint_angles() solo actualiza los objetivos; el bucle de control incrementa los ángulos de comando hacia los objetivos bajo el límite de velocidad.
tip

Si llamas a stop() inmediatamente después de establecer los objetivos, puede que veas casi ningún movimiento. Los ejemplos usan wait_for_command_targets() (ver examples/_bootstrap.py) para esperar hasta que los ángulos de comando se acerquen a los objetivos antes de volver a cero.

Secuencia de conexión y habilitación​

Dentro de connect(), el orden es: registrar motores → cambiar al modo MIT → habilitar → leer posiciones mecánicas actuales (para inicializar los objetivos y evitar un salto repentino después de habilitar). RobStride mechPos (0x7019) se puede leer de forma fiable después de habilitar.

Para lectura pasiva de posición (Tutorial 5), llama a disable_motors() después de connect() para que puedas mover el brazo a mano y seguir leyendo ángulos.

Protección de temperatura de tres niveles​

Umbral (predeterminado)Comportamiento
≥ 80°CAlarma de temperatura (una vez por motor por cada cruce de sobretemperatura), continúa funcionando
≥ 125°CDetener el movimiento, retorno lento a cero a velocidad térmica máxima, luego deshabilitar
≥ 140°CDeshabilitado de emergencia inmediato, sin retorno a cero

Retorno a cero seguro​

El retorno a cero usa una trayectoria smoothstep. Duración:

duration = max(min_time_s, per-joint time estimated from peak speed)

La velocidad máxima es max_speed_deg_s (normal) o thermal_max_speed_deg_s (térmica). Ambas son por defecto 30°/s; min_time_s tiene como valor predeterminado 3.0 s.

Método de salidaComportamiento
Esc / primer Ctrl+C / arm.stop()Retorno lento a cero → deshabilitar → cerrar CAN
Segundo Ctrl+C durante el retorno a ceroAbortar el retorno a cero y deshabilitar inmediatamente
Error de comunicaciónDeshabilitado de emergencia, sin retorno a cero

Unidades​

ContextoUnidades
API externa (ángulos, velocidades)grados, deg/s
Internos MIT de MotorBridgeradianes, rad/s

Tutoriales​

Ejecuta todos los ejemplos desde la raíz del proyecto. Cada script documenta el Movimiento esperado al principio e imprime una línea [Expected / 预期] al iniciar.

TutorialArchivoComando
1. Inicio rápidoexamples/quick_start.pypython3 examples/quick_start.py
2. Configuración personalizadaexamples/custom_config.pypython3 examples/custom_config.py
3. Monitorizar estadoexamples/monitor_status.pypython3 examples/monitor_status.py
4. Articulación única + pinzaexamples/single_joint_adjust.pypython3 examples/single_joint_adjust.py
5. Leer posicionesexamples/read_joint_angles.pypython3 examples/read_joint_angles.py
6. Opciones de paradaexamples/stop_options.pypython3 examples/stop_options.py default
7. Estructura del programaexamples/recommended_structure.pypython3 examples/recommended_structure.py
Demo completaexamples/mit_position_control.pypython3 examples/mit_position_control.py

1. Inicio rápido (quick_start.py)​

Movimiento esperado: J1 se mueve a +20° a ~15°/s; las otras articulaciones y la pinza permanecen en 0°; luego retorno lento a cero y deshabilitar.

python3 examples/quick_start.py

Flujo: start() → set_max_speeds() → set_joint_angles() → esperar al movimiento → stop().


2. Archivo de configuración personalizada (custom_config.py)​

python3 examples/custom_config.py
python3 examples/custom_config.py config/rebotarm_rs.yaml

Movimiento esperado: J1 → +15° (~15°/s), las demás en 0°, luego retorno a cero.


3. Monitorizar mientras se ejecuta (monitor_status.py)​

python3 examples/monitor_status.py

Movimiento esperado: J1 → +30°; la terminal imprime continuamente objetivo / enviado / temperatura del MOS. Pulsa Esc o Ctrl+C para salir y volver a cero.

Notas:

  • Objetivo vs enviado: los ángulos enviados van con retraso respecto a los objetivos (suavizado limitado por velocidad).
  • Temperatura: lee arm.last_temperatures; no necesitas sondear el bus CAN tú mismo.

4. Ajuste de articulación única y pinza (single_joint_adjust.py)​

python3 examples/single_joint_adjust.py

Objetivos predeterminados:

J1J2J3J4J5J6J7 Pinza
+25°+15°+15°-15°0°0°180°

joint_id: 1–6 son articulaciones del brazo; 7 es la pinza (ID CAN 7).


5. Leer posiciones reales (read_joint_angles.py)​

python3 examples/read_joint_angles.py

Movimiento esperado:

  1. connect(): cambiar al modo MIT y habilitar (establecer comunicación), leer los ángulos actuales como valores iniciales de objetivo.
  2. disable_motors(): deshabilitar inmediatamente para que puedas mover el brazo a mano.
  3. La terminal imprime los ángulos reales de las articulaciones a ~30 Hz; los valores deberían cambiar cuando muevas el brazo.
  4. Pulsa Ctrl+C para salir; stop(return_to_zero=False) cierra CAN sin retorno a cero.

Este ejemplo no llama a start(), por lo que no se ejecuta ningún hilo de control MIT y no se envían objetivos de movimiento.

Flujo del código:

arm.connect()           # MIT → enable → read current angles
arm.disable_motors() # disable — arm can be moved by hand

while True:
actual = arm.read_joint_angles() # ~30 Hz
print(actual)

# After Ctrl+C
arm.stop(return_to_zero=False, wait=True)
tip

read_joint_angles() accede al bus CAN de forma síncrona (lee mechPos de los 7 motores en secuencia), por lo que la frecuencia alcanzable depende del tiempo de ida y vuelta del bus. El ejemplo apunta a 30 Hz; si cada lectura tarda más, la frecuencia real será menor. Mientras el control MIT está en ejecución, usa get_command_angles() para monitorizar el movimiento comandado en lugar de llamar a read_joint_angles() a alta frecuencia.


6. Opciones de parada segura (stop_options.py)​

Cada modo primero mueve J1 a ~+20°, luego se detiene según el modo:

python3 examples/stop_options.py default      # slow return-to-zero (recommended)
python3 examples/stop_options.py no_return # disable without return-to-zero
python3 examples/stop_options.py async # stop(wait=False) + wait_until_stopped()
python3 examples/stop_options.py emergency # emergency disable, no return-to-zero
peligro

no_return / emergency dejan el brazo en una pose distinta de cero y deshabilitan los motores. Asegúrate de que el área sea segura; sujeta el brazo con la mano si es necesario.


Demuestra try / except / finally para que stop() se ejecute incluso en caso de errores.

python3 examples/recommended_structure.py

Demo completa de parámetros (mit_position_control.py)​

Edita TARGET_ANGLES (longitud 7) y JOINT_SPEEDS_DEG_S al principio del archivo, luego ejecuta:

python3 examples/mit_position_control.py

Predeterminado: J1 → +50° (20°/s), las demás y la pinza en 0°; la terminal muestra objetivo / enviado / temperatura; Esc / Ctrl+C sale con retorno a cero.

peligro

El brazo puede moverse rápidamente en modo MIT. Mantén a las personas y al equipo alejados, y permanece dentro de aproximadamente el 70% del espacio de trabajo.


Uso como biblioteca​

Ejemplo mínimo​

from rebot import ReBotRSMITController

arm = ReBotRSMITController() # loads config/rebotarm_rs.yaml

arm.start(enable_esc=True)
arm.set_max_speeds([15.0] * 7)
arm.set_joint_angles([20.0, 0, 0, 0, 0, 0, 0]) # J1–J6 + gripper J7

# Wait for motion to finish before stop; see examples/quick_start.py
arm.stop() # slow return-to-zero → disable → close CAN

Configuración personalizada y pinza​

from rebot import (
ReBotRSMITController,
load_config,
GRIPPER_JOINT_ID,
)

arm = ReBotRSMITController(load_config("config/rebotarm_rs.yaml"))
arm.start()
arm.set_max_speeds([20.0] * 7)
arm.set_joint_angles([25, 15, 15, -15, 0, 0, 0])
arm.set_joint_angle(GRIPPER_JOINT_ID, 180.0) # gripper = J7

Lectura pasiva de posición​

from rebot import ReBotRSMITController

arm = ReBotRSMITController()
arm.connect() # MIT → enable → read current angles
arm.disable_motors() # disable — move arm by hand

actual = arm.read_joint_angles()
print(actual)

arm.stop(return_to_zero=False, wait=True) # close CAN, no return-to-zero

Ciclo de vida del controlador​

Control de movimiento MIT:

create → start() → set_max_speeds() → set_joint_angles() / set_joint_angle() → … → stop()

Lectura pasiva de posición (sin movimiento ordenado):

create → connect() → disable_motors() → read_joint_angles() → … → stop(return_to_zero=False)

API principal​

Método / atributoDescripción
connect()Conecta CAN, modo MIT, habilita, lee ángulos actuales; se llama automáticamente mediante start()
disable_motors()Deshabilita todos los motores sin cerrar CAN (para lectura pasiva)
start(enable_esc=True, install_signal_handlers=True)Inicia los hilos de control y temperatura
set_joint_angles(angles_deg)Establece 7 ángulos objetivo (grados)
set_joint_angle(joint_id, angle_deg)Establece una articulación / pinza (1–7)
set_max_speeds(speeds_deg_s)Establece 7 velocidades máximas (grados/s)
get_target_angles() / get_command_angles()Ángulos objetivo / de comando suavizados
read_joint_angles()Lectura síncrona de posiciones mecánicas reales (grados); usa CAN
last_temperaturesTemperatura MOS por motor
is_stoppedIndica si el apagado seguro ha finalizado
stop(return_to_zero=True, wait=True)Detiene (vuelve a cero por defecto)
request_stop(..., emergency=True)Parada avanzada / deshabilitado de emergencia

Constantes exportadas: GRIPPER_MOTOR_ID = 7, GRIPPER_JOINT_ID = 7.


Preguntas frecuentes (FAQ)​

  • Permission denied / no se puede abrir can0
    Asegúrate de que la interfaz CAN esté up y de que tu usuario pueda acceder a dispositivos de red. Usa sudo para ip link si es necesario, o revisa las reglas de udev.

  • Sin respuesta del motor / fallo al habilitar

    1. Confirma que la tasa de bits es 1 Mbps;
    2. Confirma que channel, host_id y los IDs de motor en config/rebotarm_rs.yaml coinciden con el hardware;
    3. Vuelve a ejecutar ip link después de reconectar el USB CAN.
  • Se establecen ángulos pero el brazo apenas se mueve
    set_joint_angles() solo actualiza los objetivos. Establece set_max_speeds() razonables y espera hasta que los ángulos de comando se acerquen a los objetivos antes de stop(). Consulta examples/quick_start.py.

  • La pinza no se mueve
    La pinza es J7 / ID CAN 7. Pasa 7 valores a set_joint_angles (el último es la pinza), o usa set_joint_angle(7, angle).

  • Tiempo de espera al leer posición / no se pueden leer ángulos
    mechPos se puede leer de forma fiable en modo MIT después de habilitar. El Tutorial 5 usa connect() y luego disable_motors() para que puedas mover el brazo a mano y seguir leyendo. Si ensure_mode o las lecturas de parámetros agotan el tiempo de espera, revisa el cableado CAN, la terminación y la alimentación de los motores.

  • Spam de alarma de temperatura
    Las alarmas se disparan por flancos con histéresis: una alarma por motor por evento de sobretemperatura; se vuelve a alarmar solo después de que la temperatura baje por debajo de alarm_c - 2°C.

  • Protección contra bloqueo de la articulación 2 / el brazo cae
    A menudo es causado por permanecer más allá de ~70% de extensión del espacio de trabajo. Apaga y enciende para borrar la protección y reduce los ángulos objetivo y el tiempo de permanencia.

  • Comportamiento tras errores de comunicación
    Ante un fallo de comunicación en el bucle de control, el programa deshabilita de emergencia sin volver a cero para evitar movimiento bajo malas comunicaciones.

  • Pinocchio / MeshCat / compensación de gravedad
    Este repositorio se centra en el control de posición MIT. Para cinemática, simulación y compensación de gravedad, consulta reBotArm_control_py y la guía de Pinocchio y MeshCat en el Wiki de Seeed.


Contacto​


Referencias​

Loading Comments...