Una introducción al sistema operativo de robot: el marco de aplicación de robot definitivo

Publicado: 2022-03-11

El sistema operativo de robot (ROS) no es un sistema operativo real, sino un marco y un conjunto de herramientas que brindan la funcionalidad de un sistema operativo en un clúster de computadoras heterogéneas. Su utilidad no se limita a los robots, sino que la mayoría de las herramientas proporcionadas están enfocadas a trabajar con hardware periférico.

ROS se divide en más de 2000 paquetes, cada paquete proporciona una funcionalidad especializada. La cantidad de herramientas conectadas al marco es probablemente su mayor poder.

¿Por qué debo usar Robot OS?

ROS proporciona funcionalidad para la abstracción de hardware, controladores de dispositivos, comunicación entre procesos en varias máquinas, herramientas para pruebas y visualización, y mucho más.

La característica clave de ROS es la forma en que se ejecuta el software y la forma en que se comunica, lo que le permite diseñar software complejo sin saber cómo funciona cierto hardware. ROS proporciona una forma de conectar una red de procesos (nodos) con un concentrador central. Los nodos se pueden ejecutar en varios dispositivos y se conectan a ese concentrador de varias maneras.

Las principales formas de crear la red son proporcionar servicios solicitables o definir conexiones de publicador/suscriptor con otros nodos. Ambos métodos se comunican a través de tipos de mensajes específicos. Los paquetes principales proporcionan algunos tipos, pero los paquetes individuales pueden definir tipos de mensajes.

Los desarrolladores pueden ensamblar un sistema complejo conectando soluciones existentes para problemas pequeños. La forma en que se implementa el sistema nos permite:

  • Reemplace los componentes con interfaces similares sobre la marcha, eliminando la necesidad de detener el sistema para varios cambios

  • Multiplexación de salidas de múltiples componentes en una entrada para otro componente, lo que permite la resolución paralela de varios problemas

  • Conecte componentes creados en varios lenguajes de programación simplemente implementando los conectores adecuados en el sistema de mensajería, lo que facilita el desarrollo de software conectando módulos existentes de varios desarrolladores.

  • Cree nodos en una red de dispositivos, sin preocuparse por dónde se ejecuta el código e implementando sistemas de comunicación entre procesos (IPC) y llamada a procedimiento remoto (RPC).

  • Conéctese directamente a fuentes a pedido desde hardware remoto sin escribir ningún código adicional, empleando los dos puntos anteriores

Planeamos demostrar cuán útil es desarrollar iterativamente una solución simple. Hay varias ventajas clave en comparación con otros enfoques. ROS tiene soporte multiplataforma y permite conexiones entre procesos en múltiples dispositivos a través de conexiones peer-to-peer que se manejan en segundo plano. El diseño permite la compatibilidad con cualquier idioma envolviendo las clases de comunicación de C++ o desarrollando clases manualmente para la interfaz del idioma.

ROS está hecho por su propia comunidad, destinado a su comunidad. Después de varios años, eso resultó en una gran cantidad de paquetes reutilizables que son fáciles de integrar, gracias a la arquitectura del sistema.

Enfoques alternativos como MRPT, CARMEN, LCM, Player, Microsoft RDS y otros brindan algunas de esas funciones, pero no todas. La mayoría de las veces, las fallas de diseño son las limitaciones de soporte de idiomas, la comunicación no optimizada entre procesos o la falta de soporte para varios dispositivos, lo que podría decirse que es el problema más difícil de solucionar.

¿Qué vamos a construir?

Dado que nuestro enfoque es el marco y no los algoritmos reales para problemas particulares, el problema dado será bastante simple. Nuestro objetivo es crear software para una computadora a bordo que nos permita controlar y monitorear de forma remota un robot, conectado a nosotros a través de Wi-Fi, usando un gamepad en nuestra computadora y una señal de la cámara montada en el robot.

En primer lugar, haremos que un programa simple se conecte a una simulación simple, solo para demostrar los principios básicos de ROS. Conectaremos un gamepad a una computadora e intentaremos diseñar un buen esquema de control para convertir la entrada del gamepad en señales de control para un robot.

Los principales lenguajes para escribir código ROS son C++ y Python, siendo C++ el preferido debido a su mejor rendimiento. Explicaremos nuestros ejemplos en Python debido a que hay menos repeticiones en el código y no hay necesidad de una construcción explícita.

Instalacion y configuracion

