如何正确读取J1939消息从.asc文件与cantools?



我试图创建一个CAN日志转换器从。asc文件到。csv文件(在人类可读的形式)。我算是成功了。我的代码可以很好地工作在几乎所有的数据库,但j1939.dbc。

问题是,如果我打印出从dbc文件中读取的消息,我可以看到来自j1939的消息。DBC被读入数据库。但是它无法在已处理的日志文件中找到任何这些消息。同时,我可以使用Vector CANalyzer读取相同的文件,没有问题。

我想知道为什么会发生这种情况,为什么它只影响j1939。DBC而不是其他。

我怀疑也许我转换这些消息的方式是错误的,因为它从来没有经过if msg_id in database:行(如上所述,这些消息肯定存在,因为Vector CANalyzer与它们一起工作得很好)。

编辑:我意识到问题可能不是cantools,而是python-can包,也许can.ASCReader()不能很好地处理j1939帧并忽略它们?我要自己调查一下,但我希望有更擅长编程的人能帮忙。

import pandas as pd
import can
import cantools
import time as t
from tqdm import tqdm
import re
import os
from binascii import unhexlify

dbcs = [filename.split('.')[0] for filename in os.listdir('./dbc/') if filename.endswith('.dbc')]
files = [filename.split('.')[0] for filename in os.listdir('./asc/') if filename.endswith('.asc')]
start = t.time() 
db = cantools.database.Database()
for dbc in dbcs:
with open(f'./dbc/{dbc}.dbc', 'r') as f:
db.add_dbc(f)

f_num = 1
for fname in files:
print(f'[{f_num}/{len(files)}] Parsing data from file: {fname}')    
log=can.ASCReader(f'./asc/{fname}.asc')
entries = []
all_msgs =[]

message = {'Time [s]': ''}
database = list(db._frame_id_to_message.keys())
print(database)
lines = sum(1 for line in open(f'./asc/{fname}.asc'))
msgs = iter(log)
try:
for msg, i in zip(msgs, tqdm(range(lines))):
msg = re.split("\s+", str(msg))
timestamp = round(float(msg[1]), 0)
msg_id = int(msg[3], 16)
try:
data = unhexlify(''.join(msg[7:15]))
except:
continue
if msg_id in database:
if timestamp != message['Time [s]']:
entries.append(message.copy())
message.update({'Time [s]': timestamp})
message.update(db.decode_message(msg_id, data))
except ValueError:
print('ValueError')

df = pd.DataFrame(entries[1:])
duration = t.time() - start
df.to_csv(f'./csv/{fname}.csv', index=False)
print(f'DONE IN {int(round(duration, 2)//60)}min{round(duration % 60, 2)}s!n{len(df.columns)} signals extracted!')
f_num += 1

类可以。ASCReader(文件,基地="六角")基地:can.io.generic.BaseIOHandler来自ASC日志文件的CAN消息的迭代器。元数据(注释,总线统计,J1939 Transport协议消息)被忽略。可能会回答你的问题…

最新更新