Rosanswers logo

Hello everyone. I'm writing a test program, which receives messages from two different topics and stores them in different queues.
The program, works on a while loop and, at every iteration, before checking for the arrival of new messages, it deletes the top elements of the queues if they have both one.
The program subscribes to a third queue, too, that I use to send a termination message.
Here is the code:

#include "/opt/ros/fuerte/include/ros/ros.h"
#include "/opt/ros/fuerte/include/nav_msgs/Odometry.h"
#include "/opt/ros/fuerte/include/geometry_msgs/Pose.h"
#include "/opt/ros/fuerte/include/geometry_msgs/Point.h"
#include "/opt/ros/fuerte/include/std_msgs/String.h"
#include "/opt/ros/fuerte/include/sensor_msgs/LaserScan.h"
#include "/opt/ros/fuerte/stacks/geometry/tf/include/tf/transform_listener.h"

#include "odom_node.h"
#include "scan_node.h"
#include "messageListener.h"

#include "list"
#include "vector"
#include "coord.h"
#include "math.h"
#include "stdlib.h"
#include "iterator"
#include "string"
#include "iostream"
#include "fstream"
#include "string"
#include "sstream"

#include "stdio.h"
#include "iostream"
#include "map"
#include "math.h"
#include "stdlib.h"
#include "string"

using namespace std;

    odomCounter = 0;
    scanCounter = 0;

