PTENES
MÓDULO 4.4 · FUNDAMENTO

📡 LiDAR y mapas (SLAM)

Hasta ahora, tu robot sabía cuánto giraban las ruedas. Ahora va a ver las paredes en 360 grados con un LiDAR, dibujar el mapa del lugar y descubrir dónde está dentro de él al mismo tiempo. Todo empieza en la simulación; el LiDAR real entra cuando quieras.

6
Temas
Avanzado
Nivel
Fundamentos
Tipo
LiDAR 2D
Opcional (hay simulación)
0%
0 de 0 temas leídos · Sección 1 de 6

Contenido detallado

1

🔦 Qué ve un LiDAR (LaserScan)

Un LiDAR 2D es un sensor de distancia que gira. Emite un haz de luz infrarroja, mide cuánto tarda la luz en volver (o el ángulo en que regresa) y registra la distancia. Como el cabezal gira varias veces por segundo, cada vuelta se convierte en un «anillo» de cientos de mediciones alrededor del robot, todas a la misma altura. Es como un sensor ultrasónico del módulo 1.4, pero apuntando a todos lados al mismo tiempo y con precisión de centímetros.

🌱 ¿Eres nuevo aquí?

LiDAR viene de «Light Detection and Ranging»: medir distancias con luz. En ROS 2, cada vuelta del LiDAR llega como un mensaje del tipo sensor_msgs/msg/LaserScan, publicada en un tópico que por convención se llama /scan. El mensaje y el tópico son los mismos del módulo 4.1: un nodo publica y otros escuchan.

caja sombra robot + LiDAR

Cómo leer: cada línea ámbar es un haz y cada punto brillante es una medición que regresó. Observa la sombra cian detrás de la caja: el LiDAR solo ve la primera superficie que toca el haz. Para «ver» detrás, el robot tiene que moverse.

El mensaje LaserScan no guarda puntos (x, y). Guarda una lista de distancias y las reglas para saber el ángulo de cada una: dónde empieza la vuelta, dónde termina y cuántos grados separan una medición de la siguiente. Las mediciones que no regresaron aparecen como inf (nada al alcance) o quedan fuera de los límites range_min/range_max.

ranges[ ] (metros) 1.82 1.80 0.64 inf 2.31 … índice 01234 ángulo = angle_min + índice × angle_increment ej.: angle_min = −3,14 rad, incremento = 0,0087 rad (~0,5°) el índice 3 devolvió «inf»: no hay obstáculos dentro del alcance

Cómo leer: la fila de cajas es el vector ranges. Para dibujar el punto, ROS 2 toma el índice, calcula el ángulo con la fórmula cian y convierte (ángulo, distancia) en (x, y). RViz2 y slam_toolbox hacen ese cálculo por ti.

✓ El LiDAR 2D ve bien

  • ✓Paredes, puertas, muebles altos y patas de mesa a la altura del haz.
  • ✓Pasillos y esquinas: excelentes para hacer coincidir una vuelta con otra.
  • ✓En la oscuridad: trae su propia luz, no depende de la iluminación de la sala.

✗ El LiDAR 2D no ve

  • ✗Vidrio y espejos: la luz los atraviesa o rebota lejos.
  • ✗La superficie de una mesa por encima del haz y los objetos que quedan por debajo (juguetes, escalones).
  • ✗Escaleras que bajan: el suelo desaparece, pero el haz horizontal no lo detecta.

Por qué aprender

El LiDAR es el sensor más usado en robots móviles que navegan dentro de casa, desde aspiradoras hasta robots de almacén. Entender qué mide y qué no mide determina si tu robot esquivará la silla o chocará contra el vidrio de la puerta.

Conceptos clave

LiDAR 2D
distancia en 360°
LaserScan
lista de distancias
/scan
tópico predeterminado
Sombra
solo la 1.ª superficie
2

🔌 Conectar el LiDAR a ROS 2

Los LiDAR económicos más comunes para makers son el RPLIDAR C1 o A1 (Slamtec) y el LD19 (LDRobot). Todos se conectan a la PC o a la Raspberry Pi 5 mediante un adaptador USB-serial. Quien transforma los bytes del puerto serial en mensajes /scan es un controlador: un paquete ROS 2 del fabricante que compilas en tu workspace, como hiciste con colcon en el módulo 4.2.

