Ask Your Question
0

Subscriber callback function isn't invoked

asked 2016-03-02 12:43:36 -0600

kvmanohar22 gravatar image

Two publishers publish array of integers to two different topics (Topic_1 and Topic_2) and a third node subscribes to these two topics.

  ros::Publisher publisher = nh.advertise<std_msgs::Int32MultiArray>("Topic_1",1000);
    std_msgs::Int32MultiArray vec;

      ROS_INFO("Array elements from file [array1.txt] are published to Topic_1:\n");
      ifstream infile("array1.txt");

      while(infile >> temp)
          vec.data.push_back(temp);

      publisher.publish(vec);
      ros::spin();
      return 0;
    }

Here is the code for second publisher

...
...
 ros::Publisher publisher = nh.advertise<std_msgs::Int32MultiArray>("Topic_2",1000);

    std_msgs::Int32MultiArray vec2;
    ROS_INFO("Array elements from file [array2.txt] are published to Topic_2:\n");

  ifstream infile("array2.txt");
  while(infile >> temp)
      vec2.data.push_back(temp);

  publisher.publish(vec2);
  ros::spin();

  return 0;
}

Here is the one for subscriber:

#include "ros/ros.h"
#include<bits/stdc++.h>
#include<std_msgs/Int32MultiArray.h>

void sort();

void callback_1(const std_msgs::Int32MultiArray::ConstPtr& vec1)
{ 
  ROS_INFO("Vector recieved! over Topic_1\n");
}

void callback_2(const std_msgs::Int32MultiArray::ConstPtr& vec2)
{
  ROS_INFO("Vector recieved! over Topic_2\n");
}


int main(int argc, char **argv)
{

  ros::init(argc, argv, "listener");

  ROS_INFO("Reading the vectors from both the topics");

  ros::NodeHandle nh;

  ros::Subscriber sub_1 = nh.subscribe("Topic_1",1000,callback_1);
  ros::Subscriber sub_2 = nh.subscribe("Topic_2",1000,callback_2);

  ros::spin();
  return 0;
}

But ROS_INFO("Vector recieved! over Topic_1\n");statements are not at all executed. I even wrote a launch file to start these three nodes but the above statement is not executed. But when I run rosnode list, all the three nodes are listed and even both the topics are displayed when I run rostopic list What could probably be going wrong?

edit retag flag offensive close merge delete

Comments

Have you tried replacing spin() with a while loop and ros::spinOnce() ? Subscription will not require a while loop, just spinOnce will suffice.

arttp2 gravatar imagearttp2 ( 2016-03-02 13:10:44 -0600 )edit

2 Answers

Sort by » oldest newest most voted
1

answered 2016-03-02 13:33:12 -0600

It looks like you "immediately" publish your messages after advertising the topic. Your publishers are probably not up when sending the messages, thus they are just dropped.

There is no built-in way of reliably waiting on the publishers to be up. However, you can latch the topic if messages are not published repeatedly / with a fixed rate (see 1.2):

ros::Publisher publisher = nh.advertise<std_msgs::Int32MultiArray>("Topic_1",1000, true);
edit flag offensive delete link more

Comments

Thanks a lot!! That worked

kvmanohar22 gravatar imagekvmanohar22 ( 2016-03-02 15:47:02 -0600 )edit
0

answered 2016-03-02 13:35:55 -0600

tbh gravatar image

updated 2016-03-03 10:03:17 -0600

As it is, you only publish the message once for each publisher. Is that by design? It's likely that by the time your subscriber is up and running, the messages have already been published and are unavailable to your subscriber. Here are a few options:

If all you need is a vector one time, then the parameter server would be an excellent choice.

If this is just test code, and you plan in the future to publish in a loop, your subscriber should be fine. Note, however, that a subscriber must be up when messages are published in order to recieve those messages.

You could also use latched publishers if you want to make sure you get the first message.

EDIT: In reference to your first sub-question, I agree. I'd expect the messages to be immediately received by the subscriber if the subscriber existed before the publishers were started. Note that roslaunch makes no guarantee of launch order. It also takes some time to set up the subscriber, so perhaps the publishers had already published the messages by the time the subscriber was alive. In any case, I'm glad latching the publishers solved your problem. If you want to delve deeper, look here and here.

Here is the std_msgs documentation. A link to the Int32MultiArray is on there. You used the data parameter correctly in your publisher examples above. From there you'd just use it as a normal c++ array.

Hope that answers your questions. In the future, I encourage you to ask other questions in new questions so that others can find them in searches.

edit flag offensive delete link more

Comments

I tried running the subscriber node first and then start the both the publishers. But the messages were not recieved by the subscriber, shouldn't the messages be stored in queue and readily available to the subscriber after the publishers are started?

kvmanohar22 gravatar imagekvmanohar22 ( 2016-03-03 06:25:21 -0600 )edit

What are the member functions for 'vec1' in

void callback_1(const std_msgs::Int32MultiArray::ConstPtr& vec1)

to access data of vec1? For string c_str() was used, so are there any similar member functions for std_msgs::Int32MultiArray

kvmanohar22 gravatar imagekvmanohar22 ( 2016-03-03 06:56:20 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-03-02 12:43:36 -0600

Seen: 282 times

Last updated: Mar 03 '16