Las versiones de ROS se mencionan por su nombre. A partir de esta fecha, el último lanzamiento es Jade Turtle y la última versión LTS Indigo Igloo . Es preferible optar por la versión LTS, y la compatibilidad con versiones anteriores no está garantizada en ROS, por lo que todos los ejemplos se escribirán para Indigo .

ROS está disponible en varias plataformas *NIX. La versión con soporte oficial está en Ubuntu. Las versiones de OS X, Arch Linux, Debian, Raspbian y Android son compatibles con la comunidad.

Pasaremos por el proceso de instalación de Ubuntu 14.04 en el escritorio. Los procesos para todas las versiones y plataformas compatibles están disponibles en el sitio web oficial. También están disponibles máquinas virtuales con ROS instalado.

La instalación depende de la plataforma (y la mayoría de las plataformas tienen paquetes proporcionados), pero la configuración del espacio de trabajo es la misma para todas las plataformas.

Instalación en Ubuntu

ROS proporciona sus propios repositorios. El primer paso es agregarlos.

 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update

Después de eso, tendrá todos los paquetes alojados para todas las versiones de ROS disponibles para su versión de Ubuntu. Por ejemplo, Ubuntu 14.04 admite indigo y jade .

La instalación de los paquetes base en el escritorio tiene una de tres opciones:

  • sudo apt-get install ros-indigo-ros-base para una instalación mínima

  • sudo apt-get install ros-indigo-desktop para tener las herramientas GUI adicionales básicas

  • sudo apt-get install ros-indigo-desktop-full para tener todas las funciones oficiales, incluidos varios simuladores y bibliotecas para navegación y percepción

Para obtener la mejor experiencia laboral, se recomienda la opción completa. Para la instalación en dispositivos que solo se utilizarán para ejecutar nodos, la versión base es suficiente. Independientemente de la opción que elija, puede instalar cualquier paquete necesario llamado package_name ejecutando:

 sudo apt-get install ros-indigo-<package-name>

Los guiones bajos se reemplazan por guiones en el nombre final, por lo que stage_ros estará en el paquete ros-indigo-stage-ros .

El siguiente paso es inicializar rosdep . Los paquetes en ROS pueden declarar de qué componentes dependen. rosdep le permite compilar esos paquetes sin demasiado manejo manual de dependencias. Para inicializarlo, llame a:

 sudo rosdep init rosdep update

ROS tiene varias variables de entorno utilizadas por sus herramientas. Con la instalación predeterminada, el script bash para inicializarlos se encuentra en /opt/ros/indigo/setup.bash . Las variables deben inicializarse dentro de cada sesión de bash, por lo que la mejor solución es agregarlas a ~/.bashrc .

 echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc source ~/.bashrc

Algunos paquetes instalan dependencias externas a través de rosinstall , que está disponible como paquete y se instala a través sudo apt-get install python-rosinstall .

Este es el final de la instalación en Ubuntu. Lo que sigue es una breve introducción a la instalación de espacios de trabajo.

Configuración

Desde Groovy Galapagos , los espacios de trabajo de ROS se administran a través de catkin . Necesitamos definir un directorio para todos los paquetes que hospedamos. Dentro del directorio, creamos una carpeta src y llamamos al formulario catkin_init_workspace dentro de ella. Eso creará varios enlaces simbólicos a la versión de ROS de origen actual. El siguiente paso es agregar este espacio de trabajo a las variables de entorno también.

Para realizar toda esta configuración del espacio de trabajo, elija un directorio vacío y ejecute los siguientes comandos:

 mkdir src cd src catkin_init_workspace cd .. catkin_make echo "source $(pwd)/devel/setup.bash" >> ~/.bashrc source ~/.bashrc

Ahora ha creado un espacio de trabajo dentro del cual puede crear sus propios paquetes ROS.

Familiarizarse con las herramientas

Crear cualquier código es un gran salto. Primero, familiaricémonos con algunos de los sistemas que se ejecutan detrás de escena. Nuestro primer paso será ejecutar la GUI básica y ver qué mensajes genera.

Para ejecutar cualquier cosa en ROS, se debe iniciar un proceso central. Es tan fácil como abrir una nueva ventana de terminal y escribir:

 roscore

En toda su red de dispositivos conectados, roscore debe iniciarse solo una vez, en el dispositivo que alojará el concentrador central para el envío de comunicaciones.

La función principal de roscore es decirle a los nodos a qué otros nodos deben conectarse y de qué manera (ya sea a través de un puerto de red o memoria compartida). El objetivo es permitir que los nodos solo se preocupen por los datos que quieren saber, en lugar de a qué nodo quieren conectarse, mientras se minimiza el tiempo y el ancho de banda necesarios para realizar todas las comunicaciones.

