Saltar al contenido principal

Introducción al control de posición MIT en reBot Arm B601-RS

License: MITPython VersionPlatformMIT Mode

6+1 GDL · RobStride · CAN @ 1 Mbps · Control de posición MIT · Protección de temperatura · Retorno seguro a cero · API de Python de código abierto

traj_sim_geodesic

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 de seguridad importante
  • 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 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 brazoKit ensamblado reBot Arm B601-RS con gripper
GDL6+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 articulaciónJ1: ±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ónCC 48V
Fuente de alimentaciónCC 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)

FunciónEstado
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 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 (CC 48V 15A)1
Cable USB-C1
Gripper1

Requisitos

ÍtemRequisito
Python3.10+
SOUbuntu 22.04+ (recomendado)
Interfaz CANcan0 por defecto
AlimentaciónCC 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([...]) (grados/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 a modo MIT → habilitar → leer posiciones mecánicas actuales (para inicializar los objetivos y evitar un salto repentino después de habilitar). El mechPos (0x7019) de RobStride 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 (por defecto)Comportamiento
≥ 80°CAlarma de temperatura (una vez por motor por cruce de sobretemperatura), continuar en funcionamiento
≥ 125°CDetener el movimiento, retorno lento a cero a velocidad pico térmica y luego deshabilitar
≥ 140°CDeshabilitado de emergencia inmediato, sin retorno a cero

Retorno seguro a cero

El retorno a cero utiliza 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 tienen como valor predeterminado 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 ceroAborta el retorno a cero y deshabilita inmediatamente
Error de comunicaciónDeshabilitado de emergencia, sin retorno a cero

Unidades

ContextoUnidades
API externa (ángulos, velocidades)grados, deg/s
Internos de MotorBridge MITradianes, 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
Demostración 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 demás 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 movimientostop().


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 una sola articulación y pinza (single_joint_adjust.py)

python3 examples/single_joint_adjust.py

Objetivos predeterminados:

J1J2J3J4J5J6J7 Pinza
+25°+15°+15°-15°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(): cambia al modo MIT y habilita (establece la comunicación), lee los ángulos actuales como semillas de objetivo.
  2. disable_motors(): deshabilita 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 el bus 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

Demostración 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 el 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 comandado):

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 los ángulos actuales; llamado automáticamente por start()
disable_motors()Deshabilita todos los motores sin cerrar el bus CAN (para lectura pasiva)
start(enable_esc=True, install_signal_handlers=True)Inicia los hilos de control y de 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 (deg/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 del MOS por motor
is_stoppedIndica si la parada segura ha finalizado
stop(return_to_zero=True, wait=True)Detiene (retorno 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

  • Permission denied / no se puede abrir can0
    Asegúrate de que la interfaz CAN esté up y de que tu usuario pueda acceder a los 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 velocidad de transmisión es 1 Mbps;
    2. Confirma que channel, host_id y los IDs de los motores 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 / CAN ID 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...