ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
1 | initial version |
Based on the comments from Lorenz, the problem seems to be that the publisher is too fast; that is, it publishes before the subscriber has opened a direct connection to the publisher. Therefore, the goal is to make the publisher "wait" until all subscribers have established a connection. I don't think that the problem stems from closing the publisher too soon.
Here is an idea that I have not tested, but that should work with multiple subscribers. It is not 100% robust, but assuming that no subscribers comes or leaves exactly when the publisher is launched, it should not have problems.
int numSubscribersConnected = 0;
void connectCallback(const ros::SingleSubscriberPublisher& pub)
{
numSubscribersConnected++;
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "MyPublisher");
ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<foo::MyMessage>("/myTopic", 100, connectCallback);
ros::Time maxTime(ros::Time::now()+1000); // Will wait at most 1000 ms
while(pub.getNumSubscribers()!=numSubscribersConnected && ros::Time::now()<maxTime)
{
sleep(10);
}
// Now the publisher is ready
foo::MyMessage msg;
pub.publish(msg);
return 0;
}
2 | Fixed a typo with the sleep duration |
Based on the comments from Lorenz, the problem seems to be that the publisher is too fast; that is, it publishes before the subscriber has opened a direct connection to the publisher. Therefore, the goal is to make the publisher "wait" until all subscribers have established a connection. I don't think that the problem stems from closing the publisher too soon.
Here is an idea that I have not tested, but that should work with multiple subscribers. It is not 100% robust, but assuming that no subscribers comes or leaves exactly when the publisher is launched, it should not have problems.
int numSubscribersConnected = 0;
void connectCallback(const ros::SingleSubscriberPublisher& pub)
{
numSubscribersConnected++;
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "MyPublisher");
ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<foo::MyMessage>("/myTopic", 100, connectCallback);
ros::Rate poll_rate(100);
ros::Time maxTime(ros::Time::now()+1000); // Will wait at most 1000 ms
while(pub.getNumSubscribers()!=numSubscribersConnected && ros::Time::now()<maxTime)
{
sleep(10);
poll_rate.sleep();
}
// Now the publisher is ready
foo::MyMessage msg;
pub.publish(msg);
return 0;
}
3 | Noted that the solution would not work because of getNumSubscribers() |
Based on the comments from Lorenz, the problem seems to be that the publisher is too fast; that is, it publishes before the subscriber has opened a direct connection to the publisher. Therefore, the goal is to make the publisher "wait" until all subscribers have established a connection. I don't think that the problem stems from closing the publisher too soon.
Here is an idea that I have not tested, but that should work with multiple subscribers. It is not 100% robust, but assuming that no subscribers comes or leaves exactly when the publisher is launched, it should not have problems.
EDIT: This method would not work because a functionality that I expected available from ROS does not seem to be there. See comments in the code.
int numSubscribersConnected = 0;
void connectCallback(const ros::SingleSubscriberPublisher& pub)
{
numSubscribersConnected++;
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "MyPublisher");
ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<foo::MyMessage>("/myTopic", 100, connectCallback);
ros::Rate poll_rate(100);
ros::Time maxTime(ros::Time::now()+1000); // Will wait at most 1000 ms
while(pub.getNumSubscribers()!=numSubscribersConnected // This is wrong. It returns only the number of subscribers that have already established their direct connections to this publisher
//int numExistingSubscribers = pub.getNumSubscribers();
// This method does not exist, as far as I know. In the comments below, I suggested having a similar functionality. This method would return the number of total subscribers to this topic over the ROS network
int numExistingSubscribers = ros::getNumSubscribers("/myTopic");
while(numExistingSubscribers!=numSubscribersConnected && ros::Time::now()<maxTime)
{
poll_rate.sleep();
}
// Now the publisher is ready
foo::MyMessage msg;
pub.publish(msg);
return 0;
}