Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

One of your problems has a solution described here: https://stackoverflow.com/a/48544551/1076564 . In short, you're looking for SubscribeOptions.allow_concurrent_callbacks, which effectively allows more threads to process callbacks for a single subscriber. You just have to make sure then to correctly handle shared data access (e.g. accessing class member variables).

Borrowing code from Fruchtzwerg:

ros::SubscribeOptions ops;
ops.template init<std_msgs::String>("chatter", 1000, chatterCallback);
ops.transport_hints = ros::TransportHints();
ops.allow_concurrent_callbacks = true;
ros::Subscriber sub = nh.subscribe(ops);

I haven't tested that, but it should work.

However, I faced the very same problem you have with the high CPU usage when the callback blocks for longer then is the interval between messages. I'd expect queue_size to slowly crawl in and start throwing away messages that did not make it, but instead the Async/Multithreaded spinner just spins all the threads in a busy-wait for some reason. The only case where it doesn't happen is when you start these spinners with a single thread. I looked for what's the difference, and it seems it's either calling callAvailable() in the 1-threaded case, or callOne() in the more-threaded case. So I'd look for the bug somehere around, but I haven't succeeded yet. Maybe https://github.com/ros/ros_comm/issues/1343 is also relevant (however I debug this problem in Indigo which is not affected by the mentioned bug, or at least a fix for it hasn't been backported there; and I do not have a custom build of ros_comm).