如何用asammdf的extract_bus_logging解码长度超8的CAN/J1939数据?
问题解决:asammdf无法解码51字节GNSS长帧
可能原因与对应解决方案
1. 总线类型配置错误
你当前代码指定的总线类型是CAN,但该长帧属于J1939类型。asammdf需要匹配正确的总线类型才能识别J1939的多帧传输协议并完成拼接解码。
修改代码中的总线类型为J1939:
from asammdf import MDF with MDF(path_to_mdf_file) as mdf: # 将总线类型从"CAN"改为"J1939" db = {"J1939": [("GNSS.dbc", 7)]} extracted_mdf = mdf.extract_bus_logging(database_files=db)
2. 未启用CAN FD支持
如果该长帧是CAN FD格式(支持超过8字节的单帧数据),需要在解码时显式开启CAN FD支持:
from asammdf import MDF with MDF(path_to_mdf_file) as mdf: db = {"CAN": [("GNSS.dbc", 7)]} # 添加fd=True参数启用CAN FD解析 extracted_mdf = mdf.extract_bus_logging(database_files=db, fd=True)
3. 手动拼接分帧并解码
如果自动拼接失效,可以手动提取分帧数据,拼接后用底层的cantools库解码:
import cantools from asammdf import MDF # 加载DBC文件并获取目标帧定义 dbc = cantools.database.load_file("GNSS.dbc") gnss_frame = dbc.get_message_by_name("GNSS_PositionData") with MDF(path_to_mdf_file) as mdf: # 遍历总线数据,收集目标帧的所有分帧 frame_fragments = [] for raw_frame in mdf.iter_bus_logging(bus_type="J1939", source=7): # 通过帧ID或名称匹配目标帧 if raw_frame.id == gnss_frame.frame_id: frame_fragments.append(raw_frame.data) # 拼接成完整的51字节数据并解码 full_payload = b''.join(frame_fragments) decoded_values = gnss_frame.decode(full_payload) # 输出经纬度物理值 print(f"经度: {decoded_values['GNSS_Longitude']}") print(f"纬度: {decoded_values['GNSS_Latitude']}")
4. 升级asammdf至最新版本
旧版本的asammdf对J1939长帧或CAN FD的支持可能存在缺陷,执行以下命令升级:
pip install --upgrade asammdf
内容的提问来源于stack exchange,提问作者VictorGardi
相关产品推荐
相关产品推荐