pedir

Después de ejecutar roscore , podemos iniciar la herramienta GUI principal para ROS: rqt . Lo que vemos es muy decepcionante: una ventana vacía. rqt alberga una amplia variedad de complementos que se pueden configurar en cualquier configuración visual y cualquier cantidad de vistas predefinidas.

Captura de pantalla de una ventana GUI vacía titulada "Predeterminado - rqt" y con los menús Archivo, Complementos, En ejecución, Perspectivas y Ayuda.

Para empezar, ejecutemos el complemento Dirección de robot , seleccionándolo en Plugins > Robot Tools > Robot Steering de robot. Lo que obtenemos son dos controles deslizantes, que representan el movimiento lineal y rotacional que queremos que tenga nuestro robot. En la parte superior del complemento, vemos un cuadro de texto con /cmd_vel . Podemos cambiarle el nombre a lo que queramos. Representa el nombre del tema al que se dirige la publicación. Las herramientas de terminal son el mejor lugar para ver lo que sucede en segundo plano.

Captura de pantalla que muestra la misma ventana que antes, pero con una interfaz de dirección de robot, con iconos D, recargar, ayuda, minimizar, círculo y X, dentro de ella. La primera línea tiene un cuadro de texto con "/cmd_vel" y un botón Detener. Debajo hay un control deslizante vertical centrado verticalmente establecido en el medio a 0,0 m/s, con botones a la izquierda para +, 0 y -, y controles numéricos arriba y abajo que dicen 1,00 y -1,00. Debajo hay un control deslizante similar que es horizontal y se mide en rad/s, configurado en 0 en el medio, con los controles numéricos en 3,00 a la izquierda y -3,00 a la derecha.

Herramientas terminales

ROS tiene varias herramientas poderosas para inspeccionar lo que sucede en el sistema. La primera herramienta que presentaremos es rostopic . Nos permite inspeccionar temas a los que los nodos pueden suscribirse y publicar. Ejecutar rostopic list producirá:

 /cmd_vel /rosout /rosout_agg

Los últimos 2 temas siempre se están ejecutando y están relacionados con los sistemas ROS centrales. El tema /cmd_vel está siendo publicado por nuestra dirección. Cambiar el nombre del tema en la dirección también lo cambiará aquí. Ahora, estamos interesados ​​en lo que está pasando dentro del tema. Ejecutar rostopic echo /cmd_vel no nos mostrará nada (a menos que haya manipulado los controles deslizantes). El proceso se ejecuta hasta que lo cancelamos. Muevamos ahora el deslizador vertical a 20 m/s. Mirando el eco, podemos ver que lo siguiente se repite una y otra vez:

 linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0

¿Con qué frecuencia envía spam a este mensaje? rostopic hz /cmd_vel dice a una tasa promedio de 10 Hz. Bueno, ¿cuántos temas como este puedo ejecutar a través de mi lenta conexión Wi-Fi? rostopic bw /cmd_vel detecta un promedio de 480 B/s.

Eso está muy bien, pero hablamos sobre los tipos de mensajes. Estos datos son buenos para un ser humano, pero una aplicación necesitará los datos sin procesar y necesitará saber el tipo de mensaje para poder interpretar los datos. El tipo se puede determinar con rostopic type /cmd_vel , diciéndonos que es un geometry_msgs/Twist . Todas las herramientas de terminal de ROS llamadas sin ningún argumento devuelven un mensaje de ayuda estándar.

El Wiki de ROS es lo suficientemente bueno como para hacer que una búsqueda en la web de esta cadena resulte en una explicación Wiki de lo que contiene y cómo está estructurado. Pero no tenemos que depender de ello. rosmsg es la herramienta general para tipos de mensajes. Ejecutar rosmsg show geometry_msgs/Twist devolverá:

 geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z

El mensaje consta de dos vectores 3D, que representan la velocidad lineal y angular en el espacio 3D.

Si queremos a qué temas está conectado un nodo, rosnode info <node-name> nos dará datos detallados sobre el nodo. Las herramientas rostopic , rosmsg y rosnode son las herramientas principales para inspeccionar la funcionalidad de ROS sin procesar. ROS tiene muchas más herramientas GUI y de terminal, pero esas están fuera de nuestro alcance en esta introducción.

