Guía para Desarrolladores del Simulador Web reBot Arm B601-DM y ROS2/MuJoCo

Visualización con Three.js · Carga de URDF · Puente rosbridge · Control LLM/MCP
Esta guía está dirigida a desarrolladores. Explica cómo ejecutar y ampliar el simulador web reBotArm_simulator-DM. El simulador es una consola web ligera basada en Node.js + Three.js que lee el URDF y las mallas STL desde el workspace de ROS2 en el mismo repositorio, renderiza en el navegador el cuerpo de 6 GDL y el efector final del reBot Arm B601-DM, y se comunica con ROS2 a través de un WebSocket de rosbridge. Admite todo el flujo de trabajo de desarrollo: espejado de articulaciones, bloqueo de control, compensación de gravedad, agarre visual y control por texto mediante LLM.
Esta guía utiliza Ubuntu 24.04 + ROS2 Jazzy como backend de ROS2. El front-end web se ejecuta en cualquier navegador moderno en Windows, macOS o Linux. ROS2 Humble / Ubuntu 22.04 pueden seguir el mismo flujo de trabajo.
Funciones del Proyecto
-
Front-end sin compilación
No depende de empaquetadores como Webpack/Vite. Todos los recursos de front-end son HTML/CSS/JS simples servidos directamente por un servidor estático de Node.js, lo que mantiene muy bajos los costes de despliegue y depuración. -
Carga directa de URDF + STL
URDFLoaderleereBot-DevArm_fixend.urdfy las mallas STL del cuerpo del brazo desdesrc/rebotarm_bringup/description/en el workspace de ROS2 del mismo repositorio, por lo que el modelo del cuerpo no necesita una segunda copia en el directorio web. Las mallas visuales del efector final se almacenan por separado ensplit_meshes/grouped_gripper/en el directorio web, porque el URDF termina enend_link. -
Puente rosbridge bidireccional
ReBotRosClientencapsula el protocolo JSON de rosbridge y se suscribe al estado de las articulaciones, estado del efector final, estado del brazo, imagen de la cámara virtual y resultados de detección de visión, y publica comandos de articulación única, comandos del efector final y poses objetivo. -
Control por texto con LLM/MCP
La página web no llama a ROS directamente. En su lugar, hace proxy a través del servidor Node.js hacia un servicio HTTP de agente de texto que se ejecuta en la VM, y un Servidor MCP restringe la intención en lenguaje natural a operaciones estructuradas del robot. -
Instalación con un clic y lanzamiento unificado
setup.shinstala automáticamente las dependencias del sistema, clona el SDK, crea el entorno virtual de Python, instala las dependencias y ejecutacolcon build. El punto de entrada unificadorebotarmproporciona comandos comostart web / dm / sim,doctor,statusystop. Es idempotente: los componentes que ya existen y cumplen los requisitos se omiten automáticamente.
Notas sobre Cableado y Red
El propio simulador web no se conecta directamente al hardware. Todos los comandos de control se reenvían a ROS2 a través de rosbridge. Deben confirmarse dos cosas:
- Lado del host Ubuntu: El puente serie USB2CAN conecta el bus CAN del brazo, el motor del efector final está en el mismo bus CAN y la alimentación de 24 V está conectada. Confirma que el host reconoce el puerto serie:
ls /dev/ttyACM*
Salida esperada
/dev/ttyACM0
Ver /dev/ttyACM0 (o ttyACM1, etc.) en la lista significa que se ha reconocido el puerto serie.
- Lado del host web: Confirma que puedes alcanzar el puerto rosbridge del host Ubuntu (por defecto
9090). Prueba la conectividad WebSocket desde el navegador o la terminal del host web, por ejemplo:
# Confirm the Ubuntu host IP is reachable
ping <Ubuntu IP>
# Confirm the rosbridge port is open (rosbridge must already be running on Ubuntu)
curl -i http://<Ubuntu IP>:9090
Si necesitas abrir temporalmente los permisos del puerto serie (en el lado de Ubuntu):
sudo chmod 666 /dev/ttyACM0
Es mejor añadir el usuario actual al grupo dialout, lo que surtirá efecto tras volver a iniciar sesión:
sudo usermod -a -G dialout $USER
Requisitos de Entorno
| Elemento | Recomendado |
|---|---|
| Sistema operativo (backend) | Ubuntu 24.04; Ubuntu 22.04 también funciona |
| ROS2 | Jazzy; Humble también funciona |
| Python | Python del sistema, 3.12 para Jazzy |
| Node.js | 18 o superior |
| Navegador | Chrome / Edge 90+, Firefox 90+, Safari 14+ |
| MuJoCo (opcional) | 3.10+, solo necesario para la pila completa de simulación física |
Pasos de Instalación
Paso 0. Completar la configuración básica del brazo
Antes de comenzar el desarrollo del simulador web, completa los pasos de reBot Arm B601-DM Quick Start, incluyendo el montaje del brazo, la configuración de los ID de los motores, la inicialización del punto cero y las comprobaciones básicas de conectividad.
El repositorio del proyecto ya contiene el workspace de ROS2, el URDF y las mallas STL requeridas por el simulador web. No necesitas construir otro workspace siguiendo la guía reBot Arm B601-DM ROS2 Integration.
reBotArm_control_py es la dependencia externa principal, que proporciona drivers para el robot real, cinemática inversa, cálculo de dinámica y compensación de gravedad. El simulador web no importa este SDK directamente, pero el nodo de robot real rebotarmcontroller en el backend ROS2, el bucle de par de MuJoCo y la función de compensación de gravedad dependen de él. Si solo ejecutas el modo de simulación pura con Fake Driver + web, el SDK no es necesario; en cuanto quieras controlar el robot real o usar la compensación de gravedad, debe estar instalado.
setup.sh obtiene automáticamente el SDK desde reBotArm_control_py y lo instala en ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main/third_party/reBotArm_control_py/ (fijado a un commit verificado). Si ~/reBotArm_control_py/ ya existe, se detecta automáticamente y no se clona de nuevo.
Estructura de directorios después de la instalación:
reBotArm_control_py/
├─ reBotArm_control_py/
│ ├─ actuator/ RebotArm class, JointGroup, motor control
│ ├─ controllers/ RebotArmEndPose (trajectory, IK, gravity compensation)
│ ├─ kinematics/ forward/inverse kinematics, load_robot_model, pad_q_for_model
│ └─ dynamics/ dynamics functions such as compute_generalized_gravity
├─ config/
│ └─ rebotarm_dm.yaml DM motor config (ID, baud rate, limits, PID)
├─ urdf/ Pinocchio dynamics model URDF
└─ pyproject.toml
El pyproject.toml del SDK declara requires-python >=3.10,<3.12, pero este proyecto lo referencia mediante sys.path en lugar de instalarlo con pip, por lo que funciona correctamente en Python 3.12. Si pip install -e . informa de un conflicto de versión, omite ese paso y solo asegúrate de que el directorio esté en reBotArmController_ROS2-main/third_party/reBotArm_control_py/ o ~/reBotArm_control_py/ (el código busca automáticamente en estas rutas).
Paso 1. Instalación con un clic
El proyecto open source oficial de reBot Arm está disponible en Seeed-Projects/reBot-DevArm. El simulador web, el workspace de ROS2 y el código de simulación MuJoCo utilizados en esta guía están alojados en Yang-Ci/Borot-Arm_Mujoco. Clona el repositorio de software en ~/reBot_Arm_Mujoco-DM/:
git clone https://github.com/Yang-Ci/Borot-Arm_Mujoco.git ~/reBot_Arm_Mujoco-DM
cd ~/reBot_Arm_Mujoco-DM
El setup.sh en la raíz del repositorio es idempotente y configura automáticamente todo el entorno:
- Instala los paquetes de sistema apt que falten (ROS 2, Node.js, ros-dev-tools, etc.)
- Clona el SDK
reBotArm_control_pyenthird_party/(se omite si ya existe) - Crea el entorno virtual de Python (
reBotArmController_ROS2-main/.venv, con--system-site-packages) - Instala las dependencias de Python desde
requirements.txt - Crea el
.envweb a partir de.env.example - Ejecuta la resolución de dependencias
rosdepycolcon build --symlink-install
./setup.sh
El instalador es idempotente: los componentes que ya existen y cumplen los requisitos se omiten, y nunca elimina el SDK existente, el entorno virtual ni el .env web; solo se instalan los elementos que faltan. Al final resume los elementos instalados, omitidos, con versiones no coincidentes y fallidos.
Solo comprobación, sin modificar el sistema:
./setup.sh --check
Después de la instalación, ejecuta diagnósticos para confirmar que el entorno está listo:
./rebotarm doctor
Salida esperada (resumen)
[rebotarm-setup] Checking supported platform
[rebotarm-setup] Checking runtime versions
[rebotarm-setup] Checking reBotArm_control_py SDK
[rebotarm-setup] Checking project virtual environment
[rebotarm-setup] Checking web configuration
[rebotarm-setup] Resolving ROS dependencies and building the workspace
Installed/updated (6)
- apt nodejs
- SDK ...
- virtual environment ...
- Python requirements checked/updated in project venv
- created .env from example
- ROS workspace built with colcon
Already usable; skipped (5)
- Ubuntu 24.04 supported
- Python 3.12.3 compatible
- Node.js v18.19.0 compatible
- existing SDK preserved
- critical Python and SDK imports pass
Setup complete. Next:
./rebotarm doctor
./rebotarm start web
./rebotarm start dm
Un mensaje Setup complete con una sección Failed or still missing vacía significa que todo se ha realizado correctamente.
Si setup.sh no instala automáticamente ROS 2 (por ejemplo, porque la fuente apt de ROS aún no se ha añadido al sistema), el instalador descarga automáticamente el paquete oficial ros2-apt-source desde GitHub, añade la fuente y vuelve a intentarlo. No necesitas configurar manualmente la fuente apt.
Paso 2. Configurar las variables de entorno
setup.sh ya creó .env a partir de .env.example. Para cambiar el puerto o el destino del proxy, edita .env:
# reBotArm_simulator-DM/.env key fields
PORT=3001
REBOTARM_TEXT_AGENT_URL=http://localhost:8082
REBOTARM_MCP_URL=http://localhost:8081/mcp
Si la página web se ejecuta en Windows y ROS2 se ejecuta en una máquina virtual de Ubuntu, cambia REBOTARM_TEXT_AGENT_URL y REBOTARM_MCP_URL a la IP real de la máquina virtual de Ubuntu, por ejemplo http://<Ubuntu IP>:8082.
Paso 3. Iniciar el servidor web
cd ~/reBot_Arm_Mujoco-DM
./rebotarm start web
Este comando carga automáticamente el entorno de ROS2 y arranca rosbridge (reutilizando un listener existente si el puerto ya está en uso) y el servidor web de Node.js. Después de iniciarse, la terminal imprime la URL de acceso:
ROS WebSocket: ws://localhost:9090 (started by this command)
Web: http://localhost:3001
Ctrl+C stops processes started by this command.
Abre http://localhost:3001 en un navegador y espera a que terminen de cargarse el URDF y el STL; la aparición del modelo 3D significa que el front-end está funcionando. La página ya está conectada al rosbridge local por defecto, así que puedes operar directamente en el panel "ROS2 Bridge".
Si solo quieres ejecutar una demo web pura (sin iniciar rosbridge), también puedes iniciarla manualmente desde el directorio web:
cd ~/reBot_Arm_Mujoco-DM/reBotArm_simulator-DM
node server.js
En este caso la página te permite arrastrar los deslizadores de las articulaciones, usar preajustes de pose y arrastre del TCP, pero no se conectará a ningún nodo ROS.
Puesta en marcha del proyecto
El comando ./rebotarm carga internamente el entorno, por lo que no necesitas ejecutar manualmente source scripts/source_rebotarm_env.sh. Sin embargo, si ejecutas directamente comandos ros2 sin envoltorio, cada nueva terminal sigue necesitando cargar el entorno primero.
- Demo web pura
- Simulación con Fake Driver
- Simulación física completa
- Control del robot real
La forma más ligera de ejecutar: solo se inicia el servidor web, sin conexión ROS2. Es adecuado para demostración de poses, enseñanza y desarrollo de la interfaz:
cd ~/reBot_Arm_Mujoco-DM/reBotArm_simulator-DM
node server.js
Abre http://localhost:3001 en un navegador. Puedes arrastrar los deslizadores de las articulaciones, usar preajustes de pose, arrastre del TCP y enseñanza-grabación, pero todas las operaciones solo afectan al modelo 3D y no accionarán ningún hardware ni nodo ROS.