LiDARC1/A1/LD19 nodo driverpaquete del fabricante RViz2 (ver) slam_toolbox (mapear) USB /scan TF: base_link → laser indica dónde está montado el LiDAR en el robot

Cómo leer: tu trabajo es solo la parte ámbar: conectar el USB e iniciar el nodo driver. A partir de /scan (cian), cualquier nodo de ROS 2 puede usar el dato. La frase de abajo señala el detalle que más suele fallar: sin la transformación base_link → laser, RViz2 no sabe dónde dibujar.

Paso a paso con el LiDAR real

1

Encuentra el puerto

Conecta el LiDAR y ejecuta ls /dev/ttyUSB*. Normalmente aparece /dev/ttyUSB0. Dale permiso a tu usuario con el grupo dialout (bloque de abajo) y cierra la sesión y vuelve a iniciarla.

2

Descarga y compila el driver

RPLIDAR: repositorio rplidar_ros de Slamtec (rama de ROS 2). LD19: ldlidar_stl_ros2 de LDRobot. Clónalo dentro de ~/ros2_ws/src y compílalo con colcon.

3

Inicia el launch de tu modelo

Cada driver incluye un launch por modelo. El nombre cambia entre versiones: lista la carpeta launch/ del paquete y usa el de tu sensor.

4

Comprueba en RViz2

En RViz2, configura Fixed Frame = laser (o el frame que use el driver), haz clic en Add → LaserScan y elige el tópico /scan.

Objetivo: ver el LiDAR publicando en /scan. El ejemplo usa el RPLIDAR; para el LD19, cambia el repositorio y el launch. Ejecútalo en una terminal con ROS 2 cargado (<distro> = jazzy o lyrical).

terminal
# 1) permiso para usar el puerto serial (cierra la sesión y vuelve a iniciarla después)
sudo usermod -aG dialout $USER

# 2) driver en el workspace (comprueba la rama de ROS 2 en el README del repositorio)
source /opt/ros/<distro>/setup.bash
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws/src
git clone https://github.com/Slamtec/rplidar_ros.git -b ros2
cd ~/ros2_ws && colcon build --symlink-install
source install/setup.bash

# 3) comprueba qué launch files tiene el paquete e inicia el de tu modelo
ls $(ros2 pkg prefix rplidar_ros)/share/rplidar_ros/launch
ros2 launch rplidar_ros rplidar_c1_launch.py serial_port:=/dev/ttyUSB0

# 4) en OTRA terminal: comprueba el tópico
ros2 topic hz /scan
ros2 topic echo /scan --once --field ranges

Cómo verificar

  • ✓El LiDAR empieza a girar y ros2 topic hz /scan muestra una tasa estable (cerca de 10 Hz en los modelos mencionados; consulta la ficha técnica del tuyo).
  • ✓O echo imprime una lista de números; acerca la mano al sensor y los valores de ese lado disminuyen.
  • ✗«Permission denied» en el puerto: el grupo dialout todavía no se aplicó; sal de la sesión. Error de launch inexistente: usa el nombre que ls mostró.

🌱 ¿Eres nuevo aquí?

Un frame (marco de coordenadas) es un «punto de vista» con origen y ejes propios: el centro del robot (base_link), el propio LiDAR (laser). TF2, que viste en el módulo 4.2, guarda cómo está posicionado un frame con respecto al otro. Si tu URDF ya tiene el link del LiDAR, robot_state_publisher publica esa relación automáticamente.

Por qué aprender

Un sensor nuevo en ROS 2 siempre sigue los mismos pasos: puerto, permiso, driver, launch, tópico, frame. Después de hacerlo con el LiDAR, puedes conectar una cámara de profundidad o una IMU siguiendo el mismo camino.

Conceptos clave

Driver
serial → /scan
dialout
permiso del puerto
Frame láser
dónde está el sensor
ros2 topic hz
tasa de publicación
3

🗺️ SLAM explicado: mapa y posición al mismo tiempo

Para dibujar el mapa, el robot necesita saber dónde estaba cuando hizo cada medición. Para saber dónde está, necesita un mapa. Este problema del «huevo y la gallina» se llama: SLAM, localización y mapeo simultáneos. El resultado es estimar ambas cosas juntas y corregir una con la otra con cada nueva vuelta del LiDAR.

