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

Subscriber node not working for topic at 50Hz

asked 2012-07-09 11:29:54 -0500

Nishant gravatar image

updated 2014-01-28 17:12:58 -0500

ngrennan gravatar image

Hello all,

So I have a topic published by a publisher node, at 50 Hz. The topic publishes a message 'loadMsg' which consists of the following data types

1) string unit

2) float64 load

Now I have my subscriber node, which is the following piece of code

#include <ros/ros.h>
#include <robot_comm/robot_comm.h>
#include "std_msgs/String.h"
#include "cell_node/loadMsg.h"


void loadSensor(const cell_node::loadMsg &d)
{
  ROS_INFO("Load Unit = [%s] , Value = [%lf] ", d.unit.c_str(),d.load);
}



int main(int argc, char** argv)
{
  ros::init(argc, argv, "demo");
  //FILE * pFile;

  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("loadSensor", 1000, loadSensor);
  //ros::Rate loop_rate(50);
int i = 0;
while(i<10)
{
  usleep(20000);
  ros::spinOnce();
  i++;
}
  //pFile = fopen ( "myfile.txt" , "w+" );
  //fwrite (buffer , 1 , sizeof(buffer) , pFile );
  //fclose (pFile);

return 0;
}

So what this should do is basically sample from the stream of 'loadMsg' data being published at 50Hz. And the sampling should happen again at 50Hz (1/20000usec).

However, I am not getting any output! rosmake/make work perfectly, without any errors. When I run the node however, I get nothing.

What may be going wrong? In an earlier post, I asked a similar question. But it worked then, it refuses to work now. Here is the link to that:

http://answers.ros.org/question/38131/rosspinonce-not-functioning-properly/

Also, if I replace ros::spinOnce() by ros::spin() and remove the while loop, then it does sample from the topic, but seemingly at a lesser frequency.

All help is greatly appreciated!

edit retag flag offensive close merge delete

Comments

Hey ipso, thanks for the hint to topic_tools. However, I don't get one thing. When I did sleep(N) in my while loop here

http://answers.ros.org/question/38131/rosspinonce-not-functioning-properly/

why did polling work here?

Nishant gravatar image Nishant  ( 2012-07-09 14:13:43 -0500 )edit

Also, what do you think about the ros::Timer library? Can I use that instead of this method where I poll every time I want data from the topic stream?

Nishant gravatar image Nishant  ( 2012-07-09 14:15:22 -0500 )edit

@Nishant: read my answer: you're not polling from the topic 'stream' (actually: events). You either receive the publications or you don't. AFAIK there is currently no support for polled topics in ROS. You could use ros::Timer in your publisher yes, your subscriber does not need it.

ipso gravatar image ipso  ( 2012-07-09 20:47:56 -0500 )edit

@Nishant: the only thing you change by running your own while loop (as in the answer you linked) is the rate at which ROS looks at the queue of incoming events. @PerkinsJames also describes this in the accepted answer. As you publisher is @10Hz, so is your subscriber's callback.