Las principales herramientas para ejecutar nodos ROS son rusrun y roslaunch . rosrun puede ejecutar nodos a través rosrun <package_name> <node_name> , y roslaunch ejecuta nodos basados ​​en archivos de inicio, con los que nos familiarizaremos un poco, ya que son el elemento más complejo de la automatización de ROS.

Podemos cerrar todo lo que ejecutamos para comenzar a trabajar en nuestro primer código. Para referencia futura, no hace falta decir que ejecutar cualquier cosa relacionada con ROS requiere una instancia activa de roscore . Muchos de los problemas con los que te encuentras se pueden resolver cerrando la ventana de la terminal en la que se ejecuta roscore y abriendo una nueva para reiniciarla. Esto actualiza todas las dependencias que necesitaban recargarse, tanto en bash como en roscore .

Creación de teleoperación de gamepad

Nuestro primer objetivo es imitar la funcionalidad de Robot Steering mediante la creación de un nodo que publique datos de geometry_msgs/Twist en /cmd_vel en función de la entrada del gamepad. Nuestra primera parada es el paquete de joy .

El paquete de la joy

El paquete joy proporciona controladores ROS genéricos para joysticks y gamepads. No está incluido en la instalación predeterminada, por lo que debe instalarse a través de:

 sudo apt-get install ros-indigo-joy

Después de la instalación, podemos ejecutar rosrun joy joy_node . Esto nos conectará con el joystick o gamepad predeterminado. Ejecutar rostopic list nos muestra que tenemos un tema llamado /joy . Escucharlo a través rostopic echo nos muestra mensajes del siguiente formato (tenga en cuenta que debe interactuar con el gamepad o joystick para que se publiquen los mensajes).

 header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Puede ignorar los encabezados por ahora. Aparte de eso, tenemos axes y buttons , explicando muy bien lo que representan. Mover ejes y presionar botones en el controlador hará que estos números cambien. Usando nuestras herramientas, podemos determinar que el tipo de mensaje es sensor_msgs/Joy y el formato es:

 std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons

Creando nuestra teleoperación

El primer paso para escribir código es hacer un paquete. Dentro de la carpeta src del espacio de trabajo, ejecute:

 catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs

Aquí indicamos el nombre del paquete que estamos creando, seguido de los paquetes de los que planeamos depender. No se preocupe, las dependencias se pueden actualizar manualmente más adelante.

Ahora tenemos una carpeta toptal_tutorial . Dentro de la carpeta, cree una carpeta de scripts que albergará todos nuestros scripts de Python.

Vamos a crear un archivo llamado teleop.py , y dentro de él pondremos:

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

También necesitaremos configurar chmod +x teleop.py para que el script se pueda ejecutar. Ejecutar rosrun joy joy_node en una terminal y rosrun toptal_tutorial teleop.py en otra dará como resultado que la salida de terminal de teleop.py se llene con mensajes de alegría.

Examinemos lo que hace el código.

Primero, importamos rospy, que alberga la biblioteca para interactuar con el marco ROS. Cada paquete que define mensajes tiene un subpaquete msg con definiciones de mensajes. Estamos importando Joy para manejar la entrada. No es necesario importar tipos de mensajes incrustados (como el Header de std_msgs.msg que está en el mensaje de Joy ) a menos que queramos mencionarlos explícitamente.

Nuestro primer paso es inicializar un nodo con un nombre específico (en este caso, lo llamamos "teleop"). Después de eso, creamos un suscriptor que se suscribe al tema "joy" de tipo sensor_msgs.msg.Joy y que maneja cada mensaje llamando a la función joy_callback . Las devoluciones de llamada reciben un parámetro, los datos del mensaje. Acceder a los miembros de los datos es simple. Si quisiéramos imprimir el estado del primer eje, si recordamos el tipo de mensaje, llamaríamos a print data.axes[0] y sería un flotante. El ciclo al final se repite hasta que ROS se apaga.

Nuestro próximo paso sería manejar nuestros datos de alguna manera. Deberíamos crear un mensaje Twist que cambie según la entrada, y luego lo publicaríamos en el tema cmd_vel .

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

Primero, agregamos el mensaje Twist y agregamos soporte para vincular argumentos de función a través functools.partial . Creamos un editor, pub , que publica en cmd_vel un mensaje de tipo Twist . Vinculamos a ese editor a la devolución de llamada y hacemos que publique un mensaje Twist en cada entrada con las velocidades representadas por los dos primeros ejes. Este código hace lo que esperamos que haga, y podemos ver la salida resultante a través rostopic echo /cmd_vel .

