簡體   English   中英

如何使用 cantools 從.asc 文件中正確讀取 J1939 消息?

[英]How to properly read J1939 messages from .asc file with cantools?

我正在嘗試創建一個 CAN 日志轉換器,從 .asc 文件到 .csv 文件(以人類可讀的形式)。 我有點成功。 我的代碼幾乎適用於除 j1939.dbc 之外的任何數據庫。

問題是,如果我打印出從 dbc 文件讀取的消息,我可以看到來自 j1939.dbc 的消息被讀入數據庫。 但它無法在已處理的日志文件中找到任何這些消息。 同時,我可以毫無問題地使用 Vector CANalyzer 讀取相同的文件。

我想知道為什么會發生這種情況以及為什么它只影響 j1939.dbc 而不會影響其他。

我懷疑我轉換這些消息的方式可能是錯誤的,因為它永遠不會通過if msg_id in database:行(如上所述,這些消息肯定存在,因為 Vector CANalyzer 可以很好地與它們配合使用)。

編輯:我意識到問題可能不是 cantools,而是 python-can package,也許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

class can.ASCReader(file, base='hex') 基礎:can.io.generic.BaseIOHandler 來自 ASC 日志文件的 CAN 消息迭代器。 元數據(注釋、總線統計信息、 J1939 傳輸協議消息)被忽略。 可能會回答你的問題...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM