00001
00002
00003
00004
00005 import rospy
00006 import rosbag
00007
00008 from optparse import OptionParser
00009 import StringIO
00010 from datetime import datetime
00011 import uuid
00012
00013
00014 def message_to_csv(stream, msg, flatten=False):
00015 """
00016 stream: StringIO
00017 msg: message
00018 """
00019 try:
00020 for s in type(msg).__slots__:
00021 val = msg.__getattribute__(s)
00022 message_to_csv(stream, val, flatten)
00023 except:
00024 msg_str = str(msg)
00025 if msg_str.find(",") is not -1:
00026 if flatten:
00027 msg_str = msg_str.strip("(")
00028 msg_str = msg_str.strip(")")
00029 msg_str = msg_str.strip(" ")
00030 else:
00031 msg_str = "\"" + msg_str + "\""
00032 stream.write("," + msg_str)
00033
00034 def message_type_to_csv(stream, msg, parent_content_name="", flatten=False):
00035 """
00036 stream: StringIO
00037 msg: message
00038 """
00039 try:
00040 for s in type(msg).__slots__:
00041 val = msg.__getattribute__(s)
00042 if flatten and type(val) == tuple:
00043 for i in range(len(val)):
00044 stream.write("," + ".".join([parent_content_name, s, str(i)]))
00045 else:
00046 stream.write("," + ".".join([parent_content_name, s]))
00047 except:
00048 stream.write("," + parent_content_name)
00049
00050 seq = 0
00051 nowtime = datetime.now().strftime("%Y%m%d-%H%M%S")
00052
00053 def format_csv_filename(form, topic_name):
00054 global seq
00055 ret = form.replace('%t', topic_name.replace('/','-'))
00056 ret = ret.replace('%s', str(seq))
00057 seq += 1
00058 ret = ret.replace('%d', nowtime)
00059 ret = ret.replace('%u', str(uuid.uuid4()))
00060 return ret
00061
00062 def bag_to_csv(options, args):
00063 try:
00064 bag = rosbag.Bag(args[0])
00065 streamdict= dict()
00066 stime = None
00067 if options.start_time:
00068 stime = rospy.Time(options.start_time)
00069 etime = None
00070 if options.end_time:
00071 etime = rospy.Time(options.end_time)
00072 except Exception as e:
00073 rospy.logfatal('failed to load bag file: %s', e)
00074 exit(1)
00075
00076 try:
00077 for topic, msg, time in bag.read_messages(topics=options.topic_names,
00078 start_time=stime,
00079 end_time=etime):
00080 if streamdict.has_key(topic):
00081 stream = streamdict[topic]
00082 else:
00083 stream = open(format_csv_filename(options.output_file_format, topic),'w')
00084 streamdict[topic] = stream
00085
00086 if options.header:
00087 stream.write("time")
00088 message_type_to_csv(stream, msg, flatten = options.flatten)
00089 stream.write('\n')
00090
00091 stream.write(datetime.fromtimestamp(time.to_time()).strftime('%Y/%m/%d/%H:%M:%S.%f'))
00092 message_to_csv(stream, msg, flatten = options.flatten)
00093 stream.write('\n')
00094 [s.close for s in streamdict.values()]
00095 except Exception as e:
00096 rospy.logwarn("fail: %s", e)
00097 finally:
00098 bag.close()
00099
00100 if __name__ == '__main__':
00101 rospy.init_node('bag2csv', anonymous=True)
00102 parser = OptionParser(usage="%prog [options] bagfile")
00103 parser.add_option("-a", "--all", dest="all_topics",
00104 action="store_true",
00105 help="exports all topics", default=False)
00106 parser.add_option("-t", "--topic", dest="topic_names",
00107 action="append",
00108 help="white list topic names", metavar="TOPIC_NAME")
00109 parser.add_option("-O", "--output", dest="output_file_format",
00110 help="output file names format\n%t: topic name\n%s: sequential number\n%d: datetime (now)\n%u: uuid\ne.g.: -O jskbag-$t-$d.csv", metavar="DESTINATION")
00111 parser.add_option("-s", "--start-time", dest="start_time",
00112 help="start time of bagfile", type="float")
00113 parser.add_option("-e", "--end-time", dest="end_time",
00114 help="end time of bagfile", type="float")
00115 parser.add_option("-n", "--no-header", dest="header",
00116 action="store_false", default=True,
00117 help="no header / flatten array value")
00118 parser.add_option("-f", "--flatten", dest="flatten",
00119 action="store_true",
00120 help="output the list type topic with flatten format", default=False)
00121 (options, args) = parser.parse_args()
00122
00123 if len(args) != 1:
00124 parser.print_help()
00125 exit(0)
00126
00127 bag_to_csv(options, args)