ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

publishers two message on the same topic not working for subscriber

asked 2013-03-19 23:16:02 -0500

this post is marked as community wiki

This post is a wiki. Anyone with karma >75 is welcome to improve it.

Hi everyone; I am sending two deferent data message publishers on the same topic, and I see both data publisher in output when I use echo. I use two node and I make the subscriber from this publisher I see just the last message publish. Always loses the first message and stay the last. M y code is:

  output_modem_publisher_ = nh_.advertise<std_msgs::String>(modem_topic_, 100);
  modemin_subscriber_ = nh_.subscribe(modem_in_, 100, &Depth::modeminCallback, this);

void Depth::callPublisher()
{
    std::string out_modem2;
    std::stringstream monsun2;
    monsun2 << 2 << "@" << "d";
    out_modem2 = monsun2.str();
    std_msgs::String m2;
    m2.data = out_modem2;
    output_modem_publisher_.publish(m2);    


    std::string out_modem3;
    std::stringstream monsun3;
    monsun3 << 3 << "@" << "d" ;
    out_modem3 = monsun3.str();
    std_msgs::String m3;
    m3.data = out_modem3;
    output_modem_publisher_.publish(m3);    
}
 ...
 ...

  ros::Rate loop_rate(15);
  int count = 0;
  while (ros::ok())
  {
    depth.callPublisher();
    ros::spinOnce();
    loop_rate.sleep();
    ++count;
  }

The echo results are for the publisher:

rostopic echo depth/modem_topic 

data: 2@d
---
data: 3@d
---
data: 2@d
---
data: 3@d
---

... The echo results are for the subscriber :

rostopic echo depth2/modem_in:


    data: 3@d
    ---
    data: 3@d
    ---
    data: 3@d
    ---
    ...

when I use usleep(ms) for 10ms I see both data by subscriber. But I don't like to use usleep() due to make low performance for my program.

the code of subscriber is:

void DepthMonsun::modeminCallback(const std_msgs::StringPtr& modemin_msg)
{
//  ROS_INFO(" modeminCallback ");

  std::string in_modem;
  in_modem = modemin_msg->data;
  std::vector<std::string> v;
  split(in_modem, v, '@');
    //decoder the data that received from modem/out of MONSUN

    if (in_modem[0] == '2')
    {
      std::vector<std::string> v;
      split(in_modem, v, '@');
      x = 0;
      x = atof(v.at(2).c_str());
....
    }
else if (in_modem[0] == '3')
{
      std::vector<std::string> v;
      split(in_modem, v, '@');
      y = 0;
      y = atof(v.at(2).c_str());
...
}

Any idea for solving this problem...,

thanks

edit retag flag offensive close merge delete

Comments

1

Why do you want to have two publishers, publishing at the same time, for different data ?

Stephane.M gravatar image Stephane.M  ( 2013-03-19 23:48:10 -0500 )edit
1

Have you checked via rxgraph? So if the subscriber is the one not working, could you post its code?

felix k gravatar image felix k  ( 2013-03-19 23:56:46 -0500 )edit

I had a mistake in explaining the problem. I have one publisher but for two messages on the same publisher. excuse me.

underwater gravatar image underwater  ( 2013-03-20 00:43:05 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2013-03-20 02:17:08 -0500

Claudio gravatar image

The code for the subscriber is not meaningful: you're just posting the callback, while the problem probably resides in the main loop.

For example while you clearly use ros.rate in the publisher, why would you use usleep in the subscriber? Use ros.rate there as well. And be sure to run the subscriber faster than the publisher, at least twice that.

That said it seems you're running both the publisher and the subscriber from the same process. That is bound to give you problems unless you interleave perfectly.

What this means is that whenever you ask ROS to do work for you (send, receive, set parameters, whatever), ROS will take an arbitrary amount of time to do the work, possibly requiring multiple calls to ros.spinOnce() to obtain the required results.

So in your case where you want to both send and receive from the same process, you better have the main loop run faster than the tasks subloops. This entails designing your code to publish at a sub-rate of the main loop.

For example you could run your main loop at 50Hz and publish at 5Hz by decimating with an if

int decimator = 0;
while(n.ok())
{
    if ((decimator % 10) == 0)
    {
        //do stuff like publishing
        decimator = 0;
    }
    decimator++;

    //rest of the main loop
}

This way you'd be sure to give roscomm enough time to process the various messages. Theoretically since you're using the same publisher to send more than one message in the same time-slice (you call ros.spinOnce() only once for every two messages) it is possible that only the last one is latched inside your process, thus your subscriber receives only one message because of the fact that you don't allow servicing to happen.

Always remember to run your servicing routines (ros.spinOnce() in this case) faster than the services using them.

edit flag offensive delete link more

Comments

I use usleep in publisher code between the messages publisher m2 and m3 and thus I can see the both m2 and m3 in subscriber. I dont like to use it. But when I dont use it I get just m3 in subscriber.

underwater gravatar image underwater  ( 2013-03-20 04:11:00 -0500 )edit

its correct I running both the publisher and the subscriber from the same process.

underwater gravatar image underwater  ( 2013-03-20 04:17:34 -0500 )edit

Thanks a lot for your answer

underwater gravatar image underwater  ( 2013-03-21 23:35:51 -0500 )edit

Question Tools

Stats

Asked: 2013-03-19 23:16:02 -0500

Seen: 2,803 times

Last updated: Mar 20 '13