ros2 / rmw_cyclonedds

ROS 2 RMW layer for Eclipse Cyclone DDS
Apache License 2.0
112 stars 91 forks source link

rmw_cyclonedds API: access native Cyclone DDS entities #457

Closed cfveeden closed 1 year ago

cfveeden commented 1 year ago

I'm cross-posting from rosanswers with the hope of getting more visibility.

My question is:

Based on the discussion on rosdiscourse, I'm expecting cyclonedds to have a similar ros_to_dds API, however, I cannot find any documentation about it. Is there such an API?

In particular, I would like to be able to set the partition DDS QoS for a publisher and subscriber dynamically at runtime. Or do something similar to this using the OWNER QoS at startup and OWNER_STRENGTH QoS dynamically at runtime.

I do not have the resources to make modifications to rmw_cyclonedds as mentioned in this thread and was hoping ros2 offers this sort of functionality through the ros_to_dds interface.

eboasson commented 1 year ago

Based on the discussion on rosdiscourse, I'm expecting cyclonedds to have a similar ros_to_dds API, however, I cannot find any documentation about it. Is there such an API?

Not that I am aware of. To use the Cyclone entities created in the RMW layer from your application code, all you'd need to obtain is the https://github.com/ros2/rmw_cyclonedds/blob/ee3485a5d34cd052c55d43ce24379b68650f3317/rmw_cyclonedds_cpp/src/rmw_node.cpp#L232 for the entity you want to manipulate. It should be trivial to add such a function and then if you link directly with rmw_cyclonedds_cpp you'd be able to use it. You'd lose the portability, and I am not so sure it is worth it. From the discussion you linked, it seems most people are hesitant to do such tricks.

In particular, I would like to be able to set the partition DDS QoS for a publisher and subscriber dynamically at runtime.

Cyclone supports setting it at creation time but not after creation.

For creation time, there is the problem that ROS 2 doesn't do partitions, and so it is tricky to set it. It would be easy if there is a way to "wrap" a reader/writer created in DDS as a ROS 2 subscription/publisher, but I am not aware that is supported.

Changing the partition is possible according to the spec, but there are a number of problems with allowing that that have led to a decision to not support it in Cyclone. It is not clear what it would mean for retransmits and for matching and historical data for transient-local readers/writers; and especially if it changes back-and-forth all the time. So in Cyclone, we've decided not to support it. (Though always with the caveat that if the use case is good enough, we'll reconsider.)

I do think the ROS community could be interested in adding something like partitions to ROS 2, perhaps in a more limited fashion. What I would look into first is mapping the ROS 2 name spaces to DDS partitions, that might be enough to cover some interesting use cases and could be handled entirely inside the RMW layer.

Or do something similar to this using the OWNER QoS at startup and OWNER_STRENGTH QoS dynamically at runtime.

With Cyclone, you can change the ownership strength at run-time, and if that ros_to_dds thing is implemented, that would be easy enough. The tricky bit is again to select "exclusive ownership" at creation time.

cfveeden commented 1 year ago

Thank you @eboasson. The knowledge of which parts of the spec are supported by Cyclone is valuable.

So for now, setting exclusive ownership at creation time and manipulating owner strength dynamically is possible in Cyclone, but it's tricky to implement the exclusive ownership part. This knowledge alone is enough to address my current use-case, however, it might not be worth it as you mentioned.

I think I'll explore approaches that do not expose the RMW layer first and revisit this in future when I have more experience with my system.

FYI, for the proposal to map ROS 2 namespaces to DDS partitions, it seems this was considered in the "Alternative using DDS Partitions" section in the design document, but was discarded.