Ask Your Question

Revision history [back]

Can't publish or use time in my class constructor

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("First publish at " << 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 current time 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("Time in main after constructor is " << ros::Time::now());
  ros::spin();
  return 0;
}

And the output:

[ INFO] [1438286118.670196332]: First publish at 0.000000000
[ INFO] [1438286118.670353480]: Time in main after constructor is 0.000000000
[ INFO] [1438286119.440117003, 4853.700000000]: The current time 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?

Can't publish or use time in my class constructor

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("First publish at 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 current 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("Time in main after constructor is " << ros::Time::now());
  ros::spin();
  return 0;
}

And the output:

[ INFO] [1438286118.670196332]: First publish at The time in the constructor is 0.000000000
[ INFO] [1438286118.670353480]: Time in main after constructor is 0.000000000
[ INFO] [1438286119.440117003, 4853.700000000]: The current 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?

Can't publish or use time in my class constructor

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("Time 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]: Time 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?

Can't publish or use time in my class constructor

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 initial publish inside the constructor still did not work.

Upon reading the Clock documentation, I noticed the following:

If the /use_sim_time parameter is set, the ROS Time API will return time=0 until it has received a value from the /clock topic.

If publishing and subscribing aren't working inside the class constructor, this would explain the return of 0 time since no value has been received from the /clock topic. So from this, I think the problem boils down to publishing and subscribing not working. It has nothing to do with time.

EDIT 2

And on further inspection, adding a small ros::Duration(0.1).sleep(); before the publish command solves everything. I'm wondering now if there is a more elegant way to wait until publishing and subscribing is working. A try, catch or something?