publish and subscribe in the same node but fails, subscribe does't work.
Hello guys, I'm trying to change the demo in the tutorial(publisher and subscriber) to two nodes which can subscribe and publish by themselves.
Talker will start first and advertise the topic "chatter" and after publishing it will subscribe to "chatter1".
After the talker start, listener will subscribe to "chatter" and advertise the topic "chatter1" , then publish messages to chatter1.
void chatterCallback1(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Subscriber sub = n.subscribe("chatter1", 1000, chatterCallback1);
ros::Rate loop_rate(10);
int count = 0;
int np=sub.getNumPublishers();; // number of publishers
while (ros::ok())
{
num = chatter_pub.getNumSubscribers();
ROS_INFO("%d",num);
if(num>0)
{
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
++count;
}
loop_rate.sleep();
if(np==0)
{
sub = n.subscribe("chatter1", 1000, chatterCallback1);
// ros::Duration(0.4).sleep();
}
np = sub.getNumPublishers();
ROS_INFO("pub num is %d",np);
ros::spinOnce();
}
return 0;
}
Because the listener runs after the talker, the topic "chatter1" is not advertised yet, so I re-declare the subscriber in the loop.
However it still can't subscribe to chatter1.
Here's the listener:
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter1", 1000);
int count1=0;
int num1=0;
while(ros::ok())
{
num1=chatter_pub.getNumSubscribers();
if(num1>0)
{
ROS_INFO("number of subscribers %d chatter1",num1);
std_msgs::String msg1;
std::stringstream ss;
ss << "hello world " <<count1;
msg1.data = ss.str();
chatter_pub.publish(msg1);
++count1;
}
ros::spinOnce();
}
}
I runs talker first and then the listener. The listener can get the message from the talker but the talker can't heard from the listener.
I checked the topic by running
rostopic list
and
rostopic echo /chatter1
I find topic chatter1 exists and also I can get the message from echo.
Are there anyone who can explain why the subscriber in the talker.cpp doesn't work?
Thanks a lot.
I don't see a reason to recreate a subscriber in a loop. In fact, there's some overhead in creating a subscriber so creating one in a loop (especially without any
sleep()
s) is probably going to be problematic. Try creating the subscriber only once, outside of the loop, and see what happens.@jayess Thanks, however, when I create the subscriber outside the loop, it seems that the callback function never works.
That means that it's not receiving messages on the topic
@jayess I just create another node talker2 to continually publish the message on the topic chatter1. I tried in different order. If I start the node talker2 at first, the talker will receive messages. However when I start talker first, although talker2 continually publish message to the topic. There's still no message received by talker.