Inicia el Fake Driver, rosbridge y el servidor web. La página web refleja el estado de las articulaciones a través de rosbridge y envía comandos de control. Es útil para verificar interfaces, direcciones de las articulaciones y límites.
Terminal 1 — iniciar el Fake Driver:
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
source scripts/source_rebotarm_env.sh
ros2 launch rebotarm_bringup fake_bringup.launch.py
Terminal 2 — iniciar rosbridge + web (un solo comando):
cd ~/reBot_Arm_Mujoco-DM
./rebotarm start web
Después de que la página se conecte a ws://localhost:9090, marca "Mirror real joint state to the web" para ver el estado de las articulaciones del Fake Driver sincronizado con el modelo 3D. Tras marcar "Allow the web to send control to the real arm", los deslizadores de las articulaciones y el movimiento de Pose enviarán comandos a través de rosbridge.

Un solo comando inicia toda la pila: Fake Driver, simulación física de agarre con MuJoCo, servidor de tareas, cámara virtual, detector de color y rosbridge:
cd ~/reBot_Arm_Mujoco-DM
./rebotarm start sim
Salida esperada
[rebot-mujoco-all] starting fake_bringup...
[rebot-mujoco-all] starting mujoco_physics_grasp...
[rebot-mujoco-all] starting sim_task_server...
[rebot-mujoco-all] starting sim_rgb_camera...
[rebot-mujoco-all] starting sim_color_detector...
[rebot-mujoco-all] starting rosbridge_websocket on :9090...
Todos los nodos se inician en secuencia; si no hay ningún ERROR, se considera correcto.
Este script es internamente equivalente a reBotArmController_ROS2-main/scripts/start_rebot_mujoco_all.sh. De forma predeterminada inicia el Fake Driver, robot_state_publisher, la simulación física de agarre con MuJoCo, el servidor de tareas, la cámara RGB cenital, el detector de color y rosbridge. Luego ejecuta ./rebotarm start web en otra terminal para iniciar la página web. Después de que el navegador se conecte a ROS, puedes usar la demo de agarre visual.