🌱 ¿Eres nuevo aquí?

Odometría es la posición calculada a partir de los giros de las ruedas (módulo 2.2). Tiene deriva: los pequeños errores se acumulan y, después de unos metros, el robot «cree» que está lejos de donde realmente está. Emparejamiento de escaneos (scan matching) consiste en encajar la nueva vuelta del LiDAR sobre las anteriores, como piezas de un rompecabezas, para corregir esa deriva. Cierre de lazo (loop closure) consiste en reconocer «ya pasé por aquí» y distribuir el error acumulado a lo largo de todo el recorrido.

1. predecirodometría de las ruedas 2. encajarescaneo en el mapa 3. corregirposición + mapa cierre de lazo«ya estuve aquí» → ajusta todo el recorrido se repite con cada vuelta del LiDAR

Cómo leer: el ciclo ámbar (predecir, encajar, corregir) se ejecuta todo el tiempo. El cuadro cian con línea discontinua ocurre solo de vez en cuando, cuando el robot vuelve a un lugar conocido; es lo que evita que el pasillo se «tuerza» en el mapa final.

En ROS 2, el paquete estándar para SLAM con LiDAR 2D es slam_toolbox. Guarda las posiciones del robot como nodos de un grafo y los escaneos asociados a ellos; cuando cierra un lazo, reajusta todo el grafo. El resultado aparece en el tópico /map y en la transformación map → odom, que es precisamente la corrección de la deriva. Los tutoriales antiguos mencionan paquetes de ROS 1; en ROS 2 usa slam_toolbox. Cartographer también existe, pero recibe menos mantenimiento.

FuenteBueno paraDébil para
Odometría (ruedas)corto plazo, suave, rápidaderiva; patina sobre la alfombra
LiDAR (emparejamiento)corrige la deriva con las paredespasillos lisos y uniformes, vidrio
Cierre de lazoendereza todo el mapasolo si vuelves a un lugar que ya viste

Por qué aprender

Cuando el mapa salga torcido o «duplicado», sabrás dónde buscar: odometría deficiente, escaneo pobre o un lazo que no se cerró. Sin este modelo mental, la única opción es cambiar parámetros a ciegas.

Conceptos clave

SLAM
mapa + posición juntos
Deriva
error que se acumula
Loop closure
«ya estuve aquí»
map → odom
la corrección publicada
4

🖥️ slam_toolbox en la simulación

Antes de llevar el robot al salón, mapea un mundo simulado. Tienes dos opciones: tu robot del módulo 4.2 en Gazebo (Harmonic con Jazzy, Jetty con Lyrical), siempre que tenga un LiDAR simulado que publique /scan; o el TurtleBot simulado que viene con los ejemplos de Nav2, sin tener que armar nada. slam_toolbox no nota la diferencia: solo necesita /scan, la odometría y el TF.

Objetivo: instalar los paquetes, abrir el TurtleBot en un mundo simulado con SLAM activado y manejarlo con el teclado hasta que aparezca el mapa. Los nombres de los launch files de simulación cambian entre distribuciones: consulta la página «Getting Started» de docs.nav2.org.

terminal
# instalar SLAM, Nav2 y los robots de ejemplo (reemplaza <distro> por jazzy o lyrical)
sudo apt update
sudo apt install ros-<distro>-slam-toolbox ros-<distro>-navigation2 ros-<distro>-nav2-bringup
sudo apt install ros-<distro>-nav2-minimal-tb*        # TurtleBot simulado (consulta el nombre en la documentación)

# terminal 1: TurtleBot en Gazebo + RViz2 con slam_toolbox ya activado
source /opt/ros/<distro>/setup.bash
ros2 launch nav2_bringup tb4_simulation_launch.py slam:=True headless:=False

# terminal 2: manejar con el teclado (teclas i, j, l, coma)
source /opt/ros/<distro>/setup.bash
ros2 run teleop_twist_keyboard teleop_twist_keyboard

Cómo verificar

  • ✓Gazebo se abre con el robot; RViz2 muestra los puntos del LiDAR y un mapa gris que crece mientras lo manejas.
  • ✓ros2 topic list muestra /map, /scan e /odom.
  • ✗¿Aparece «Package not found» en el launch? Es posible que tu Nav2 use tb3_simulation_launch.py; lista $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/launch.

