python拆分CANLog
通过CANOE 导出的log通常有很多个ID的数据,如何才能找到某一个ID下的特殊的信号?利用python可以简单的进行这个步骤,代码如下:
说明:
最终的效果是将log信息,分不同的ID进行拆分,并单独生成文件log_id.csv的文件夹。
1. 需要输入输入文件夹
2. 生成_out文件夹。
3. 没有错误处理
4. 采用"[A-F|\d]{3}"匹配CAN ID
1 #log analy about CAN Signal for CANOE 2 import os 3 import re 4 5 ID_Info = {} 6 fold_in = input("Please input Folder In:") 7 fold_out = fold_in + "_out" 8 os.mkdir(fold_out) 9 rep_id = r"[A-F|\d]{3}" 10 patt_id = re.compile(rep_id) 11 def Info_Report(): 12 ''' 13 CAN Log中的信息有固定的位数。 14 0:时间戳 15 1:1/2 16 2:ID 17 3:Rx/Tx 18 4: d 19 5: data Length 20 6: data length number info 21 ''' 22 pass 23 24 def Dev_Folder(folder_in): 25 for fi in os.listdir(folder_in): 26 #打开文件 27 with open(os.path.join(folder_in,fi),"r") as file: 28 #遍历文件行 29 for line in file: 30 #拆分文件,去掉空格,去掉前后逗号 31 a = re.sub('\s+',',',line).strip(",") 32 #判断List是否有3个以上的元素,并且第3个是否为ID. 33 if len(a.split(",")) > 2 and patt_id.match(a.split(",")[2]): 34 if a.split(",")[2] in ID_Info.keys(): 35 #如果在字典中,直接将信息写入到该文件中 36 pass 37 else: 38 #新建一个文件,关联字典 39 ID_Info[a.split(",")[2]] = open((os.path.join(fold_out + "\\" + "Log_" + a.split(",")[2]) + ".csv"),"w") 40 ID_Info[a.split(",")[2]].write(a+"\n") 41 #print(a.split(",")[0]) 42 for key in ID_Info: 43 ID_Info[key].close() 44 45 if __name__ == '__main__': 46 Dev_Folder(fold_in) 47
以上拆分为单个的ID了,那么如何找到某一个信号的值呢?可以通过下面的代码进行计算:
1 ''' 2 CANOE Log 3 ''' 4 ''' 5 6 ''' 7 start_bit = 0 8 data_length = 0 9 can_mode = 0 10 11 def Info_Report(): 12 ''' 13 Need Input This information about CAN setting. 14 start bit: start_bit 15 Length : Data_Length 16 start bit mode : LSB(0)/MSB(1) 17 default:LSB(0) 18 ''' 19 pass 20 21 def SetBit(start,length,mode = 0): 22 ''' 23 for Get Info or set info 24 ''' 25 start_bit = start 26 data_length = length 27 can_mode = mode 28 29 def Analyse_ID_File(File_Input_Name,File_Output_Name): 30 ''' 31 Analyse id for Every ID Signal 32 ''' 33 #open file 34 file_out = open(File_Output_Name,"w") 35 with open(File_Input_Name,"r") as file: 36 for line in file: 37 #拆分每一行,放入到list中 38 data_list = line.split(",") 39 data_length = int(data_list[5],16) 40 list_in = data_list[6:6+data_length] 41 data_signal = Find_FromList(list_in) 42 file_out.write(data_list[0]+","+str(data_signal)+"\n") 43 file_out.close() 44 45 def Find_FromList(data_list): 46 dataMerge = '' 47 a,b,c = Find_StartEnd(start_bit,data_length,can_mode) 48 #print(data_list) 49 if len(data_list) > b: 50 for i in range(a,b+1): 51 #print(i) 52 dataMerge = dataMerge + data_list[i] 53 #print(dataMerge) 54 data_Digit = (int(dataMerge,16)>>c) & ((1<<(data_length))-1) 55 return (data_Digit) 56 #print(dataMerge) 57 58 def Find_StartEnd(start,length,mode): 59 ''' 60 This Function return value: 61 byte_little,byte_big,bigbyte_bit 62 ''' 63 startbyte = start >> 3 64 startbit = start % 8 65 if mode == 0: 66 litByte = startbyte - ((startbit+length-1)>>3) 67 BigByte = startbyte 68 Endbit = startbit 69 else: 70 pass 71 return (litByte,BigByte,Endbit) 72 73 if __name__ == '__main__': 74 #print(Find_StartEnd(32,20,1)) 75 file_name = input("Please input file You need Analyse:") 76 file_out_name = input("Please input file You need Out(.csv):") 77 start_bit,data_length,can_mode = map(int,input("please input can info(start_bit,data_length,can_mode(0/1),PV为0):").split(",")) 78 Analyse_ID_File(file_name,file_out_name)
以上,如果不通过导入每个信号信息含义的话,是可以快速的找到某个信号在整个log中的值得变化的。
以上,只支持以LSB开始,计算长度的算法。如果以MSB需要在''Find_StartEnd"函数中增加''mode == 1''的处理。