Hasta aquí todo fue simulación. En este capítulo llevas el mismo nodo drive al coche real: lo montas, instalas el repositorio en la Raspberry Pi, compruebas cada sensor y cada actuador por separado, y solo al final haces una primera ronda en el campo.
Aquí importa ir despacio: un error en el simulador cuesta una ronda, y uno aquí puede costar un cable arrancado o un coche contra la pared.
Qué está probado y qué no. Separo lo que se midió en un coche real de lo que solo he visto en simulación.
- Medido en el coche real (equipo Robotek, 7 a 9 de octubre de 2026, montaje anterior): el retardo del servo, el ángulo real de las ruedas con círculos, la tabla de velocidad del motor, el LiDAR, la IMU, la cámara, el botón y los LED de la placa. De ahí salen los números de
robot.yamly del simulador.- Rondas Open en el coche real: el 8 de octubre el equipo hizo ocho intentos con su propia estrategia (el v4) y su propio lanzador, que viven en otro repositorio. El primero chocó contra el muro a los 2,9 s: el color de la pared de la sala se confundió con una línea. Con el motor limitado al 40 % el coche dio los 12 giros y llegó a
DONEen 47,1 s, y el operador dijo que funcionó. Con el 50 %, 40,4 s, pero rozó dos veces la isla interior. Los demás fallaron por un cable suelto (varias veces), un Start falso, un reinicio del Pi con la batería a 6,5 V y un choque al 90 % del motor. No hubo juez: no sé cuántos puntos habrían sido, solo hay una estimación provisional.- Después de eso el coche se reconstruyó (21 de octubre): el servo de dirección cambió de sitio y giró 90 grados, y la Raspberry y la placa van de canto. Hasta donde llegan mis notas, el servo y los ejes de la IMU de esa construcción no se han vuelto a medir y no se ha hecho ninguna ronda con ella.
- No probado en el coche real:
car.launch.py,tools/setup-pi.sh, el paquetemy_opende esta guía y los comandos de este capítulo. Los he escrito leyendo el código y los datos del equipo, no ejecutándolos en el coche. Si algo no coincide con lo que ves, tú tienes la razón: cuéntamelo.
1. Qué necesitas
Piezas
- Una Raspberry Pi 5 con Ubuntu 24.04 (la del equipo). Una Pi 4 no la he probado: el motor usa el chip de GPIO 4 del Pi 5, y en otra placa ese número cambia (
gpiochipenrobot.yaml). - La placa HiWonder RRC Lite: IMU (MPU6050), botones K1 y K2, dos LED RGB y el servo de dirección.
- El LiDAR LDROBOT LD19, con su adaptador USB serie, y una cámara USB (la del equipo solo da YUYV 640x480).
- El motor de tracción con un puente TB6612FNG conectado a pines GPIO del Pi.
- Una batería LiPo 2S (7,4 V nominales) para la electrónica y, mejor, otra aparte para el motor.
- Soportes para levantar el coche del suelo (cajas, libros). Es lo más útil de la lista.
Conexiones
| Qué | Dónde se conecta | Cómo lo ves en Linux |
|---|---|---|
| Placa RRC Lite | USB del Pi | /dev/ttyACM0 (USB 1a86:55d4) |
| Servo de dirección | Conector J4 de la RRC Lite (canal PWM 2) | lo manda el driver de la placa |
| Botón de Start | K1 de la RRC Lite (K2 también cuenta) | /rrc/button |
| LED de estado | Los dos RGB de la RRC Lite (1 izquierdo, 2 derecho) | los maneja status_leds |
| LiDAR LD19 | USB del Pi, con su adaptador CP2102 | /dev/ttyUSB0, 230400 baudios (USB 10c4:ea60) |
| Cámara | USB del Pi | /dev/v4l/by-id/...-video-index0 |
| Motor | Puente TB6612FNG a GPIO del Pi: PWM 12, AIN1 5, AIN2 6, STBY 13 | chip gpiochip4 |
Enchufa la placa, el LiDAR y la cámara antes de encender el Pi. El pin STBY (13) es fácil de olvidar: si el puente no lo recibe en alto, el motor no se mueve (al equipo le pasó: el servo respondía y el motor solo andaba a ratos). motor_driver lo pone en alto solo.
Alimentación
- Usa una batería buena y cargada. La tabla de velocidad del motor se midió con la batería casi vacía (7,0 a 7,4 V), y con otra carga el coche va a otra velocidad. En una prueba, con 6,5 V y el motor al 80 %, el Pi se reinició a mitad de ronda.
- La RRC Lite acepta de 6 a 14 V y da 5 V y 5 A al Pi.
battery_guardavisa a 6,8 V (3,4 V por celda). Por debajo de 6 V la placa se apaga y las celdas se dañan. - El equipo decidió dar al motor su propia batería, para que no hunda la tensión del Pi. Ten en cuenta que
battery_guardsolo vigila la de la placa: la del motor no la vigila nadie. - Corriente del motor: no la medí. La hoja de datos del TB6612FNG da 1,2 A continuos y 3,2 A de pico por canal, así que comprueba que tu motor no pide más. Un motor con la rueda bloqueada es lo que más corriente pide.
- Reinicios. El Pi del equipo se reinició varias veces. Medido: con pulsos de motor, los 5 V del Pi no bajaron de 4,8 V y nunca hubo aviso de subtensión, así que la fuente estaba bien. Las causas que sí aparecieron fueron un cable flojo y una tira de LED de 30 píxeles en blanco al 100 %, que consume unos 1,8 A y apagó el Pi. De algunos reinicios no se llegó a saber la causa. Si el tuyo se reinicia: revisa primero cada conector y no cuelgues cosas grandes de los 5 V del Pi.
La seguridad, primero
- La primera vez, el coche sobre soportes, con las ruedas en el aire. Todas las pruebas de este capítulo se hacen así, salvo la ronda final.
- Una pulsación del botón es Start y la siguiente para el coche (
/robotek/stop). Pero el botón ignora pulsaciones separadas por menos de 1,5 s: en el primer segundo y medio no puedes parar con él. Ten la mano cerca de las ruedas y el cable de la batería a mano.Ctrl+Cen la terminal también corta el motor. - Un Start falso es posible. En una de las rondas del equipo
/startse publicó sin que nadie tocara el botón. Por eso las ruedas en el aire valen también para las pruebas con la estrategia lanzada. - Pulsos cortos. El equipo no encendió el motor más de 0,25 s seguidos en sus pruebas, y solo llegó a pulsos de 1 s con el 30 % o menos. Haz lo mismo: potencia baja, duración corta, y sube poco a poco.
- Arranca siempre a baja potencia. A fondo desde parado el coche del equipo levantó las ruedas delanteras y la dirección dejó de actuar. Por eso
base_adapterlimita la aceleración a 1 m/s² y la deceleración a 0,6 m/s², ymotor_max_pctlimita el motor.
2. Clonar y preparar el Pi con un comando
El camino corto: la estrategia de referencia
Si solo quieres ver al coche hacer la ronda con la estrategia terminada de los pasos 2 a 9, son tres comandos en el Pi, con internet:
git clone https://github.com/renzodamgo/robotek-learn.git && cd robotek-learn
bash tools/setup-pi.sh --with-reference
source install/setup.bash && ros2 launch robotek_course open_challenge.launch.py motor_max_pct:=30
El segundo comando instala todo y, además, saca la estrategia terminada de la etiqueta step-9 y la deja en src/my_open. Con el tercero arrancan los nodos del coche. Cuando las luces estén verdes, pulsas el botón de la placa una vez para empezar y otra vez para parar. Antes de pulsarlo la primera vez, lee la sección 4: el coche en alto, el motor limitado y la batería cargada. Y ojo con la dirección: el archivo robot.yaml trae el centro y el signo del servo del coche del equipo (servo_measured: false). Si tu coche es otro, el servo saltará a ese centro en cuanto la estrategia publique y el coche saldrá torcido. Haz antes las comprobaciones 3.5 y 3.6.
Si ya tienes la estrategia de otra forma, get-reference.sh no la pisa: avisa y sale. Con --force guarda una copia (src/my_open.bak-FECHA) y la reemplaza. Si lanzas sin tener my_open, el lanzador no da un error técnico: te dice en español los dos caminos y sale.
El camino largo: tu propia estrategia
Clona igual:
git clone https://github.com/renzodamgo/robotek-learn.git
cd robotek-learn
Tu estrategia my_open no está en git (el repositorio la ignora en main). Cópiala desde tu ordenador a robotek-learn/src/my_open/ antes de seguir, con rsync, scp o clonándola de tu propio repositorio. Cada vez que cambies tu código en el ordenador tendrás que volver a copiarla.
Ahora el script (sin --with-reference, porque ya tienes tu paquete):
bash tools/setup-pi.sh
Es repetible: lo que ya está hecho se salta. Pide sudo y tarda varios minutos (--dry-run muestra los comandos sin ejecutarlos). Hace cuatro cosas:
- Comprueba que el sistema es Ubuntu 24.04. En otro sistema se niega, salvo
ROBOTEK_FORCE=1. - Instala ROS 2 Jazzy sin Gazebo ni RViz (en el Pi no los necesitas) y los paquetes de apt del coche:
cv_bridge,robot_state_publisher,xacro,python3-serial,python3-lgpio,python3-opencv,v4l-utils. - Instala las reglas de udev (
tools/99-robotek.rules) y te añade a los gruposdialout(puertos serie),video(cámara) ygpio(motor). - Compila todo con
colcon build --symlink-install.
Los drivers de terceros ya vienen en el repositorio, en src/: el del LiDAR (ldlidar_stl_ros2, de LDROBOT, con licencia MIT) y el de la placa (rrc_lite_driver y rrc_lite_msgs, basado en el código de Hiwonder). Los de Hiwonder se incluyen con su permiso; los créditos están en CREDITS.md. No hay que descargar nada más.
Las reglas de udev dan nombres fijos, /dev/rrc_lite a la placa y /dev/ldlidar al LiDAR, que no dependen del puerto USB, y evitan que ModemManager ocupe la placa. Los grupos solo cuentan en una sesión nueva: cierra la sesión y vuelve a entrar, o reinicia el Pi.
Después, comprueba sin tocar nada:
bash tools/setup-pi.sh --check
Imprime una línea por cosa: ok, FALTA o aviso. Mira el sistema, ROS, los paquetes compilados (incluido my_open), la placa, el LiDAR, la cámara, el GPIO, lgpio, pyserial y los grupos, y termina con el recuento. Un FALTA en un USB es casi siempre un cable. --check no arranca nada.
El script no se ha probado en un Pi limpio. Si falla, mira qué comando falló y cuéntamelo.
3. Las comprobaciones, una a una
Carga el entorno en cada terminal del Pi:
cd ~/robotek-learn
source /opt/ros/jazzy/setup.bash
source install/setup.bash
3.1 Los dispositivos USB (sin ROS)
ls -l /dev/serial/by-id/ /dev/v4l/by-id/ /dev/rrc_lite /dev/ldlidar /dev/gpiochip4
Debes ver la placa (1a86 en el nombre), el LiDAR (Silicon_Labs_CP2102) y la cámara terminada en video-index0. Si falta uno, lo primero es el cable. Si solo faltan /dev/rrc_lite o /dev/ldlidar, las reglas de udev no están activas: desenchufa y enchufa, o reinicia. Si falta /dev/gpiochip4, tu Pi no es un Pi 5. Y si mueves un dispositivo de puerto con todo en marcha, relanza: los nodos que lo tenían abierto se quedan sin datos.
3.2 La cámara
Con el coche sobre soportes lanza todo, sin pulsar el botón:
ros2 launch robotek_course car.launch.py strategy:=my_open
Verás avisos amarillos: base_adapter dice que servo_measured es falso y imu_adapter dice que los ejes no están medidos. Es lo esperado hasta que calibres (3.4 y 3.5). No pulses el botón. Este lanzador deja tu drive esperando Start.
car.launch.py --show-args lista las opciones: camera:=false, video_device:=..., camera_driver:=usb_cam, battery_guard:=false, status_leds:=false, lidar_package:=''.
En otra terminal:
ros2 topic hz /usb_cam/image_raw
Debes ver entre 5 y 15 imágenes por segundo. La cámara del equipo, con exposición automática, daba unos 6,5 con la luz de una sala y hasta unos 15 con otra. El simulador usa 6. El nodo camera_publisher busca la cámara solo; si no la encuentra, avisa y reintenta cada segundo (mira su mensaje en la primera terminal). Si usas otra cámara, video_device:=/dev/v4l/by-id/..., y camera_driver:=usb_cam cambia al paquete ros-jazzy-usb-cam.
Para ver la imagen, desde otro ordenador con pantalla (la red, en 3.3):
ros2 run rqt_image_view rqt_image_view /usb_cam/image_raw/compressed # Ubuntu
Usa siempre el tópico compressed por Wi-Fi: la imagen cruda pesa unos 0,9 MB por cuadro y no llega. En la Mac del curso no hay rqt: usa una pantalla Image de RViz con ese mismo tópico (el equipo tuvo que instalar ros-jazzy-compressed-image-transport en RoboStack). El Pi solo comprime si alguien se suscribe.
Sin pantalla: guardar un cuadro en el Pi
python3 - <<'PY'
import cv2, rclpy
from cv_bridge import CvBridge
from rclpy.qos import qos_profile_sensor_data
from sensor_msgs.msg import Image
rclpy.init()
node = rclpy.create_node('grab_frame')
def save(msg):
cv2.imwrite('cuadro.png', CvBridge().imgmsg_to_cv2(msg, 'bgr8'))
raise SystemExit
node.create_subscription(Image, '/usb_cam/image_raw', save, qos_profile_sensor_data)
try:
rclpy.spin(node)
except SystemExit:
print('guardado cuadro.png')
PY
Cópialo a tu ordenador. Mira que se ven las líneas naranja y azul y que no hay reflejos de las luces.
3.3 El LiDAR: tasa y vista en RViz
ros2 topic hz /robotek/scan
Debes ver cerca de 10 Hz (el LD19 del equipo daba 10,1). Si no hay nada, el driver no abrió el puerto y terminó: mira la primera terminal.
Ahora mira lo que ve. Desde otro ordenador de la misma red (el que usaste para el simulador), con el mismo número de dominio que el Pi. tools/macos_env.sh usa el 42 y limita el descubrimiento a tu propio ordenador, así que hay que cambiar eso. En clase, cada coche necesita su propio número (elige uno entre 1 y 100), o verás los sensores de tus compañeros mezclados con los tuyos.
En el Pi, antes de lanzar (o añade las líneas a ~/.bashrc):
export ROS_DOMAIN_ID=7 # el tuyo
export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET # por defecto
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
En el ordenador:
export ROS_DOMAIN_ID=7 # macos_env.sh respeta este valor (si no hay, usa 42)
source tools/macos_env.sh ~/robotek-ros/jazzy # en Ubuntu: source /opt/ros/jazzy/setup.bash y
# export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET # macos_env.sh pone LOCALHOST: lo cambiamos
ros2 topic list # deben aparecer /robotek/scan y /rrc/...
ros2 run rviz2 rviz2
El equipo lo usó así por Wi-Fi, con el mismo middleware y dominio en los dos lados y el cortafuegos de macOS apagado. Si ros2 topic list no muestra nada, casi siempre es el dominio, el middleware o la red. Fuera de la red local, DDS no funciona sin una VPN.
En RViz: pon Fixed Frame en lidar_link y añade una pantalla LaserScan con el tópico /robotek/scan y Reliability Policy en Best Effort (el LiDAR publica así; con otra no verás nada). La prueba es esta: con una pared delante, la ves delante. Pon la mano a la izquierda del coche y debe aparecer a la izquierda. Si todo sale girado 180 grados o espejado, es angle_offset (el LD19 tiene el cero hacia atrás: el valor por defecto es π) o reverse en robot.yaml. Además, el LiDAR del coche solo ve ±110 grados: detrás los rayos dan en el propio chasis, y scan_adapter los descarta.
3.4 La IMU: tasa y signo del giroscopio
ros2 topic hz /rrc/imu_raw
ros2 topic hz /robotek/imu
ros2 topic echo /rrc/battery --once
La IMU debe dar unos 49 Hz en los dos (el simulador usa 50). La batería publica a 1 Hz, en milivoltios: de 7000 a 8400 es una 2S sana.
Ahora lo que más importa del capítulo. Tu estrategia integra angular_velocity.z como la velocidad de giro, y espera que girar a la izquierda sea positivo. Si el signo o el eje están mal, el coche cree que gira al revés y se estrella en la primera esquina.
ros2 topic echo /robotek/imu --field angular_velocity.z
Coge el coche con la mano y gíralo despacio hacia la izquierda, en sentido contrario a las agujas del reloj visto desde arriba. Debes ver valores positivos. Con el coche quieto deben quedarse cerca de cero (el equipo midió un sesgo de 0,006 rad/s y un ruido de 0,0019). Comprueba también:
ros2 topic echo /robotek/imu --field linear_acceleration
Con el coche en reposo z ronda +9,8 m/s². Un empujón suave hacia delante da x positiva.
Si algo falla, los ejes de la placa no coinciden con los del coche. Es casi seguro si montas la placa de canto. La herramienta imu_axes los mide, y solo escucha (puedes dejarla con el resto corriendo):
ros2 run robotek_hardware imu_axes
Deja el coche quieto 3 s y, cuando diga PUSH, dale un empujón suave hacia delante y suéltalo. Imprime un bloque con forward_axis, left_axis y up_axis y el error angular de cada eje (más de 15 grados: placa inclinada o empujón torcido, repítelo). Copia el bloque en la sección imu_adapter de src/robotek_hardware/config/robot.yaml, pon measured: true y recompila:
colcon build --symlink-install --packages-select robotek_hardware
Relanza y repite la prueba del giro a mano. Los valores de robot.yaml son los de otro montaje: no te fíes de ellos.
3.5 La dirección: centro y signo
Para el servo y el motor, para el lanzador (Ctrl+C): base_adapter y la estrategia mandan órdenes constantemente y se pisarían con las tuyas. Lanza solo el driver de la placa y el nodo de prueba, que mueve solo el servo, nunca el motor:
ros2 launch rrc_lite_driver controller.launch.py # terminal 1: el driver de la placa
ros2 run robotek_hardware servo_steer # terminal 2
En una tercera terminal, publica el ángulo. Es en radianes y positivo es a la izquierda:
ros2 topic pub -r 5 /steer std_msgs/msg/Float32 "{data: 0.0}"
Si dejas de publicar, el servo vuelve al centro a los 0,5 s. Mira las ruedas desde arriba con una regla: con 0.0 deben quedar rectas. Si no, ajusta el centro (servo_center_us, 1500 por defecto) de 10 en 10 µs:
ros2 run robotek_hardware servo_steer --ros-args -p servo_center_us:=1510.0
Sube con cuidado: la palanca del servo puede topar con la placa o las varillas. Ahora el signo, con data: 0.35 (unos 20 grados, que se ven bien; a 10 grados casi no se aprecia). Mirando el coche desde atrás, las ruedas deben girar hacia tu izquierda. Con -0.35, a la derecha. Si salen al revés, cambia servo_sign (de -1.0 a 1.0).
Cuando el centro y el signo estén bien, mide el ángulo real de cada rueda para 10, 15, 20 y 25 grados de servo, a cada lado, con un transportador o una foto desde arriba, y rellena servo_center_us, servo_sign, wheel_table_servo_deg, wheel_table_left_deg, wheel_table_right_deg y wheel_limit_deg en robot.yaml. Después pon servo_measured: true. base_adapter avisa en cada arranque mientras sea false.
Un dato del coche del equipo, con el montaje anterior: 25 grados de servo daban unos 19,7 grados de rueda a la izquierda y 17,6 a la derecha, y base_adapter limitaba a 17,6 en los dos lados. No te sirve de valor, pero te dice que las ruedas no giran lo que pides.
3.6 El motor: velocidad baja
Aún con las ruedas en el aire y el servo parado. Solo el nodo del motor:
ros2 run robotek_hardware motor_driver
Debe decir TB6612FNG ready. Si dice GPIO chip 4 not usable, falta python3-lgpio, tu usuario no está en el grupo gpio o el chip se llama de otra forma (ls /dev/gpiochip* y gpiochip en robot.yaml).
En otra terminal, un 15 % de potencia, que es poco. El equipo vio mover el coche desde un 10 %:
ros2 topic pub -r 20 /motor_vel std_msgs/msg/Float32 "{data: 15.0}"
Las ruedas traseras deben girar hacia delante. Si giran hacia atrás, intercambia los cables del motor. Hay que repetir la orden a 20 Hz: motor_driver corta el motor si pasan 0,3 s sin orden (y lo para con una rampa de 0,6 s, a propósito: parar en seco hacía patinar al coche). Para, y prueba -15.0 para la marcha atrás. Sube de 5 en 5 hasta un 30 % como máximo en esta prueba, sin dejar nunca el motor encendido más de unos segundos.
Para el motor, esto es lo que midió el equipo con la batería baja: el coche empieza a moverse hacia el 6,5 %, y a un 20 % va a unos 0,20 m/s, a un 30 % a unos 0,32 m/s. La regla que usa base_adapter es % = 6,5 + 73 x velocidad. Con la batería cargada irá más rápido.
4. La primera ronda, en el suelo
Antes de poner el coche en el campo
- Las comprobaciones 3.1 a 3.6 pasan, y
servo_measuredeimu_adapter.measuredsontrue. - Baja el tope del motor. Lánzalo con
motor_max_pct:=30(o cambiamotor_max_pctenrobot.yamly recompilarobotek_hardware). Con el valor del equipo (50) el coche irá a unos 0,4 m/s; con 30, a unos 0,3. Es lento y es lo que quieres para empezar. - La batería cargada:
ros2 topic echo /rrc/battery --once. - Un campo Open montado, la isla fija y el coche en la sección de salida, como en el simulador.
Lanzar
Guarda la salida de la consola, que es tu registro:
mkdir -p ~/rondas-coche
ros2 launch robotek_course open_challenge.launch.py motor_max_pct:=30 2>&1 | tee ~/rondas-coche/ronda-01.log
Espera a que las luces se pongan verdes. Con la batería cargada y el coche en su posición de salida, pulsa el botón una vez.
Qué significan los LED
Las luces son muy tenues a propósito (2 de 255): con más brillo se reflejaban en la cámara. Míralas de cerca.
| Estado | LED izquierdo | LED derecho |
|---|---|---|
| Arrancando (primeros 15 s) | apagado | apagado |
| Listo, esperando Start (LiDAR, IMU y cámara con datos) | verde | verde |
| Falta un sensor antes de Start | rojo | azul = LiDAR, magenta = IMU, amarillo = cámara |
| Calibrando tras Start | azul | azul |
| En ronda, o parado con el botón | apagado | apagado |
Terminó (DONE) |
verde parpadeando | verde parpadeando |
Fallo de la estrategia (FAULT, DIRECTION_FAULT, STALLED, PARK_FAIL) |
rojo fijo | rojo fijo |
| Batería baja (menos de 6,8 V), hay que cambiarla | rojo parpadeando | rojo parpadeando |
Los estados salen de lo que publica tu nodo en /robotek/state (lo hace drive.py desde el paso 7). Si falta un sensor, solo muestra el primero en este orden: LiDAR, IMU, cámara. Durante la ronda las luces van apagadas aunque falle un sensor.
El botón
- Primera pulsación: publica
/starty pita una vez. El zumbador de la placa del equipo está quemado, así que allí no suena: no dependas del pitido. - Segunda pulsación: publica
/robotek/stopy pita dos veces.base_adapterymotor_driverponen el motor a 0 y lo mantienen. Tu nodo pasa aOPERATOR_STOPy no se mueve más hasta lanzar de nuevo. - Las pulsaciones a menos de 1,5 s de la anterior se ignoran.
Qué imprime la consola. Son líneas del código, no la captura de una ronda real. Al arrancar: Press the button to start; press it again to stop. (start_button), TB6612FNG ready (motor_driver) y Status RGBs at level 2/255. (status_leds). Con el primer pulso: Start. y el Start de tu drive, y después lo que escribiste en cada paso (Giro a la izquierda (esquina N)). Con el segundo: Stop (button pressed again). y Operator stop: motor held at 0.. Si la batería baja de 6,8 V: Battery X V < 6.80 V: change it before the next round.
El registro de una ronda
En el coche no hay juez, ni posición real, ni registro de contactos, y ros2 run robotek_course score no puntúa rondas reales. El juez eres tú. Apunta, para cada intento, también los fallidos:
- El archivo de registro, la batería antes (
ros2 topic echo /rrc/battery --once),motor_max_pcty qué cambiaste desde el intento anterior. - El sentido que detectó y desde dónde salió.
- El tiempo desde el botón hasta
DONEcon cronómetro (el estado se ve conros2 topic echo /robotek/state). - Si tocó un muro o movió la isla, dónde se paró y qué viste.
5. El coche real no es el simulador
El simulador real_car modela lo que el equipo midió. Conviene saber qué es y qué no.
| Parte | Lo que modela el simulador (medido en el coche) |
|---|---|
| Servo | Retardo de 0,06 s; velocidad de giro de 1,2 rad/s; el ángulo de las ruedas limitado a 17,6 grados |
| Motor | Retardo de 0,06 s y respuesta de 0,15 s; aceleración 1,0 y deceleración 0,6 m/s²; una tabla de velocidad medida con la batería baja (pedir 0,30 da 0,27 m/s, pedir 0,60 da 0,42). El 100 % (0,60 m/s) se infirió, no se midió |
| LiDAR | ±110 grados, 306 rayos, 10 Hz, ruido de unos 8 mm y un 4,3 % de rayos perdidos al azar |
| IMU | 50 Hz, ruido del giroscopio de 0,0019 rad/s y un sesgo de 0,006 rad/s |
| Cámara | Unos 6 fps y el campo de visión del coche, con la cámara girada 4,4 grados |
Y esto es lo que no modela:
- Patinaje de las ruedas y la fricción del suelo. En Gazebo las ruedas no resbalan como en el piso real.
- La caída de la batería al acelerar, y cualquier velocidad por encima de lo medido (más del 30 % de motor, con baja carga). Con la batería cargada el coche va más rápido que el modelo, y los giros se disparan tarde.
- El encabritamiento: a fondo desde parado el morro se levanta. No pasa en simulación.
- La luz. El simulador tiene colores perfectos. Los rangos de
line_lengthsde la guía son los del simulador y con la luz de tu sala pueden fallar. Al equipo le pasó: la pared beige de la sala cayó dentro del naranja y el coche giró mal. El remedio fue mirar solo la parte del suelo de la imagen y medir los colores reales. - La distorsión de la lente de la cámara y el retardo propio de los sensores.
- Las medidas del coche que cambian cuando reconstruyes: la distancia entre ejes (0,1174 m en el repositorio), el sitio del LiDAR y de la cámara, el sesgo real del giroscopio.
Una ronda perfecta en Gazebo no demuestra nada sobre el coche. Y una mala en el coche suele ser un sensor (el color, el sesgo, un signo) o la velocidad real, casi nunca tu algoritmo.
6. Cuando algo falla
- El coche se estrella al arrancar, vuelca, el giroscopio está invertido o no hay datos de un sensor: Solución de problemas del coche real.
- Funciona pero quieres ir más rápido o con más margen: Afinar.
Antes, repite la primera ronda un par de veces con la misma batería y el mismo tope de motor: una ronda buena no dice nada todavía.