El modo de robot real inicia el bringup/controlador real y rosbridge, y la página web controla a través de la misma interfaz ROS. Se recomienda primero verificar interfaces, direcciones de las articulaciones y límites con el Fake Driver antes de cambiar al robot real a baja velocidad:
# Before starting, confirm the device node and grant permissions
ls /dev/ttyACM0
sudo chmod 666 /dev/ttyACM0
# Start the real-robot driver (auto-sources the environment)
cd ~/reBot_Arm_Mujoco-DM
./rebotarm start dm
En otra terminal, inicia rosbridge + web:
cd ~/reBot_Arm_Mujoco-DM
./rebotarm start web
Cuando estés conectado al controlador del robot real, los comandos web accionan hardware real. Verifica siempre primero las direcciones y los límites de las articulaciones con el Fake Driver. Al usar el robot real por primera vez, prueba la articulación final con movimientos pequeños. Si algo es anómalo, haz clic inmediatamente en "Disable" o cancela el bloqueo de control. No confíes solo en las casillas de verificación de la web; mantén un paro de emergencia, límites y aislamiento del espacio operativo en el lugar.
Arquitectura del proyecto
reBot_Arm_Mujoco-DM/
├─ setup.sh Idempotent one-click install and version check
├─ rebotarm Unified entry for start, stop, status, and diagnostics
├─ requirements.txt Python dependency version ranges
├─ PROJECT_ARCHITECTURE_ZH.md Overall architecture, simulation principles, and debouncing notes
├─ reBotArmController_ROS2-main/ ROS 2 workspace
│ ├─ scripts/ One-click launch scripts and environment loading
│ ├─ third_party/ reBotArm_control_py SDK for fresh installs
│ ├─ .venv/ Project Python virtual environment (created by setup.sh)
│ └─ src/
│ ├─ rebotarm_msgs/ Custom msg/srv/action
│ ├─ rebotarmcontroller/ Real-robot driver, Fake Driver, hardware management
│ ├─ rebotarm_bringup/ URDF, STL, launch, motor config
│ ├─ rebotarm_mujoco/ MuJoCo simulation, IK, camera, vision
│ ├─ rebotarm_agent/ MCP Server and text agent
│ ├─ rebotarm_moveit_config/ MoveIt 2 configuration
│ └─ rebotarm_moveit_demos/ MoveIt 2 application demos
└─ reBotArm_simulator-DM/ Node.js + Three.js web console
├─ public/ Pages, styles, front-end logic
└─ split_meshes/grouped_gripper/ Web gripper meshes
Flujo de datos: el navegador accede al servidor estático de Node.js mediante HTTP /api y se comunica bidireccionalmente con ROS2 a través de rosbridge WebSocket; el lenguaje natural es reenviado por Node.js al Text Agent / MCP Server y luego se convierte en llamadas de herramientas estructuradas que entran en ROS2. ROS2 acciona hacia abajo el driver falso/real y el brazo, y se conecta lateralmente a la simulación física de MuJoCo, al servidor de tareas y a la cámara virtual. La página web, el Agente LLM y el robot real no codifican llamadas directas entre sí; están desacoplados mediante topics, servicios y acciones de ROS2.
El punto de entrada unificado rebotarm es la forma principal de operar el proyecto:
| Comando | Descripción |
|---|---|
./rebotarm start web | Iniciar rosbridge + servidor web (carga automáticamente el entorno) |
./rebotarm start dm | Iniciar el driver de robot real DM (terminal separada, carga automáticamente el entorno) |
./rebotarm start sim | Iniciar toda la pila de simulación MuJoCo (no iniciar junto con el robot real) |
./rebotarm doctor | Comprobación de diagnóstico (equivalente a ./setup.sh --check) |
./rebotarm status | Ver el estado de procesos, puertos, puertos serie y nodos ROS |
./rebotarm stop | Detener los procesos en segundo plano gestionados por start web |
Todos los comandos ./rebotarm ejecutan internamente source scripts/source_rebotarm_env.sh, por lo que no necesitas cargar el entorno manualmente. Sin embargo, si ejecutas directamente comandos ros2 sin envoltorio (como iniciar manualmente un archivo de lanzamiento), aún necesitas cargar el entorno primero:
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
source scripts/source_rebotarm_env.sh
Este script carga, en orden, ROS2 (/opt/ros/jazzy/setup.bash), el entorno virtual de Python (.venv/bin/activate), las rutas de cmeel (extensiones C de Pinocchio) y el workspace (install/setup.bash).
Notas sobre los módulos principales (haz clic para desplegar)
server.js — servidor estático de Node.js
server.js es un servidor HTTP de Node.js sin dependencias. Sus principales responsabilidades:
- Servir los recursos estáticos del front-end bajo
public/; - Leer el URDF y las mallas STL desde el workspace de ROS2 en el mismo repositorio y exponer los endpoints
/api/urdfy/api/description/meshes/<file>; - Servir las mallas del gripper solo web
/api/gripper_meshes/<file>(desdesplit_meshes/grouped_gripper/); - Hacer proxy de las solicitudes de chat del LLM
/api/llm/chaty de la comprobación de estado/api/llm/healthal servicio HTTP del agente de texto en la VM; - Proporcionar el endpoint de configuración MCP
/api/mcp/config, devolviendotextAgentUrlymcpUrl.
Resolución de ruta de clave (server.js):
const BRINGUP_DIR = path.resolve(
path.join(ROOT, '..', 'reBotArmController_ROS2-main', 'src', 'rebotarm_bringup')
);
const URDF_FILE = path.join(BRINGUP_DIR, 'description', 'urdf', 'reBot-DevArm_fixend.urdf');
const MESHES_DIR = path.join(BRINGUP_DIR, 'description', 'meshes');
const GRIPPER_MESHES_DIR = path.join(ROOT, 'split_meshes', 'grouped_gripper');
server.js localiza el espacio de trabajo ROS2 mediante la ruta relativa ../reBotArmController_ROS2-main/.... Si mueves el directorio web a otra ubicación, debes actualizar estas rutas en consecuencia, o mantener una copia del modelo de la misma versión que el espacio de trabajo ROS2 en el directorio web.
rebot-sim.js — núcleo de la escena 3D
rebot-sim.js es el núcleo del front-end (unas 1700 líneas), responsable de:
- Inicializar la escena de Three.js, la cámara, el renderer y el controlador de órbita personalizado;
- Cargar el URDF mediante
URDFLoader;loader.packagesmapeapackage://rebotarm_bringupa${origin}/apipara que las solicitudes de mallas pasen por el endpoint de Node.js; - Adjuntar el grupo visual del gripper solo web (4 STL) al
end_link, con un rango de accionamiento de 0–90mm; - Implementar el solucionador de cinemática inversa DLS (damped least squares)
IKSolver, que admite arrastre del TCP y resolución de pose objetivo; - Proporcionar presets de pose, deslizadores de articulaciones, arrastre del TCP, grabación/reproducción/exportación de enseñanza, estimación del sobre de alcance y objetivo fantasma;
- Exponer la API a través del objeto
window.reBotSimpara querebot-ros-ui.jslo llame.
Definiciones de articulaciones (rebot-sim.js):
const jointDefs = [
{ name: 'joint1', label: 'J1 base yaw', min: -2.8, max: 2.8, home: 0 },
{ name: 'joint2', label: 'J2 shoulder', min: -3.14, max: 0, home: 0 },
{ name: 'joint3', label: 'J3 elbow', min: -3.14, max: 0, home: 0 },
{ name: 'joint4', label: 'J4 wrist pitch', min: -1.87, max: 1.57, home: 0 },
{ name: 'joint5', label: 'J5 wrist yaw', min: -1.57, max: 1.57, home: 0 },
{ name: 'joint6', label: 'J6 tool roll', min: -3.14, max: 3.14, home: 0 },
{ name: 'gripper', label: 'J7 gripper', min: 0, max: 0.09, home: 0, unit: 'm' }
];
El sistema de coordenadas de Three.js en la web difiere del marco ROS. Three.js usa Y hacia arriba por defecto, mientras que ROS usa Z hacia arriba. rebot-sim.js realiza la conversión con threeToRos(v): { x: v.x, y: -v.z, z: v.y }. Al desarrollar funciones de pose personalizadas, debes usar esta conversión, de lo contrario las coordenadas serán incorrectas.
rebot-ros-client.js — cliente rosbridge
ReBotRosClient extiende EventTarget y envuelve el protocolo JSON de rosbridge v2, proporcionando:
connect(url)/disconnect(): gestión de la conexión WebSocket, con reconexión automática (autoReconnect,reconnectDelay);subscribe(topic, type, callback, options): suscribirse a un tópico, con soporte de limitaciónthrottleRate;callService(service, type, args): llamar a un servicio y devolver una Promise;sendActionGoal(actionName, actionType, goal): llamar a una acción mediante/_action/send_goal;- Envolturas de alto nivel:
enable(),disable(),safeHome(),startGravityCompensation(),setGripper(),moveToPose(),solveMoveToPoseIK(),followJointTrajectory(); - Envolturas de publicación:
publishJointCommand(),publishGripperCommand(),publishTargetPose().
El espacio de nombres por defecto es rebotarm, y todas las rutas de tópicos/servicios se prefijan con /rebotarm/.
rebot-ros-ui.js — panel de control ROS
rebot-ros-ui.js (unas 1500 líneas) es la capa de negocio que conecta ReBotRosClient y reBotSim, responsable de:
- Suscribirse al estado de las articulaciones, estado del gripper, estado del brazo, imagen de la cámara virtual, resultados de detección de visión y eventos de animación de simulación;
- Implementar los dos interruptores "Mirror real joint state to the web" y "Allow the web to send control to the real arm";
- Limitación de comandos de articulaciones (
COMMAND_INTERVAL_MS = 45ms) y retención del espejo (MIRROR_HOLD_MS = 1800ms); - Inicio/parada de la compensación de gravedad y consulta de estado;
- Control del gripper y espera hasta alcanzar (
commandGripperAndWait); - Comprobación de IK, movimiento de pose, envío de trayectorias y modo de reproducción de bajo nivel como respaldo;
- El flujo completo de agarre visual (retirada, alineación, pre-descenso, descenso, agarre, elevación, tránsito);
- Eventos de animación de simulación (
attach_object/release_object) que hacen que el gripper web siga al objeto.
El bloqueo de control es una salvaguarda importante contra operaciones accidentales. controlAllowed() comprueba de forma uniforme: cuando ROS no está conectado o el bloqueo de control no está marcado, todos los comandos de control se interceptan y la página solo actualiza el modelo 3D.
rebot-llm.js — interfaz de control de texto LLM
rebot-llm.js implementa la interfaz de chat en lenguaje natural. La cadena es:
web rebot-llm.js
-> Node.js /api/llm/chat
-> Text Agent HTTP service (default :8082)
-> MCP Server (default :8081/mcp)
-> ROS 2 service/action/topic
Al iniciarse primero llama a /api/llm/health para comprobar el estado del agente de texto; tras el éxito habilita el cuadro de entrada. Los mensajes se envían por proxy al agente de texto a través de /api/llm/chat, y el text y los events devueltos (proceso de llamada de herramientas) se renderizan en el área de chat. Al detenerse, envía { text: '__reset__', reset: true } para limpiar el contexto.
Resumen de la interfaz ROS2 (haz clic para expandir)
Las interfaces ROS2 clave a las que el simulador web se suscribe y publica se enumeran a continuación. El espacio de nombres por defecto es rebotarm.
Tópicos suscritos
| Tópico | Tipo | Descripción |
|---|---|---|
/rebotarm/joint_states | sensor_msgs/msg/JointState | Posición en tiempo real de 6 articulaciones + gripper |
/rebotarm/gripper/state | rebotarm_msgs/msg/JointMotorState | Posición/velocidad/par del gripper |
/rebotarm/arm_status | rebotarm_msgs/msg/ArmStatus | Habilitación, modo, máquina de estados |
/rebotarm/mujoco/overhead_rgb/image_raw | sensor_msgs/msg/Image | Imagen de la cámara RGB cenital del escritorio |
/rebotarm/vision/color_blocks/detections | std_msgs/msg/String | Resultado de detección de bloques de color (JSON) |
/rebotarm/sim/animation_event | std_msgs/msg/String | Evento de animación de simulación (agarre/liberación) |
Tópicos publicados
| Tópico | Tipo | Descripción |
|---|---|---|
/rebotarm/joints/<jointN>/cmd | rebotarm_msgs/msg/JointMotorCmd | Comando disperso de articulación única (mode=1 POS_VEL) |
/rebotarm/gripper/cmd | rebotarm_msgs/msg/JointMotorCmd | Comando del gripper (m, 0~0.09) |
/rebotarm/mujoco/target_pose | geometry_msgs/msg/PoseStamped | Pose objetivo de arrastre del TCP |
Servicios llamados
| Servicio | Tipo | Descripción |
|---|---|---|
/rebotarm/enable | std_srvs/srv/Trigger | Habilitar todos los motores |
/rebotarm/disable | std_srvs/srv/Trigger | Deshabilitar todos los motores |
/rebotarm/safe_home | std_srvs/srv/Trigger | Retorno seguro a cero |
/rebotarm/gravity_compensation/start | std_srvs/srv/Trigger | Iniciar compensación de gravedad |
/rebotarm/gravity_compensation/stop | std_srvs/srv/Trigger | Detener compensación de gravedad |
/rebotarm/gravity_compensation/status | std_srvs/srv/Trigger | Consultar estado de la compensación de gravedad |
/rebotarm/gripper/set | rebotarm_msgs/srv/SetGripper | Servicio de alcance del gripper |
/rebotarm/move_to_pose_ik | rebotarm_msgs/srv/MoveToPoseIK | Servicio de resolución de IK |
/rosapi/topics | rosapi_msgs/srv/Topics | Diagnóstico: listar todos los tópicos |
/rosapi/services | rosapi_msgs/srv/Services | Diagnóstico: listar todos los servicios |
Acciones llamadas
| Acción | Tipo | Descripción |
|---|---|---|
/rebotarm/move_to_pose | rebotarm_msgs/action/MoveToPose | Movimiento de pose cartesiana |
/rebotarm/follow_joint_trajectory | control_msgs/action/FollowJointTrajectory | Ejecución de trayectoria de articulaciones |
Cuando el servicio _action/send_goal para FollowJointTrajectory o MoveToPose no se encuentra en el entorno ROS2, la página web vuelve automáticamente al modo de "reproducción de bajo nivel": publica comandos de articulación única punto por punto según las marcas de tiempo de los puntos de la trayectoria y sincroniza la interpolación en el modelo 3D. Esto permite que la página web demuestre trayectorias incluso en un entorno mínimo con solo el Fake Driver.
Unidades del gripper y convenciones de coordenadas
La web y las interfaces ROS usan metros como unidad del gripper:
close: 0.00 m
open: 0.09 m
El firmware del motor usa radianes (0.0 = cerrado, −5.0 = abierto). La conversión se realiza en el HardwareManager del controlador ROS2; la página web no maneja radianes directamente.
En el URDF, finger_left / finger_right son articulaciones prismáticas con límites 0~0.0285 (m). La página web mapea la apertura de finger_left al rango de comando del gripper 0~0.09 m mediante fingerOpeningToGripperCommand().
Para el sistema de coordenadas, Three.js en la web usa Y hacia arriba por defecto, mientras que ROS usa Z hacia arriba. Todas las poses del TCP se convierten con threeToRos() antes de publicarse en ROS:
function threeToRos(v) {
return { x: v.x, y: -v.z, z: v.y };
}
Control de texto LLM/MCP
El control en lenguaje natural no se llama directamente desde el navegador a ROS. Se hace proxy a través de Node.js. El diseño por capas permite que el LLM entienda la intención mientras que la capa MCP restringe la intención en operaciones de robot estructuradas.
Iniciar el servidor MCP y el agente de texto
Inicia el servidor MCP en la VM de Ubuntu (modo bloqueado por defecto, solo lectura):
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
source scripts/source_rebotarm_env.sh
ros2 launch rebotarm_agent rebotarm_mcp.launch.py
Modo de movimiento de simulación (movimiento permitido):
ros2 launch rebotarm_agent rebotarm_mcp.launch.py motion_mode:=allow
Inicia el servicio HTTP del agente de texto (para que lo llame la página web):
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
./scripts/start_rebotarm_text_agent_http.sh
Salida esperada
[rebotarm-text-agent-http] MCP=http://127.0.0.1:8081/mcp
[rebotarm-text-agent-http] model=qwen-plus
INFO: Uvicorn running on http://0.0.0.0:8082
Cuando aparezca Uvicorn running on http://0.0.0.0:8082, estará listo.
De forma predeterminada escucha en 0.0.0.0:8082, MCP apunta a http://127.0.0.1:8081/mcp, y el LLM usa qwen-plus por defecto.
Uso en la web
En el panel "LLM text control" de la página web, haz clic en "Start AI assistant". La página primero realiza un health-check del text-agent; tras tener éxito habilita el cuadro de entrada. Puedes escribir directamente comandos en lenguaje natural, por ejemplo:
- Consultar el estado del brazo
- Mover a X=0.3 Y=0 Z=0.3
- Abrir el gripper
- Agarrar el bloque rojo
La respuesta del text-agent y el proceso de llamada de herramientas se muestran en el área de chat.
Configurar el destino del proxy
La página web localiza el backend mediante REBOTARM_TEXT_AGENT_URL y REBOTARM_MCP_URL en .env. Si la página web se ejecuta en Windows y ROS2 se ejecuta en una VM de Ubuntu, cámbialos a la IP real de la VM:
REBOTARM_TEXT_AGENT_URL=http://<Ubuntu IP>:8082
REBOTARM_MCP_URL=http://<Ubuntu IP>:8081/mcp
Después de cambiarlo, reinicia ./rebotarm start web (o node server.js). Al iniciarse, la página lee y muestra el backend de proxy actual desde /api/mcp/config.
Panel de visualización MCP Dashboard
El MCP Dashboard es una entrada de depuración independiente y no necesita el simulador web. Iniciarlo requiere dos pasos:

Terminal 1 — iniciar el MCP Server:
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
source scripts/source_rebotarm_env.sh
ros2 launch rebotarm_agent rebotarm_mcp.launch.py motion_mode:=allow
Terminal 2 — iniciar el text-agent (incluye el MCP Dashboard):
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
./scripts/start_rebotarm_text_agent_http.sh
Acceso desde el navegador:
http://localhost:8082/
Abre http://<Ubuntu IP>:8082/ en un navegador para acceder; no se necesita instalación adicional.
Funciones:
- Resumen de herramientas: obtiene automáticamente todas las herramientas registradas desde el MCP Server y las agrupa por categoría (estado y diagnóstico, control de habilitación, control de movimiento, control del gripper, compensación de gravedad, agarre visual, grabación y reproducción);
- Filtro de búsqueda: el cuadro de búsqueda superior filtra en tiempo real los nombres y descripciones de las herramientas;
- Formulario de parámetros: genera automáticamente cuadros de entrada basados en el
inputSchemade cada herramienta; rellena los parámetros y haz clic en "Call" para llamar directamente a la herramienta MCP correspondiente; - Etiqueta de movimiento: las herramientas que requieren
motion_mode=allowse marcan con una etiqueta "Motion"; - Registro de herramientas personalizadas: haz clic en el botón "Register new tool", rellena el nombre de la herramienta, descripción, categoría, URL del Webhook y el esquema de parámetros (JSON) para añadir una herramienta personalizada al panel. Al llamarla, los parámetros se envían por POST como JSON a la URL del Webhook;
- Interruptor CN/EN: el botón de idioma en la esquina superior derecha cambia la interfaz CN/EN con un clic; la elección se guarda en el
localStoragedel navegador; - Entrada en lenguaje natural: escribe comandos en lenguaje natural en el cuadro de chat de la derecha; pasan por el endpoint
/chata través de la cadena LLM → MCP, y la respuesta y el proceso de llamada de herramientas se muestran en el área de registro en tiempo real.
El MCP Dashboard es una entrada de depuración independiente y no depende del simulador web. Mientras el MCP Server (:8081) y el Text Agent (:8082) estén ejecutándose, abre http://<Ubuntu IP>:8082/ para ver y llamar a las 18 herramientas MCP.
Resumen de endpoints:
| Endpoint | Método | Descripción |
|---|---|---|
/ o /dashboard | GET | Devuelve la página HTML del Dashboard (tema de panel de vidrio oscuro, admite cambio CN/EN) |
/tools | GET | Devuelve el JSON de la lista de herramientas MCP (nombre, descripción, esquema de parámetros, categoría, marca de personalizado) |
/call_tool | POST | Llama directamente a la herramienta MCP especificada, cuerpo: {"name":"...", "arguments":{...}} |
/register_tool | POST | Registra una herramienta personalizada, cuerpo: {"name":"...", "description":"...", "category":"...", "webhook_url":"...", "parameters":{...}} |
/unregister_tool | POST | Elimina una herramienta personalizada registrada, cuerpo: {"name":"..."} |
/chat | POST | Conversación en lenguaje natural, cuerpo: {"text":"..."} |
/health | GET | Comprobación de estado (health check) |
Guía de desarrollo secundario
Modificar límites de articulaciones o presets
Los límites de articulaciones y las poses preestablecidas se definen en los objetos jointDefs y presets al principio de rebot-sim.js. Después de modificarlos, actualiza la página para que surtan efecto; no es necesario recompilar. Ten en cuenta que los límites de articulaciones deben ser coherentes con <limit> en el URDF, de lo contrario el modelo web y el comportamiento en ROS no coincidirán.
Añadir una interfaz ROS personalizada
Si necesitas suscribirte a un nuevo tópico o llamar a un nuevo servicio, añádelo a REQUIRED_TOPICS o REQUIRED_SERVICES en rebot-ros-ui.js, y llama a client.subscribe() o client.callService() en los eventos de los botones. ReBotRosClient ya encapsula el protocolo rosbridge, por lo que no necesitas escribir la comunicación WebSocket a mano.
Ampliar herramientas LLM
Las herramientas LLM están definidas por el MCP Server en rebotarm_agent. Añadir una nueva herramienta requiere implementarla en el paquete rebotarm_agent en el espacio de trabajo ROS2; después de recompilar, el text-agent la expone automáticamente. No se necesitan cambios en la parte web; el proceso de llamada de herramientas se devuelve a través del campo events de /api/llm/chat y se renderiza.
Modificar las mallas del gripper en la web
Los STLs del gripper solo para la web están en split_meshes/grouped_gripper/, incluyendo gripper_base.stl, gripper_hardware.stl, left_finger.stl y right_finger.stl. Sustituye estos archivos y actualiza la página. No añadas una segunda copia de urdf/ o meshes/ en el directorio web; en tiempo de ejecución solo se usan estos cuatro STLs del gripper.
Modificar la dirección de conexión de rosbridge
La dirección WebSocket de rosbridge la introduce manualmente el usuario en el panel "ROS2 Bridge" de la página web; no está codificada de forma fija por defecto. Para cambiar la dirección predeterminada o preestablecida:
reBotArm_simulator-DM/public/js/ros/rebot-ros-client.js(el valor predeterminado del cliente está vacío y lo proporciona el cuadro de entrada)reBotArm_simulator-DM/public/js/ros/rebot-ros-ui.js(lee la última dirección desdelocalStorage)
La página intenta cargar la última dirección guardada cuando el cuadro de entrada está vacío. Modifica el valor predeterminado o introduce directamente la dirección real en el panel de conexión web.
Referencia rápida de archivos clave (haz clic para expandir)
| Archivo | Propósito |
|---|---|
reBotArm_simulator-DM/server.js | Servidor estático Node.js + proxy LLM |
reBotArm_simulator-DM/package.json | Scripts npm (start / dev) |
reBotArm_simulator-DM/.env | Configuración de puerto y destino del proxy |
reBotArm_simulator-DM/public/index.html | Entrada de la aplicación de una sola página y diseño del panel de control |
reBotArm_simulator-DM/public/css/rebot-sim.css | Estilos de tema oscuro |
reBotArm_simulator-DM/public/js/rebot-sim.js | Escena 3D, IK, enseñanza, núcleo de arrastre |
reBotArm_simulator-DM/public/js/rebot-llm.js | Interfaz de chat LLM |
reBotArm_simulator-DM/public/js/ros/rebot-ros-client.js | Cliente WebSocket de rosbridge |
reBotArm_simulator-DM/public/js/ros/rebot-ros-ui.js | Interfaz del panel de control ROS y lógica de negocio |
reBotArm_simulator-DM/public/lib/three-r128.min.js | Motor de renderizado Three.js |
reBotArm_simulator-DM/public/lib/STLLoader-umd.js | Cargador de mallas STL |
reBotArm_simulator-DM/public/lib/URDFLoader.js | Analizador URDF |
reBotArm_simulator-DM/split_meshes/grouped_gripper/ | STLs del gripper solo para la web (4 archivos) |
Preguntas frecuentes (FAQ)
1. Después de abrir el navegador, sigue mostrando "Loading Rebot_ARM-B601-DM arm model..."
Si la página se queda atascada en la superposición de carga, la solicitud del URDF o de la malla STL ha fallado. Abre el panel Network en las herramientas de desarrollador del navegador y comprueba si /api/urdf y /api/description/meshes/*.STL devuelven 200. Causas comunes:
- La ruta
BRINGUP_DIRenserver.jsse resuelve de forma incorrecta (el directorio web se movió a una ubicación que no es monorepo), por lo que no se puede encontrarsrc/rebotarm_bringup/description/; package://rebotarm_bringup/...en el URDF no se puede mapear; confirma queloader.packagesapunta a${origin}/api;- Falta el archivo STL o la coincidencia de mayúsculas y minúsculas de la ruta no es correcta (Linux distingue entre mayúsculas y minúsculas).
2. Después de conectar a ROS, el estado permanece en "offline"
Comprueba en este orden:
- Si rosbridge se está ejecutando en el lado de Ubuntu y escuchando en
0.0.0.0:9090(no en127.0.0.1); - Si el host web puede alcanzar el puerto 9090 de Ubuntu (firewall, modo de red de la VM);
- Si la dirección WebSocket comienza con
ws://(comows://localhost:9090);
3. El deslizador de articulaciones no puede controlar el robot real
Controlar el robot real desde la página web requiere tres pasos de desbloqueo:
- Conectarse a ROS en el panel "ROS2 Bridge" (el WebSocket se conecta al rosbridge del controlador del robot real);
- Marcar "Allow the web to send control to the real arm" → haz clic en "OK" en el cuadro de diálogo de confirmación;
- Hacer clic en el botón "Enable".
Los tres pasos son necesarios. Cuando el bloqueo de control no está marcado, arrastrar el deslizador solo mueve el modelo 3D y no envía comandos ROS.
4. El gripper no se sincroniza con la web
La position de /rebotarm/gripper/state debe estar en metros (0~0.09), no en radianes. Si no se sincroniza, comprueba si ros_publishers.py en el controlador ROS2 usa gripper_position_m(). La página web también infiere la apertura del gripper a partir de finger_left en /rebotarm/joint_states como fuente de retroalimentación alternativa.
5. El asistente LLM no se inicia
Cuando la página web muestra "Connection failed", confirma que el servicio HTTP del text-agent se está ejecutando en la VM de Ubuntu:
cd ~/reBot_Arm_Mujoco-DM/reBotArmController_ROS2-main
./scripts/start_rebotarm_text_agent_http.sh
Y confirma que REBOTARM_TEXT_AGENT_URL en .env apunta a la IP y puerto correctos de la VM (por defecto 8082). La página primero llama a /api/llm/health para hacer un health-check; si falla, muestra el error específico en el área de mensajes.
6. La demostración de agarre visual no funciona
El agarre visual depende de toda la pila de simulación física. Comprueba:
- Si la cámara RGB cenital de MuJoCo se está ejecutando y
/rebotarm/mujoco/overhead_rgb/image_rawtiene una imagen; - Si el detector de color se está ejecutando y
/rebotarm/vision/color_blocks/detectionstiene resultados; - Si la vista previa de la cámara web muestra un fotograma y el estado de reconocimiento de color muestra "N / target X";
- Si la selección del color objetivo es correcta (auto/rojo/amarillo/azul).
7. Los cambios en el código del front-end no surten efecto
Los recursos del front-end son servidos de forma estática por Node.js; después de hacer cambios, actualiza el navegador. La versión actual no registra un Service Worker, por lo que no hay caché sin conexión que impida que se actualice la versión antigua. Si el navegador sigue mostrando contenido antiguo, usa una actualización forzada (Ctrl+Shift+R) o borra la caché normal.
8. "URDFLoader" o "THREE" no encontrados
Son bibliotecas de terceros bajo public/lib/, cargadas por index.html mediante etiquetas <script>. Confirma:
public/lib/three-r128.min.js,public/lib/URDFLoader.jsypublic/lib/STLLoader-umd.jsexisten;- Las rutas de las etiquetas
<script>enindex.htmlson correctas, y el orden de carga es Three.js → STLLoader → URDFLoader → scripts de negocio; - No hay errores 404 ni errores de orden de carga en la consola del navegador.
9. setup.sh informa de un error o la instalación falla
setup.sh es idempotente; los componentes que fallan se enumeran en el resumen final en Failed or still missing. Casos comunes:
- Fuente apt de ROS no configurada: el instalador descarga automáticamente el paquete
ros2-apt-sourcey añade la fuente, lo cual requiere sudo; - Versión de Python no coincidente: Jazzy necesita 3.12, Humble necesita 3.10; una discrepancia se enumera en
Version/platform mismatches; - Fallo al clonar el SDK: comprueba la red y la accesibilidad a GitHub, o clónalo manualmente en
reBotArmController_ROS2-main/third_party/reBotArm_control_py/y vuelve a ejecutar; colcon buildfalló: comprueba sirosdepestá inicializado (sudo rosdep init && rosdep update), luego vuelve a ejecutar./setup.sh.
Contacto
- Soporte técnico: Submit an Issue
- Repositorio del proyecto: Github
- Foro: Seeed Studio Forum
Referencias
- Inicio rápido de reBot Arm B601-DM
- Integración de reBot Arm B601-DM con ROS2
- Demostración de agarre visual de reBot Arm B601-DM
- reBot Arm B601-DM Pinocchio y MeshCat
- Tutorial de reBot Arm B601-DM LeRobot
- Documentación de ROS2 Jazzy
- Documentación de rosbridge_suite
- Documentación de Three.js
- URDFLoader (gkjohnson)
- Model Context Protocol