Todavía tenemos un problema. El tema /joy se puede publicar a muy buen precio. Si monitoreamos el rostopic hz /cmd_vel y movemos la palanca analógica en círculos, podemos ver una gran cantidad de mensajes. Eso no solo da como resultado una gran cantidad de comunicación, sino que los procesos que reciben estos mensajes tienen que procesar cada uno de ellos. No hay necesidad de publicar esos datos con tanta frecuencia, y es mejor publicarlos a una velocidad estable de 10 Hz. Podemos lograr eso con el siguiente código.

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()

Modificamos la devolución de llamada para recibir el objeto Twist mutable y modificarlo dentro del ciclo. La función de sleep de rospy.Rate mantiene una frecuencia de salida estable.

El código final dará como resultado que el tema /cmd_vel obtenga comandos de velocidad a 10 Hz, imitando la salida del complemento Robot Steering rqt .

Ejecución de un sistema simulado

Simulando el mundo

Nuestro primer objetivo es crear un entorno en el que podamos simular un escenario que queremos lograr. El nodo stageros dentro del paquete stage_ros nos permite ejecutar un robot dentro de un escenario 2D definido a través de una imagen. Hay una sintaxis completa, descrita dentro del paquete stage_ros para archivos de mundo y cómo generarlos. Es bastante simple, pero está fuera de nuestro alcance. Por suerte, el paquete viene con varias demos mundiales. Primero, vayamos al directorio de archivos ejecutando:

 roscd stage_ros cd world

Dentro de la carpeta hay varios archivos. Ejecutemos uno.

 rosrun stage_ros stageros willow-erratic.world

Esto creó varios temas. El significado de cada uno de ellos también está documentado con el paquete. La parte importante es que tiene cmd_vel .

Captura de pantalla de una ventana titulada Escenario: sauce-errático.mundo. La etiqueta de estado dice "0m 20s 300mseg (1.0)". Hay una escala a la derecha que va desde 18 en la parte inferior hasta 30 en la parte superior, en incrementos de uno. La imagen principal es un tablero de ajedrez con puntos y líneas negros principales dispersos, además de un cuadrado azul cerca del medio y un cuadrado rojo un poco más grande a unos pocos cuadrados de tablero de ajedrez de distancia.

Dentro del escenario que se muestra, hay un cuadrado azul que representa el robot que controlas. Al usar nuestro código o Robot Steering , podemos controlar este robot. Pruébalo.

Configuración de nuestro sistema a través de archivos de lanzamiento

creemos una carpeta de launch dentro de nuestro paquete, y dentro de ella creamos un archivo llamado teleop.launch . La estructura de carpetas final debería verse así:

 toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src

Dentro del archivo teleop.launch definiremos un conjunto de nodos y sus interconexiones.

 <launch> <arg name="world_file" default="$(find stage_ros)/world/willow-four-erratics-multisensor.world" /> <node pkg="stage_ros" type="stageros" name="simulated_world" args="$(arg world_file)"></node> <group ns="robot_0"> <node pkg="joy" type="joy_node" name="joy_input"></node> <node pkg="toptal_tutorial" type="teleop.py" name="joy_convert"></node> </group> </launch>

El nuevo mundo consta de cuatro robots, y cada uno de sus temas tiene un prefijo de robot_<n> . Entonces, el robot número 0 tiene un tema de comando de velocidad llamado robot_0/cmd_vel . Es por eso que ponemos nuestro control dentro de un espacio de nombres llamado robot_0 , para ajustar sus nombres a la nueva forma. En ese sentido, puede pensar en los nombres de los temas como carpetas en un sistema de archivos.

Diagrama con dos secciones, mundo-simulado y /robot_0. Este último tiene cajas y burbujas que comienzan con /robot_0/. El primero tiene una burbuja etiquetada como /simulated-world conectada a la burbuja cmd_vel de este último, que se une a un cuadro joy_convert, que se une a un cuadro joy, que se une a una burbuja joy_input. /simulated-world también se conecta a cuatro cuadros en /robot-0, a saber, image_1, depth_0, depth_1 e image_0.

Para ejecutar archivos de lanzamiento, no se necesita roscore . En cierto sentido, roscore es solo un caso especial de un archivo de lanzamiento que no hace nada. Si falta un roscore , solo el primer archivo de lanzamiento ejecutado ejecutará un núcleo, mientras que el resto se conectará a él. Ahora, ejecutamos el lanzamiento con:

 roslaunch toptal_tutorial teleop.launch

