ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks?

Just use ros::Publisher::publish(..)? As long as you're not running multithreaded or asynchronous spinners, callback queue processing is singlethreaded, so you should not run into issues.

I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.

Calling spinOnce() inside a callback is not a good idea in any case, for whatever reason. It generally points to bad data / control flow design.

Use case: Publishing messages as timing statements in different parts of a long running callback. rosbag record just the topics for the timing statements, look at their timing in rqt_bag

Could you describe your design for this a bit more? If you're publishing msg type X for your timing info, and your long running callback is triggered by publications of type Y, where do you expect there to be an issue with self-triggering?

What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks?

Just use ros::Publisher::publish(..)? As long as you're not running multithreaded or asynchronous spinners, callback queue processing is singlethreaded, so you should not run into issues.

I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.

Calling spinOnce() inside a callback is not a good idea in any case, for whatever reason. It generally points to bad data / control flow design.

Use case: Publishing messages as timing statements in different parts of a long running callback. rosbag record just the topics for the timing statements, look at their timing in rqt_bag

Could you describe your design for this a bit more? If you're publishing msg type X for your timing info, and your long running callback is triggered by publications of type Y, where do you expect there to be an issue with self-triggering?


edit:

It is broken in the sense that spinOnce() isn't enough to result in even remotely reliable timings.

I'd expect this to be the case because the infrastructure was never designed for this use case (the stamp field is there for a reason).

As to your issue:

  • perhaps (this is really a guess) see if using UDPROS improves anything. Since it uses UDP, it should not do any buffering like TCP does
  • use the stamp field and accept that for analysis / visualisation you can't directly use rqt_bag, but would need to process the messages and extract the timestamp
  • use proper profiling tools (like perf, oprofile, gprof, etc)
  • see if you can use rqt_graphprofiler (but really only for messaging analysis)

In general I'd say that if your bottleneck is in messaging, then yes, you could use bags and their visualisation to get an idea of that, and your approach makes sense. If the bottleneck is in the callbacks, then it is an algorithm issue, and you should be profiling that.

What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks?

Just use ros::Publisher::publish(..)? As long as you're not running multithreaded or asynchronous spinners, callback queue processing is singlethreaded, so you should not run into issues.

I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.

Calling spinOnce() inside a callback is not a good idea in any case, for whatever reason. It generally points to bad data / control flow design.

Use case: Publishing messages as timing statements in different parts of a long running callback. rosbag record just the topics for the timing statements, look at their timing in rqt_bag

Could you describe your design for this a bit more? If you're publishing msg type X for your timing info, and your long running callback is triggered by publications of type Y, where do you expect there to be an issue with self-triggering?


edit:

It is broken in the sense that spinOnce() isn't enough to result in even remotely reliable timings.

I'd expect this to be the case because the infrastructure was never designed for this use case (the stamp field is there for a reason).

As to your issue:

  • you could probably get around the "spinOnce() calls my callback while I'm in the callback" by some judicious use of multiple callback queues and associated spinners. You are responsible for spinning custom queues, so that should allow you to call spinOnce() without triggering execution of callback_Y
  • perhaps (this is really a guess) see if using UDPROS improves anything. Since it uses UDP, it should not do any buffering like TCP doesdoes, which might reduce the latency you observe
  • use the stamp field and accept that for analysis / visualisation you can't directly use rqt_bag, but would need to process the messages and extract the timestamp
  • use proper profiling tools (like perf, oprofile, gprof, etc)
  • see if you can use rqt_graphprofiler and rosprofiler (but really only for messaging analysis)analysis). Dan Brooks gave a presentation on this () at

In general I'd say that if your bottleneck is in messaging, then yes, you could use bags and their visualisation to get an idea of that, and your approach makes sense. If the bottleneck is in the callbacks, then it is an algorithm issue, and you should be profiling that.

What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks?

Just use ros::Publisher::publish(..)? As long as you're not running multithreaded or asynchronous spinners, callback queue processing is singlethreaded, so you should not run into issues.

I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.

Calling spinOnce() inside a callback is not a good idea in any case, for whatever reason. It generally points to bad data / control flow design.

Use case: Publishing messages as timing statements in different parts of a long running callback. rosbag record just the topics for the timing statements, look at their timing in rqt_bag

Could you describe your design for this a bit more? If you're publishing msg type X for your timing info, and your long running callback is triggered by publications of type Y, where do you expect there to be an issue with self-triggering?


edit:

It is broken in the sense that spinOnce() isn't enough to result in even remotely reliable timings.

I'd expect this to be the case because the infrastructure was never designed for this use case (the stamp field is there for a reason).

As to your issue:

  • you could probably get around the "spinOnce() calls my callback while I'm in the callback" by some judicious use of multiple callback queues and associated spinners. You are responsible for spinning custom queues, so that should allow you to call spinOnce() without triggering execution of callback_Y
  • perhaps (this is really a guess) see if using UDPROS improves anything. Since it uses UDP, it should not do any buffering like TCP does, which might reduce the latency you observe
  • use the stamp field and accept that for analysis / visualisation you can't directly use rqt_bag, but would need to process the messages and extract the timestamp
  • use proper profiling tools (like perf, oprofile, gprof, etc)
  • see if you can use rqt_graphprofiler and rosprofiler (but really only for messaging analysis). Dan Brooks gave a Random presentation on this () at about this: ROS System Profiling and Visualization.

In general I'd say that if your bottleneck is in messaging, then yes, you could use bags and their visualisation to get an idea of that, and your approach makes sense. If the bottleneck is in the callbacks, then it is an algorithm issue, and you should be profiling that.

What's the cleanest way to publish a message immediately, without triggering any subscriber callbacks?

Just use ros::Publisher::publish(..)? As long as you're not running multithreaded or asynchronous spinners, callback queue processing is singlethreaded, so you should not run into issues.

I would expect calling ros::spinOnce() inside a callback to (potentially) result in stack overflow as the callback calls itself.

Calling spinOnce() inside a callback is not a good idea in any case, for whatever reason. It generally points to bad data / control flow design.

Use case: Publishing messages as timing statements in different parts of a long running callback. rosbag record just the topics for the timing statements, look at their timing in rqt_bag

Could you describe your design for this a bit more? If you're publishing msg type X for your timing info, and your long running callback is triggered by publications of type Y, where do you expect there to be an issue with self-triggering?


edit:

It is broken in the sense that spinOnce() isn't enough to result in even remotely reliable timings.

I'd expect this to be the case because the infrastructure was never designed for this use case (the stamp field is there for a reason).

As to your issue:

  • you could probably get around the "spinOnce() calls my callback while I'm in the callback" by some judicious use of multiple callback queues and associated spinners. You are responsible for spinning custom queues, so that should allow you to call spinOnce() without triggering execution of callback_Y
  • perhaps (this is really a guess) see if using UDPROS improves anything. Since it uses UDP, it should not do any buffering like TCP does, which might reduce the latency you observe
  • use the stamp field and accept that for analysis / visualisation you can't directly use rqt_bag, but would need to process the messages and extract the timestamp
  • use proper profiling tools (like perf, oprofile, gprof, etc)
  • see if you can use rqt_graphprofiler and rosprofiler (but really only for messaging analysis). Random presentation about this: ROS System Profiling and Visualization.

In general I'd say that if your bottleneck is in messaging, then yes, you could use bags and their visualisation to get an idea of that, and your approach makes sense. may make sense (but I'd use other tools for that). If the bottleneck is in the callbacks, then it is an algorithm issue, and you should be profiling that.

those algorithms, without the middleware interfering.