Open chenxin199305 opened 3 months ago
I've figured this one out from the source code of this ros1-zenoh bridge: the zenoh topic name has some prefixes. I've written the following code in python to convert a ros topic name to the corresponding zenoh topic name, using the rosbags
python package:
def get_zenoh_name_of_ros1_topic(ros1_store, topic: str, msg_type: str) -> str:
# Get md5 and encode msg_type to construct zenoh topic
msg_type_split = msg_type.split('/')
msg_type_encoded = '/'.join([msg_type_split[0],msg_type_split[2]]).encode('utf-8').hex()
md5 = ros1_store.generate_msgdef(msg_type)[1]
zenoh_topic = '/'.join([msg_type_encoded, md5, topic])
return zenoh_topic
with a script example that uses this function:
from rosbags.typesys import Stores, get_typestore
ros1_store = get_typestore(Stores.ROS1_NOETIC)
zenoh_topic = get_zenoh_name_of_ros1_topic(ros1_store, topic="/my/poincloud/topic", msg_type="sensor_msgs/msg/PointCloud2")
My example is for the pointcloud2 type of message, but it also works for other standard ROS message definitions. However, note the difference in naming, it is "sensor_msgs/msg/PointCloud2" and NOT "sensor_msgs/PointCloud2".
You can now subscribe to the middle zenoh message with this generated topic name.
Thanks a lot @edouard-fu for the Python snippet.
I had to add a little fix to remove the leading /
on the topic name because the '/'.join()
adds a second /
which is not supported by Zenoh:
- zenoh_topic = '/'.join([msg_type_encoded, md5, topic])
+ zenoh_topic = '/'.join([msg_type_encoded, md5, topic[1:]])
Using rosbags, I have added the deserialization to your example:
import zenoh, time
from rosbags.typesys import Stores, get_typestore
TOPIC = '/topic'
TYPE = 'std_msgs/msg/String'
def get_zenoh_name_of_ros1_topic(ros1_store, topic: str, msg_type: str) -> str:
# Get md5 and encode msg_type to construct zenoh topic
msg_type_split = msg_type.split('/')
msg_type_encoded = '/'.join([msg_type_split[0],msg_type_split[2]]).encode('utf-8').hex()
md5 = ros1_store.generate_msgdef(msg_type)[1]
zenoh_topic = '/'.join([msg_type_encoded, md5, topic[1:]])
return zenoh_topic
def listener(sample):
msg = ros1_store.deserialize_ros1(sample.payload, TYPE)
print(f'ROS1 msg: {msg.data}')
if __name__ == "__main__":
session = zenoh.open(zenoh.Config())
ros1_store = get_typestore(Stores.ROS1_NOETIC)
zenoh_topic = get_zenoh_name_of_ros1_topic(ros1_store, topic=TOPIC, msg_type=TYPE)
print(f'ROS topic {TOPIC} is converted to Zenoh {zenoh_topic}')
sub = session.declare_subscriber(zenoh_topic, listener)
time.sleep(60)
Just chiming in that this is still a usability problem, first day attempting to use Zenoh and this plugin and have been tripping over this for hours.
The examples: https://github.com/eclipse-zenoh/zenoh-plugin-ros1/blob/main/zenoh-plugin-ros1/examples/ros1_sub.rs really make it look like this "should just work".
Would dearly love a config option like "No Mangle Names" or "Proxy Topics Unmangled" that would allow for this to work directly.
Describe the bug
When try the example:
I can not find a way create a zenoh subscriber to listen to the middle zenoh message (using "topic" key). Is there a way to do it? or can you give an example?
To reproduce
as mentioned above.
System info
Ubuntu 20.04