背景:最近在制作kimera的數據集,尤其是運行semantic模塊所需要的bag文件中有很多topic,但是很多不知道topic中裝的是什么數據,及其格式,所以我就想著怎么可以將bag中的topic都解析數來,這樣就能知道bag中都有啥了.有網友提供了下面的代碼,我稍作了些修改,可以在python3下可以順利運行.如果你的文件夾下有多個bag文件,這個代碼可以挨個處理這些bag文件,先為每個bag文件創建一個相應的文件夾,然后把bag文件拷貝進去,然后將bag中的topic都解析為csv格式
?
#!/usr/bin/python
'''
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 providedWritten by Nick Speal in May 2013 at McGill University's Aerospace Mechatronics Laboratory
www.speal.caSupervised 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]]numberOfFiles = "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 upsys.exit(1)count = 0
for bagFile in listOfBagFiles:count += 1print("reading file " + str(count) + " of " + numberOfFiles + ": " + bagFile)#access bagbag = rosbag.Bag(bagFile)bagContents = bag.read_messages()bagName = bag.filename#/home/yunlei/COOL/kalibr-cde/test/2020-06-13-11-57-29.bag#create a new directory string.rstrip(bagName, ".bag")folder = bagName.split(".bag")[0]try: #else already existsos.makedirs(folder)except:passshutil.copyfile(bagName, folder + '/' + bagName.split('/')[-1])#get list of topics from the baglistOfTopics = []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 folder + '/' + string.replace(topicName, '/', '_slash_') + '.csv'filename = folder + '/' + topicName.split('/')[-1] + '.csv'with open(filename, 'w+') as csvfile:filewriter = csv.writer(csvfile, delimiter = ',')firstIteration = True #allows header rowfor 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 listsmsgString = str(msg)msgList = msgString.split('\n')instantaneousListOfData = []for nameValuePair in msgList:splitPair = nameValuePair.split(':')for i in range(len(splitPair)): #should be 0 to 1splitPair[i] = splitPair[i].strip()instantaneousListOfData.append(splitPair)#write the first row from the first element of each pairif firstIteration: # headerheaders = ["rosbagTimestamp"] #first column headerfor pair in instantaneousListOfData:headers.append(pair[0])filewriter.writerow(headers)firstIteration = False# write the value from each pair to the filevalues = [str(t)] #first column will have rosbag timestampfor pair in instantaneousListOfData:if len(pair) > 1:values.append(pair[1])filewriter.writerow(values)bag.close()
print("Done reading all " + numberOfFiles + " bag files.")
?