-
Notifications
You must be signed in to change notification settings - Fork 0
/
bag2csv.py
executable file
·101 lines (89 loc) · 3.37 KB
/
bag2csv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#'''
#This script saves each topic in a bagfile as a csv.
#Accepts a filename as an optional argument. Operates on all bagfiles in current directory if no #argument provided
#Usage1 (for one bag file):
# python bag2csv.py filename.bag
#Usage 2 (for all bag files in current directory):
# python bag2csv.py
#
#Written by Nick Speal in May 2013 at McGill University's Aerospace Mechatronics Laboratory
#www.speal.ca
#
#Supervised by Professor Inna Sharf, Professor Meyer Nahon
#'''
import rosbag, sys, csv
import time
import string
import os #for file management make directory
import shutil #for file management, copy file
#verify correct input arguments: 1 or 2
if (len(sys.argv) > 2):
print "invalid number of arguments: " + str(len(sys.argv))
print "should be 2: 'bag2csv.py' and 'bagName'"
print "or just 1 : 'bag2csv.py'"
sys.exit(1)
elif (len(sys.argv) == 2):
listOfBagFiles = [sys.argv(1)]
print "reading only 1 bagfile: " + str(listOfBagFiles(0))
elif (len(sys.argv) == 1):
listOfBagFiles = [f for f in os.listdir(".") if f[-4:] == ".bag"] #get list of only bag files in current dir.
numberOfFiles = str(len(listOfBagFiles))
print "reading all " + numberOfFiles + " bagfiles in current directory: \n"
for f in listOfBagFiles:
print f
print "\n press ctrl+c in the next 10 seconds to cancel \n"
time.sleep(10)
else:
print "bad argument(s): " + str(sys.argv) #shouldnt really come up
sys.exit(1)
count = 0
for bagFile in listOfBagFiles:
count += 1
print "reading file " + str(count) + " of " + numberOfFiles + ": " + bagFile
#access bag
bag = rosbag.Bag(bagFile)
bagContents = bag.read_messages()
bagName = bag.filename
#create a new directory
folder = string.rstrip(bagName, ".bag")
try: #else already exists
os.makedirs(folder)
except:
pass
shutil.copyfile(bagName, folder + '/' + bagName)
#get list of topics from the bag
listOfTopics = []
for topic, msg, t in bagContents:
if topic not in listOfTopics:
listOfTopics.append(topic)
for topicName in listOfTopics:
#Create a new CSV file for each topic
filename = folder + '/' + string.replace(topicName, '/', '_slash_') + '.csv'
with open(filename, 'w+') as csvfile:
filewriter = csv.writer(csvfile, delimiter = ',')
firstIteration = True #allows header row
for subtopic, msg, t in bag.read_messages(topicName): # for each instant in time that has data for topicName
#parse data from this instant, which is of the form of multiple lines of "Name: value\n"
# - put it in the form of a list of 2-element lists
msgString = str(msg)
msgList = string.split(msgString, '\n')
instantaneousListOfData = []
for nameValuePair in msgList:
splitPair = string.split(nameValuePair, ':')
for i in range(len(splitPair)): #should be 0 to 1
splitPair[i] = string.strip(splitPair[i])
instantaneousListOfData.append(splitPair)
#write the first row from the first element of each pair
if firstIteration: # header
headers = ["rosbagTimestamp"] #first column header
for pair in instantaneousListOfData:
headers.append(pair[0])
filewriter.writerow(headers)
firstIteration = False
# write the value from each pair to the file
values = [str(t)] #first column will have rosbag timestamp
for pair in instantaneousListOfData:
values.append(pair[1])
filewriter.writerow(values)
bag.close()
print "Done reading all " + numberOfFiles + " bag files."