Con tu propio robot simulado (o real), slam_toolbox se inicia por sí solo. El modo online_async procesa los escaneos «lo más rápido posible» y se salta algunos si la computadora está ocupada; es el modo recomendado para empezar y para Raspberry Pi 5.

terminal
# con tu robot ya publicando /scan, /odom y el TF (simulado: usa_sim_time:=true)
source /opt/ros/<distro>/setup.bash
ros2 launch slam_toolbox online_async_launch.py use_sim_time:=true

# comprobar el árbol de frames: map -> odom -> base_link -> laser
ros2 run tf2_tools view_frames

Cómo verificar: o view_frames genera un PDF con el árbol de frames; debe tener map en la parte superior, seguido de odom, base_link y el frame del LiDAR. En el robot real, cambia a use_sim_time:=false.

💡 use_sim_time: la trampa nº 1

En la simulación, el reloj es el de Gazebo (tópico /clock). Si un nodo usa el reloj de la PC y otro el del simulador, los mensajes parecen «del futuro» o «demasiado antiguos» y TF da errores. Regla: en la simulación, use_sim_time:=true en todos los nodos; en el robot real, false en todos.

Por qué aprender

En la simulación puedes equivocarte sin costo: chocar contra la pared, rehacer el mapa, cambiar parámetros, sin batería agotada ni muebles rayados. Cuando pases al robot real, solo cambian las fuentes de /scan e /odom.

Conceptos clave

online_async
modo para empezar
TurtleBot
robot de ejemplo
use_sim_time
reloj del simulador
view_frames
comprueba el TF
5

🏠 Mapea tu casa o salón de clases

Mapear un lugar real requiere más «habilidad para conducir» que código. slam_toolbox hace los cálculos; tú decides la ruta, la velocidad y si vuelves a lugares que ya viste. Un buen mapa se obtiene con un recorrido lento, giros suaves y pasando dos veces por los mismos puntos de referencia. En esta etapa todavía conduces el robot (teleop); la navegación autónoma llega en el módulo 4.5.

Guía para mapear

1

Prepara el entorno

Deja las puertas en la posición en que estarán, retira del suelo los cables y juguetes, y avisa a las personas y los animales. Cierra o bloquea el acceso a las escaleras.

2

Empieza en una esquina con paredes

El punto de partida se convierte en el origen del mapa. Un lugar con esquinas le da a slam_toolbox referencias firmes desde la primera vuelta.

3

Conduce despacio y gira despacio

En teleop, reduce la velocidad (tecla z) a unos 0,1–0,2 m/s. Los giros rápidos son lo que más distorsiona el mapa: las ruedas patinan y la odometría falla.

4

Cierra los bucles

Da la vuelta a una habitación y termina donde empezaste; vuelve a pasar por el pasillo. Observa en RViz2 cómo el mapa «se endereza» cuando se cierra el bucle.

5

Guarda antes de apagar

Cuando tengas un buen mapa en pantalla, guárdalo (tema 6). Si apagas slam_toolbox antes, el mapa se pierde.

✓ Hazlo

  • ✓Monta el LiDAR en el punto más alto y despejado del robot, sin cables que crucen el haz.
  • ✓Cubre las puertas de vidrio o los espejos con papel al momento de mapear.
  • ✓Mantente siempre al alcance del robot y del interruptor para apagar los motores.

✗ No lo hagas

  • ✗Mapear mientras hay gente caminando alrededor: las piernas se convierten en «paredes» en el mapa.
  • ✗Dejar el robot cerca de una escalera descendente: el LiDAR 2D no detecta el escalón.
  • ✗Mapear un salón enorme y vacío: si no hay paredes al alcance, no hay nada con qué hacer coincidir las lecturas.

🌱 ¿Eres nuevo aquí?

¿Todavía no tienes el robot real? Puedes hacer toda esta guía en la simulación del tema 4, incluso en un salón de clases con un proyector: un estudiante conduce, el grupo observa el mapa e indica dónde se cerró el bucle. Gazebo también te permite crear un mundo parecido a tu salón, con cajas en lugar de muebles.

