Parte 1: Primeros pasos con ROS 2
Introducción¶
Ejercicios: 8
Tiempo estimado de finalización: 2 horas
Nivel de dificultad: Principiante
Objetivos¶
En la primera parte de este laboratorio aprenderás los fundamentos de ROS 2 y te familiarizarás con algunas herramientas y principios clave del framework, lo que te permitirá programar robots y trabajar con aplicaciones ROS 2 de manera efectiva.
A lo largo de este curso, y de aquí en adelante, nos referiremos a ROS 2 simplemente como "ROS" para facilitar las cosas.
En su mayor parte, interactuarás con ROS usando la línea de comandos de Linux, por lo que también te familiarizarás con algunas herramientas clave de la línea de comandos de Linux que te serán de ayuda. Finalmente, aprenderás cómo crear algunos Nodes básicos de ROS usando Python y tendrás un primer vistazo de cómo funciona la comunicación a través de ROS Topics e Interfaces.
Resultados de Aprendizaje Esperados¶
Al finalizar esta sesión serás capaz de:
- Controlar un robot de simulación usando ROS.
- Lanzar aplicaciones ROS usando
ros2 launchyros2 run. - Consultar aplicaciones ROS en ejecución usando herramientas clave de la línea de comandos de ROS.
- Crear un package de ROS compuesto por múltiples nodes y programar estos nodes (en Python) para que se comuniquen entre sí usando los métodos de comunicación de ROS.
- Crear una interfaz de mensaje personalizada de ROS y crear Nodes Python para usarla.
- Navegar por un sistema de archivos Linux y aprender a realizar diversas operaciones del sistema de archivos desde una terminal Linux.
Accesos Rápidos¶
Ejercicios¶
- Ejercicio 1: Lanzar una simulación y hacer mover un robot
- Ejercicio 2: Visualizar la Red ROS
- Ejercicio 3: Explorar ROS Topics y Mensajes
- Ejercicio 4: Crear tu propio package de ROS
- Ejercicio 5: Crear un node publisher
- Ejercicio 6: Crear un node subscriber
- Ejercicio 7: Definir nuestro propio mensaje
- Ejercicio 8: Usar un mensaje ROS personalizado
Recursos Adicionales¶
- Un Publisher Python simple (para el Ejercicio 5)
- Un Subscriber Python simple (para el Ejercicio 6)
- El Publisher del mensaje
Example(para el Ejercicio 8)
Primeros Pasos¶
Paso 1: Acceder a un entorno ROS 2 para este curso¶
Si aún no lo has hecho, consulta aquí todos los detalles sobre cómo instalar o acceder a un entorno ROS para este curso.
Paso 2: Lanzar ROS¶
Inicia tu entorno ROS.
- Si estás usando WSL-ROS2 en una computadora del laboratorio, sigue las instrucciones aquí para iniciarlo.
- Si estás ejecutando WSL-ROS2 en tu propia computadora, necesitarás abrir la Terminal de Windows para acceder a una instancia de terminal WSL-ROS2.
- Si estás usando Docker, puedes encontrar más instrucciones aquí.
De cualquier manera, ahora deberías tener acceso a ROS 2 a través de una instancia de terminal Linux, y nos referiremos a esta instancia de terminal como TERMINAL 1.
Paso 3: Descargar el Repositorio del Curso¶
Hemos preparado algunos packages de ROS específicamente para este curso. Todos se encuentran en el repositorio del curso, y deberás descargarlo e instalarlo en tu entorno ROS ahora, antes de continuar.
-
En TERMINAL 1, navega hacia el "ROS Workspace" usando el comando
cd1: -
Luego, ejecuta el siguiente comando para clonar el repositorio del curso desde GitHub:
-
Una vez hecho esto, necesitarás compilarlo usando una herramienta llamada "Colcon"2:
No te preocupes demasiado por lo que acabas de hacer por ahora. Lo cubriremos con más detalle a lo largo del curso. Por el momento es suficiente; más adelante empezaremos a usar algunos de los packages que acabamos de instalar.
Ejercicio 1: Lanzar una simulación y hacer mover un robot¶
Ahora que todo está en marcha, lancemos ROS y pongamos en funcionamiento la simulación del robot...
-
En TERMINAL 1 ingresa el siguiente comando para lanzar una simulación del robot en un mundo vacío:
-
Se debería abrir una ventana de Gazebo Sim:
- Acercar y alejar usando la rueda de desplazamiento del mouse.
- Rotar la vista de la cámara presionando y manteniendo simultáneamente el botón izquierdo del mouse y la tecla Shift de tu teclado, y luego moviendo el mouse.
Usando ambos métodos deberías poder obtener una mejor vista del robot, que es una representación aproximada de nuestros robots reales.
-
Con la simulación de Gazebo en funcionamiento, regresa a tu terminal y abre una segunda instancia de terminal (TERMINAL 2)
-
En esta nueva instancia de terminal ingresa el siguiente comando:
-
Sigue las instrucciones proporcionadas en la terminal para controlar el robot usando teclas específicas de tu teclado:
Resumen¶
Acabas de lanzar varias aplicaciones diferentes en una red ROS usando dos comandos diferentes de ROS: ros2 launch y ros2 run:
ros2 launch turtlebot3_gazebo empty_world.launch.pyros2 run turtlebot3_teleop teleop_keyboard
Estos dos comandos tienen una estructura similar, pero funcionan de manera ligeramente diferente.
El primer comando que usaste fue un comando launch, que tiene las siguientes dos partes (después de la parte launch):
La Parte [1] es el nombre del package de ROS que contiene la funcionalidad que queremos ejecutar. La Parte [2] es un archivo dentro de ese package que le indica a ROS exactamente qué scripts ('nodes') queremos lanzar. Podemos lanzar múltiples nodes al mismo tiempo desde un único archivo launch.
El segundo comando fue un comando run, que tiene una estructura similar a launch:
Aquí, la Parte [1] es la misma que en el comando launch, pero la Parte [2] es ligeramente diferente: {[2] Nombre del node}. Aquí estamos especificando directamente un único script que queremos ejecutar. Por lo tanto, usamos ros2 run si solo queremos lanzar un único node en la red ROS: el node teleop_keyboard (un script Python), en este caso.
Packages y Nodes de ROS¶
Packages¶
Las aplicaciones ROS se organizan en packages. Los packages son básicamente colecciones que contienen scripts, configuraciones y archivos launch (formas de lanzar esos scripts y configuraciones), todos relacionados con alguna funcionalidad robótica común. ROS usa packages como una manera de organizar todos los programas que se ejecutan en un robot.
Info
El sistema de packages es un concepto fundamental en ROS y todos los programas de ROS se organizan de esta manera.
Crearás varios packages a lo largo de este curso, cada uno conteniendo diferentes nodes, archivos launch y otras cosas más. Comenzaremos a explorar esto más adelante.
Nodes¶
Los Nodes de ROS son ejecutables que realizan tareas y operaciones específicas del robot. Antes (por ejemplo) usamos ros2 run para ejecutar un node llamado teleop_keyboard, que nos permitió controlar remotamente (o "teleop") el robot.
Question
¿Cuál era el nombre del package de ROS que contenía el node teleop_keyboard? (Recuerda: ros2 run {[1] Nombre del package} {[2] Nombre del node})
Un robot ROS podría tener cientos de nodes individuales ejecutándose simultáneamente para llevar a cabo todas sus operaciones y acciones necesarias. Cada node se ejecuta de forma independiente, pero usa métodos de comunicación de ROS para compartir datos con los demás nodes en la red ROS.
La Red ROS¶
Podemos usar el comando ros2 node para ver todos los nodes que están actualmente activos en una red ROS.
Ejercicio 2: Visualizar la Red ROS¶
Actualmente deberías tener dos instancias de terminal activas: la primera en la que lanzaste la simulación de Gazebo (TERMINAL 1) y la segunda con tu node teleop_keyboard activo (TERMINAL 2).
- Abre una nueva instancia de terminal ahora (TERMINAL 3).
-
Usa el siguiente comando para ver qué nodes están actualmente activos en la red:
Solo debería aparecer una pequeña cantidad de nodes:
-
Podemos visualizar las conexiones entre los nodes activos usando una aplicación llamada RQT. RQT es una colección de herramientas gráficas que nos permiten interactuar e interrogar la red ROS. Lanza la aplicación principal de RQT ingresando
rqten TERMINAL 3 (es posible que veas algunas advertencias en la terminal al hacerlo, pero no te preocupes por ellas):Debería abrirse una ventana:
-
Desde aquí, queremos cargar el plugin Node Graph. Desde el menú superior selecciona
Plugins>Introspection>Node Graph. -
Selecciona
Nodes/Topics (all)del menú desplegable superior izquierdo, y en la secciónHidedesmarca todo exceptoDebugyParams(puede que necesites presionar el botón de actualizar):(Haz clic en la imagen para ampliarla.) Aquí, los nodes están representados por elipses y los topics por rectángulos (pasa el cursor sobre una región del gráfico para activar el resaltado de color).
Esta herramienta nos muestra que (entre otras cosas) el node
/teleop_keyboardse está comunicando con otro node llamado/ros_gz_bridge. La dirección de la flecha nos indica que/teleop_keyboardes un Publisher y/ros_gz_bridgees un Subscriber. Los dos nodes se comunican a través de un ROS Topic llamado/cmd_vel.
Publishers y Subscribers: Un Método de Comunicación de ROS¶
Los ROS Topics son fundamentales para hacer que las cosas sucedan en un robot. Los nodes pueden publicar (escribir) y/o subscribirse a (leer) ROS Topics para compartir datos a través de la red ROS. Los datos se publican en los topics usando ROS Messages. Como acabamos de aprender, el node teleop_keyboard estaba publicando mensajes en un topic (/cmd_vel) para hacer mover el robot.
Veamos esto con un poco más de detalle...
Ejercicio 3: Explorar ROS Topics y Mensajes¶
Podemos encontrar más información sobre el topic /cmd_vel usando el comando ros2 topic.
-
Abre otra nueva instancia de terminal (TERMINAL 4) y escribe lo siguiente:
Esto nos muestra todos los topics que están actualmente disponibles en la red ROS (muchos de los cuales vimos en el Node Graph de RQT arriba):
/camera/camera_info /camera/image_raw /camera/image_raw/compressed /camera/image_raw/compressedDepth /camera/image_raw/theora /camera/image_raw/zstd /clock /cmd_vel /imu /joint_states /odom /parameter_events /robot_description /rosout /scan /tf /tf_staticAveriguemos un poco más sobre
/cmd_vel... -
Usa el comando
topic infoahora:Esto debería proporcionar la siguiente salida:
Ahora hemos establecido la siguiente información sobre
/cmd_vel:- El topic tiene 1 publisher escribiendo datos en él (el node
/teleop_keyboard, como se estableció a partir del RQT Graph) - El topic también tiene 1 subscriber leyendo estos datos (el node
ros_gz_bridge) -
Los datos se transmiten en el topic
/cmd_velusando una Interface. Esta interface particular se define como:geometry_msgs/msg/TwistStamped.Definiciones de Interfaces
Las Interfaces son estructuras de datos estandarizadas que se usan para transmitir datos a través de la red ROS. La definición de interface anterior (y, de hecho, toda definición de interface) tiene tres partes:
geometry_msgs: el nombre del package de ROS al que pertenece esta interface.msg: indica que esto es un topic message en lugar de otro tipo de interface (hay tres tipos de interface, y aprenderemos sobre los otros dos más adelante en este curso).TwistStamped: el nombre real de la interface
En resumen, hemos establecido que si queremos hacer mover el robot necesitamos publicar mensajes
TwistStampeden el topic/cmd_vel.
- El topic tiene 1 publisher escribiendo datos en él (el node
-
Todavía en TERMINAL 4, usa el comando
ros2 interfacepara mostrarnos la estructura de datos (estandarizada) usada por la InterfaceTwistStamped:De esto, obtenemos lo siguiente:
std_msgs/Header header builtin_interfaces/Time stamp int32 sec uint32 nanosec string frame_id Twist twist Vector3 linear float64 x float64 y float64 z Vector3 angular float64 x float64 y float64 zAprenderemos más sobre lo que esto significa en la Parte 2.
-
Para finalizar, ingresa Ctrl+C en cada una de las tres terminales que actualmente deberían tener procesos ROS en ejecución (Terminales 1, 2 y 3). Las ventanas de Gazebo y del Node Graph de RQT deberían cerrarse como resultado de esto también.
Tip
Siempre que necesites detener cualquier proceso ROS usa Ctrl+C en la terminal donde está ejecutándose.
Creando tus Primeras Aplicaciones ROS¶
En breve crearemos algunos nodes simples de publisher y subscriber en Python y enviaremos datos simples entre ellos. Como aprendimos antes, los nodes de ROS siempre deben vivir dentro de packages, por lo que necesitamos crear un package primero para poder comenzar a crear nuestros propios nodes de ROS.
Es importante trabajar en una ubicación específica del sistema de archivos cuando creamos y trabajamos en nuestros propios packages de ROS. Estos se llaman "Workspaces" y ya deberías tener uno listo para usar dentro de tu entorno ROS local llamado ros2_ws3, con un subdirectorio dentro de él llamado src:
¡Todos los nuevos packages DEBEN estar ubicados dentro de la carpeta src del workspace!
Note
~ es un alias para tu directorio home. Entonces cd ~/ros2_ws/src/ es lo mismo que escribir cd /home/{tu nombre de usuario}/ros2_ws/src/.
Ejercicio 4: Crear tu propio package de ROS¶
La interfaz de línea de comandos (CLI) ros2 que hemos estado usando hasta ahora incluye una herramienta para crear nuevos packages de ROS: ros2 pkg create4. Sin embargo, para este curso adoptaremos un enfoque ligeramente diferente para la creación de packages, para brindarnos un poco más de flexibilidad y facilidad de uso (especialmente para cosas que haremos más adelante)5. Por lo tanto, usaremos una Plantilla de Package ROS 2 disponible en GitHub, y ahora veremos cómo usarla para crear nuevos packages...
-
Navega hacia el directorio
ros2_ws/srcusando el comandocdde Linux (cambiar directorio). En TERMINAL 1 ingresa lo siguiente: -
Desde aquí, usa
gitpara clonar nuestra Plantilla de Package ROS 2 desde GitHub: -
Esta plantilla de package contiene un script llamado
init_pkg.sh, que usaremos para convertir la plantilla en nuestro primer package de ROS 2. Ejecuta el script de la siguiente manera, para convertir la plantilla en un package de ROS 2 llamadopart1_pubsub:Como resultado de hacer esto, el directorio
ros2_pkg_templateha sido renombrado apart1_pubsub, y varias otras cosas dentro del package también han sido actualizadas, para inicializar el package con el nombre que especificamos. -
Navega hacia el directorio del package (usando
cd): -
treees un comando de Linux que nos muestra el contenido del directorio actual en un formato de árbol. Usatreeahora para mostrar el contenido actual del directoriopart1_pubsub:...lo que debería mostrar:
. ├── CMakeLists.txt ├── package.xml ├── part1_pubsub_modules │ ├── __init__.py │ └── tb3_tools.py └── scripts ├── basic_velocity_control.py └── stop_me.py 3 directories, 6 filesscripts: es un directorio que contendrá todos los Nodes Python que crearemos (notarás que ya hay un par allí).-
part1_pubsub_modules: es un directorio que podemos usar para almacenar módulos Python, que luego podemos importar en nuestros nodes Python principales(
from part1_pubsub_modules.tb3_tools import ..., por ejemplo) -
package.xmlyCMakeLists.txt: son ambos archivos que definen nuestro package y cómo debe compilarse (usandocolcon build). Los exploraremos más en breve...
Ejercicio 5: Crear un node publisher¶
-
Desde la raíz de tu package
part1_pubsub, navega hacia la carpetascriptsusando el comandocd. -
touches un comando de Linux que podemos usar para crear un archivo vacío. Úsalo para crear un archivo vacío llamadopublisher.py, al que añadiremos contenido en breve: -
Usa
lspara verificar que el archivo ha sido creado, pero usa la opción-lcon esto, para que el comando muestre su salida en "formato de lista larga":Esto debería mostrar algo similar a lo siguiente:
-rwxr-xr-x 1 student student 1500 MMM DD HH:MM minimal_node.py -rw-r--r-- 1 student student 0 MMM DD HH:MM publisher.py -rwxrwxr-x 1 student student 816 MMM DD HH:MM stop_me.pyEsto confirma que el archivo
publisher.pyexiste, y el0en esa línea indica que el archivo está vacío (es decir, su tamaño actual es de 0 bytes), lo cual es lo esperado. -
Por lo tanto, ahora necesitamos abrir el archivo y añadirle contenido. Recomendamos usar Visual Studio Code (VS Code) como IDE para este curso. Lanza VS Code y accede a tu entorno ROS 2 (cómo hacerlo variará según cómo tengas ROS instalado en tu computadora).
-
Usando el Explorador de Archivos de VS Code, localiza el archivo
publisher.pyvacío que acabas de crear (~/ros2_ws/src/part1_pubsub/scripts/) y haz clic en el archivo para abrirlo en el editor principal. -
El código de
publisher.pyse proporciona aquí:El código de publisher.pyÉchale un vistazo y ten en cuenta el siguiente contenido adicional de esta página también:
- Haz clic en los íconos para expandir las anotaciones en el código. Es importante que entiendas cómo funciona el código, ¡así que asegúrate de leer estas anotaciones!
- Hay una sección adicional debajo del código llamada "Definición de Dependencias del Package". ¡Asegúrate de seguir también los pasos descritos allí!
-
Una vez que hayas revisado el código, toma una copia de él, pégalo en tu archivo
publisher.pyy guárdalo. -
Ahora, necesitamos añadir nuestro archivo
publisher.pycomo un ejecutable alCMakeLists.txtde nuestro package. Esto asegurará que se compile cuando ejecutemoscolcon build(en el siguiente paso).En VS Code, abre el archivo
CMakeLists.txtque está en la raíz del directorio de tu packagepart1_pubsub(ros2_ws/src/part1_pubsub/CMakeLists.txt). Localiza las líneas (cerca del final del archivo) que dicen:# Install Python executables install(PROGRAMS scripts/basic_velocity_control.py scripts/stop_me.py DESTINATION lib/${PROJECT_NAME} )Añade el Node
publisher.pyde la siguiente manera: -
Ahora, usa
colconpara compilar tu package.-
DEBES ejecutar esto desde la raíz de tu Colcon Workspace (es decir:
~/ros2_ws/), NO el directoriosrc(~/ros2_ws/src/), así que navega allí ahora usandocd: -
Luego, usa el siguiente comando
colconpara compilar tu package:¿Qué hacen los argumentos adicionales anteriores?
--packages-select: Compila únicamente el packagepart1_pubsub, nada más (sin esto,colconintentaría compilar cada package en el workspace).--symlink-install: Asegura que no tengas que volver a ejecutarcolcon buildcada vez que realices un cambio en los ejecutables de tu package (es decir, tus nodes Python en el directorioscripts).
-
Finalmente, "re-sourcea" tu
bashrc6:
-
-
Ahora deberíamos poder ejecutar este node usando el comando
ros2 run.Recuerda:
ros2 run {nombre del package} {nombre del script}, entonces:... ¿Hmm, algo no está del todo bien? Si escribiste el comando exactamente como arriba y luego intentaste ejecutarlo, probablemente acabas de recibir el siguiente error:
Cuando creamos un archivo usando
touch, se le asignan ciertos permisos por defecto. Recuerda la salida del comandols -lque ejecutamos antes (haz clic aquí para volver a esto como recordatorio):La primera parte nos indica sobre los permisos que actualmente están asignados al archivo
publisher.py:-rw-r--r--Esto nos indica quién tiene permiso para hacer qué con este archivo y (actualmente) la primera parte:
-rw-, nos indica que tenemos permiso para leer o escribir en él. Sin embargo, hay una tercera opción que también podemos configurar, que es el permiso de ejecución, y podemos configurarlo usando el comando de Linuxchmod... -
Usa
cdpara navegar de vuelta al directorioscriptsde nuestro package (donde se encuentra el archivopublisher.py):Luego ejecuta el comando
chmodde la siguiente manera para dar al archivopublisher.pypermisos de ejecución: -
Ahora, ejecuta
ls -lnuevamente para ver qué ha cambiado:Ahora hemos otorgado permiso para que el archivo también sea ejecutado:
-
Bien, ahora usa
ros2 runnuevamente para (¡con suerte!) ejecutar el nodepublisher.py(recuerda:ros2 run {nombre del package} {nombre del script}).Si ves un mensaje en la terminal similar al siguiente, entonces el node se ha lanzado exitosamente:
¡Genial!
-
Podemos verificar adicionalmente que nuestro node publisher está en ejecución usando varias herramientas diferentes. Intenta ejecutar los siguientes comandos en TERMINAL 2:
ros2 node list: Esto proporcionará una lista de todos los nodes que están actualmente activos en el sistema. Verifica que el nombre de nuestro node publisher sea visible en esta lista (¡probablemente es el único elemento en la lista en este momento!).ros2 topic list: Esto proporcionará una lista de los topics que actualmente están siendo usados por los nodes del sistema. Verifica que el nombre del topic al que nuestro publisher está publicando mensajes (/my_topic) esté presente en esta lista.
Interrogando ROS Topics¶
Hasta ahora hemos usado el comando ROS ros2 topic con dos argumentos adicionales:
list: para proporcionarnos una lista de todos los topics que están activos en nuestro sistema ROS, yinfo: para proporcionarnos información sobre un topic de interés en particular.
Podemos averiguar qué otros sub-comandos están disponibles para usar con ros2 topic solicitando ayuda. Ejecuta lo siguiente en TERMINAL 2:
Lo que debería proporcionarnos una lista de todas las opciones:
Commands:
bw Display bandwidth used by topic
delay Display delay of topic from timestamp in header
echo Output messages from a topic
find Output a list of available topics of a given type
hz Print the average publishing rate to screen
info Print information about a topic
list Output a list of available topics
pub Publish a message to a topic
type Print a topic's type
Call `ros2 topic <command> -h` for more detailed usage.
Hablemos de algunos de estos:
-
ros2 topic hz {nombre del topic}proporciona información sobre la frecuencia (en Hz) a la que se están publicando mensajes en un topic:Esto debería decirnos que nuestro node publisher está publicando mensajes en el topic
/my_topica (o cerca de) 1 Hz, que es exactamente lo que solicitamos en el archivopublisher.py(en la parte__init__de nuestra clasePublisher). Ingresa Ctrl+C para detener este comando. -
ros2 topic echo {nombre del topic}muestra los mensajes que se están publicando en un topic:Esto proporcionará un flujo en vivo de los mensajes que nuestro node
publisher.pyestá publicando en el topic/my_topic. Ingresa Ctrl+C para detener esto. -
Podemos ver algunas opciones adicionales para el comando
echoviendo la documentación de ayuda para este también:Desde aquí, por ejemplo, podemos aprender que si solo quisiéramos imprimir el primer mensaje que se recibió podríamos usar la opción
--once, por ejemplo:
Ejercicio 6: Crear un node subscriber¶
Para ilustrar cómo se puede pasar información de un node a otro (a través de topics y mensajes) ahora crearemos otro node para subscribirse al topic al que nuestro node publisher está transmitiendo mensajes.
-
En TERMINAL 2 usa los comandos del sistema de archivos que se introdujeron antes (
cd,ls, etc.) para navegar hacia la carpetascriptsde tu packagepart1_pubsub. -
Usa el mismo procedimiento que antes para crear un nuevo archivo Python vacío llamado
subscriber.py¡y recuerda hacerlo ejecutable! -
Luego, abre este archivo
subscriber.pyrecién creado en VS Code. -
El código del archivo
subscriber.pyse proporciona aquí:El código de subscriber.pyUna vez más, es importante que entiendas cómo funciona este código, ¡así que asegúrate de leer las anotaciones del código!
¡Completa el
{BLANK}!¡Este código no funcionará de inmediato! Busca un
{BLANK}, que es una indicación para que reemplaces este texto con algo más. -
Ahora necesitamos añadir esto como un ejecutable adicional del package.
Abre el archivo
CMakeLists.txten la raíz del directorio de tu packagepart1_pubsubnuevamente, regresa a la sección# Install Python executablesy añade el archivosubscriber.pycomo se ilustra a continuación: -
Ahora necesitamos ejecutar
colcon buildnuevamente.-
Asegúrate de estar en la raíz del Colcon Workspace:
-
Ejecuta
colcon buildsolo en el packagepart1_pubsub: -
Y luego re-sourcea el
bashrc:
-
-
Usa
ros2 run(en TERMINAL 2) para ejecutar tu nodesubscriber.pyrecién creado (recuerda:ros2 run {nombre del package} {nombre del script}). Si tus nodes publisher y subscriber están funcionando correctamente deberías ver una salida como esta: -
Interroga tu red ROS:
-
Como antes, podemos saber qué nodes están ejecutándose en nuestro sistema usando el comando
ros2 node list. Ejecuta esto en TERMINAL 3, deberías ver tanto tu node publisher como tu node subscriber listados allí. -
Usa el comando
ros2 topicpara listar todos los topics que están disponibles en la red. Deberías ver/my_topiclistado allí. -
Usa el comando
ros2 topicnuevamente para encontrar más info sobremy_topic. -
Usa el comando
ros2 interfacepara mostrar qué tipo de datos se están enviando entre los dos nodes.
-
-
Finalmente, cierra tus nodes publisher y subscriber ingresando Ctrl+C en las terminales donde están ejecutándose (deberían ser 1 y 2).
Ejercicio 7: Definir nuestro propio mensaje¶
Acabamos de crear un publisher y un subscriber que pudieron comunicarse entre sí a través de un topic.
Los datos que el publisher enviaba al topic eran muy simples: un mensaje de tipo example_interfaces/msg/String.
ros2 topic info /my_topic
Type: example_interfaces/msg/String
Publisher count: 1
Subscription count: 1
Este mensaje solo tiene un campo llamado data de tipo string:
Los mensajes ROS generalmente serán más complejos que esto, típicamente conteniendo varios campos en un solo mensaje. Ahora definiremos nuestro propio mensaje personalizado, esta vez con dos campos, para que puedas ver cómo funcionan las cosas con estructuras de datos un poco más complejas.
-
Las interfaces de mensajes deben definirse dentro de una carpeta
msgen la raíz de nuestro directorio del package, así que vamos a crear esta carpeta ahora en TERMINAL 1:-
Primero, navega hacia tu package:
-
Luego usa
mkdirpara crear un nuevo directorio:
-
-
Crearemos un mensaje llamado
Example, y para hacerlo necesitaremos crear un nuevo archivo llamadoExample.msgdentro de la carpetamsg: -
Para definir la estructura de datos de este mensaje, ahora necesitamos abrir el archivo y añadir el siguiente contenido:
El mensaje tendrá por lo tanto dos campos:
# Nombre del Campo Tipo de Dato 1 infostring2 timeint32Podemos dar a nuestros campos cualquier nombre que queramos, pero los tipos de datos deben ser tipos incorporados u otras interfaces ROS preexistentes.
-
Ahora necesitamos declarar este mensaje en el archivo
CMakeLists.txtde nuestro package, para que el código Python necesario pueda ser creado (porcolcon build) y nos permita importar este mensaje en nuestros propios archivos Python.Añade las siguientes líneas a tu archivo
part1_pubsub/CMakeLists.txt, encima de la líneaament_package(): -
También necesitamos modificar nuestro archivo
package.xml. Añade las siguientes líneas a este, justo encima de la línea<export>: -
Ahora podemos usar Colcon para generar el código fuente necesario para el mensaje:
-
Primero, asegúrate de estar en la raíz del ROS 2 Workspace:
-
Luego ejecuta
colcon build: -
Y finalmente re-sourcea el
.bashrc:
-
-
Ahora podemos verificar que esto funcionó con más herramientas de línea de comandos de
ros2:-
Primero, lista todos los mensajes ROS que están disponibles para nosotros en nuestro sistema:
Desplázate por esta lista y comprueba si puedes encontrar nuestro mensaje allí (estará listado como
part1_pubsub/msg/Example) -
Luego, muestra la estructura de datos de la interface:
Esto debería coincidir con cómo lo definimos en nuestro archivo
part1_pubsub/msg/Example.msg.
-
Ejercicio 8: Usar un mensaje ROS personalizado¶
-
Crea una copia del archivo
publisher.pydel Ejercicio 5. También hagamos esto desde la línea de comandos (en TERMINAL 1):-
Navega hacia la carpeta
scriptsde tu package: -
Y usa el comando
cppara hacer una copia del archivopublisher.pyy llamar a este nuevo archivocustom_msg_publisher.py: -
También hagamos una copia del archivo
subscriber.py, ya que estamos aquí:
-
-
Declara estos dos nuevos archivos como ejecutables adicionales en nuestro
CMakeLists.txt: -
Ejecuta Colcon nuevamente (¡última vez!):
- Primero:
- Luego:
- Y finalmente:
-
Ahora modifica tu archivo
custom_msg_publisher.pysegún el código proporcionado a continuación:El código de custom_msg_publisher.py -
Tarea Final:
Modifica el node
custom_msg_subscriber.pyahora para adaptarlo a los nuevos mensajes de interface que se están publicando en/my_topic.
Conclusión¶
En esta sesión hemos cubierto los fundamentos de ROS, y aprendido sobre algunos conceptos clave como Packages; Nodes; y cómo enviar datos a través de una red ROS usando Topics, Messages y el Método de Comunicación Publisher-Subscriber.
Hemos aprendido cómo usar algunos comandos clave de ros2:
launch: para lanzar múltiples Nodes de ROS a través de archivos launch.run: para ejecutar ejecutables dentro de un package de ROS.node: para mostrar información sobre los Nodes de ROS activos.topic: para mostrar información sobre los topics de ROS activos.interface: para mostrar información sobre todas las Interfaces de ROS que están disponibles para usar en una aplicación ROS.
También hemos aprendido cómo trabajar en la Terminal de Linux y navegar por un sistema de archivos Linux usando comandos clave como:
ls: lista los archivos en el directorio actual.cd: cambiar directorio para moverse por el sistema de archivos.mkdir: crear un nuevo directorio (mkdir {nueva_carpeta}).chmod: modificar permisos de archivos (es decir, para añadir permisos de ejecución a un archivo para todos los usuarios:chmod +x {archivo}).touch: crear un archivo sin ningún contenido.
Además de esto, también hemos aprendido cómo crear un package de ROS 2, y cómo crear nodes Python simples que pueden publicar y subscribirse a topics en una red ROS.
Hemos trabajado con mensajes ROS prefabricados para hacer esto y también hemos creado nuestra propia interface de mensaje personalizada para ofrecer una funcionalidad más avanzada.
Usuarios de WSL-ROS2 con Computadoras del Laboratorio: ¡Guarda tu trabajo!¶
Recuerda, el trabajo que has realizado en el entorno WSL-ROS2 durante esta sesión no se preservará automáticamente para futuras sesiones o en diferentes computadoras del laboratorio. Para guardar el trabajo que has realizado hoy deberías ejecutar ahora el siguiente script en cualquier instancia de Terminal WSL-ROS2 inactiva:
Esto exportará tu directorio home a tu unidad U:\, permitiéndote restaurarlo en otra computadora del laboratorio la próxima vez que inicies WSL-ROS2.
-
¿Qué es un ROS 2 Workspace? Puedes encontrar más información aquí. ↩
-
¿Qué es Colcon? Descubre más aquí. ↩
-
ros2_wses un nombre común utilizado para un ROS 2 workspace en muchos tutoriales en línea, el nombre no importa realmente, podría llamarse de cualquier manera. Puedes aprender más sobre los ROS 2 Workspaces aquí. ↩ -
Puedes aprender más sobre todo esto en los Tutoriales Oficiales de ROS 2 (si te interesa). ↩
-
El enfoque que adoptamos está basado en este tutorial (cortesía de Robotics Backend), así que no dudes en revisarlo si deseas obtener más información. ↩
-
¿Qué hace
source ~/.bashrc? Consulta aquí para una explicación. ↩