Waffle (& ROS) Básico¶
Habiendo completado los pasos de la página anterior, tu robot y laptop ya deben estar emparejados y ROS debe estar en funcionamiento (en el robot). ¡Ahora estás listo para darle vida al robot!
En esta página encontrarás una serie de ejercicios para trabajar, ver cómo funcionan los robots, explorar algunos conceptos fundamentales de ROS y utilizar herramientas clave de ROS, en caso de que aún no hayas tenido la oportunidad de explorarlas en simulación.
Enlaces Rápidos¶
- Ejercicio 1: Hacer que el Robot se Mueva
- Ejercicio 2: Ver los Sensores en Acción
- Ejercicio 3: Visualizar la Red de ROS
- Ejercicio 4: Explorar Topics e Interfaces de ROS
- Ejercicio 5: Un Nodo de Control de Velocidad en Python
- Ejercicio 6: Usar SLAM para crear un mapa del entorno
Control Manual¶
Ejercicio 1: Hacer que el Robot se Mueva¶
Existe una aplicación ROS ya lista muy útil llamada teleop_keyboard (del paquete turtlebot3_teleop) que usaremos para conducir un Waffle. ¡Este nodo funciona exactamente de la misma manera tanto en simulación como en el mundo real!
-
Ya deberías tener dos instancias de terminal activas:
- TERMINAL 1: La terminal del robot con los procesos de "bringup" en ejecución (Lanzando ROS, Paso 3)
- TERMINAL 2: La terminal de la laptop con el nodo
rmw_zenohden ejecución (Lanzando ROS, Paso 4)
-
Abre una nueva instancia de terminal en la laptop usando el atajo de teclado Ctrl+Alt+T o haciendo clic en el ícono de la aplicación Terminal; la llamaremos TERMINAL 3. En esta terminal, ingresa el siguiente comando
ros2 runpara iniciar el nodoteleop_keyboard: -
Sigue las instrucciones que aparecen en la terminal para conducir el robot utilizando teclas específicas del teclado:
Warning
¡Ten cuidado de evitar obstáculos y otras personas en el laboratorio mientras haces esto!
-
Una vez que hayas pasado un tiempo con esto, cierra la aplicación ingresando Ctrl+C en TERMINAL 3.
Paquetes y Nodos¶
Las aplicaciones ROS se organizan en paquetes. Los paquetes son básicamente carpetas que contienen scripts, configuraciones y archivos de lanzamiento (formas de iniciar esos scripts y configuraciones).
Los scripts le indican al robot qué hacer y cómo actuar. En ROS, estos scripts se llaman nodos. Los Nodos de ROS son programas ejecutables que realizan tareas y operaciones específicas del robot. Típicamente están escritos en C++ o Python, aunque también es posible escribir Nodos de ROS en otros lenguajes de programación.
Hay dos formas principales de lanzar aplicaciones ROS:
ros2 launchros2 run
Recuerda que acabamos de usar el comando ros2 run en el Ejercicio 1 para lanzar el nodo teleop_keyboard. Este comando tiene la siguiente estructura:
La Parte [1] especifica el nombre del paquete de ROS que contiene la funcionalidad que queremos ejecutar. La Parte [2] se usa para especificar un único script dentro de ese paquete que queremos ejecutar. Por lo tanto, usamos comandos ros2 run para lanzar ejecutables individuales (también conocidos como Nodos) en la red ROS (en el Ejercicio 1, por ejemplo, lanzamos el nodo teleop_keyboard).
El comando ros2 launch tiene una estructura similar:
Aquí, la Parte [1] es igual que en el comando ros2 run, pero la Parte [2] es ligeramente diferente: {[2] Archivo de lanzamiento}. En este caso, la Parte [2] es un archivo dentro de ese paquete que especifica cualquier número de Nodos que queremos lanzar en la red ROS. Por lo tanto, podemos lanzar múltiples nodos al mismo tiempo desde un único archivo de lanzamiento.
Sensores y Herramientas de Visualización¶
Nuestros Waffles tienen sensores bastante sofisticados que les permiten "ver" el mundo a su alrededor. Ahora veamos lo que nuestro robot percibe, usando algunas herramientas útiles de ROS.
Ejercicio 2: Ver los Sensores en Acción¶
-
No debería haber nada ejecutándose en TERMINAL 3 ahora, después de que cerraste el nodo
teleop_keyboard(usando Ctrl+C) al final del ejercicio anterior. Regresa a esta terminal e ingresa el siguiente comando:Esto lanzará una aplicación llamada RViz, una herramienta muy útil que nos permite visualizar los datos de todos los sensores a bordo de nuestros robots. Cuando RViz se abra, deberías ver algo similar a lo siguiente:
Haz clic en la casilla junto a "Camera" en la lista de "Displays" para habilitar la suscripción a la cámara. Luego debería aparecer una transmisión en vivo de la cámara del robot en el panel Camera en la parte inferior izquierda.
-
En el panel principal de RViz deberías ver un modelo digital del robot, rodeado por muchos puntos verdes. Esta es una representación de los datos de desplazamiento láser provenientes del sensor LiDAR (el dispositivo negro en la parte superior del robot). El sensor LiDAR gira continuamente, enviando pulsos láser al entorno mientras lo hace. Cuando un pulso alcanza un objeto, se refleja de vuelta al sensor, y el tiempo que tarda este proceso se usa para calcular a qué distancia está el objeto.
El sensor LiDAR gira y realiza este proceso de forma continua, por lo que se puede generar un escaneo completo de 360° del entorno. Por lo tanto, estos datos son muy útiles para cosas como evasión de obstáculos y mapeo.
-
Coloca tu mano frente al robot y observa si la posición de los puntos verdes cambia para coincidir con la ubicación de tu mano. Mueve tu mano hacia arriba y hacia abajo y considera a qué altura el sensor LiDAR puede detectarla.
-
Luego, acerca y aleja tu mano y observa cómo los puntos verdes se mueven para reflejar esto.
-
Abre una nueva instancia de terminal (TERMINAL 4) y lanza el nodo
teleop_keyboardcomo lo hiciste en el Ejercicio 1. Observa cómo cambian los datos en la pantalla de RViz mientras conduces el robot.
Ejercicio 3: Visualizar la Red de ROS¶
Al usar ros2 run y ros2 launch como hemos hecho hasta ahora, es fácil terminar con muchos procesos o Nodos de ROS diferentes ejecutándose en la red, algunos de los cuales interactuaremos con ellos, pero otros pueden simplemente estar ejecutándose en segundo plano. A menudo es útil saber exactamente qué está ejecutándose en la red ROS, y hay varias formas de hacer esto.
-
Abre una nueva instancia de terminal ahora (TERMINAL 5) y desde aquí usa el comando
ros2 nodepara listar los nodos que están ejecutándose actualmente:Como mínimo, deberías ver la siguiente lista:
-
Podemos visualizar las conexiones entre los nodos activos usando un nodo de ROS llamado
rqt_graph. En la misma terminal, inícialo de la siguiente manera:Debería abrirse una ventana:
-
Desde aquí, queremos cargar el plugin Node Graph. En el menú superior selecciona
Plugins>Introspection>Node Graph. -
En la ventana que se abre, selecciona
Nodes/Topics (active)en el menú desplegable de la parte superior izquierda.Lo que deberías ver entonces es un mapa de todos los nodos de la lista anterior (como óvalos) y flechas que ilustran el flujo de información entre ellos. ¡Esta es una representación visual de la red ROS!
Los elementos con borde rectangular son ROS Topics. Los ROS Topics son esencialmente canales de comunicación, y los Nodos de ROS pueden leer (suscribirse) o escribir (publicar) en estos topics para acceder a datos de sensores, pasar información por la red y hacer que sucedan cosas.
Si el Nodo
teleop_keyboardaún está activo (en TERMINAL 4), el gráfico debería mostrarnos que este nodo está publicando mensajes en un topic llamado/cmd_vel, al cual a su vez se suscribeturtlebot3_node.Este nodo se ejecuta en el robot y controla su velocidad. Le enviamos instrucciones (publicando en el topic
/cmd_vel) para hacer que el robot se mueva.
Un Robot ROS podría tener cientos de nodos individuales ejecutándose simultáneamente para llevar a cabo todas sus operaciones y acciones necesarias. Cada nodo se ejecuta de forma independiente, pero utiliza métodos de comunicación de ROS para comunicarse y compartir datos con los demás nodos en la Red ROS.
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 Nodos pueden publicar (escribir) y/o suscribirse (leer) a ROS Topics para compartir datos en la red ROS. Los datos se publican en los topics a través de interfaces de tipo mensaje.
Veamos esto con un poco más de detalle...
Ejercicio 4: Explorar Topics e Interfaces de ROS¶
Al igual que el comando ros2 node list, podemos usar ros2 topic list para listar todos los topics que están actualmente activos en la red ROS.
-
Cierra la ventana de RQT Graph si aún no lo has hecho. Esto liberará TERMINAL 5 para que podamos ingresar comandos en ella nuevamente. Regresa a esta ventana de terminal e ingresa lo siguiente:
Ahora debería imprimirse una nueva lista de elementos en la terminal. Intenta identificar el elemento
/cmd_velen la lista.Como aprendimos antes, este topic se usa para controlar la velocidad del robot ('velocidad de comando').
-
Obtengamos más información sobre esto usando el comando
ros2 topic info.Esto debería proporcionar una salida similar a la siguiente:
Esto nos dice que el tipo de datos que se comunican en el topic
/cmd_velse llama:geometry_msgs/msg/TwistStamped.La descripción de la interfaz tiene tres partes:
geometry_msgs: El nombre del paquete de ROS al que pertenece esta interfaz.msg: El tipo de interfaz. En este caso mensaje, pero también hay otros tipos.TwistStamped: El nombre de la interfaz de mensaje.
Así, acabamos de aprender que si queremos hacer que el robot se mueva, necesitamos publicar mensajes
TwistStampeden el topic/cmd_vel. -
Podemos usar el comando
ros2 interfacepara obtener más información sobre el mensajeTwistStamped:Con esto deberíamos obtener 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 zAquí tenemos una lista de campos, subcampos y tipos de datos. La interfaz tiene dos campos base (indicados por las líneas que no están indentadas):
# Nombre del Campo Tipo del Campo 1 headerstd_msgs/Header2 twistTwistDe los anteriores, nos interesa principalmente el Campo 2, que contiene dos subcampos adicionales:
# Nombre del Campo Tipo del Campo 1 linearVector32 angularVector3Cada uno de estos contiene 3 subcampos adicionales:
x,yyz:# Nombre del Campo Tipo de Dato 1 xfloat642 yfloat643 zfloat64Veamos qué significa todo esto...
Control de Velocidad¶
El movimiento de cualquier robot móvil puede definirse en términos de sus tres ejes principales: X, Y y Z. En el contexto de nuestro TurtleBot3 Waffle, estos ejes (y el movimiento en torno a ellos) se definen de la siguiente manera:
En teoría, un robot puede moverse linealmente o angularmente en cualquiera de estos tres ejes, como se muestra con las flechas en la figura. Eso son seis Grados de Libertad (GDL) en total, logrados según el diseño del robot y los actuadores con que cuenta. Vuelve a mirar la salida de ros2 interface show mostrada anteriormente. Esperamos que ahora quede más claro que el subcampo twist de la interfaz TwistStamped está formateado para darle a un programador de ROS la capacidad de pedirle a un robot que se mueva en cualquiera de sus seis GDL.
Vector3 linear
float64 x <-- Adelante (o Atrás)
float64 y <-- Izquierda (o Derecha)
float64 z <-- Arriba (o Abajo)
Vector3 angular
float64 x <-- "Balanceo" (Roll)
float64 y <-- "Cabeceo" (Pitch)
float64 z <-- "Guiñada" (Yaw)
¡Nuestro robot TurtleBot3 solo tiene dos motores, por lo que en realidad no tiene seis GDL! Los dos motores pueden controlarse de forma independiente, lo que le da lo que se llama una configuración de "tracción diferencial", pero aun así solo le permite moverse con dos grados de libertad en total, como se ilustra a continuación.
Por lo tanto, solo puede moverse linealmente en el eje x (Adelante/Atrás) y angularmente en el eje z (Guiñada).
Ejercicio 5: Un Nodo de Control de Velocidad en Python¶
Important
Antes de comenzar, asegúrate de que no haya nada ejecutándose en TERMINAL 3, 4 ni 5 (ingresa Ctrl+C en cada una de estas terminales para detener cualquier proceso que pueda estar ejecutándose allí).
Como hemos visto, hacer que un robot se mueva con ROS es simplemente publicar los datos correctos (geometry_msgs/msg/TwistStamped) en el topic de ROS correcto (/cmd_vel). Anteriormente usamos el nodo teleop_keyboard para conducir el robot, un poco como un auto de control remoto. En el fondo, lo que realmente ocurría era que el nodo convertía las pulsaciones de teclas del teclado en comandos de velocidad y los publicaba en el topic /cmd_vel.
En la realidad, los robots necesitan ser capaces de navegar entornos complejos de forma autónoma, lo cual es una tarea bastante difícil y requiere que construyamos aplicaciones a medida. Podemos construir estas aplicaciones usando Python, y veremos los conceptos fundamentales detrás de esto ahora, construyendo un nodo simple que le permitirá a nuestro robot ser un poco más "autónomo". ¡Lo que haremos aquí forma la base de las aplicaciones más complejas que aprenderás durante el curso de laboratorio!
-
Anteriormente hablamos de cómo los Nodos de ROS deben estar contenidos dentro de paquetes, así que creemos uno ahora usando un script auxiliar que ya hemos preparado. (Esto se cubre con más detalle en el curso de ROS, pero para los propósitos de este ejercicio, simplemente ejecuta el script sin preocuparte demasiado por él.)
En TERMINAL 3, navega al Espacio de Trabajo de ROS2 en la laptop:
-
Desde aquí, usa
gitpara clonar nuestra "Plantilla de Paquete ROS 2" desde GitHub: -
Esta plantilla de paquete contiene un script llamado
init_pkg.sh, que puede ejecutarse para convertir la plantilla en un paquete de ROS 2 real. Ejecuta el script de la siguiente manera, lo que convertirá la plantilla en un paquete de ROS 2 llamadowaffle_demo: -
Navega al directorio de este nuevo paquete (usando
cd): -
Este paquete contiene un subdirectorio llamado
scripts, y dentro de él hay dos nodos básicos para comenzar: -
Abramos nuestro paquete ahora en Visual Studio Code (VS Code).
Note
¡No olvides incluir el
.al final, es importante! -
A continuación, en el explorador de archivos de VS Code, abre el directorio
scripts, encuentra el archivobasic_velocity_control.pyy haz clic en él para abrirlo en el editor.Este es un Nodo Python de ROS 2 (bastante) básico que controlará la velocidad del robot. Analicemos su contenido:
-
Primero, tenemos algunas importaciones:
rclpyes la biblioteca cliente de ROS para Python. La necesitamos para que nuestro nodo Python pueda interactuar con ROS.- Sabemos de antes que para hacer que un robot se mueva necesitamos publicar mensajes en el topic
/cmd_vel, y que este topic usa una estructura de datos (o Interfaz) llamadageometry_msgs/msg/TwistStamped. Así es como importamos la interfaz a nuestro nodo Python para poder crear comandos de velocidad para nuestro robot (a lo cual llegaremos en breve...). - Usaremos esto para controlar el tiempo en nuestro nodo.
Haz clic en los íconos para revelar más información sobre cada línea del código.
-
Luego, declaramos algunas variables que podemos usar y adaptar durante la ejecución principal de nuestro código:
- Dentro del bucle
while(explicado en breve) definimos dos estados operativos diferentes para el robot, y podemos controlar cuál está activo cambiando este valor de1a2(y viceversa). -
Aquí estamos instanciando un mensaje de Interfaz
TwistStampedy lo llamamosvel. Le asignaremos valores de velocidad en el buclewhilemás adelante.Recuerda que un mensaje
TwistStampedcontiene seis componentes diferentes a los que podemos asignar valores. ¿Cuáles dos son relevantes para nuestro robot?
- Dentro del bucle
-
Luego configuramos algunas cosas importantes relacionadas con ROS:
rclpy.init(args=None) # (1)! node = rclpy.create_node("basic_velocity_control") # (2)! vel_pub = node.create_publisher(TwistStamped, "cmd_vel", 10) # (3)!- Inicializa
rclpyy todas las comunicaciones de ROS necesarias para nuestro nodo. - Inicializa este script Python como un nodo de ROS real, proporcionando un nombre con el que se registrará en la red ROS ("basic_velocity_control" en este caso).
- Aquí configuramos un publisher al topic
/cmd_velpara que el nodo pueda enviar comandos de velocidad al robot (usando datosTwistStamped).
- Inicializa
-
Después de esto, definimos otra variable:
- ¿Qué hora es ahora mismo? Esto nos indica el "Tiempo de ROS" actual (en nanosegundos), que será útil para comparar en el bucle while.
-
Ahora entramos en un bucle
while, donde nuestro código pasará la mayor parte de su tiempo una vez que esté en funcionamiento:while rclpy.ok(): # (1)! time_now = node.get_clock().now().nanoseconds # (2)! elapsed_time = (time_now - timestamp) * 1e-9 # (3)! ...- Esto retorna
Truemientras el nodo esté activo, por lo que todo el código dentro del buclewhilecontinuará ejecutándose mientras esto sea así. - ¿Qué hora es ahora? Verifica el tiempo al inicio de cada iteración del bucle
whiley asígnalo a una variable llamadatime_now. - Determina cuánto tiempo ha transcurrido (en segundos) desde que se actualizó por última vez el
timestamp.
-
Una sentencia
ifcontrola ahora el estado de operación de nuestro robot.-
En el estado
1establecemos velocidades que harán que el robot se mueva hacia adelante (solo velocidad lineal en X) durante cierta cantidad de tiempo y luego se detenga. ¿Cuánto tiempo se moverá el robot hacia adelante y a qué velocidad?if state == 1: if elapsed_time < 2: # (1)! vel.twist.linear.x = 0.05 # (2)! vel.twist.angular.z = 0.0 else: # (3)! vel.twist.linear.x = 0.0 # (4)! vel.twist.angular.z = 0.0 state = 2 # (5)! timestamp = node.get_clock().now().nanoseconds # (6)!- Si el tiempo transcurrido es menor a 2 segundos...
- Establece una velocidad lineal para que el robot se mueva hacia adelante.
- Si el tiempo transcurrido ha superado los 2 segundos...
- Establece las velocidades del robot a
0.0para que se detenga. - En la siguiente iteración del bucle, pasa al estado 2.
- Reinicia el timestamp para empezar a contar de nuevo.
-
En el estado
2establecemos velocidades que harán que el robot gire en el lugar (solo velocidad angular en Z) durante cierta cantidad de tiempo y luego se detenga. ¿Cuánto tiempo lo hará y a qué velocidad?elif state == 2: if elapsed_time < 4: # (1)! vel.twist.linear.x = 0.0 vel.twist.angular.z = 0.2 # (2)! else: # (3)! vel.twist.linear.x = 0.0 # (4)! vel.twist.angular.z = 0.0 state = 1 # (5)! timestamp = node.get_clock().now().nanoseconds # (6)!- Mientras el tiempo transcurrido sea menor a 4 segundos...
- Aplica una velocidad angular al robot para que gire en el lugar.
- Una vez que el tiempo transcurrido haya superado los 4 segundos...
- Regresa las velocidades del robot a
0.0para que se detenga. - En la siguiente iteración del bucle, regresa al estado 1 (avanzar).
- Reinicia el timestamp una vez más.
-
-
Y después de la sentencia
if:node.get_logger().info( # (1)! f"\n[State = {state}] Publishing velocities:\n" f" - linear.x: {vel.twist.linear.x:.2f} [m/s]\n" f" - angular.z: {vel.twist.angular.z:.2f} [rad/s].", throttle_duration_sec=1, ) vel_pub.publish(vel) # (2)!- Esto (y las siguientes 5 líneas) imprimirá un mensaje en la terminal para proporcionarnos actualizaciones regulares sobre en qué estado se encuentra actualmente el nodo y qué velocidades se han establecido (en la sentencia
ifanterior). -
Esta línea es crucial: esta operación publica los comandos de velocidad en el topic
/cmd_velpara que el robot actúe en base a nuestras instrucciones.Independientemente de lo que ocurra en los estados del
ifanteriores, siempre publicamos un comando de velocidad en el topic/cmd_velaquí (en cada iteración del bucle).
- Esto (y las siguientes 5 líneas) imprimirá un mensaje en la terminal para proporcionarnos actualizaciones regulares sobre en qué estado se encuentra actualmente el nodo y qué velocidades se han establecido (en la sentencia
- Esto retorna
-
-
Ahora estamos listos para compilar nuestro paquete y poder ejecutarlo. Usamos una herramienta llamada "Colcon" para esto, pero DEBE ejecutarse desde la raíz del Espacio de Trabajo de ROS 2 (es decir,
~/ros2_ws/), así que naveguemos allí ahora usandocd. Regresa a TERMINAL 3 y ejecuta lo siguiente:Luego, usa el comando
colcon buildpara compilar tu paquete:Y finalmente, "recarga" el entorno:
-
Ahora podemos ejecutar el código.
Note
¡Asegúrate de que el robot esté en el suelo y tenga suficiente espacio para moverse antes de hacer esto!
Observa qué hace el robot. Cuando hayas visto suficiente, ingresa Ctrl+C para detener el nodo.
-
Ahora es el momento de adaptar el código:
El objetivo aquí es hacer que el robot siga una trayectoria cuadrada. Lo que puede que hayas observado al ejecutar el código es que el robot ¡en realidad no hace eso! Estamos usando un enfoque basado en tiempo para que el robot alterne entre dos estados diferentes de forma continua:
- Avanzando hacia adelante
- Girando en el lugar
Observa el código para determinar cuánto tiempo pasará el robot actualmente en cada estado.
Queremos que el robot siga una trayectoria cuadrada de 0.5m x 0.5m. Para lograrlo correctamente tendrás que ajustar los tiempos, la velocidad del robot, o ambos. ¡Edita el código para que el robot siga realmente una trayectoria cuadrada de 0.5m x 0.5m!
SLAM¶
El Mapeo y Localización Simultáneos (SLAM, por sus siglas en inglés: Simultaneous Localisation and Mapping) es una sofisticada herramienta integrada en ROS. Usando datos del sensor LiDAR del robot, más el conocimiento de cuánto se ha movido el robot1, un robot es capaz de crear un mapa de su entorno y mantener un seguimiento de su ubicación dentro de ese entorno al mismo tiempo. En el ejercicio que sigue verás lo fácil que es implementar SLAM con el Waffle.
Ejercicio 6: Usar SLAM para crear un mapa del entorno¶
-
En TERMINAL 3 ingresa el siguiente comando para lanzar todos los nodos de SLAM necesarios:
Tip
¡En la laptop, este comando también está disponible como un alias:
tb3_slam!Esto lanzará una nueva instancia de RViz, mostrando una vista aérea del entorno y puntos de varios colores que representan los datos en tiempo real del LiDAR.
SLAM ya habrá comenzado a procesar estos datos para empezar a construir un mapa de los límites actualmente visibles para el Waffle según su ubicación en el entorno.
-
Regresa ahora a TERMINAL 4 y lanza el nodo
teleop_keyboard. Comienza a conducir el robot despacio y con cuidado para construir un mapa completo del área.Tip
Es mejor hacerlo despacio y realizar múltiples circuitos del área para construir un mapa más preciso.
-
Una vez que estés satisfecho con el mapa que ha construido tu robot de su entorno, puedes guardarlo usando el nodo
map_saver_clidel paquetenav2_map_server:-
Primero, crea un nuevo directorio dentro de tu paquete de ROS en la laptop. Regresa a TERMINAL 5 y navega a la raíz del paquete
waffle_demoque creaste anteriormente: -
Crea un directorio aquí llamado
maps: -
Navega a este directorio:
-
Luego, usa
ros2 runpara ejecutar el nodomap_saver_cliy guardar una copia del mapa de tu robot:Reemplaza
NOMBRE_MAPAcon un nombre apropiado para tu mapa. Esto creará dos archivos:- un
NOMBRE_MAPA.pgm - un archivo
NOMBRE_MAPA.yaml
...ambos contienen datos relacionados con el mapa que acabas de crear.
- un
-
El archivo
.pgmse puede abrir usando una aplicación llamadaeogen la laptop:
-
-
Regresa a TERMINAL 3 y cierra SLAM presionando Ctrl+C. El proceso debería detenerse y RViz debería cerrarse.
-
Cierra también el nodo
teleop_keyboarden TERMINAL 4, si aún está en ejecución.
Próximos Pasos¶
Habiendo dominado los conceptos básicos, debes asegurarte de revisar algunas Consideraciones Esenciales antes de avanzar mucho más en este curso; estas destacarán algunos desafíos que los estudiantes enfrentan comúnmente al trabajar con los robots. Conocerlos con anticipación puede marcar una gran diferencia y ahorrarte muchos dolores de cabeza en el laboratorio.
... y cuando hayas terminado con tu robot al final de cada sesión de laboratorio, asegúrate de apagarlo correctamente.
-
Aprenderás mucho más sobre "Odometría del Robot" en el curso de laboratorio. ↩