Cómo enviar mensajes ros2 desde un servidor websocket a clientes conectados en tornado
Tengo un script de publicador ros2 que envía mensajes personalizados desde nodos ros2. Lo que necesito hacer es tener un suscriptor (que también es mi servidor de websocket) para escuchar el mensaje que envía el publicador, luego convertirlo a un diccionario y enviarlo como un json desde el servidor de websocket a un cliente de websocket conectado. Ya he revisado el repositorio de rosbridge pero no pude hacer que funcione. No tiene suficiente documentación y soy nuevo en ros.
Necesito algo como esto:
import rclpy
import sys
from rclpy.node import Node
import tornado.ioloop
import tornado.httpserver
import tornado.web
import threading
from custom.msg import CustomMsg
from .convert import message_to_ordereddict
wss = []
class wsHandler(tornado.websocket.WebSocketHandler):
def open(self):
print('Online')
if self not in wss:
wss.append(self)
def on_close(self):
print('Offline')
if self in wss:
wss.remove(self)
def wsSend(message):
for ws in wss:
ws.write_message(message)
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(CustomMsg, 'topic', self.CustomMsg_callback, 10)
self.subscription
def CustomMsg_callback(self, msg):
ws_message = message_to_ordereddict(msg)
wsSend(ws_message)
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(tornado.web.Application(wsHandler))
http_server.listen(8888)
main_loop = tornado.ioloop.IOLoop.instance()
# Start main loop
main_loop.start()
Entonces, la función de devolución de llamada en la clase MinimalSubscriber recibe el mensaje ros, lo convierte en un diccionario y lo envía al cliente de websocket. Estoy un poco confundido acerca de cómo hacer que estos dos hilos (ros y websocket) se comuniquen entre sí.
davy.ai
Para hacer que el script del publicador de ROS2 y el servidor de websockets se comuniquen entre sí, puedes usar las bibliotecas de cliente de ROS2 en Python, que pueden publicar o suscribirse a temas en tu red de ROS2. Luego, puedes pasar mensajes entre el suscriptor de ROS2 y el servidor de websockets convirtiéndolos a formatos compatibles. Esto se puede hacer utilizando la función message_to_ordereddict() de ROS2 para convertir los mensajes de ROS2 en un diccionario de Python y luego utilizando JSON para enviar el diccionario al cliente de websockets.
Aquí hay un ejemplo de cómo puedes modificar el código que proporcionaste para implementar esto:
En el código anterior, hemos modificado la función wsSend() para convertir el diccionario de mensajes a JSON antes de enviarlo al cliente de websockets utilizando la función write_message(). También hemos agregado un QoSProfile al suscriptor de ROS2, que especifica el número máximo de mensajes que se pueden almacenar en búfer antes de que se descarten los mensajes antiguos.
En la función main(), hemos inicializado ROS2 utilizando rclpy.init(), creado una instancia de la clase MinimalSubscriber y agregado el suscriptor a un MultiThreadedExecutor. También hemos creado un servidor de websockets utilizando la biblioteca Tornado y lo hemos iniciado en un hilo separado. Finalmente, hemos iniciado tanto los hilos de ROS2 como los del servidor de websockets y los hemos unido al hilo principal.
Este código debería permitir que tu servidor de websockets escuche los mensajes de ROS2 y los envíe como JSON a los clientes conectados. Ten en cuenta que es posible que debas modificar el tema y los tipos de mensajes de ROS2 para que coincidan con los de tu propio código.