前言

blf 数据是 CAN 数据录制的一种格式,以二进制格式存储数据,需要用 CANoe 等工具进行解析才能查看数据,下面介绍使用 Python 解析 blf 数据。

工具包安装

1
pip install cantools python-can

解析blf文件

一般情况下,解析 blf 需要 dbc 文件,当然其实不用 dbc 也可以,只不过解析比较麻烦,推荐还是配合 dbc 解析,这个也是我们最常用的办法。所以要用 dbc,需要先加载 dbc 文件,这里需要cantools。

1
2
3
4
import cantools
import can
dbc_file = r"xxx.dbc"
dbc = cantools.db.load_file(dbc_file)

加载完 dbc 文件,就可以解析 blf 文件了。

1
2
3
4
f = r"xxx.blf"
log_data = can.BLFReader(f)
for msg in log_data:
print(msg)

打印结果是这样的

1
2
3
4
Timestamp: 1673917200.026000    ID: 0301    S Rx    DL:  8    1d b0 41 54 07 02 00 00    Channel: 0
Timestamp: 1673917200.026000 ID: 070b S Rx DL: 8 00 c8 0c b6 24 b8 24 b8 Channel: 0
Timestamp: 1673917200.028000 ID: 0322 S Rx DL: 8 00 00 00 00 00 00 03 00 Channel: 0
Timestamp: 1673917200.126000 ID: 030d S Rx DL: 8 00 14 00 00 00 00 00 00 Channel: 0

上面 msg 输出的格式为“时间戳、can_id、属性(比如是否是 canfd 帧、是否是错误帧、是 rx 还是 tx 帧等等)、长度(也就是 dlc)、以 16 进制格式输出的 raw data、can channel”。

由于 msg 本身就是一个 can.message 类,因此我们也可以手动取到它的各种属性
img

可以发现,时间戳解析出来了,其它的数据都是 16 进制,没法直接看。当然我们如果熟悉 blf 格式,可以自己把数据还原出来,但是既然已经用第三方库,我们当然就不用自己解析了,而且仔细观察一下即可发现,之前的加载 dbc 并没有用上,所以这时一个重要的函数登场了,那就是dbc.decode_message(id, data),具体代码如下

1
2
3
4
5
6
7
8
9
10
11
decoded = {}
for msg in logdata:
try:
dec = dbc.decode_message(msg.arbitration_id, msg.data)
if dec:
for key, data in dec.items():
if key not in decoded:
decoded[key] = []
decoded[key].append([msg.timestamp, data])
except:
pass

因为我要把 blf 数据解析出来转成 mf4 了,所以构建了一个 decoded 字典,每个 key 里记一个信号,熟悉 mf4 的应该知道,mf4 里每个信号主要包含两部分,一个是时间戳,一个是数据,有了这两个,我们就可以创建 mf4 文件了,最后放上创建 mf4 的代码。

1
2
3
4
5
6
7
8
9
10
11
from asammdf import MDF,Signal
sigs = []
for k,v in decoded.items():
timestamps = [i[0] for i in v]
data = [i[1] for i in v]
s = Signal(data, timestamps, name=k)
sigs.append(s)

mdf = MDF()
mdf.append(sigs)
mdf.save("xx.mf4", overwrite=True)

这样就实现了 blf 文件的解析与转换,当然,转换的格式很自由,只要熟悉相应的格式,比如 csv,hdf5,xlsx,json,pickle 都可以,因为我们已经拿到原始数据了,保存成什么格式就很简单了。


©2018 - Felicx 使用 Stellar 创建
总访问 113701 次 | 本页访问 326
共发表 83 篇Blog · 总计 127.5k 字