Open EnzoGhisoni opened 2 months ago
I believe message_type =
should be String
not String()
serialized message seems to be wrong, the following works w/o any problem.
def main():
msg = String()
msg.data = 'Hello, world!'
msg_serialized = serialize_message(msg)
print(msg_serialized)
msg_deserialized = deserialize_message(msg_serialized, String)
print(msg_deserialized)
the output is,
b'\x00\x01\x00\x00\x0e\x00\x00\x00Hello, world!\x00'
std_msgs.msg.String(data='Hello, world!')
I have tried what you suggest @fujitatomoya and I'm able to successfully decode the string, the issue is that my data come from foxglove_bridge and the encoding seems to be a bit different.
To give a bit more context, I try to create a ws-client to subscribe to a topic with a foxglove_bridge (https://github.com/foxglove/ros-foxglove-bridge), so I have: ROS2 string publisher -> foxglove_bridge-> ws-client The data copy pasted in the question is the string received from the foxglove_bridge.
Here is the complete python script of the ws-client:
import asyncio
import websockets
import json
from std_msgs.msg import String
from rclpy.serialization import deserialize_message
from mcap.reader import make_reader
from mcap_ros2.reader import read_ros2_messages
from mcap_ros2.decoder import DecoderFactory
async def handle_event(websocket, message, subscribed):
# Handle different types of events here
print("Received event:", message)
if subscribed == False:
subscribed = True
subsriber = {
"op": "subscribe",
"subscriptions": [
{"id": 3, "channelId": 3} # replace by the selected channel id the subscribe
]
}
await websocket.send(json.dumps(subsriber))
if type(message) == bytes:
print("Start to deserialize")
message_type = String()
# Decode the message here
#decoded_data = deserialize_message(serialized_message=message, message_type=message_type)
# print(decoded_data)
async def connect_to_server():
uri = "ws://0.0.0.0:9090" # Change this to your server URI
subscribed = False
async with websockets.connect(uri, subprotocols=["foxglove.websocket.v1"]) as websocket:
print("Connected to server.")
try:
while True:
message = await websocket.recv()
await handle_event(websocket, message, subscribed)
subscribed = True
except websockets.ConnectionClosed:
print("Connection to server closed.")
async def main():
await connect_to_server()
if __name__ == "__main__":
asyncio.run(main())
I try to get data from a ros-foxglove-bridge (more detail on the scope here https://github.com/orgs/foxglove/discussions/991). I'm able to receive a ROS2 raw coded message in binary format but I'm not able to decode it properly. I tried to use deserialize_message to deserialize the data but I'm not able to make it work.
Required Info:
Steps to reproduce issue
Here is a standalone code with only the data received from the websocket hardcoded. The original message is a ROS2 std_msgs.msg String at the format:
data: Hello, world! Time(nanoseconds=1713770713401001821, clock_type=ROS_TIME)
Expected behavior
I would like to be able to decode the string message to get a deserialized value (to be able to also decode more advanced message.
Actual behavior
It shows the following error message: return _rclpy.rclpy_deserialize(serialized_message, message_type) rclpy._rclpy_pybind11.RMWError: failed to deserialize ROS message: rmw_serialize: invalid data size, at ./src/rmw_node.cpp:1727
I'm not sure if I'm not able to use the function without error because of validity of my data or just because of the provided arguments.