Robotics StackExchange | Archived questions

rclcpp publish Image message field out of an shared_ptr message

I'm converting some ros1 code that stored Images inside other messages (sometimes service requests or responses), did work internally then would publish the image out on a regular Image topic.

Now I have changed the aggregate message to a std::sharedptr, but I think the Image messages within it are not themselves separate sharedptrs. If I publish a sub-message the node crashes immediately(no helpful exception messages-- is ros2 run hiding those?) (update whoops forgot to createpublisher there, that's the reason for the immediate crash) . The outer message sharedptr has no idea that some data within it needs to live on as a published message so would free it all when it can.

If I call pub->publish(somemsg->image) is a copy of the image taking place? Is there a way to make this work without copying?

Going the other direction has a similar question and answer- how to store a received Image shared_ptr into another message.

Asked by lucasw on 2018-10-31 13:33:21 UTC

Comments

Did you try the aliasing constructor for a shared pointer?

template <class Y>
shared_ptr (const shared_ptr<Y>& r, T* p) noexcept;

Asked by allenh1 on 2018-10-31 14:45:05 UTC

I'll look into that. I can make a new Image shared_ptr using the aggregate message shared_ptr in the constructor, and it does the right thing- doesn't free memory until both the message and the Image are finished with it?

Asked by lucasw on 2018-10-31 15:11:51 UTC

the idea is that it tells the parent shared pointer that one of its members is a dependent, so that it increments the ref count. So if the parent gets scoped out, but there is still a reference to a child object, it doesn't dangle and preserves the parent until the child is also scoped out.

Asked by allenh1 on 2018-11-01 07:45:21 UTC

Answers

If I call pub_->publish(some_msg->image) is a copy of the image taking place?

Yes.

Is there a way to make this work without copying?

The only way to prevent a copy when publishing is to use a unique_ptr.

Even if you were to share the ownership of the message with ROS, ROS could not ensure you didn't change it while it was in use.

For us, publish may always be asynchronous, so you can't depend on the idea that ROS is "done" with the message when publish returns. That's why it either needs to take ownership (unique_ptr) or make a copy.

Going the other direction has a similar question and answer- how to store a received Image shared_ptr into another message.

There's no way to do this that I'm aware of. The sub message is part of the larger message.

Asked by William on 2018-10-31 15:40:26 UTC

Comments

Now that I search for unique_ptr I see https://github.com/ros2/demos/blob/bouncy/intra_process_demo/include/image_pipeline/camera_node.hpp is using it for Image, and there is some text in the CMakeLists.txt about minimizing copies.

Asked by lucasw on 2018-11-01 09:09:50 UTC

There's also this tutorial: https://index.ros.org/doc/ros2/Intra-Process-Communication/ and this issue is also related: https://github.com/ros2/rclcpp/pull/504

Asked by William on 2018-11-01 12:32:41 UTC