0
$\begingroup$

Rosanswers logo

Hello guys,

I have seen searching about it and found some discussions (123), but I couldn't make things work (I explain why below).

My problem

I have some bag files (db3 files) that I saved using rosbag2 record from here. Now, I would like to get information from the file and save it in a different format (.txt, .mat, it does not matter). For example, get messages from a specific topic and plot all data.

It seems that there is no python API ready yet, as there was for ROS1.

Possible solutions/Problems I found

I thought about some solutions, but faced a few limitations:

  1. Replay data, create a node that subscribes to all these topics, and then process this data in "real-time", saving it in a different format in the end.
    • The problem of doing this would be that it takes the time of the recorded data. If the experiment duration is 15minutes, it will take that long to get all data. And it does not make much sense for me.
  2. Create my own python API that opens the db3 file (sqlite3) and then process it.
    • I actually developed this quite a bit. I can open the file, see all topics, and get all messages on those topics. However, when it is time to interpret this data, it gets confusing as to how the cdr file is constructed. I explained that a little bit more here.
  3. Use the code that is being under development at the rosba2 github.
    • It seems that some packages (in cpp and in py) are starting to deserialize data. But I am really noob at this. I can build the rosbag2_cpp package, but I don't know how to test it. I don't know where to start from there actually.

Any help is really appreciated.

Using

  • Ubuntu 20.04
  • ROS2 foxy
  • rosbag2

Originally posted by Ana de Sousa on ROS Answers with karma: 106 on 2020-08-04

Post score: 5

$\endgroup$

4 Answers 4

0
$\begingroup$

Rosanswers logo

I solved this issue using sqlite3, get_message (from rosidl_runtime_py) and deserialize_message (from rclpy). In case others have similar issues, it is better explained here. This solution is temporary while there is no API ready (like we had in ROS1).


Originally posted by Ana de Sousa with karma: 106 on 2020-08-05

This answer was ACCEPTED on the original site

Post score: 1

$\endgroup$
0
$\begingroup$

Rosanswers logo

Here is an example using sqlite.

import sqlite3
from rosidl_runtime_py.utilities import get_message
from rclpy.serialization import deserialize_message

import matplotlib.pyplot as plt

class BagFileParser():
    def __init__(self, bag_file):
        self.conn = sqlite3.connect(bag_file)
        self.cursor = self.conn.cursor()

        ## create a message type map
        topics_data = self.cursor.execute("SELECT id, name, type FROM topics").fetchall()
        self.topic_type = {name_of:type_of for id_of,name_of,type_of in topics_data}
        self.topic_id = {name_of:id_of for id_of,name_of,type_of in topics_data}
        self.topic_msg_message = {name_of:get_message(type_of) for id_of,name_of,type_of in topics_data}

    def __del__(self):
        self.conn.close()

    # Return [(timestamp0, message0), (timestamp1, message1), ...]
    def get_messages(self, topic_name):
        
        topic_id = self.topic_id[topic_name]
        # Get from the db
        rows = self.cursor.execute("SELECT timestamp, data FROM messages WHERE topic_id = {}".format(topic_id)).fetchall()
        # Deserialise all and timestamp them
        return [ (timestamp,deserialize_message(data, self.topic_msg_message[topic_name])) for timestamp,data in rows]



if __name__ == "__main__":

        bag_file = '/workspaces/foxy_leg_ws/rosbag2_2021_04_28-04_42_07/rosbag2_2021_04_28-04_42_07_0.db3'

        parser = BagFileParser(bag_file)

        trajectory = parser.get_messages("/joint_trajectory")[0][1] 
        p_des_1 = [trajectory.points[i].positions[0] for i in range(len(trajectory.points))]
        t_des = [trajectory.points[i].time_from_start.sec + trajectory.points[i].time_from_start.nanosec*1e-9 for i in range(len(trajectory.points))]

        actual = parser.get_messages("/joint_states")

        plt.plot(t_des, p_des_1)

        plt.show()

Originally posted by justinberi with karma: 41 on 2021-05-05

This answer was NOT ACCEPTED on the original site

Post score: 4

$\endgroup$
0
$\begingroup$

Rosanswers logo

There are some sample code offered in the official ros2/rosbag 2 repo found here: https://github.com/ros2/rosbag2/tree/master/rosbag2_py/test

the test_sequential_reader.py has some code that you can reuse to read data in the bag files using python. Hope you find this useful.


Originally posted by Praveen Nellihela with karma: 31 on 2021-10-13

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$
0
$\begingroup$

Rosanswers logo

You can use the rosbags package: https://ternaris.gitlab.io/rosbags/

from rosbags.rosbag2 import Reader
from rosbags.serde import deserialize_cdr

# create reader instance and open for reading
with Reader('/home/ros/rosbag_2020_03_24') as reader:
    # topic and msgtype information is available on .connections list
    for connection in reader.connections:
        print(connection.topic, connection.msgtype)

    # iterate over messages
    for connection, timestamp, rawdata in reader.messages():
        if connection.topic == '/imu_raw/Imu':
            msg = deserialize_cdr(rawdata, connection.msgtype)
            print(msg.header.frame_id)

Originally posted by lorepieri with karma: 50 on 2022-07-20

This answer was NOT ACCEPTED on the original site

Post score: 4

$\endgroup$

Your Answer

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