C++ subscriber not working for first messages [closed]

asked 2019-10-01 00:35:28 -0600

teshansj gravatar image

updated 2019-10-01 01:49:45 -0600

Just out of curiosity, I modified the simple c++ publisher and simple python publisher. I got rid of the while loop and did the following.

c++

loop_rate.sleep();

msg.data = "hello world 1";
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();

msg.data = "hello world 2";
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();

msg.data = "hello world 3";
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();

python

rate.sleep()

hello_str = "1-hello world py"
pub.publish(hello_str)
rate.sleep()

hello_str = "2-hello world py"
pub.publish(hello_str)
rate.sleep()

hello_str = "3-hello world py"
pub.publish(hello_str)
rate.sleep()

Now when I run both publishers one after the other, rostopic echo gives me the following, which is expected

data: "1-hello world py"
---
data: "2-hello world py"
---
data: "3-hello world py"
---
data: "hello world 1"
---
data: "hello world 2"
---
data: "hello world 3"
---

The problem is, c++ subscriber callback is not triggered for the first messages. To be exact, it gets triggered after only the 3rd message for c++ publisher and after the 2nd message for python publisher. After that it works fine. This is the c++ subscriber output I get

[ INFO] [1569905819.772859593]: I heard: [2-hello world py]
[ INFO] [1569905819.874401168]: I heard: [3-hello world py]
[ INFO] [1569905825.212111970]: I heard: [hello world 3]

Python subscriber works fine

[INFO] [1569905819.678143]: /listener_17329_1569905813773I heard 1-hello world py
[INFO] [1569905819.772875]: /listener_17329_1569905813773I heard 2-hello world py
[INFO] [1569905819.875100]: /listener_17329_1569905813773I heard 3-hello world py
[INFO] [1569905825.012191]: /listener_17329_1569905813773I heard hello world 1
[INFO] [1569905825.112169]: /listener_17329_1569905813773I heard hello world 2
[INFO] [1569905825.212244]: /listener_17329_1569905813773I heard hello world 3

Can someone please explain what's happening here? I don't get it.


c++ publisher - talker.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

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::Rate loop_rate(10);
  std_msgs::String msg;
  std::stringstream ss;
  loop_rate.sleep();

  msg.data = "hello world 1";
  ROS_INFO("%s", msg.data.c_str());
  chatter_pub.publish(msg);
  ros::spinOnce();
  loop_rate.sleep();

  msg.data = "hello world 2";
  ROS_INFO("%s", msg.data.c_str());
  chatter_pub.publish(msg);
  ros::spinOnce();
  loop_rate.sleep();

  msg.data = "hello world 3";
  ROS_INFO("%s", msg.data.c_str());
  chatter_pub.publish(msg);
  ros::spinOnce();
  loop_rate.sleep();

  return 0;
}

python publisher - talker.py

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    rate.sleep()

    hello_str = "1-hello world py"
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()

    hello_str = "2-hello world py"
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()

    hello_str = "3-hello world py"
    rospy.loginfo(hello_str)
    pub.publish(hello_str)
    rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

Subscribers are identical to the ones provided in the example pages (c++, python)

edit retag flag offensive reopen merge delete

Closed for the following reason duplicate question by gvdhoorn
close date 2019-10-01 03:47:53.690422

Comments

2

The relevant part of the code is missing (the definition of the subscriber as well as what comes after it). But after you register a subscriber, it might take a little while until it is fully set-up and connected to all topics. So you could simply add a sleep for a second or so after the instantiation of the subscriber and check if this already solves you issue.

mgruhler gravatar imagemgruhler ( 2019-10-01 00:44:14 -0600 )edit

As I have mentioned at the beginning, I modified the code in the examples c++ and python. Didn't include it in the question since it would make the question too long to read. I'll append it at the bottom of the question

teshansj gravatar imageteshansj ( 2019-10-01 01:45:07 -0600 )edit

@mgruhler Yes adding a delay solves the problem. So it it happening because init functions exit before they actually finish initializing things?

teshansj gravatar imageteshansj ( 2019-10-01 01:55:15 -0600 )edit

Are you running all your nodes from a single launch file ? Try launching only the listeners nodes first and then after one or two secs the talkers nodes. As @mgruhler said, it's not related to init functions but to the time to connect to the topics.

Delb gravatar imageDelb ( 2019-10-01 02:06:02 -0600 )edit

I am launching them separately. And of course I am running the listeners first. To solve the problem, delay need to be added in the publisher after the init

teshansj gravatar imageteshansj ( 2019-10-01 02:46:13 -0600 )edit
2

Please see #q287548 and #q313491, of which your question appears to be a duplicate @teshansj.

You probably already did, but just to make sure: please try to search for previous Q&As before posting a new one. Try to use Google, as it's much better than the built-in search. Using something like first message lost site:answers.ros.org got me #q287548 and #q313491 as the two top results.

delay need to be added

don't add delays (time-based). A state-based approach will always be more robust.

Finally: if message reception (and acknowledgement) are really important, don't use publish-subscribe (in ROS 1). It's a fire-and-forget communication pattern, with literally no guarantees about anything whatsoever (see also #q203129). Use services or actions.

gvdhoorn gravatar imagegvdhoorn ( 2019-10-01 03:16:58 -0600 )edit
1

I've actually closed this as a duplicate.

If you don't agree @teshansj, please comment here, clarify and we could re-open if that would be justified.

gvdhoorn gravatar imagegvdhoorn ( 2019-10-01 03:48:33 -0600 )edit