
En casa, sobre una estantería, vive un pequeño rover marciano Adeept PiCar-B. El plan a largo plazo es gloriosamente poco práctico: convertirlo en una IA que funcione en el propio dispositivo y que reconozca y juegue con nuestros dos gatos, Pancho y Nala. Antes de nada, el robot tenía que funcionar de verdad. Esta es la historia de devolverlo a la vida, y del hardware que se nos resistió por el camino.
Empezar de cero
El kit viene con una imagen de tarjeta SD ya preparada, pero estaba anticuada: Bullseye de 32 bits de mediados de 2023, sin ni rastro de paquetes de machine learning para ARM64. Como el objetivo final es la visión por ordenador, regrabamos la Raspberry Pi 3B+ con una Raspberry Pi OS Bookworm Lite de 64 bits recién instalada y reconstruimos toda la pila de software desde cero sobre ella.
La grata sorpresa: el código del fabricante ya es compatible con Bookworm en su mayor parte. Se apoya en picamera2, gpiozero y Adafruit CircuitPython, que se portan bien en el sistema de 64 bits. La cámara es una OV5647, y en Bookworm el viejo comando de detección miente: vcgencmd dice que no hay cámara aunque funcione. La respuesta honesta la da rpicam-hello --list-cameras.
Una interfaz pequeña y segura en lugar de la pila del fabricante
El servidor web del fabricante tiene una costumbre alarmante: al arrancar pone en marcha el motor de tracción trasero, con las ruedas en el suelo, antes de que hayas tocado nada. Para un robot que está sobre una mesa junto a un gato dormido, eso es inadmisible.
Así que, en vez de pelearnos con la pila del fabricante, escribimos la nuestra. Una interfaz en Flask de unas 150 líneas transmite vídeo en directo y ofrece tres deslizadores, uno por servo, y un botón de inicio. No toca en ningún momento los canales del motor. Es trivial de leer, trivial de depurar y, físicamente, no puede mover las ruedas. Un servicio de systemd la mantiene en marcha y la recupera tras un reinicio.
El caso del conector muerto
El robot tiene un PCA9685 que controla sus servos por I2C. El primer enigma fue un servo de barrido horizontal que simplemente no se movía. ¿Era el servo, el cableado o la placa?
La jugada decisiva fue leer directamente los registros del PCA9685. El chip emitía una señal PWM perfectamente correcta en su canal. La señal sencillamente nunca llegaba al conector: la salida número uno de la HAT estaba eléctricamente muerta, casi con toda seguridad dañada en un incidente anterior, cuando el motor giró libremente y la fuerza contraelectromotriz se coló por el raíl compartido de los servos. Lo confirmamos del único modo que no deja dudas: moviendo físicamente el cable del servo a otro conector, donde cobró vida. Lección anotada: mantén las ruedas en el aire durante la puesta a punto, y no te fíes nunca de un conector que no hayas probado.
La versión que no era
La siguiente trampa fue más silenciosa. El software del fabricante se dirige al PCA9685 en la dirección I2C 0x5F, la de la HAT V3.1. La nuestra es una placa V3.0 en 0x40. Hubo que cambiar ese único número en dos ficheros de código. Un detalle revelador: justo al lado del 0x5F escrito a fuego había un comentario que decía default 0x40. Estaba claro que al propio autor del fabricante ya le había mordido esto antes.
Calibrar la cabeza de la cámara
Un robot que va a vigilar gatos necesita saber con exactitud hacia dónde mira. La cámara va montada sobre un servo de inclinación con un recorrido bruto de 0 a 180 grados, pero esos números no significan nada hasta que los relacionas con el mundo real. Así que lo calibramos por la vía empírica: parar el servicio de control para liberar el bus I2C, barrer el servo por todo su recorrido en pasos fijos y capturar un fotograma en cada ángulo. Emparejar cada ángulo con lo que la cámara veía de verdad convirtió una posición abstracta del servo en un mapa con sentido de la habitación.
De ese barrido salieron números claros. A 0 grados la cámara mira en vertical hacia las propias ruedas del robot. A 45 grados mira al frente y ligeramente hacia abajo, la mirada natural en reposo, así que la adoptamos como posición de inicio. Hacia los 60 grados la vista queda más o menos a la altura del horizonte. A 90 grados ya apunta a la parte alta de la pared, y por encima de 130 grados se limita a estudiar el techo. Dos límites físicos enmarcan el resto: el chasis recorta la parte inferior de la imagen por debajo de 0 grados, y el techo por encima de 130 grados es inútil para encontrar a un gato en el suelo.
Eso nos dio exactamente los offsets que fijar. En lugar de dejar que el servo recorriera todo su rango mecánico, acotamos el recorrido útil a 0-130 grados con un inicio en 45 grados, y enseñamos al deslizador de la interfaz a rechazar cualquier valor fuera de esa ventana. Limitar los offsets por software es un cambio pequeño con tres beneficios reales: la cabeza nunca fuerza contra un tope mecánico, nunca malgasta fotogramas en un trozo de techo vacío y siempre vuelve a una pose sensata, al frente y hacia abajo, al arrancar el robot. La misma lógica se aplica a la dirección delantera, que acotamos deliberadamente a su rango seguro de giro a la izquierda hasta que se arregle un atasco mecánico en el lado derecho.
Cómo está la cosa
Hoy el rover tiene una superficie de control estable y segura: cámara en directo, un servo de inclinación calibrado, un servo de dirección que funciona y una interfaz que no puede hacer daño a nadie. Algunas cosas todavía se nos resisten, y somos sinceros al respecto. La dirección tiene un atasco mecánico en un lado, así que de momento solo gira a la izquierda dentro de su rango acotado. El motor de tracción se queda deliberadamente sin tocar hasta que entendamos con exactitud qué hace la cadena del fabricante para activarlo. Y el servo de barrido, tras su odisea con el conector, hay que sustituirlo.
Nada de eso bloquea el objetivo real. El siguiente capítulo es la visión: un detector de gatos ligero, que funcione íntegramente en el propio dispositivo, sobre TensorFlow Lite y OpenCV, sin que ningún fotograma de la cámara salga jamás de la Raspberry Pi. Aquí la privacidad no es una ocurrencia tardía, es la restricción de diseño. Pancho prefiere una tarde tranquila y un vídeo de El Rey León; Nala es una gatita con el instinto cazador de un pequeño leopardo. Enseñar a un rover marciano rescatado a distinguirlos, y a jugar en consecuencia, es exactamente el tipo de problema de fin de semana que disfrutamos en LTC Labs.