Control Robótico con ROS: Construyendo un Sistema de Navegación Simple para Robots Móviles
Este tutorial te guiará en la creación de un sistema de navegación simple para robots móviles utilizando ROS (Robot Operating System). Explorarás los conceptos clave de ROS, configurarás sensores y actuarás sobre un robot virtual o físico para la navegación autónoma básica. ¡Prepárate para dar tus primeros pasos en la robótica avanzada!
Introducción a la Navegación Robótica con ROS 🤖
¡Bienvenido al emocionante mundo de la robótica y el sistema operativo para robots (ROS)! En este tutorial, nos embarcaremos en un viaje para construir un sistema de navegación simple para robots móviles. ROS es una poderosa suite de herramientas, librerías y convenciones que facilita la creación de aplicaciones robóticas complejas y distribuidas. Si alguna vez soñaste con que tu robot se moviera de forma autónoma, ¡estás en el lugar correcto!
La navegación robótica es una de las áreas más fascinantes y desafiantes de la robótica. Implica que un robot pueda moverse de un punto A a un punto B en un entorno desconocido o semi-desconocido, evitando obstáculos y planificando su propia ruta. Con ROS, este proceso se vuelve modular y manejable.
¿Qué es ROS y por qué usarlo para navegación? 🎯
ROS (Robot Operating System) no es un sistema operativo en el sentido tradicional, sino un meta-sistema operativo que proporciona funcionalidades similares a las de un sistema operativo en un clúster de computadoras conectadas. Ofrece servicios como abstracción de hardware, comunicación entre procesos, administración de paquetes y herramientas para la visualización y depuración.
Ventajas de ROS para la Navegación:
- Modularidad: Permite construir sistemas complejos a partir de componentes pequeños e independientes (
nodos). - Reusabilidad: Gran cantidad de paquetes existentes para diversas funcionalidades (sensores, actuadores, algoritmos de navegación, etc.).
- Comunidad: Una comunidad global activa que contribuye con código, soporte y documentación.
- Abstracción de Hardware: Permite que el mismo código funcione con diferentes plataformas robóticas.
🛠️ Requisitos Previos e Instalación
Antes de sumergirnos en la navegación, necesitamos preparar nuestro entorno. Asegúrate de tener lo siguiente:
- Sistema Operativo: Ubuntu (preferiblemente 20.04 LTS o 22.04 LTS, dependiendo de la versión de ROS).
- Conocimientos Básicos: Familiaridad con la línea de comandos de Linux y conceptos básicos de programación (Python o C++).
- Hardware (Opcional): Un robot móvil diferencial (como un TurtleBot o un robot DIY con ROS) o un simulador como Gazebo.
Instalación de ROS Noetic (Ubuntu 20.04 LTS) o ROS Foxy/Humble (Ubuntu 22.04 LTS)
Para este tutorial, asumiremos ROS Noetic (Ubuntu 20.04), pero los conceptos son fácilmente adaptables a versiones más recientes como Foxy o Humble. Si ya tienes ROS instalado, puedes saltarte esta sección.
- Configurar fuentes de paquetes:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
- Configurar claves:
sudo apt install curl # si no lo tienes instalado
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
- Actualizar índice de paquetes:
sudo apt update
- Instalar ROS Desktop Full:
sudo apt install ros-noetic-desktop-full # Para ROS Noetic
# o
# sudo apt install ros-foxy-desktop-full # Para ROS Foxy
# sudo apt install ros-humble-desktop-full # Para ROS Humble
- Inicializar rosdep:
sudo rosdep init
rosdep update
- Configurar el entorno de ROS:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
(Asegúrate de cambiar `noetic` por `foxy` o `humble` si instalaste otra versión).
🗺️ Conceptos Clave de Navegación en ROS
La navegación en ROS se basa en varios paquetes y conceptos interconectados que trabajan juntos para permitir que un robot se mueva de forma autónoma. Aquí están los pilares:
1. Sistema de Coordenadas y Transformaciones (TF) ✨
Los robots tienen múltiples sensores y actuadores, cada uno con su propio sistema de coordenadas. tf es un sistema que mantiene un árbol de relaciones de coordenadas espaciales entre marcos de referencia, permitiendo transformar puntos, vectores, etc., entre diferentes marcos en cualquier momento. Es fundamental para saber dónde está el robot en relación con el mundo y dónde están sus sensores.
Ejemplo de Marcos TF:
map: El marco de referencia del mundo, donde se construye el mapa.odom: El marco de referencia para la odometría del robot (posición y orientación estimadas a corto plazo).base_link: El centro del robot (su chasis).laser_frame: El marco donde está montado el sensor LiDAR.
2. Odometría (Odometry) 🚶
La odometría es la estimación de la posición y orientación de un robot a lo largo del tiempo, generalmente basada en la lectura de los encoders de las ruedas. Es una forma de localización relativa.
- Pros: Sencilla de implementar, funciona bien a corto plazo.
- Contras: Acumula errores con el tiempo (deriva), especialmente en superficies irregulares o con deslizamiento.
3. Mapeo y Localización Simultánea (SLAM) 🌍
SLAM (Simultaneous Localization and Mapping) es el proceso por el cual un robot construye un mapa de un entorno desconocido mientras se localiza simultáneamente dentro de ese mapa. Es un problema complejo pero crucial para la navegación autónoma.
Paquetes ROS comunes para SLAM:
gmapping: SLAM basado en LiDAR, usa filtros de partículas (partícula filtrada).cartographer: SLAM 2D y 3D, de Google, robusto y eficiente.Hector SLAM: SLAM basado en LiDAR de alta frecuencia, no requiere odometría inicial.
4. Navegación (ROS Navigation Stack) 🧭
El navigation stack de ROS es un conjunto de paquetes que proporciona la funcionalidad para que un robot se mueva de forma autónoma desde un punto A a un punto B. Utiliza la información de odometría, sensores (LiDAR, cámaras) y un mapa para planificar rutas y evitar obstáculos.
Componentes clave del Navigation Stack:
move_base: El nodo principal que orquesta todos los demás componentes para la navegación.global_planner: Planifica una ruta "global" desde el inicio hasta el objetivo en el mapa estático.local_planner: Planifica rutas "locales" y ajusta la trayectoria para evitar obstáculos dinámicos en tiempo real.costmap_2d: Crea mapas de costo que representan la probabilidad de colisión en diferentes áreas del entorno. Hay un costmap global (para elglobal_planner) y uno local (para ellocal_planner).
⚙️ Configurando el Entorno de Navegación
Para este tutorial, utilizaremos un robot virtual en Gazebo. Esto nos permite experimentar sin la necesidad de hardware físico. Asumiremos que tenemos un modelo de robot diferencial básico con un sensor LiDAR (o un sensor de profundidad simulado).
1. Creación del Workspace y Paquete 📦
Primero, crearemos un catkin workspace y un paquete ROS para nuestro proyecto de navegación.
cd ~/
mkdir -p catkin_ws/src
cd catkin_ws/src
catkin_init_workspace
catkin_create_pkg my_robot_navigation rospy tf nav_msgs geometry_msgs sensor_msgs # Ajusta las dependencias según necesites
cd ..
catkin_make
source devel/setup.bash
2. Simulación de Robot en Gazebo
Necesitamos un modelo de robot en Gazebo que publique mensajes de odometría (nav_msgs/Odometry), datos de láser (sensor_msgs/LaserScan) y que pueda recibir comandos de velocidad (geometry_msgs/Twist).
Normalmente, esto implica:
- Un archivo URDF (Unified Robot Description Format) que describe la geometría, cinemática y sensores del robot.
- Archivos de lanzamiento (
.launch) para Gazebo que cargan el modelo del robot y los plugins necesarios (ej.gazebo_ros_diff_drivepara el control diferencial ygazebo_ros_laserpara el LiDAR).
Para simplificar, usaremos el turtlebot3_simulations como base. Puedes instalarlo con:
sudo apt install ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-navigation
Una vez instalado, podemos lanzar el robot en un entorno de Gazebo.
export TURTLEBOT3_MODEL=burger # O waffle, o waffle_pi
roslaunch turtlebot3_gazebo turtlebot3_world.launch
Esto abrirá Gazebo con un TurtleBot3 en un mundo predefinido. Abre otra terminal y verifica los tópicos:
rostopic list
Deberías ver tópicos como /odom, /scan, /cmd_vel, etc.
3. Configuración del navigation stack
El navigation stack se configura a través de varios archivos .yaml y .launch.
Los archivos .yaml más importantes son:
costmap_common_params.yaml: Parámetros comunes para los costmaps global y local (tamaño del robot, sensores).global_costmap_params.yaml: Parámetros específicos para el costmap global.local_costmap_params.yaml: Parámetros específicos para el costmap local.base_local_planner_params.yaml: Parámetros para el planificador local (DWA, Trajectory Rollout, etc.).
Estos archivos suelen estar en el paquete my_robot_navigation/config.
Ejemplo costmap_common_params.yaml (simplificado):
robot_radius: 0.18 # Radio del robot en metros
footprint: [[-0.105, -0.105], [-0.105, 0.105], [0.105, 0.105], [0.105, -0.105]] # Huella poligonal
laser_scan_sensor:
sensor_frame: base_scan
topic: scan
observation_sources: laser_scan_sensor
data_type: LaserScan
clearing: true
marking: true
obstacle_layer:
observation_sources: laser_scan_sensor
laser_scan_sensor: {sensor_frame: base_scan, data_type: LaserScan, topic: scan, marking: true, clearing: true}
Ejemplo global_costmap_params.yaml:
global_costmap:
global_frame: map
robot_base_frame: base_footprint
update_frequency: 1.0
publish_frequency: 1.0
static_map: true
transform_tolerance: 0.5
Ejemplo local_costmap_params.yaml:
local_costmap:
global_frame: odom
robot_base_frame: base_footprint
update_frequency: 5.0
publish_frequency: 2.0
static_map: false
rolling_window: true
width: 3.0
height: 3.0
resolution: 0.05
Ejemplo base_local_planner_params.yaml (usando DWA Planner):
DWAPlannerROS:
max_vel_x: 0.2
min_vel_x: -0.2
max_vel_theta: 1.0
min_vel_theta: -1.0
acc_lim_x: 2.5
acc_lim_theta: 3.2
# Goal Tolerance Parameters
yaw_goal_tolerance: 0.05
xy_goal_tolerance: 0.10
# Forward Simulation Parameters
sim_time: 1.7
sim_granularity: 0.025
goal_distance_bias: 32.0
path_distance_bias: 24.0
occdist_scale: 0.02
# Trajectory Scoring Parameters
pdist_scale: 0.6
gdist_scale: 0.8
occdist_scale: 0.01
4. Lanzamiento de Navegación 🚀
Para lanzar el navigation stack completo, necesitamos un archivo .launch que cargue todos los parámetros y los nodos necesarios (principalmente move_base).
Crea un archivo my_robot_navigation/launch/my_robot_navigation.launch:
<launch>
<!-- Carga de parámetros del navigation stack -->
<rosparam file="$(find my_robot_navigation)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find my_robot_navigation)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find my_robot_navigation)/config/local_costmap_params.yaml" command="load" />
<rosparam file="$(find my_robot_navigation)/config/global_costmap_params.yaml" command="load" />
<rosparam file="$(find my_robot_navigation)/config/base_local_planner_params.yaml" command="load" />
<!-- Nodo move_base -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />
<remap from="cmd_vel" to="cmd_vel"/>
<remap from="odom" to="odom"/>
<param name="global_costmap/laser_scan_sensor/topic" value="scan"/>
<param name="local_costmap/laser_scan_sensor/topic" value="scan"/>
</node>
</launch>
🗺️ Mapeo y Localización (SLAM) con GMapping
Para que el robot navegue, necesita un mapa del entorno. Usaremos gmapping para crear un mapa 2D del mundo de Gazebo.
1. Lanzar GMapping
En una nueva terminal, lanza el nodo gmapping. Si estás usando el TurtleBot3, ya hay un archivo de lanzamiento para esto.
export TURTLEBOT3_MODEL=burger
roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping
Esto iniciará gmapping y también rviz (Robot Visualization) para que puedas ver el proceso de mapeo.
2. Explorar el Entorno para Crear el Mapa
Ahora, necesitas mover el robot para que explore el entorno y gmapping pueda construir el mapa. Puedes hacerlo manualmente usando un joystick, publicando mensajes /cmd_vel o usando un nodo de teleoperación.
Para teleoperar el TurtleBot3:
export TURTLEBOT3_MODEL=burger
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
Mientras mueves el robot, observa RVIZ. Deberías ver cómo se construye el mapa en la ventana "Map".
3. Guardar el Mapa
Una vez que estés satisfecho con el mapa, guárdalo:
rosrun map_server map_saver -f ~/catkin_ws/src/my_robot_navigation/maps/my_gazebo_map
Esto creará dos archivos: my_gazebo_map.pgm (la imagen del mapa) y my_gazebo_map.yaml (metadatos del mapa).
🚀 Navegación Autónoma: ¡Movimiento!
Con un mapa guardado, el siguiente paso es la navegación autónoma. Ahora usaremos el navigation stack con nuestro mapa estático.
1. Lanzar el Mapa y el Nodo amcl (Localización Adaptativa)
amcl (Adaptive Monte Carlo Localization) es un algoritmo de localización probabilística que utiliza un filtro de partículas para localizar un robot en un mapa estático conocido. Es crucial para corregir la deriva de la odometría.
Para lanzar el mapa y amcl, puedes usar un archivo de lanzamiento como este (o el proporcionado por TurtleBot3):
<launch>
<!-- Mapa estático -->
<arg name="map_file" default="$(find my_robot_navigation)/maps/my_gazebo_map.yaml"/>
<node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)" />
<!-- Nodo AMCL -->
<include file="$(find amcl)/examples/amcl_diff.launch">
<arg name="initial_pose_x" value="0.0"/>
<arg name="initial_pose_y" value="0.0"/>
<arg name="initial_pose_a" value="0.0"/>
<arg name="odom_frame_id" value="odom"/>
<arg name="base_frame_id" value="base_footprint"/>
<arg name="global_frame_id" value="map"/>
</include>
<!-- Nodo de navegación (move_base) -->
<include file="$(find my_robot_navigation)/launch/my_robot_navigation.launch"/>
<!-- RVIZ para visualización -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_robot_navigation)/rviz/my_navigation.rviz"/>
</launch>
Guarda esto como my_robot_navigation/launch/start_navigation.launch. Asegúrate de que los archivos .yaml de move_base y el archivo .rviz estén configurados correctamente. Para el .rviz, puedes empezar con una configuración básica y añadir los displays de Map, RobotModel, LaserScan, Path y PoseArray (para AMCL).
Lanza el robot en Gazebo (si no está ya activo) y luego tu pila de navegación:
export TURTLEBOT3_MODEL=burger
roslaunch turtlebot3_gazebo turtlebot3_world.launch # Si no está activo
roslaunch my_robot_navigation start_navigation.launch
2. Localización Inicial en RVIZ
Cuando amcl se inicia, el robot no sabe dónde está en el mapa. Necesitas "darle una pista" de su posición inicial.
- En RVIZ, haz clic en el botón "2D Pose Estimate" (generalmente una flecha con un cuadrado).
- Haz clic y arrastra en el mapa para indicar la posición y orientación aproximadas del robot.
Verás un "enjambre" de flechas (partículas) que se concentrarán a medida que el robot se mueva y amcl refine su posición.
3. Establecer un Objetivo de Navegación
Una vez que el robot esté localizado, puedes darle un objetivo:
- En RVIZ, haz clic en el botón "2D Nav Goal" (generalmente una flecha con una 'G').
- Haz clic y arrastra en el mapa para indicar la posición y orientación final deseada para el robot.
El navigation stack calculará una ruta global, y el planificador local comenzará a mover el robot, ajustando su trayectoria para evitar obstáculos.
4. Monitoreo y Depuración
rqt_graph: Visualiza el grafo de nodos y tópicos de ROS para entender el flujo de datos.rostopic echo /cmd_vel: Verifica qué comandos de velocidad está enviando elmove_base.rostopic hz /scan: Comprueba la frecuencia de publicación de los sensores.rosrun tf tf_echo map odom: Muestra la transformación entre los marcosmapyodom, crucial para verificar la localización.
📈 Optimizando la Navegación
La navegación es un campo complejo y la optimización es clave para un rendimiento robusto.
1. Parámetros del Costmap
robot_radiusofootprint: Ajusta estos valores para que representen con precisión el tamaño de tu robot y evite colisiones.inflation_radius: Define qué tan lejos de un obstáculo el robot comenzará a considerarlo como un "costo" para planificar.observation_sources: Asegúrate de que todos los sensores relevantes (LiDAR, cámaras de profundidad) estén configurados para marcar y/o borrar obstáculos en el costmap.
2. Parámetros del Planificador Local (DWA Planner)
El DWAPlannerROS tiene muchos parámetros para controlar el comportamiento del robot. Experimenta con ellos cuidadosamente.
| Parámetro | Descripción | Impacto |
|---|---|---|
| --- | --- | --- |
max_vel_x | Velocidad lineal máxima en X | Velocidad máxima del robot |
max_vel_theta | Velocidad angular máxima en Z | Capacidad de giro del robot |
| --- | --- | --- |
acc_lim_x | Aceleración lineal máxima en X | Suavidad de las aceleraciones/frenadas |
sim_time | Tiempo de simulación para evaluar trayectorias | Cuanto más largo, más "vista" hacia el futuro |
| --- | --- | --- |
path_distance_bias | Pondera qué tan cerca debe estar de la ruta global | Ayuda a seguir la ruta planificada |
occdist_scale | Pondera la proximidad a obstáculos | Evitar colisiones |
3. Integración de Sensores Adicionales
Para entornos más complejos, podrías necesitar:
- Cámaras de profundidad (Kinect, RealSense): Para detectar obstáculos por encima o por debajo del plano del LiDAR.
- Sensores ultrasónicos/IR: Para detección de corto alcance.
- IMU: Para una mejor estimación de la orientación del robot.
¿Por qué la odometría sola no es suficiente?
La odometría basada en encoders de ruedas es propensa a errores acumulativos debido al deslizamiento, las imperfecciones del suelo o el simple redondeo de valores. A largo plazo, la posición reportada por la odometría se "desvía" de la posición real. Por eso es crucial combinarla con un sensor externo (LiDAR, cámara) y un algoritmo de localización como AMCL o SLAM.Conclusión y Próximos Pasos ✅
¡Felicidades! Has completado un viaje intensivo a través de la configuración de un sistema de navegación simple para robots móviles utilizando ROS. Hemos cubierto desde la instalación de ROS hasta la configuración de la simulación, el mapeo con gmapping, la localización con amcl y, finalmente, la navegación autónoma con el move_base.
Este es solo el comienzo. La robótica con ROS es un campo vasto y en constante evolución. Aquí hay algunos pasos para continuar tu aprendizaje:
- Explora otros algoritmos SLAM: Investiga
CartographeroHector SLAMpara ver sus ventajas en diferentes escenarios. - Integrar con Hardware Real: Aplica estos conceptos a un robot físico (ej. TurtleBot3, tu propio robot DIY).
- Navegación en Entornos Dinámicos: Aprende sobre cómo manejar objetos en movimiento y personas en el entorno del robot.
- Planificación de Misiones: Desarrolla scripts para enviar múltiples objetivos de navegación secuencialmente.
- Percepción Avanzada: Incorpora visión por computadora para reconocimiento de objetos y detección de semántica del entorno.
La robótica es una disciplina que recompensa la perseverancia y la experimentación. ¡Sigue construyendo, aprendiendo y haciendo que tus robots cobren vida!
Tutoriales relacionados
- Robots ORCA: Diseño y Construcción de un Robot Submarino de Código Abierto para Exploraciónintermediate25 min
- Diseño y Construcción de un Robot Móvil Diferencial Controlado por ESP32intermediate20 min
- Diseño y Programación de un Brazo Robótico de 3 Grados de Libertad con Servomotoresintermediate25 min
- Navegación Autónoma para Rovers: Sensores y Algoritmos para Evitar Obstáculosintermediate18 min
- Control Robótico Avanzado con Visión Artificial para Clasificación de Objetos ✨intermediate30 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!