ros2 / rosbag2

Apache License 2.0
274 stars 246 forks source link

[Documentation/Example] Please add example on how to read a rosbag with python #1692

Closed firesurfer closed 2 months ago

firesurfer commented 4 months ago

Description

There are currently only examples on how to create a rosbag with python (and c++) but there are none on how to read a rosbag.

Related Issues

There is currently an open PR for adding a reader example in c++: https://github.com/ros2/rosbag2/pull/1683

Completion Criteria

Example should show:

Bonus:

fujitatomoya commented 4 months ago

I think this is reasonable and useful for beginners, in addition we can also add the documentation tutorial for this.

firesurfer commented 3 months ago

In the mean time for whoever is looking for it: a probably less than perfect example on how to read a ros2bag with python:

from rclpy.serialization import deserialize_message
import rosbag2_py
import sys
from pydoc import locate

def main():

    # Create a reader
    reader = rosbag2_py.SequentialReader()

    # Configure the storage we want to open
    storage_options = rosbag2_py._storage.StorageOptions(uri=sys.argv[1], storage_id="mcap")
    converter_options = rosbag2_py._storage.ConverterOptions("", "")

    # Actually open it
    reader.open(storage_options, converter_options)

    # Obtain a list of all topics and their types
    all_topics_and_types = reader.get_all_topics_and_types()

    print("Topics:")
    typestr_to_type = {}

    for meta_info in all_topics_and_types:
        print(" ", meta_info.name, meta_info.type)
        # Some python magic. We use the topic type to locate and import the python type
        typestr_to_type[meta_info.name] = locate(meta_info.type.replace("/", "."))

    # You can set a filter via:
    reader.set_filter(rosbag2_py._storage.StorageFilter(topics=["/joint_states"]))

    # Read it step for step
    while reader.has_next():
        next = reader.read_next()
        # Actually create the actual message
        msg = deserialize_message(next[1], typestr_to_type[next[0]])

        # NOTE: This is strictly sequential in the sense: as recorded.
        # This means read_next() will always return 1 (__one__) message!
        print(msg)

if __name__ == "__main__":
    main()
fujitatomoya commented 3 months ago

related to https://github.com/ros2/ros2_documentation/issues/4560

fujitatomoya commented 2 months ago

@clalancette can you close this too? https://github.com/ros2/ros2_documentation/issues/4560 closes this one too.