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

Filter out messages from a ros bag

asked 2016-08-01 10:08:33 -0500

2ROS0 gravatar image

updated 2016-08-02 11:22:11 -0500


I'd like to filter out some "bad messages" from my rosbags. I'm using the C++ rosbag API. Should I open the bagfile in read mode and republish the good messages and record them in another bag using 'rosbag record'? Or is there a way to modify the bag in place when it's in read or write mode?

I've gone through the C++ API of rosbag a bit, I couldn't find examples similar to what I want to do. Thanks.

Update: Is there a method to find out the list of topics that are present in the bag and other statistics through the API? Is there a way to find out which topic, a particular message instance is from while iterating over them in a boost foreach loop as shown in the example here

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted

answered 2016-08-02 11:20:05 -0500

2ROS0 gravatar image

I opened the bag file in read mode and used the rosbag::View class to look at each topic individually. Then saved all the messages into an object I'm more comfortable with (std::vector for instance). It's based off of the example on this page in the Wiki.

And so perform all operations/logic on the more familiar data structure and then open a new bag file in write mode into which you can add all the required messages.

This is a roundabout way to do it, but I couldn't find a method in the API to: 1. find out which topic a particular message is coming from (if I were to view all topics at once in a single for loop) or 2. modify the messages in a particular topic in place or query what topics are present in a bag and other things like that.

edit flag offensive delete link more

answered 2016-08-01 17:49:42 -0500

NEngelhard gravatar image

It's a bit easier with python:

import rosbag

with rosbag.Bag('output.bag', 'w') as outbag:
    for topic, msg, t in rosbag.Bag('input.bag').read_messages():
        if topic == "/tf" and msg.transforms:
            outbag.write(topic, msg, msg.transforms[0].header.stamp)
            outbag.write(topic, msg, msg.header.stamp if msg._has_header else t)

edit flag offensive delete link more


Yeah, I came across this on the wiki. This doesn't help though because I specifically want to use the C++ API. I figured out a roundabout way to do it (based off of the C++ API which I have shared in my answer).

2ROS0 gravatar image 2ROS0  ( 2016-08-02 11:10:09 -0500 )edit

More specific link where you got this code from:

eRCaGuy gravatar image eRCaGuy  ( 2020-06-06 22:02:03 -0500 )edit

I recently wrote ros_readbagfile, and this tutorial on how to use it, here: See my answer here too:

eRCaGuy gravatar image eRCaGuy  ( 2020-06-28 23:39:56 -0500 )edit

answered 2016-08-02 11:51:03 -0500

ahendrix gravatar image

The rosbag:MessageInstance object that you get for each message in the bag file has a getTopic() method. Unfortunately the docs are a bit hard to find now that the message storage has been moved to the rosbag_storage package:

edit flag offensive delete link more

answered 2020-06-28 23:38:15 -0500

eRCaGuy gravatar image

updated 2020-06-28 23:42:02 -0500

For anyone searching just how to extract, or read messages out of a bag file, as of the year 2020 you can now use ros_readbagfile, like this:

ros_readbagfile <mybagfile.bag> [topic1] [topic2] [topic3] [...] [topic1000]

I recently wrote this script, and this tutorial here:

See the tutorial for full instructions.

Thanks to this answer for getting me started:

edit flag offensive delete link more


eRCaGuy gravatar image eRCaGuy  ( 2020-08-25 16:14:45 -0500 )edit

Question Tools



Asked: 2016-08-01 10:08:33 -0500

Seen: 4,463 times

Last updated: Jun 28 '20