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

Can't publish or use time in my class constructor

asked 2015-07-30 15:16:30 -0600

updated 2015-07-31 15:40:26 -0600

I am creating a class that subscribes to an Odometry message and in the corresponding callback function updates an OccupancyGrid message which is published to a topic. I've got all this working just fine. However, in the class constructor, where I initialize the OccupancyGrid, I would like to publish that OccupancyGrid even before the callback function ever gets called. This for some reason is not working. I also notice another problem, which I think is related. When I go to set the OccupancyGrid.info.map_load_time to ros::Time::now() in the class constructor the time is always zero. However, when I do the same thing for the OccupancyGrid.header.stamp in the callback function, everything works as expected (as does the publish).

I created a simplified program that exhibits the same problem where I subscribe to a std_msgs/Bool message and publish a std_msgs/Time message. Again, the publish and ros::Time::now() don't work in the constructor but do work in the callback function.

Here's the class declaration:

class PubTest {
 private:
  std_msgs::Time time_;
  void CB(const std_msgs::Bool& msg);
  ros::NodeHandle nh_;
  ros::Publisher pub_;
  ros::Subscriber sub_;

 public:
  PubTest();
  ~PubTest();
};

Here's the Constructor:

PubTest::PubTest() {
  // Set up the publisher and subsciber objects                                 
  pub_ = nh_.advertise<std_msgs::Time>("time",1);
  sub_ = nh_.subscribe("test",10,&PubTest::CB,this);
  // Test to see if this command works or returns zero                          
  ros::Time begin = ros::Time::now();
  ROS_INFO_STREAM("The time in the constructor is " << begin);
  // And test to see if publish works                                           
  time_.data = begin;
  pub_.publish(time_);
};

The callback function:

void PubTest::CB(const std_msgs::Bool& msg){
  // Test to see if this command works or returns zero                          
  ros::Time currTime = ros::Time::now();
  ROS_INFO_STREAM("The time in the callback function is " << currTime);
  // And test to see if publish works                                           
  time_.data = currTime;
  pub_.publish(time_);
}

And finally, main:

int main(int argc, char **argv) {
  ros::init(argc, argv, "pubTest");
  PubTest pubTest;
  ROS_INFO_STREAM("The time in main after the constructor is " << ros::Time::now());
  ros::spin();
  return 0;
}

And the output:

[ INFO] [1438286118.670196332]: The time in the constructor is 0.000000000
[ INFO] [1438286118.670353480]: The time in main after the constructor is 0.000000000
[ INFO] [1438286119.440117003, 4853.700000000]: The time in the callback function is 4853.700000000

The results of running this program is that the publish in the constructor never happens and all the times that are printed to the screen with ROS_INFO_STREAM are zero (including the one that happens in main). However, whenever I publish a std_msgs/Bool to the topic "test", the correct ROS time is printed to the screen with ROS_INFO_STREAM and the publish function works correctly. Any idea what it is that I'm missing?

EDIT 1

I was previously running all of this with stage running in the background. When I shut down roscore and everything along with it and reran my pubTest node by itself the time all worked just fine and corresponded to wall time. However, the ... (more)

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2015-07-30 20:49:47 -0600

tfoote gravatar image

updated 2015-07-31 16:53:45 -0600

A time of zero means that time has not been initialized. Time documentation

It will have needed to check the parameter server for use_sim_time and then fallen back to wall clock time. (Or if you're in a simulator to have recieved a /clock signal.)

The reason it's not publishing is a similar problem that you're calling publish before the publisher has estabilized a connection with the subscribers. It's not uncommon for a message published immediately after a publisher is created to not be received.

Edit:

As mentioned in the docs. A common approach is to loop waiting for non-zero time now values. (The duration sleep implicitly does this.)

edit flag offensive delete link more

Comments

Yes, a small wait was necessary for the publishing and subscribing to begin working. This also made time = 0.0 during simulation since no message on /clock was received.

kleinma gravatar image kleinma  ( 2015-07-31 15:41:58 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-07-30 15:16:30 -0600

Seen: 971 times

Last updated: Jul 31 '15