Ask Your Question
0

Calling publisher at a specific rate

asked 2019-11-25 10:31:05 -0600

prj1508 gravatar image

updated 2019-11-26 02:32:46 -0600

Delb gravatar image

Hi,

I have a node that subscribes to a topic, does some computation and publishes the message on a different topic. The publish is implemented within subscriber callback function.

While the subscribed topic arrives at a different rate (and hence the callback), I would like to publish at a specific rate (100Hz). My implementation is in C++ and I am running Kinetic on Ubuntu 16.04. Please let me know the best way to handle this

thank you


Thank you I have couple of follow-up questions

  1. I am publishing within the subscriber callback (when I receive a topic, I call a callback, do some computation and publishing within the callback itself). How do I not modify the subscriber loop rate, but only change the publisher rate? Adding ros::Rate in main will affect both subscriber and publisher?

  2. On using timer, what should be the timeCallback? If I use the subscriber callback for this, this will not subscribe to a topic at a rate it is arriving which is different than my publisher's required rate

edit retag flag offensive close merge delete

Comments

There are several ways you can do that: Enclose the subscriber in the spin loop:

ros::Rate loop_rate(100);
while (ros::ok())
{
 //Publish here your values
 ros::spinOnce();
 loop_rate.sleep();
}

or set a Timer to publish every 100secs:

ros::Timer timer = nh.createTimer(ros::Duration(1/100), timerCallback);
Weasfas gravatar imageWeasfas ( 2019-11-25 11:16:44 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2019-11-26 02:51:09 -0600

Delb gravatar image

@Weasfas 's answer is correct for setting a particular rate of publishing and subscribing using sleep(). Accroding to your other questions you might need to use a timer because :

  1. You should not do too much things within a subscriber, imagine you receive messages at a rate of 100Hz but you take 1 sec to execute the callback, you will end up loosing data or process old data that has been stored in the callback queue. You can use a global variable to store the message data and in another function you can use the global variable and publish what's needed. About the Rate, yes it will affect both subscribers and publisher (if the publisher is within the callback). Spinning at a define rate means that your callbacks are triggered at this rate (but it will be executed as many times as messages have been stored in the queue while waiting)
  2. You should use the timer to bind it with the publisher function and define the rate at 100 for calling this function that will use the global variable that gets the data from the callback. So you hsould have one callback function to store the messages and another function that is called by the timer that deals with the data and then publish it.
edit flag offensive delete link more
1

answered 2019-11-26 03:07:18 -0600

pavel92 gravatar image

updated 2019-11-26 03:14:30 -0600

As suggested by Weasfas in the comment above, you can use a ros::Timer. The following snippet should do the work:

ros::Publisher my_pub = nh.advertise<Message>("my_topic", queue);
ros::Timer timer = nh.createTimer(ros::Duration(1/100), timerCallback);
Message modified_message;

...

// timer callback. Pub lishes modified message on a specified frequency
void timerCallback(const ros::TimerEvent &) {
  my_pub.publish(modified_message);
}

...

void subCallback(Message message_in){
// do some processing of the message_in and update modified_message
...
//
}

You can also check this question regarding using throttle to republish data to another topic, either at a maximum bandwidth or maximum message rate.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-11-25 10:31:05 -0600

Seen: 62 times

Last updated: Nov 26 '19