Si todo es correcto, esto dará como resultado un simulador con 4 robots, uno de los cuales se controla con nuestro gamepad o joystick. Este mundo tiene mucho más bajo el capó que el anterior. Cada uno de los cuatro robots tiene:

 /robot_<n>/base_pose_ground_truth /robot_<n>/base_scan_0 /robot_<n>/base_scan_1 /robot_<n>/camera_info_0 /robot_<n>/camera_info_1 /robot_<n>/cmd_vel /robot_<n>/depth_0 /robot_<n>/depth_1 /robot_<n>/image_0 /robot_<n>/image_1 /robot_<n>/odom

Reemplazamos <n> con 0, 1, 2 o 3. Esto nos lleva a nuestro último tema.

Ver nuestros datos con rqt

No profundizamos demasiado en rqt , pero es la herramienta perfecta para ver datos más complejos. Puede experimentar con todos los temas, pero nos centraremos en los image_0 , image_1 , depth_0 y depth_1 .

Iniciemos rqt y eliminemos los complementos abiertos. Ahora abriremos 4 visualizadores de imágenes ( Plugins > Visualization > Image View ) y los colocaremos en una formación de cuadrícula de 2x2. Finalmente, en la esquina superior izquierda de cada una de las vistas, elijamos uno de los cuatro temas indicados para robot_0 .

Captura de pantalla que muestra la interfaz de dirección de un robot, con el cuadro de texto y los controles deslizantes mencionados anteriormente, pero el cuadro de texto dice "/robot_0/cmd_vel". A la derecha hay cuatro vistas de imágenes. Los dos primeros (imagen_0 e imagen_1) muestran dos cuadros azules y un cuadro rojo en 3D. Los dos inferiores (profundidad_0 y profundidad_1) muestran imágenes similares a las de la parte superior, pero en escala de grises y, en particular, los cuadros de color de primer plano aquí aparecen en un gris más oscuro que los objetos del fondo.

Lo que conseguimos es visión estéreo con percepción de profundidad, con cámaras de baja resolución. Tenga en cuenta que incluso podríamos haber obtenido este resultado sin nuestro sistema de entrada. Si simplemente ejecutamos esto (desde dentro de la carpeta stage_ros/world ):

 rosrun stage_ros stageros willow-four-erratics-multisensor.world

y agregue el complemento Robot Steering con un tema llamado /robot_0/cmd_vel , habríamos obtenido los mismos resultados con los controles deslizantes en pantalla.

Aplicación de los resultados a un sistema real

Una gran cantidad de hardware tiene soporte completo para ROS, muy a menudo proporcionado por voluntarios de terceros. Muchas plataformas de robots tienen controladores que generan este tipo de mensajes, y ROS tiene nodos que toman una cámara web y publican una imagen.

Si bien el último resultado fue una simulación de lo que queremos lograr, lo mismo se puede lograr con las siguientes modificaciones:

  • Instale ROS en la computadora de a bordo de su robot
  • Cree un archivo de lanzamiento para la computadora a bordo que conecta ROS a la plataforma subyacente y todos los sensores de alto nivel como cámaras, telémetros láser y otros. Los nodos necesarios ya pueden existir, o pueden implementarse creando un publicador/suscriptor de ROS por un lado y un controlador para comunicaciones seriales por el otro.
  • Haga que el archivo de lanzamiento se ejecute al inicio
  • En su computadora remota, agregue export ROS_MASTER_URI=http://<robot_hostname>:11311/ a su inicio de bash, haciendo que la computadora remota busque roscore en ese nombre de host y puerto dados
  • Inicie rqt y/o cualquier script para monitorear y controlar el robot

A lo que realmente se reduce esto es a exportar la variable de entorno adecuada en el dispositivo remoto, y el resto se maneja solo. Ejecutar ROS en un clúster de computadoras solo necesita que se realice un paso para cada máquina.

Conclusión

Hemos demostrado cómo, con muy poca codificación, puede tener un sistema complejo de variables que puede manipular a su antojo. El sistema simple de publicador/suscriptor le permite desarrollar rápidamente una canalización de software que procesa datos en un grupo de computadoras, sin preocuparse por la implementación subyacente de ciertos elementos.

Si bien usamos un simulador simple, los simuladores más complejos como el gazebo (también incluido en la versión de escritorio completa) le permiten crear mundos 3D con física y sensores complejos, y pueden brindarle una experiencia de los resultados finales y el producto mucho antes de que se desarrolle.

Esta introducción fue muy básica, pero esperamos que se interese más en trabajar con este marco versátil.