Arquitectura para interfaz web y ros

¡Buenas! Mi nombre es Joaquín Giménez¹ , soy Desarrollador de Software en la empresa Ekumen², y generalmente trabajo desarrollando interfaces web interconectadas a sistemas ROS.

Últimamente estuve investigando sobre posibles soluciones para diseñar una arquitectura web escalable y moderna que sea compatible con ROS. Me pareció un tema interesante para hacer este post y así contribuir a nuestra comunidad en español.

No me considero un experto en el tema a desarrollar, pero la información presentada podría dar pie a futuras discusiones y contribuciones de la comunidad.

Cuando empecé a desarrollarme en el mundo de la robótica, me hice la siguiente pregunta.

¿Cómo se pueden interconectar una interfaz web y un sistema con ROS?

Luego de una búsqueda en los documentos oficiales de ROS encontré la sección³ de la wiki respondiendo a mi pregunta. La respuesta estaba en una librería escrita en JavaScript llamada roslibjs.

Debido a que la documentación oficial del ROS propone esta librería y muestra ejemplos para su aplicación no dudé en comenzar a profundizar en las funcionalidades ofrecidas por la misma.

La primera implementación que tuve con roslibjs fue con una arquitectura similar a la presentada en el siguiente cuadro.

arquitectura-1

Analizando esta implementación logré extraer lo siguiente.
Beneficios

  • Rápida implementación.
  • Fácil de comprender
  • Abundante documentación sobre el tema.

Desventajas

  • La lógica de negocios se maneja en la interfaz del cliente.
  • No permite una implementación de arquitecturas modernas.
  • No es una solución escalable.
  • roslibjs está sin actualizaciones desde junio del 2014.
  • roslibjs tiene vulnerabilidades críticas.

A raíz de lo expuesto anteriormente me hice la siguiente pregunta.

¿Cómo podemos mejorar la implementación para conectar una interfaz web y un sistema ROS?

A partir de un análisis de las desventajas presentadas por la arquitectura expuesta anteriormente me quedó claro que de alguna manera había que minimizar las vulnerabilidades de roslibjs y ofrecer a la interfaz web la posibilidad de interactuar con una API.

A continuación presento un cuadro con la propuesta de la nueva arquitectura a ser explicada posteriormente.

Como podrán notar, la arquitectura presentada contiene más elementos para lograr el mismo objetivo. Lograr interconectar interfaces web con sistemas ROS, el aumento de estos elementos conlleva una mayor complejidad a la hora de implementar la solución, no obstante, nos provee una gran cantidad de beneficios citados a continuación.
Beneficios:

  • Permite abstraer la lógica de negocios de la interfaz web.
  • Se minimiza la vulnerabilidad crítica de roslibjs al no exponerlo como medio principal de comunicación de la interfaz web.
  • Permite mejorar la seguridad en la comunicación debido a que se pueden agregar middlewares y encriptación más robusta entre la interfaz web y el backend.
  • Proporciona una arquitectura escalable.
  • Permite desarrollar fácilmente una API (REST, GraphQL, etc).
  • Provee mayor versatilidad a la hora de manejar los datos del sistema ROS.
  • Separa explícitamente la interfaz web y el backend.

Desventajas

  • Complejidad inicial mayor.
  • No hay tanta documentación.
  • Requiere mayor conocimiento técnico para su implementación.

La arquitectura propuesta consiste en dividir la capa de negocios de la interfaz que utiliza el cliente de manera a tener una mayor flexibilidad al momento de exponer los servicios a la interfaz web. Como se agrega una capa intermedia en la comunicación entre el sistema ROS y la interfaz web, podemos implementar cualquier API moderna. La implementación de una API moderna otorga al backend la capacidad de exponer distintos protocolos para la comunicación con la interfaz web, por citar algunos, HTTPS y WSS (WebSocket Secure).

Para mostrar de manera práctica esta propuesta, comencé un proyecto de Código Libre alojado en un repositorio de GitHub.

Considero que mediante Docker y Docker Compose el proyecto se puede ejecutar con mayor facilidad. En el archivo docker-compose.yml se definen cuatro servicios y dos redes para la interconexión entre ellos.

Los servicios definidos son:

  • ros-bridge: Servidor Rosbridge corriendo la distribución Noetic de ROS
  • ros-talker: Nodo de ROS publicando a un tópico
  • backend-api: Servidor Express.js
  • frontend-web: Interfaz web con React.js

Las redes definidas son:

  • ros: Se utiliza para la comunicación entre los contenedores de ros-bridge, ros-talker y el backend-api
  • api: Se utiliza para la comunicación entre los contenedores backend-api y frontend-web

En el archivo Readme.md del repositorio se cuenta con un tutorial con los requerimientos e instrucciones para levantar el proyecto. De igual manera lo explico brevemente aquí:

  1. Instalar dependencias de frontend-web
    # Posicionarse en el directorio del proyecto frontend-web
    cd frontend-web/
    # Instalar los paquetes 
    yarn  
    
  2. Instalar dependencias de backend-api
    # Posicionarse en el directorio del proyecto backend-api
    cd ../backend-api/
    # Instalar los paquetes 
    yarn  
    
  3. Correr docker-compose
    # Posicionarse en el directorio principal del proyecto
    cd ../
    # Correr el proyecto
    yarn start # por debajo ejecuta docker-compose up
    
  4. Abrir la interfaz web
    Desde el navegador http://localhost:3000/

Espero que lo expuesto haya sido de su interés y agradezco este espacio para poder compartir con ustedes contenido en español.

Información adicional
A raíz de este post surgieron las siguientes contribuciones de Código Libre.

  • Implementación de demo para demostrar la arquitectura propuesta.
  • Imagen de Docker con ROS Noetic y Rosbridge.
8 Likes

Excelente contenido Joaquín. Muchas gracias por el aporte.

Joaquin, muchas gracias por tu aporte