ipso gravatar image ipso  ( 2012-07-09 20:51:01 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2012-07-09 11:49:45 -0500

PerkinsJames gravatar image

I'm not sure of your issue, but your WHILE loop will only last for approximately 1/10th of a second, meaning there must be a message waiting for you from your publisher within that 1/10th of a second or before.

I am not sure if output from a publisher will even buffer if nothing on your system is listening to it (since ROS core somehow makes direct connections between ROS nodes once they subscribe).

Try this. Change while(i<10) to while(ros::ok()) and see if you then ever get those messages through. If you do, it probably has something to do with your timing of when the publisher sends and the the subscriber checks for it.

Also, if you are starting your publisher after the receiver, it surely wont get anything (although it seems you're not doing this).

edit flag offensive delete link more

Comments

"Also, if you are starting your publisher after the receiver, it surely wont get anything": why do you say this? Cause AFAIK there is no temporal binding between publishers and subscribers?

ipso gravatar image ipso  ( 2012-07-09 13:12:00 -0500 )edit
1

That sentence was specific to code @Nishant posted. He/she just checks for messages 10 times very quickly, which would finish and then exit more quickly than he/she could type rosrun on the publisher.

PerkinsJames gravatar image PerkinsJames  ( 2012-07-09 17:39:53 -0500 )edit

Ah ok, I understand. In that case you're right of course. I was referring to the general case.

ipso gravatar image ipso  ( 2012-07-09 20:39:56 -0500 )edit

Also, it takes a while until the connection between a publisher and a subscriber is established and 1/10th of a second might not be enough for that. Although a publisher might be up and running, no message might be received in this short time window.

Lorenz gravatar image Lorenz  ( 2012-07-09 22:55:39 -0500 )edit

Hey PerkinJames, so I tried doing what you told me to do (substitute i<10 with ros::ok()) and it worked! That does mean that it might happen that maybe my subscriber is starting to look for readings in between two readings that are actually being published by the publisher.

Nishant gravatar image Nishant  ( 2012-07-10 02:24:03 -0500 )edit

@Nishant, look at my previous comment. That's what probably is happening. After subscribing to a topic, you need to give ROS some time to actually establish the connection. 0.1 seconds might not be enough for that. More info: http://www.ros.org/wiki/ROS/Technical%20Overview

Lorenz gravatar image Lorenz  ( 2012-07-10 02:32:10 -0500 )edit

@Nishant, and to expand on @Lorenz answer, spinOnce may not wait for the connection to be fully ready to use. Hence, you could still call spinOnce when the connection is not fully set, burning through that while() loop

PerkinsJames gravatar image PerkinsJames  ( 2012-07-10 04:14:37 -0500 )edit
1

answered 2012-07-09 11:59:28 -0500

ipso gravatar image

updated 2012-07-09 12:19:24 -0500

Just something I notice in other questions on this site: the fact that you insert a sleep(N) in your while loop does not mean that you are sampling anything at any rate.

ROS is (mostly) an asynchronous event based system and messages from publishers will result in callbacks being called if there are subscriptions for them (if there are no subscriptions, no callbacks will be called). Running your own while loop (with an embedded sleep(N) in it) will only determine the pace at which ROS looks at the pile of events it has currently received. Then, it will call the registered callback(s) for each of these events.

This is very different from a synchronous polling based sampling system, which looks N times (per second/hour/whatever) at the value of a particular signal. ros::spinOnce() does not look at the 'value' of the 'loadSensor' topic, it just signals ROS that it should process any outstanding events now.


RE: your problem:

So what this should do is basically sample from the stream of 'loadMsg' data being published at 50Hz. And the sampling should happen again at 50Hz (1/20000usec).

No it should not, and the above hopefully made it clear why it shouldn't.


To slow down the rate at which events are delivered to a particular node, you could make use of the topic_tools/throttle node. This does not turn ROS into a sampling based system, but does allow you to set a limit on the maximum number of events delivered to your node.

edit flag offensive delete link more

Comments

Edit: I'm trying to understand your answer. I agree that he is only telling ROS to process events, not sample data (if there's nothing there, it will receive nothing). To answer the question, does your post just state that the ROS signal rate does not guarantee anything about the publisher?

PerkinsJames gravatar image PerkinsJames  ( 2012-07-09 17:47:48 -0500 )edit

@PerkinsJames: The post was more of a general "don't think of ROS as a synchronous sampling system", as this seems to cause a great deal of confusion (ie: thinking ros::spinOnce() is like sample(), etc). Re the question: what do you mean with 'the ROS signal rate'?

ipso gravatar image ipso  ( 2012-07-09 20:44:03 -0500 )edit

@ipso, sorry, i think i used the wrong terms. I meant the rate at which the subscriber checks for outstanding messages (the rate spinOnce is called))

PerkinsJames gravatar image PerkinsJames  ( 2012-07-10 04:17:05 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2012-07-09 11:29:54 -0500

Seen: 2,847 times

Last updated: Jul 09 '12