void messageListener::end_loop(const std_msgs::String mes){
    printf("Setting flag\n");
        while_flag = 0;

void messageListener::addOdomNode (const nav_msgs::Odometry mes){
    geometry_msgs::Pose robot_pose = mes.pose.pose;
    geometry_msgs::Point robot_point = robot_pose.position;

    odom_node *on = new odom_node();
    (*on).xCoord = robot_point.x;
    (*on).yCoord = robot_point.y;
    (*on).frame_id = mes.header.frame_id;

    double orientation = tf::getYaw(robot_pose.orientation);
    (*on).angle = (float)orientation;


vector<coord> messageListener::polar2cart(vector<float> v, float a_min, float a_inc, float range_min, float range_max){
    vector<coord> lc;
    for(int i=0; i<(int)v.size(); i++){
        if(v[i]>= range_min && v[i]<=range_max){
            coord *c = new coord();
            (*c).x = v[i]*cos(a_min + a_inc*i);
            (*c).y = v[i]*sin(a_min + a_inc*i);
    return lc;

void messageListener::addScanNode (const sensor_msgs::LaserScan mes){
    scan_node *sn = new scan_node();
    (*sn).scan = mes.ranges;
    (*sn).frame_id = mes.header.frame_id;
    (*sn).cartesian = polar2cart(mes.ranges, mes.angle_min, mes.angle_increment, mes.range_min, mes.range_max);

void messageListener::listen(int c, char** v){
    while_flag = 1;
    printf("Listening activity begun\n");
    ros::init(c,v, "listener");
    ros::NodeHandle n_odom, n_scan, n_end;

    ros::Subscriber sub_odom = n_odom.subscribe("/odom", 1000, &messageListener::addOdomNode,this);
    ros::Subscriber sub_scan = n_scan.subscribe("/base_scan", 1000, &messageListener::addScanNode,this);
    ros::Subscriber sub_end = n_end.subscribe("/end", 1000, &messageListener::end_loop,this);
    printf("Subscription complete\n");
        if(odomVector.size()>0 && scanVector.size()>0){


    printf("Exit from listening\n");
    printf("Ricevuti %i nodi odometrici e %i nodi scansione\n", odomCounter, scanCounter);
    printf("Terminazione in corso con %i nodi odometrici e %i nodi scansione in coda rimasti\n\n", (int)odomVector.size(), (int)scanVector.size());

Here, odomCounter and scanCounter are just two counters that I use to count received messages.
After starting the program, I play a bag file, whose information is reported in the following:

ubisum@ubisum:~/fuerte_workspace/gb_slam/bags$ rosbag info 230513_dis_bag.bag 
path:        230513_dis_bag.bag
version:     2.0
duration:    1:30s (90s)
start:       May 23 2013 10:57:16.08 (1369299436.08)
end:         May 23 2013 10:58:46.19 (1369299526.19)
size:        8.2 MB
messages:    1806
compression: none [11/11 chunks]
types:       nav_msgs/Odometry     [cd5e73d190d741a2f92e81eda573aca7]
             sensor_msgs/LaserScan [90c7ef2dc6895d81024acba2ac42f369]
topics:      /base_scan   903 msgs    : sensor_msgs/LaserScan
             /odom        903 msgs    : nav_msgs/Odometry

As you see, program should receive 903 messages for each kind, but at the end it just receives 901. Do you know the reason?


Originally posted by ubisum on ROS Answers with karma: 23 on 2013-09-23

Post score: 1

Original comments

Comment by dornhege on 2013-09-23:
Technically there is not guarantee that you will receive all messages. That being said: In your setting you'd hope for that given the large queue sizes. One guess: Check, which messages are missing. Are those the first ones? Then those are sent before the topic connection was made.

Comment by ubisum on 2013-09-24:
thanks for answer. I took care to start bag playing after running receiving program. I suspect that the ones to be missing are the last ones, since the playing time stops a little while before expected end (it should stop at 19 seconds, but it does at 18.8). is there a reason for this?

Comment by dornhege on 2013-09-24:
I'm not sure if there is a reason for that, but it might still be the first ones: When the player is started it takes a short amount of time for both nodes to connect, where messages might be played. Maybe it helps to start in --paused mode and wait 1 sec before running.

Comment by dornhege on 2013-09-24:
The easiest might be to check timestamps of the first/last messages in the log/received to see what's going on. Nevertheless, this doesn't need to work according to ROS, so if you really need all messages, maybe look into the rosbag API.

Comment by ubisum on 2013-09-24:
thanks for help, I'll take all this into account. just one more question: when a callback function is invoked, is its termination awaited before spinning to receive another message? is it possible that two different callback functions are running at same time, while the loop continues to receive?

Comment by dornhege on 2013-09-24:
AFAIK no, unless you use a threaded spinner.

Comment by ubisum on 2013-09-24:
that's what I expected. my system should take an odometric and scanning message, then go through corners extraction, data association, RANSAC, graph optimization... all this will take a long while before a new message can be received....


1 Answer 1


Rosanswers logo

Just to add to the reply posted by @dornhege:

It is fairly common to drop the first few messages played from a bag file.

When you start your program early, this only ensures that topic subscriptions are advertised before playing the bag-file topics. The way ROS handles message-publishing is by creating explicit connections between the publisher and subscriber once "matching" topic names/types have been identified. This connection happens when the publisher and subscriber have both advertised the same topic. Once the connection is made, then the subscriber starts processing any messages received after the connection is completed. Any messages published before that connection is finalized are simply dropped.

When playing a bag file with the default settings, there is a very small (near-zero) delay between advertising a topic and playing the messages from that topic. This can cause the first few messages to be dropped before the subscriber connection is fully completed.

Thankfully, there is an easy solution to this problem. Play the bag file with a delay option to introduce a pause between advertising the topic and publishing the messages. This delay allows time for subscriber clients to connect before publishing any messages, so none are dropped:

rosbag play -d 0.5 myData.bag

Originally posted by Jeremy Zoss with karma: 4976 on 2013-09-24

This answer was ACCEPTED on the original site

Post score: 6

Original comments

Comment by ubisum on 2013-09-24:
thanks, your solution seems to work. it's not a great damage missing the initial messages, but it's not "an engineer's approach" :))) now every message is correctly delivered.

Comment by dornhege on 2013-09-24:
If you want to guarantee all messages, the best would be to parse the file using the rosbag API.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.