Ask Your Question
0

The problem about the double messages read from a rosbag file

asked 2019-08-12 06:30:11 -0500

YancenBOB gravatar image

updated 2019-08-13 02:37:30 -0500

I want to write the time stamps of rosbag in a .txt document. There, I use two kinds of methods to do that:

  1. Reference of C++ API link text.

  2. Use the callback fuction to subscribe the topics from the rosbag played in another terminal.

But I meet a strange problem about the quantity of time stamps between two methods. The first method will output almost the double quantity of time stamps while that of the second one is right.

The rosbag I choose is from the datase EuRoC MH_easy_01.bag. It is about the indoor UAV for vision and INS (vio) SLAM. I check the inforamtion of it and there are 3682 messages for two cameras.

path:        MH_01_easy.bag
version:     2.0
duration:    3:06s (186s)
start:       Jun 25 2014 03:02:59.81 (1403636579.81)

end:         Jun 25 2014 03:06:06.70 (1403636766.70)
size:        2.5 GB
messages:    47283
compression: none [2456/2456 chunks]
types:       geometry_msgs/PointStamped [c63aecb41bfdfd6b7e1fac37c7cbe7bf]
             sensor_msgs/Image          [060021388200f6f0f447d0fcd9c64743]
             sensor_msgs/Imu            [6a62c6daae103f4ff57a132d6f95cec2]
topics:      /cam0/image_raw    3682 msgs    : sensor_msgs/Image         
             /cam1/image_raw    3682 msgs    : sensor_msgs/Image         
             /imu0             36820 msgs    : sensor_msgs/Imu           
             /leica/position    3099 msgs    : geometry_msgs/PointStamped

For the fist method, I get almost double messages (7364) and for the second one I get the same number of rosbag file. And the double number has a strange phenomenon that each message has a copy. So, it has the double number.

My environment is Ubuntu 16.05 and ROS Kinetic. Two method codes are in the following:

The first one of C++ API

#include <ros/ros.h>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/Imu.h>

#include <boost/foreach.hpp>

#define foreach BOOST_FOREACH

#include <string>
#include <vector>
#include <stdio.h>

int main (int argc, char ** argv)
{
    //Initiliaze the node and bag
    ros::init(argc,argv,"read");
    ros::NodeHandle n;
    rosbag::Bag bag;
bag.open("/home/cyx/dataset/MH_01_easy.bag");
// bag.open("data.bag");

ROS_INFO("Open the bag");

FILE *fpOut0, *fpOut1, *fpout2;
fpOut0=fopen("cam0_MH.txt", "w");
fpOut1=fopen("cam1_MH.txt", "w");
fpout2=fopen("imu_MH.txt", "w");

//Topics name in the rosbag
std::vector<std::string> topics;
topics.push_back(std::string("/cam0/image_raw"));
topics.push_back(std::string("/cam1/image_raw"));
topics.push_back(std::string("/imu0"));

rosbag::View view(bag, rosbag::TopicQuery(topics));

ROS_INFO("Start to read");
//read the time stamp and write them to .txt
foreach(rosbag::MessageInstance const m, view)
{
    sensor_msgs::Image::ConstPtr img0 = m.instantiate<sensor_msgs::Image>();
    sensor_msgs::Image::ConstPtr img1 = m.instantiate<sensor_msgs::Image>();
    sensor_msgs::Imu::ConstPtr imu = m.instantiate<sensor_msgs::Imu>();

    if(img0!=NULL)
    {
        fprintf(fpOut0, "%.9lf\n", img0->header.stamp.toSec());
        // printf("t0 = %.9lf\n", img0->header.stamp.toSec());
    }

    if(img1!=NULL)
    {
        fprintf(fpOut1, "%.9lf\n", img1->header.stamp.toSec());
        // printf("t1 = %.9lf\n", img1->header.stamp.toSec());
    }

    if(imu!=NULL)
    {
        fprintf(fpout2, "%.9lf\n", imu->header.stamp.toSec());
    }

}

bag.close();

return 1;

}

And the second one of callback function

#include <ros/ros.h>
#include <rosbag/bag.h>
#include <sensor_msgs/Imu.h>
#include <sensor_msgs/Image.h>

#include <iostream>
#include <stdio.h>

FILE *fp0, *fp1, *fp2;

void ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2019-08-13 03:30:59 -0500

updated 2019-08-13 05:26:22 -0500

Your first method is not isolating the message topics correctly which may explain the numbers of messages being twice as high as you expect.

The following lines only check if the message is an sensor_msgs::Image not which topic it is, so they will execute for both image topics:

sensor_msgs::Image::ConstPtr img0 = m.instantiate<sensor_msgs::Image>();
if(img0!=NULL)
{
    // ...
}

You want to use the rosbag::MessageInstance::getTopic() method to get the actual topic name for each message and check that instead as below.

if (m.getTopic() == "/cam0/image_raw" && m.isType<sensor_msgs::Image>())
{
    sensor_msgs::Image::ConstPtr img0 = m.instantiate<sensor_msgs::Image>();
    fprintf(fp0, "%.9lf\n", img0->header.stamp.toSec());
}

This should give you the correct number of messages.

Your second method works but message delivery in ROS is not guaranteed, so it's quite possible that some messages are dropped using this technique meaning your totals would not be correct.

Hope this fixes this for you

edit flag offensive delete link more

Comments

Thank you very much! I follow your advice and make it! Besides, during a few test, I find that the messages dropped in the second method that you said may appear sometimes. Thank you!

YancenBOB gravatar imageYancenBOB ( 2019-08-13 21:21:09 -0500 )edit

Glad you got it working.

PeteBlackerThe3rd gravatar imagePeteBlackerThe3rd ( 2019-08-14 05:22:07 -0500 )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

2 followers

Stats

Asked: 2019-08-12 06:30:11 -0500

Seen: 26 times

Last updated: Aug 13