Por qué aprender

El mapa es la base de todo lo que viene después: si tiene paredes duplicadas o huecos, Nav2 planeará rutas que atraviesan paredes o rechazará rutas posibles. Diez minutos de mapeo cuidadoso te ahorran horas de ajustes de navegación.

Conceptos clave

Origen
donde empezaste
Giro lento
menos distorsión
Bucle cerrado
vuelve al inicio
Escalera
bloquéala antes
6

💾 Guarda y carga mapas

El mapa que publica slam_toolbox es un mapa de ocupación: el suelo dividido en cuadritos (celdas) de unos centímetros, cada uno marcado como libre, ocupado o desconocido. Al guardar este mapa se generan dos archivos: una imagen .pgm (la «foto» de las celdas) y un .yaml que indica el tamaño de cada celda y dónde se encuentra el origen.

libre = 0 ocupado = 100 desconocido = −1 resolución: 0,05 m por celda mapa.pgm guarda los colores mapa.yaml guarda la escala y el origen

Cómo leer: cada cuadrito es una celda del mapa. El gris indica por dónde nunca pasó el LiDAR; el blanco es suelo libre; el negro es una pared o un mueble. El cuadrado negro del medio es un obstáculo aislado, como un armario. Con celdas de 5 cm, una habitación de 5 m × 4 m se convierte en una imagen de 100 × 80 píxeles.

Objetivo: guardar el mapa actual en ~/mapas, revisar el archivo de configuración y volver a abrir el mapa guardado para usarlo en Nav2.

terminal
# con slam_toolbox TODAVÍA en ejecución y el mapa en pantalla
source /opt/ros/<distro>/setup.bash
mkdir -p ~/mapas && cd ~/mapas
ros2 run nav2_map_server map_saver_cli -f mapa

# revisa los dos archivos generados
ls -l mapa.pgm mapa.yaml
cat mapa.yaml

# más tarde, para navegar en el mapa guardado (módulo 4.5)
ros2 launch nav2_bringup bringup_launch.py map:=$HOME/mapas/mapa.yaml

Cómo verificar

  • ✓El terminal termina con un mensaje que confirma que se guardó el mapa y aparecen mapa.pgm e mapa.yaml.
  • ✓O mapa.yaml tiene líneas como image: mapa.pgm, resolution: 0.05 e origin: [x, y, ángulo].
  • ✓Al abrir el .pgm en un editor de imágenes, puedes ver el plano del lugar en blanco, negro y gris.
  • ✗¿«Failed to receive map»? Se cerró slam_toolbox o el tema /map no existe; compruébalo con ros2 topic list.

💡 Dos formas de guardar

O map_saver_cli guarda la imagen que Nav2 usa para navegar. slam_toolbox también puede guardar su propio grafo (botón «Serialize Map» en el panel SlamToolboxPlugin de RViz2): con él puedes continuar el mapeo otro día o usar el modo de localización propio de slam_toolbox. Guarda ambos archivos; incluso puedes retocar el PGM en un editor de imágenes (pintar de negro una zona prohibida).

Por qué aprender

Volver a mapear cada vez que enciendes el robot es lento e inestable. Con el mapa guardado, el robot se enciende, se localiza y ya puede navegar, que es justo lo que Nav2 espera en el próximo módulo.

Conceptos clave

Ocupación
libre/ocupado/?
Resolución
metros por celda
.pgm + .yaml
imagen + escala
Serialize
grafo de SLAM

✅ Resumen del módulo

✓
LiDAR 2D = anillo de distancias se publica como LaserScan en /scan; no detecta vidrio, escalones ni lo que queda fuera de la altura del haz.
✓
Conectar el sensor a ROS 2: puerto, permisos, driver, launch, tópico y frame.
✓
SLAM: predecir con la odometría, hacer coincidir el barrido y corregir; el bucle cerrado endereza el mapa.
✓
slam_toolbox es el estándar en ROS 2; empieza con el TurtleBot simulado y mantén coherente use_sim_time.
✓
Mapa guardado = mapa.pgm + mapa.yaml, listo para Nav2.

Para profundizar

Siguiente módulo

4.5 · Navegación con Nav2: el robot se localiza en el mapa guardado y va solo adonde le indiques.