rosbag_pandas.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import logging
4 
5 from .flatdict import FlatterDict
6 import numpy as np
7 import pandas as pd
8 import rosbag
9 from rospy_message_converter.message_converter import convert_ros_message_to_dictionary
10 
11 
12 class RosbagPandaException(Exception):
13  pass
14 
15 
16 def topics_from_keys(keys):
17  """
18  Extracts the desired topics from specified keys
19  :param Keys: List of desired keys
20  :return: List of topics
21  """
22  topics = set()
23  for key in keys:
24  if not key.startswith("/"):
25  key = "/" + key
26  chunks = key.split("/")
27  for i in range(2, len(chunks)):
28  topics.add("/".join(chunks[0:i]))
29  return list(topics)
30 
31 
32 def bag_to_dataframe(bag_name, include=None, exclude=None):
33  """
34  Read in a rosbag file and create a pandas data frame that
35  is indexed by the time the message was recorded in the bag.
36 
37  :param bag_name: String name for the bag file
38  :param include: None, or List of Topics to include in the dataframe
39  :param exclude: None, or List of Topics to exclude in the dataframe (only applies if include is None)
40 
41  :return: a pandas dataframe object
42  """
43  logging.debug("Reading bag file %s", bag_name)
44 
45  bag = rosbag.Bag(bag_name)
46  type_topic_info = bag.get_type_and_topic_info()
47  topics = type_topic_info.topics.keys()
48 
49  # get list of topics to parse
50  logging.debug("Bag topics: %s", topics)
51 
52  if not topics:
53  raise RosbagPandaException("No topics in bag")
54 
55  topics = _get_filtered_topics(topics, include, exclude)
56  logging.debug("Filtered bag topics: %s", topics)
57 
58  if not topics:
59  raise RosbagPandaException("No topics in bag after filtering")
60 
61  df_length = sum([type_topic_info.topics[t].message_count for t in topics])
62 
63  index = np.empty(df_length)
64  index.fill(np.NAN)
65  data_dict = {}
66  for idx, (topic, msg, t) in enumerate(bag.read_messages(topics=topics)):
67  flattened_dict = _get_flattened_dictionary_from_ros_msg(msg)
68  for key, item in flattened_dict.items():
69  data_key = topic + "/" + key
70  if data_key not in data_dict:
71  if isinstance(item, float) or isinstance(item, int):
72  data_dict[data_key] = np.empty(df_length)
73  data_dict[data_key].fill(np.NAN)
74  else:
75  data_dict[data_key] = np.empty(df_length, dtype=np.object)
76  data_dict[data_key][idx] = item
77  index[idx] = t.to_sec()
78 
79  bag.close()
80 
81  # now we have read all of the messages its time to assemble the dataframe
82  return pd.DataFrame(data=data_dict, index=index)
83 
84 
86  """
87  Return a flattened python dict from a ROS message
88  :param msg: ROS msg instance
89  :return: Flattened dict
90  """
91  return FlatterDict(convert_ros_message_to_dictionary(msg), delimiter="/")
92 
93 
94 def _get_filtered_topics(topics, include, exclude):
95  """
96  Filter the topics.
97  :param topics: Topics to filter
98  :param include: Topics to include if != None
99  :param exclude: Topics to exclude if != and include == None
100  :return: filtered topics
101  """
102  logging.debug("Filtering topics (include=%s, exclude=%s) ...", include, exclude)
103  return [t for t in include if t in topics] if include is not None else \
104  [t for t in topics if t not in exclude] if exclude is not None else topics
def _get_flattened_dictionary_from_ros_msg(msg)
def bag_to_dataframe(bag_name, include=None, exclude=None)
def _get_filtered_topics(topics, include, exclude)


rosbag_pandas
Author(s): Adam Taylor
autogenerated on Mon Feb 28 2022 23:30:55