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

Subscribe vs. waitForMessage for a 30hz topic

asked 2018-10-16 10:29:32 -0500

aPonza gravatar image

updated 2018-10-17 03:40:09 -0500

I would like to read a topic (which is published at ~30hz) at specific moments in the execution of my code. This Q&A shows I have 2 ways to proceed:

  • waitForMessage (from here) which is a "fairly heavy operation" and requires "frequent publishing" (how heavy? how frequent?);
  • subscribing and updating a class member via the subscriber's callback, and using said member directly (from the second part of this).

I went the second way but realized I don't understand how to pass-by-reference (not good enough, at least, and I have found this which is related, but isn't working), so I went with:

void MyClass::frankaStateCallback(const franka_msgs::FrankaState& msg)
  current_franka_state_ = msg;

where current_franka_state_ is of type franka_msgs::FrankaState (i.e. here) which is not the simplest/lightest of messages.

I'm therefore wondering if I should use the other way or if someone could help me with understanding how to properly use a pointer in this case.

EDIT: as per lucascoelho's request

sub_franka_states_ = nh.subscribe("franka_state_controller/franka_states", 1, &MyClass::frankaStateCallback, this);

This is in the body of the constructor (wrote it following this page), but I don't understand how the problem would lie here.

edit retag flag offensive close merge delete


Maybe you are not initializing the subscriber method in a proper way. Please have a look at this page, it shows how to use a callback from an object

lucascoelho gravatar image lucascoelho  ( 2018-10-16 11:15:27 -0500 )edit

If you could edit your question and add the lines that you are setting up the subscriber it could also be helpful for identifying your problem

lucascoelho gravatar image lucascoelho  ( 2018-10-16 11:16:56 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2018-10-16 11:54:51 -0500

Personally, I think your solution is fine. Option 1 is heavy because you're creating and destroying the connections each time its called and delayed from waiting for the next message to arrive. This second way will incur a copy, another way of doing this might be to pass the callback a constptr of the msg, for instance franka_msgs::FrankaStateConstPtr. This will stop 2 copies so you'll only have 1, if my understanding of it is correct.

Essentially what you're doing has 1 copy to get into the callback, then another to your variable since storing it out of the scope of the function. The constptr is a boost shared pointer so you don't incur the second copy.

Even running at 30 hz just copying over shouldn't be too horrible for your application unless you're trying to run on something super weak (raspberry pi, etc). If you're on a desktop, this is fine.

There's no good support for "on demand" messages from a topic at the moment. I'm sure you could make one with a message filter or wrapping up the subscriber class yourself, but nothing out of the box that I am aware of.

edit flag offensive delete link more


Thanks! So you're saying the current way is lighter than waitForMessage, right? Should I be wary of storing directly a pointer as the class member? It seemingly works and would be even lighter on resources. I will soon communicate with a RasPi so this will help, if not now, then later.

aPonza gravatar image aPonza  ( 2018-10-17 04:42:25 -0500 )edit

Yes, it is better from a copy / time perspective. It's just a dynamically allocated pointer with some tools on top of it, so no, you should be fine to store it.

stevemacenski gravatar image stevemacenski  ( 2018-10-17 12:41:00 -0500 )edit

Question Tools



Asked: 2018-10-16 10:29:32 -0500

Seen: 2,036 times

Last updated: Oct 17 '18