Objetivo y caso de uso
Qué construirás: Un UGV tipo Beast con Raspberry Pi 4 y cámara Arducam OV5647, ejecutando ROS 2 Humble y un nodo propio ros2-line-follower-camera para seguir una línea negra en el suelo.
Para qué sirve
- Automatizar un robot de reparto interno que sigue una ruta marcada en el suelo dentro de un almacén.
- Guiar un vehículo educativo en circuitos de competición de seguidores de línea, con curvas suaves y cambios moderados de iluminación.
- Implementar rutas predefinidas en laboratorios o fábricas para mover piezas ligeras entre estaciones sin usar sensores adicionales.
- Prototipar AGVs de logística interna que se orientan únicamente con visión monocular (cámara frontal) y una línea en el piso.
- Practicar visión artificial básica aplicada a robótica móvil en ROS 2, incluyendo publicación de imágenes y control de velocidad.
Resultado esperado
- Mantener el centro del robot dentro de un corredor de ±5 cm respecto al centro de la línea durante al menos el 90 % del recorrido en un circuito simple.
- Publicar imágenes de la cámara en
/camera/image_rawa ≥ 15 FPS con carga de CPU < 70 % en la Raspberry Pi 4. - Publicar comandos de velocidad en
/cmd_veldesderos2-line-follower-cameraa ≥ 10 Hz, con latencia desde captura de imagen hasta comando < 100 ms. - Completar un circuito cerrado de prueba (p. ej., 10–20 m con 3–4 curvas amplias) sin salirse de la línea más de 2 veces por vuelta.
Público objetivo: Estudiantes de robótica, makers y desarrolladores que comienzan con ROS 2 en plataformas móviles; Nivel: Inicial–intermedio en ROS 2 y Linux, básico en visión por computador.
Arquitectura/flujo: La cámara Arducam OV5647 se conecta a la Raspberry Pi 4, que ejecuta un nodo de cámara (publica en /camera/image_raw) y el nodo ros2-line-follower-camera; este nodo procesa cada frame, detecta la posición de la línea, calcula el error lateral y el ángulo de la línea, los traduce en comandos de velocidad lineal y angular que publica en /cmd_vel, y el controlador del UGV aplica dichos comandos a los motores en tiempo casi real.
Prerrequisitos (SO, versiones y toolchain concreta)
Sistema operativo y hardware
- Plataforma principal:
- Raspberry Pi 4 Model B 4GB (aarch64)
- Sistema operativo:
- Ubuntu Server 22.04 LTS 64‑bit para Raspberry Pi (aarch64), sin entorno gráfico.
- Conectividad:
- Acceso SSH a la Raspberry Pi desde un PC en la misma red (para editar, compilar y probar).
Toolchain y versiones
En la Raspberry Pi (aarch64):
- ROS 2:
- Distribución: ROS 2 Humble Hawksbill
- Paquetes instalados vía
apt: ros-humble-desktopros-humble-ros2-controlros-humble-diff-drive-controllerros-humble-robot-localizationros-humble-slam-toolboxros-humble-nav2-bringupros-humble-nav2-costmap-2dros-humble-nav2-controllerros-humble-nav2-plannerros-humble-nav2-behavior-treeros-humble-nav2-lifecycle-managerros-humble-rviz2- Lenguaje principal para el nodo seguidor de línea:
- Python 3.10 (incluido en Ubuntu 22.04)
- Compilación:
colconversión instalada desde repositorios de Ubuntu (python3-colcon-common-extensions)- Gestión de paquetes:
apt(Ubuntu)- Control de versiones (opcional pero recomendado):
git≥ 2.34
Materiales
Lista de materiales principales
- 1 × Raspberry Pi 4 Model B 4GB + Arducam 5MP OV5647 Camera Module (modelo exacto solicitado).
- 1 × Tarjeta microSD (32 GB o más, clase 10), con Ubuntu Server 22.04 64‑bit instalado.
- 1 × Chasis de robot tipo UGV Beast con:
- 2 motores DC con encoder (tracción diferencial).
- 2 ruedas motrices + rueda loca.
- Controlador de motores (por ejemplo, un driver tipo L298N o un hat específico para la plataforma Beast).
- 1 × Fuente de alimentación/batería adecuada para el UGV (por ejemplo, LiPo 2S–3S con BEC o banco de baterías con regulación).
- 1 × Cable USB para depuración (si el chasis incluye microcontrolador adicional).
- 1 × Conexión a red (Ethernet o Wi-Fi configurado en la Raspberry Pi).
- Cables Dupont macho-macho / macho-hembra para la conexión GPIO (si el driver de motores se controla desde la Pi).
Material opcional (pero útil)
- Regla o metro para medir desplazamientos reales y calibrar el robot.
- Cinta aislante negra para marcar la línea en el suelo.
- Cartulina blanca o espuma EVA blanca como fondo de alto contraste.
Preparación y conexión
1. Preparación del sistema operativo y ROS 2 Humble
- Instala Ubuntu Server 22.04 64‑bit (aarch64) en la microSD (por ejemplo con Raspberry Pi Imager).
- Arranca la Raspberry Pi 4 con la microSD y conéctala a red.
- Actualiza el sistema:
bash
sudo apt update
sudo apt upgrade -y
- Instala ROS 2 Humble y paquetes necesarios:
bash
sudo apt install -y \
ros-humble-desktop \
ros-humble-ros2-control \
ros-humble-diff-drive-controller \
ros-humble-robot-localization \
ros-humble-slam-toolbox \
ros-humble-nav2-bringup \
ros-humble-nav2-costmap-2d \
ros-humble-nav2-controller \
ros-humble-nav2-planner \
ros-humble-nav2-behavior-tree \
ros-humble-nav2-lifecycle-manager \
ros-humble-rviz2 \
python3-colcon-common-extensions \
python3-argcomplete \
git
- Añade el
setup.bashde ROS 2 a tu.bashrc:
bash
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
2. Habilitar la cámara Arducam 5MP OV5647 en Raspberry Pi 4
En Ubuntu Server 22.04 para Raspberry Pi, la cámara se habilita mediante:
- Editar
/boot/firmware/config.txt:
bash
sudo nano /boot/firmware/config.txt
- Asegúrate de tener estas líneas (y sin
#):
text
start_x=1
gpu_mem=128
dtoverlay=imx219 # En algunas imágenes se usa este overlay genérico para cámaras; revisar documentación Arducam
Nota: Algunas versiones de firmware usan dtoverlay=ov5647. Si tu módulo Arducam 5MP OV5647 tiene documentación que especifica este overlay, usa:
text
dtoverlay=ov5647
- Guarda y reinicia:
bash
sudo reboot
- Verifica que el dispositivo de cámara está presente (según kernel/driver, puede ser
/dev/video0):
bash
ls /dev/video*
Debe aparecer algo como /dev/video0.
3. Conexión física de la cámara al Raspberry Pi 4
La Arducam 5MP OV5647 Camera Module se conecta mediante el conector CSI:
- En la Raspberry Pi 4 hay un conector FPC (flex cable) cerca del conector HDMI.
- Pasos (sin electricidad):
- Apaga la Raspberry Pi y desconecta la alimentación.
- Levanta suavemente la pestaña negra del conector CSI.
- Inserta el cable plano de la Arducam con los contactos metálicos apuntando hacia los contactos del conector de la Pi.
- Vuelve a bajar la pestaña hasta fijar el cable.
- Conecta la alimentación y arranca.
4. Conexión del controlador de motores al Raspberry Pi 4
No dibujaremos esquema, pero describimos la conexión lógica típica (ejemplo con driver tipo L298N y motores DC):
| Elemento | Conexión en Raspberry Pi 4 | Descripción breve |
|---|---|---|
IN1 driver motor |
GPIO 17 (pin físico 11) | Dirección rueda izquierda (bit 1) |
IN2 driver motor |
GPIO 27 (pin físico 13) | Dirección rueda izquierda (bit 2) |
IN3 driver motor |
GPIO 22 (pin físico 15) | Dirección rueda derecha (bit 1) |
IN4 driver motor |
GPIO 23 (pin físico 16) | Dirección rueda derecha (bit 2) |
ENA (PWM izquierda) |
GPIO 18 (pin físico 12, PWM) | Control velocidad izquierda |
ENB (PWM derecha) |
GPIO 13 (pin físico 33, PWM) | Control velocidad derecha |
| GND driver | GND Raspberry Pi (ej: pin 6) | Referencia común |
| +12 V (o según motores) | Batería / fuente externa | Alimentación motores (no desde la Pi) |
| 5 V lógica driver (si hay) | 5 V Pi (pin 2 o 4, según driver) | Solo lógica, revisa que no back-feed 5 V |
Importante: Asegúrate de que la masa (GND) de la Raspberry Pi y la del driver de motores está unida. Si tu chasis UGV Beast trae su propia placa controladora, adapta estos pines según la documentación del fabricante, pero mantén la lógica de “2 GPIO de dirección + 1 PWM por motor”.
Código completo del seguidor de línea con cámara
Crearemos un paquete ROS 2 en Python dentro de un workspace ~/ros2_ws. Este paquete:
- Se llamará
ros2_line_follower_camera. - Tendrá un nodo
line_follower_node.pyque: - Suscribe al tópico de la cámara
/camera/image_raw. - Usa OpenCV para procesar la imagen, detectar la línea negra en el suelo.
- Calcula un error horizontal (distancia del centro de la línea al centro de la imagen).
- Genera comandos de velocidad (lineal y angular) en
/cmd_velpara un robot diferencial controlado pordiff_drive_controller.
1. Crear el workspace y el paquete
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python ros2_line_follower_camera
Instala dependencias necesarias para procesamiento de imágenes:
sudo apt install -y python3-opencv python3-numpy
Edita el archivo package.xml del paquete (~/ros2_ws/src/ros2_line_follower_camera/package.xml) y asegúrate de incluir dependencias:
<exec_depend>rclpy</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>geometry_msgs</exec_depend>
<exec_depend>cv_bridge</exec_depend>
Instala ros-humble-cv-bridge:
sudo apt install -y ros-humble-cv-bridge
2. Nodo Python line_follower_node.py
Crea el archivo ~/ros2_ws/src/ros2_line_follower_camera/ros2_line_follower_camera/line_follower_node.py:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from geometry_msgs.msg import Twist
from cv_bridge import CvBridge
import cv2
import numpy as np
class LineFollowerNode(Node):
def __init__(self):
super().__init__('line_follower_node')
# Parámetros configurables
self.declare_parameter('camera_topic', '/camera/image_raw')
self.declare_parameter('linear_speed', 0.15) # m/s
self.declare_parameter('kp_angular', 0.0025) # ganancia proporcional
self.declare_parameter('view_height_ratio', 0.3) # zona inferior de la imagen a usar
camera_topic = self.get_parameter('camera_topic').get_parameter_value().string_value
self.linear_speed = self.get_parameter('linear_speed').get_parameter_value().double_value
self.kp_angular = self.get_parameter('kp_angular').get_parameter_value().double_value
self.view_height_ratio = self.get_parameter('view_height_ratio').get_parameter_value().double_value
# Puente ROS 2 <-> OpenCV
self.bridge = CvBridge()
# Suscriptor a la cámara
self.image_sub = self.create_subscription(
Image,
camera_topic,
self.image_callback,
10
)
# Publicador de velocidad
self.cmd_vel_pub = self.create_publisher(Twist, '/cmd_vel', 10)
self.get_logger().info(f'Line follower node iniciado. Suscrito a {camera_topic}')
def image_callback(self, msg: Image):
# Convertir a imagen OpenCV
try:
frame = self.bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
except Exception as e:
self.get_logger().error(f'Error al convertir imagen: {e}')
return
height, width, _ = frame.shape
# Usar solo la franja inferior de la imagen para buscar la línea
roi_height = int(height * self.view_height_ratio)
y_start = height - roi_height
roi = frame[y_start:height, 0:width]
# Convertir a escala de grises
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
# Suavizar para reducir ruido
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# Umbral binario: asumimos línea negra sobre fondo claro
_, binary = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Encontrar contornos
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if contours:
# Tomar el contorno más grande como la línea principal
largest_contour = max(contours, key=cv2.contourArea)
M = cv2.moments(largest_contour)
if M['m00'] > 0:
cx = int(M['m10'] / M['m00']) # centroide x
cy = int(M['m01'] / M['m00']) # centroide y (en ROI)
# Error de posición (positivo si la línea está a la derecha)
error_x = cx - width // 2
# Control proporcional para la velocidad angular
angular_z = -self.kp_angular * float(error_x)
# Crear mensaje Twist
cmd = Twist()
cmd.linear.x = self.linear_speed
cmd.angular.z = angular_z
self.cmd_vel_pub.publish(cmd)
self.get_logger().debug(
f'Linea detectada: cx={cx}, error_x={error_x}, ang_z={angular_z:.3f}'
)
else:
# No se pudo calcular el centroide: para el robot
self.stop_robot('Moment zero area (m00=0)')
else:
# Sin contornos: línea no encontrada, parar robot
self.stop_robot('No se encontraron contornos para la línea')
def stop_robot(self, reason: str):
cmd = Twist()
cmd.linear.x = 0.0
cmd.angular.z = 0.0
self.cmd_vel_pub.publish(cmd)
self.get_logger().warn(f'Robot detenido: {reason}')
def main(args=None):
rclpy.init(args=args)
node = LineFollowerNode()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.stop_robot('Nodo finalizado')
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Dale permisos de ejecución:
chmod +x ~/ros2_ws/src/ros2_line_follower_camera/ros2_line_follower_camera/line_follower_node.py
3. Ajustar setup.py del paquete
Edita ~/ros2_ws/src/ros2_line_follower_camera/setup.py:
from setuptools import setup
package_name = 'ros2_line_follower_camera'
setup(
name=package_name,
version='0.0.1',
packages=[package_name],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='tu_nombre',
maintainer_email='tu_email@example.com',
description='Nodo seguidor de línea usando cámara OV5647 en Raspberry Pi 4 con ROS 2 Humble',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'line_follower_node = ros2_line_follower_camera.line_follower_node:main',
],
},
)
Modelado del robot (URDF + ros2_control + diff_drive_controller)
Aunque el foco es el seguidor de línea, necesitamos que el UGV Beast se expose en ROS 2 como robot diferencial. Crearemos un URDF sencillo con diff_drive_controller.
1. Parámetros geométricos del UGV Beast
Debes medir tu robot:
- Radio de rueda (
wheel_radius): por ejemplo, 0.03 m (ruedas de 6 cm de diámetro). - Distancia entre centros de ruedas (
wheel_separationo track width): por ejemplo, 0.18 m.
Añade estos valores a un archivo YAML de parámetros del controlador.
2. URDF simplificado
Crea un paquete de descripción ugv_beast_description:
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake ugv_beast_description
Dentro crea urdf/ugv_beast.urdf.xacro. Para no alargar excesivamente, indicamos los elementos clave que deben existir:
base_linkleft_wheel_linkyright_wheel_link- Juntas
left_wheel_jointyright_wheel_jointde tipocontinuous - Plugin
ros2_controlcon hardware ydiff_drive_system.
En este caso práctico básico asumiremos que el control bajo nivel (GPIO/PWM) está gestionado fuera de ros2_control (por ejemplo, por un nodo propio o por firmware de la placa del Beast). Lo importante es que el diff_drive_controller publique/consuma /cmd_vel y odom.
Compilación, instalación y ejecución
1. Compilar el workspace con colcon
cd ~/ros2_ws
colcon build
Una vez completado:
echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc
2. Nodo de la cámara
Dependiendo del driver utilizado, puedes exponer la cámara como un nodo ROS 2. Una opción ligera en Ubuntu es usar un nodo genérico tipo v4l2_camera (si lo instalas). Para mantener el caso práctico sencillo, puedes usar un nodo ejemplo como image_tools (incluido en ros-humble-desktop) adaptado, pero lo más realista es:
Instalar v4l2_camera:
sudo apt install -y ros-humble-v4l2-camera
Lanzar el nodo de cámara:
ros2 run v4l2_camera v4l2_camera_node --ros-args -p video_device:=/dev/video0 -p image_size:="[640,480]"
Este nodo publicará en /image_raw. Ajusta el parámetro de tu line_follower_node para usar ese tópico, o remapea.
Ejemplo ejecutando el seguidor de línea con remapeo:
ros2 run ros2_line_follower_camera line_follower_node \
--ros-args -p camera_topic:=/image_raw
3. Lanzar el controlador diferencial (diff_drive_controller)
Asumiendo que tienes un ros2_control configurado y un archivo de parámetros YAML, lanzarías algo como:
ros2 launch ugv_beast_bringup ugv_beast_diff_drive.launch.py
En este caso práctico básico, si aún no tienes implementada la parte ros2_control real con hardware, puedes:
- Probar el nodo
line_follower_nodesin movimiento, sólo examinando/cmd_vel. - Implementar posteriormente el puente
/cmd_vel→ GPIO/PWM según tu hardware.
Validación paso a paso
1. Verificar que la cámara funciona
- Asegúrate de que
/dev/video0existe:
bash
ls /dev/video0
- Lanza el nodo
v4l2_camera:
bash
ros2 run v4l2_camera v4l2_camera_node --ros-args -p video_device:=/dev/video0
- Comprueba que el tópico de imagen está activo:
bash
ros2 topic list
Debes ver algo como:
/image_raw-
/camera_info -
Comprueba el tipo de mensaje:
bash
ros2 topic echo /image_raw --qos-reliability best_effort --qos-durability volatile
Verás muchos datos binarios/imprimibles. Para medir tasa de publicación:
bash
ros2 topic hz /image_raw
Criterio de éxito: ≥ 15 Hz.
2. Verificar el nodo ros2-line-follower-camera
- Abre otra terminal (con
source ~/ros2_ws/install/setup.bash). - Lanza el nodo:
bash
ros2 run ros2_line_follower_camera line_follower_node \
--ros-args -p camera_topic:=/image_raw
- Comprueba que se crea el tópico
/cmd_vel:
bash
ros2 topic list | grep cmd_vel
- Mide la frecuencia de publicación de
/cmd_vel:
bash
ros2 topic hz /cmd_vel
Criterio de éxito: ≥ 10 Hz mientras haya imágenes entrantes.
-
Coloca delante de la cámara una superficie blanca con una línea negra (cinta aislante). Asegúrate de que la línea cruza la parte inferior del campo de visión de la cámara.
-
Cuando la línea esté centrada, espera ver que:
-
linear.x≈ valor del parámetrolinear_speed(0.15). -
angular.z≈ 0. -
Desplaza la línea hacia la izquierda/derecha; deberías observar:
-
Si la línea se mueve hacia la derecha en la imagen (error positivo),
angular.zserá negativo (gira hacia la derecha, según la convención de tu robot). - Si la línea se mueve hacia la izquierda,
angular.zserá positivo.
Puedes comprobarlo con:
bash
ros2 topic echo /cmd_vel
3. Validar en el UGV Beast en movimiento
- Coloca el UGV Beast en el suelo sobre una pista con línea negra sobre blanco (recta de al menos 2–3 m).
- Lanza los nodos:
-
Cámara:
bash
ros2 run v4l2_camera v4l2_camera_node --ros-args -p video_device:=/dev/video0 -p image_size:="[640,480]" -
Seguidor de línea:
bash
ros2 run ros2_line_follower_camera line_follower_node \
--ros-args -p camera_topic:=/image_raw -p linear_speed:=0.10 -p kp_angular:=0.003 -
Si el puente
cmd_vel→ motores está funcional (pordiff_drive_controllero nodo propio), el robot empezará a moverse hacia adelante y ajustar su dirección. -
Criterios de validación medibles:
- El robot no se sale de la línea más de 5 cm lateralmente en la mayoría del recorrido.
- En curvas suaves, el robot desacelera el giro adecuadamente y no “zigzaguea” de manera extrema.
- El movimiento responde en menos de 0.3 s al mover la línea manualmente.
Troubleshooting (errores típicos y soluciones)
1. No aparece /dev/video0
Síntoma: ls /dev/video* no muestra /dev/video0.
Causas y soluciones:
– La cámara no está bien conectada:
– Apaga la Pi, revisa el cable plano FPC, verifica orientación y que la pestaña CSI está bien fijada.
– Configuración en config.txt incorrecta:
– Asegúrate de tener:
```text
start_x=1
gpu_mem=128
dtoverlay=ov5647 # o el recomendado por Arducam para OV5647
```
- Reinicia después de modificarlo.
- Firmware/overlay no soporta esa cámara:
- Revisa la documentación de Arducam 5MP OV5647 para Ubuntu 22.04 en Raspberry Pi 4; puede requerir un overlay distinto o actualización de firmware.
2. line_follower_node falla al convertir la imagen
Síntoma: En la consola, mensajes: Error al convertir imagen.
Causas y soluciones:
– Tipo de codificación no soportado:
– Asegúrate de que el nodo de cámara publica en un formato compatible (bgr8 o convertible).
– Con ros2 topic echo /image_raw -n 1, revisa el campo encoding.
– Si es yuyv o similar, modifica:
```python
frame = self.bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
```
por
```python
frame = self.bridge.imgmsg_to_cv2(msg)
```
y prueba.
3. Proceso de detección no encuentra contornos
Síntoma: El robot se mantiene parado con alertas Robot detenido: No se encontraron contornos para la línea.
Causas y soluciones:
– Contraste insuficiente entre línea y fondo:
– Usa fondo blanco brillante (cartulina) y cinta negra muy oscura.
– Aumenta iluminación.
– Umbral inadecuado:
– En lugar de umbral automático OTSU, prueba con un valor fijo:
```python
_, binary = cv2.threshold(blur, 100, 255, cv2.THRESH_BINARY_INV)
```
- Ajusta
100a tu entorno. - La línea está fuera de la región de interés:
- Cambia
view_height_ratio(por ejemplo, 0.5 para usar media imagen).
4. El robot oscila mucho (zigzag)
Síntoma: El UGV empeora la trayectoria, corrigiendo en exceso la dirección.
Causas y soluciones:
– Ganancia kp_angular demasiado alta:
– Reduce el valor: por ejemplo, de 0.003 a 0.0015.
– Velocidad lineal demasiado alta:
– Baja linear_speed a 0.08 o 0.05 m/s para principiantes.
– Retardo elevado de cámara:
– Reduce resolución (image_size:="[320,240]") para aumentar FPS.
5. Tópico /cmd_vel no llega al controlador de motores
Síntoma: Ves datos en /cmd_vel pero las ruedas no se mueven.
Causas y soluciones:
– diff_drive_controller no está configurado:
– Asegúrate de haber creado y lanzado un controller_manager con diff_drive_controller.
– Puente hardware no implementado:
– Este caso práctico no entra al detalle de GPIO/PWM; necesitás un nodo que subscribe /cmd_vel y maneje los pines o que tu placa Beast haga de interfaz.
– Espacio de nombres (namespace) diferente:
– Verifica que tu controlador espera /cmd_vel y no otro tópico como /diff_drive_controller/cmd_vel_unstamped.
6. ros2 topic hz /image_raw muestra tasas muy bajas (≤ 5 Hz)
Síntoma: La cámara publica a muy baja frecuencia, el robot reacciona tarde.
Causas y soluciones:
– Resolución demasiado alta:
– Reduce image_size a [320,240] en v4l2_camera.
– Exceso de carga de CPU:
– Verifica con top que no haya otros procesos pesados.
– Desactiva nodos innecesarios durante pruebas.
7. Error al construir el workspace con colcon
Síntoma: colcon build falla en ros2_line_follower_camera con errores de dependencias.
Causas y soluciones:
– Falta alguna dependencia en package.xml:
– Asegúrate de incluir rclpy, sensor_msgs, geometry_msgs, cv_bridge.
– No instalaste ros-humble-cv-bridge o python3-opencv:
– Instálalos con:
```bash
sudo apt install -y ros-humble-cv-bridge python3-opencv
```
- No ejecutaste
source /opt/ros/humble/setup.bashantes de compilar: - Asegúrate de que lo tienes en el
.bashrc.
Mejoras y variantes
Una vez tengas el caso básico funcionando, puedes plantear las siguientes mejoras:
-
Control más avanzado (PID)
En lugar de sólo control proporcional (kp_angular), añade términos integral y derivativo para suavizar y anticipar correcciones. -
Cálculo de la línea como recta
En vez de usar solo el centroide del contorno, usa técnicas como: - Ajuste de línea (regresión) a partir de puntos de la línea.
-
Hough transform para detectar segmentos.
-
Seguimiento de intersecciones
Extiende el algoritmo para reconocer cruces en T o intersecciones y tomar decisiones: - Girar a la izquierda o derecha según bandera.
-
Parar en un cruce y esperar orden externa (ej. topic de alto nivel).
-
Integrar con Nav2 y SLAM
Aunque aquí sólo usamos la línea, tu UGV Beast puede: - Mapear el entorno con
slam_toolbox. - Usar
nav2para navegación global cuando no haya línea. -
Combinar modos “seguimiento de línea” y “navegación libre”.
-
Publicar imágenes procesadas
Crea un tópico/line_follower/debug_imagepara ver por RViz o herramientas de visualización la binarización y contornos, ayudando a depurar. -
Parámetros dinámicos
Usa parámetros ROS 2 dinámicos para ajustarkp_angular,linear_speedyview_height_ratioen tiempo real sin reiniciar el nodo.
Checklist de verificación (para el alumno)
Marca cada ítem al completarlo:
- [ ] Ubuntu Server 22.04 64‑bit instalado y actualizado en Raspberry Pi 4 Model B 4GB.
- [ ] ROS 2 Humble y paquetes (
ros-humble-desktop,ros-humble-ros2-control,ros-humble-diff-drive-controller,ros-humble-robot-localization,ros-humble-slam-toolbox,ros-humble-nav2-*,ros-humble-rviz2) instalados conapt. - [ ] Cámara Arducam 5MP OV5647 Camera Module conectada al puerto CSI y habilitada en
/boot/firmware/config.txt. - [ ]
/dev/video0visible tras el arranque de la Raspberry Pi. - [ ] Nodo
v4l2_camerafuncionando y publicando en/image_rawa ≥ 15 Hz (ros2 topic hz /image_raw). - [ ] Workspace
~/ros2_wscreado, con paqueteros2_line_follower_cameray dependencias instaladas (cv_bridge,python3-opencv). - [ ]
colcon buildse ejecuta sin errores ysource ~/ros2_ws/install/setup.bashestá en.bashrc. - [ ] Nodo
line_follower_nodese ejecuta correctamente y crea el tópico/cmd_vel. - [ ] Con la línea negra en el campo de visión,
/cmd_velpublica valores razonables delinear.xyangular.z. - [ ] El puente
/cmd_vel→ controlador de motores del UGV Beast funciona y las ruedas reaccionan. - [ ] En una pista de al menos 5 m, el UGV Beast sigue la línea sin desviarse más de ±5 cm la mayor parte del tiempo.
Si todos los ítems están marcados, has completado con éxito el caso práctico ros2-line-follower-camera para el UGV Beast (ROS 2) – Raspberry Pi 4 Model B 4GB + Arducam 5MP OV5647 Camera Module a nivel básico.
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.




