问题背景
在分析CAN信号的时候,虽然利用CANoe 或者周立功工具,能够很直观的看到数据的分布情况,但是,上述工具在导出数据的时候,还是有很多限制,不利于数据的二次处理。利用python将数据解析处理,可以用excel 或者 MATLAB 进行数据处理。
代码
# 导入math模块,用于数学计算
import math
# 导入can模块,用于处理CAN总线数据
import can
# 导入struct模块,用于处理二进制数据
import struct
# 导入scipy.io模块的savemat函数,用于保存数据到MATLAB的.mat文件
from scipy.io import savemat
# 导入sys模块,这个模块提供了一些变量和函数,可以与Python解释器进行交互
import sys
# 导入pandas模块,这是一个强大的数据处理和分析库
import pandas as pd
# 定义一个空列表,用于存储时间戳数据
Timestamp = []
# 定义一个空列表,用于存储UB数据
UB = []
# 定义一个函数,用于将CAN数据转换为物理值
def CanFD_to_phy(data, factor, offset):
# 计算实际的数据值,通过乘以一个因子并加上一个偏移量
data_act = data * factor + offset
# 返回计算后的数据值
return data_act
# 定义一个函数,用于分析CAN数据
def analyze(data):
# 初始化一个计数器,用于追踪数据中的位置
num = 0
# 从data中提取8个字节的数据,并解析为一个64位整数(时间戳)
Timestamp_1 = struct.unpack('>q', data[num: num + 8])[0]
# 调用CanFD_to_phy函数,将时间戳从CAN值转换为物理值
Timestamp = CanFD_to_phy(Timestamp_1, 1, 0)
# 更新计数器的位置,跳过已经处理过的8个字节
num = num + 8
# 从data中提取1个字节的数据,并解析为一个无符号字节(UB)
UB_phy = struct.unpack('>B', data[num: num + 1])[0]
# 调用CanFD_to_phy函数,将UB从CAN值转换为物理值,然后除以2的7次方(可能是为了归一化或缩放)
UB = CanFD_to_phy(UB_phy, 1, 0) // math.pow(2, 7)
# 将处理后的时间戳和UB值组合成一个列表
Info1 = [Timestamp, UB]
# 返回处理后的信息列表
return Info1
# 定义一个主函数
def main():
# 使用can模块的BLFReader读取一个BLF文件(CAN总线数据文件)
blf_data = can.BLFReader("C:\\Users\\2.blf")
# 遍历BLF文件中的每一条消息
for msg in blf_data:
# 如果消息的仲裁ID是0x109
if msg.arbitration_id == 0x109:
# 打印消息的详细信息
print(msg)
# 调用analyze函数分析消息的数据,并获取处理后的信息
inf = analyze(msg.data)
# 打印处理后的信息
print(inf)
# 如果当前脚本是主程序(不是被其他脚本导入的模块),则执行以下操作
if __name__ == '__main__':
# 打印开始执行的提示信息
print('start')
# 调用主函数
main()
说明
1、上述struct 模块解析, 需要注意的是,打包数据采用无符号型。在用该模块的时候,当处理不满一个字节,或者非整数字节的时候,可以用数学取余,取整法,上述UB 就只有1bit。
具体使用,python之struct 模块详解_import struct-CSDN博客
2、上述未写后处理函数,具体保存为csv 还是 mat 格式,可以在上述函数添加。