Rosanswers logo

Hi All,

I have a working ROS program that contains two nodes:

  1. usb_cam_node (/opt/ros/electric/stacks/bosch_drivers/usb_cam/src/usb_cam_node) , and

  2. A node named B that processes videos with cv_bridge.

The basic logic of this program is simple:

  1. usb_cam_node gets a video frame from the USB camera, and then publishes a message (of type sensor_msgs::ImageConstPtr& msg) onto a topic to which B subscribes;

  2. B has a callback function that processes the frame upon receiving a message. This callback function looks like this:

callbackB(const sensor_msgs::ImageConstPtr& msg){//Do image processing}

So far usb_cam_node and B are working fine on Ubuntu 10.10.

Now I plan to move the image processing part within callbackB(const sensor_msgs::ImageConstPtr& msg) to a real-time task spawned by Xenomai APIs within B. B and this real-time task, say, R, are two different processes, although R is spawned within B. In this new version, callbackB(const sensor_msgs::ImageConstPtr& msg) now only notifies R the receiving of msg and sends &msg to R. Once R have &msg, it is supposed to do the exactly same thing as the old version of callBackB() does. In my experiment, R can read some basic frame (image) info such as msg->height, which means R should get the correct (?) reference to the image via msg; However, the whole program crashes when cv_bridge::toCvCopy(msg, enc::BGR8); is called.

I am confused here: It seems R gets the correct reference to msg (i.e., &msg), as msg->height gets the correct value. Then why the whole program crashes when cv_bridge::toCvCopy(msg, enc::BGR8); is called? In GDB, I did notice something related to segment fault when this call is executed. Is this related to the fact that msg is a "smart pointer" instead of a normal C++ pointer? Did I wrongly assume that B and R have the same address space? (But then why R can read msg->height correctly?)

With Man Thanks,


Originally posted by TomZ on ROS Answers with karma: 11 on 2011-10-23

Post score: 1

Original comments

Comment by ipso on 2012-07-10:
RT_TASKS spawned by rt_task_create(..) or similar can be considered threads, all within the same process. This would make R not a "different process" (Just realized this is an old question). Also: cv_bridge::toCvCopy() in a real-time task?


1 Answer 1


Rosanswers logo

There are a couple of different things going on here.

First, the function signature of your node B is indeed a smart pointer; note, however, that ROS messages have value semantics, meaning that the image is copied (over the network); this means that your node B has a copy of the image in its address space.

By specifying B's callback to take an ImageConstPtr, you've specified that the ROS machinery should (a) get the message over the wire (b) save it as a smart pointer, and (c) pass a copy of that smart pointer to your callback. (Recall that smart pointers do reference counting.)

I can't speak to how Xenomai works; in general, a "process" is something with its own address space, not something that shares addresses; Xenomai may use that term a bit differently, or get around it using memory-mapped files or some other trick. I'll assume that B and R do, in fact, share an address space.

Are you, in fact, passing &msg to R? If so, that's likely your problem. Taking &msg generates a raw pointer to a smart pointer; then, when B's callback finishes, it destroys msg, and the ROS worker threads destroy their copy (because the callback is done), and now &msg points to a destroyed value, and you risk a segfault.

The easy fix is to have your callback take an ImagePtr, not an ImageConstPtr, and then to pass the smart pointer to R, not a raw pointer; that way, everybody gets a reference, and when B's callback and ROS' copies are destroyed, R still has a valid reference, with count 1.

Originally posted by Mac with karma: 4119 on 2012-07-10

This answer was ACCEPTED on the original site

Post score: 1


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.