Hi All,
I want to ask if we could support publisher/subscription work without IDL when intra process?
Because producer-consumer is a very popular coding model, and we want to use publisher/subscription to implement it to transport any type of message when intra process, in which situation the publisher could not support remote subscription.
Excuse my ignorance, but what is it exactly that you want to do and why is it currently impossible in ROS2? I think I require some more clarification w.r.t. IDL and why it prevents the producer-consumer model. Can you elaborate more, maybe with a simple example / use-case?
In case this subject is completely over my head, I think @alsora, may be able to help with this. He was involved in making changes to how intra-process currently works in ROS2. It’s more likely he will understand what you are talking about / trying to do
Thanks for quick reply!
Yeah, the current ROS2 support IDL msg type Publisher/Subscription, but it requires a IDL file.
And this way prevents us to use it easily… like:
node1->create_publishercv::Mat()
node2->create_subscriptioncv::Mat()
Indeed, from rclcpp code source, I don’t see what the IDL for when intra-process. We want use publisher/subscription for any type easily without any IDL file…
How would you imagine this to work without an IDL description of the message content? Will you just pass a pointer to shared memory or an address between the publisher and subscriber? You would then still need to tell the subscriber what it is receiving right (size of the data, type, structure)?
I think it is easier to just fill an existing message type with the data of cv::Mat() and on the other side unpack it and store it back into a cv::Mat() object. Or if existing message types don’t fit your data-format you could create a custom message to handle it.
Or am I misunderstanding what you are trying to do?
In intra-process, the publisher will pass the Message pointer to subscriber, no pack or unpack needed.
Only needed is the unique_ptr or shared_ptr of message and its copy method.
The feature you are talking about is often referred to as type masquerading
It’s already in the roadmap, but I don’t think that it will be part of the next release (unless someone steps up and implement it).
More details here
https://index.ros.org/doc/ros2/Tutorials/Intra-Process-Communication/#looking-forward
Thanks for your reply!
" So conceivably you could have the image pipeline with a single cv::Mat
which never gets copied by the middleware. To do this requires some additional intelligence in the intra process manager, but we’ve already got a design and some proof of concepts in the works."
Do you have some design draft that can be shared with us?
I modified the rclcpp code a little, let intra-process publisher/subscription with native type don’t go into rmw layer, now it can transfer pointers, but the problem is the executor/trigger/callbacks are implemented in rmw layer… So I hope to see a better design
There are changes planned to the executor design for the Foxy release, you could voice your request (or an offer to help) to the people involved with that. The interest in a new design was to some extent kick-started by this discussion: SingleThreadedExecutor creates a high CPU overhead in ROS 2(which I was part of).
I don’t know exactly where the follow-up discussion is taking place, but if you feel like you have useful input to the discussion you could try contacting some people (I’m pretty sure wjwwood is involved).
Although, I’m also pretty sure they will see this thread so no immediate action is necessary. Just depends on how pro-active you want to be and how soon you will need this feature.
Thanks, this is very helpful!
Perhaps I am not understanding but can you not just make a string message and pass the pointer as a string through intra process shared memory?
Emmm, maybe the purpose is not passing a pointer, but use the publisher/subscriber to implement the producer-consumer model of any type data.
There are few tangled things being discussed in this thread, I’ll try to reply in line to separate them and describe what is possible and what is planned.
Currently that is neither possible nor planned, but I should emphasize that I specifically mean the without IDL part. More below.
This is also not currently a goal for us (or at least for me and as far as I know my colleagues and our partners). That doesn’t mean “never”, it’s just that I don’t think we plan to have it.
Inherent in our communication system is really three things, not just pub/sub but also discovery and serialization/deserialization. The discovery is just convenience and helps with composition and reusability. The (de)serialization is used not only for network (inter-process) transport but also for recording and playback.
We require a type to be defined by IDL mostly for the serialization part. For discovery we could just have a type “name” which could be made up and just agreed on by both sides. The type doesn’t really influence the pub/sub part, especially at the intra-process level, except to ensure the two communicating end points are using the same type.
For these reasons we need to at least associate a type with an equivalent IDL type. As pointed out by @alsora, this is what we (I) refer to as type masquerading, i.e. you define a relationship between a user type and an IDL type which allows the user type to masquerade as the IDL type in all of our APIs.
We don’t yet have type masquerading in ROS 2, but we did have it in ROS 1. We plan to implement this, but the changes go far beyond changes to the Executor in rclcpp.
However, in both cases, ROS 1 and our ideas on how to do it in ROS 2, you still need a ROS type defined in IDL, in case the user wants to record it to disk or send it over the network.
We don’t have plans to support “local-only, non-recordable” pub/sub. Requiring a user to associate a user type to a ROS type is a lot of work, but in ROS 1 it worked well as we provided existing mappings for commonly used types like cv::Mat
and pcl::PointCloud<PointT>
, and that was enough. This has the added benefit that users may remotely introspect any publisher, even if normally it is local only and never serialized. As well as the ability to record instances of them to disk.
As I said above, something like this could be possible (though cv::Mat
lacks some information that the ROS image message has, e.g. timestamp), but the pcl types are supported, see:
https://wiki.ros.org/pcl/Overview#Subscribing_to_different_point_cloud_message_types
It’s always possible for a remote subscription to come up and that case has to be handled, so there is no case currently where it is only intra-process in ROS.
Unfortunately I don’t think there exists such a document at the moment.