使用DBC文件解码BLF格式CAN日志时出现KeyError的解决咨询
CAN日志解码KeyError问题解决
问题原因
- DBC文件中没有ID为150889227的CAN消息定义,cantools找不到对应解码规则,触发KeyError。
- 可能存在CAN帧格式不匹配:日志中的帧是扩展帧/标准帧,但DBC里对应ID的帧类型定义相反,导致ID匹配失败。
解决步骤
1. 核对DBC文件的消息定义
先导出DBC里所有已定义的消息ID,确认目标ID是否存在:
import cantools db = cantools.database.load_file("你的dbc文件路径.dbc") # 遍历打印所有消息的ID、名称和帧类型 for msg in db.messages: print(f"ID: {msg.frame_id}, 名称: {msg.name}, 扩展帧: {msg.is_extended_frame}")
如果150889227不在输出结果中,说明:
- 要么用错了DBC文件,需要更换对应日志的正确DBC;
- 要么DBC文件缺失该ID的定义,需要补充对应的消息信号定义到DBC中。
2. 检查帧格式匹配情况
在原代码中添加帧类型打印,确认日志中目标ID的帧格式:
with can.BLFReader(blf_file) as can_log: for msg in can_log: print(f"ID: {msg.arbitration_id}, 扩展帧: {msg.is_extended_id}") # ... 其他代码
对比DBC中消息的is_extended_frame字段,如果两者不匹配:
- 可以修正DBC文件中对应消息的帧类型;
- 或者在解码时调整ID格式(比如提取标准帧ID部分,仅适用于扩展帧转标准帧的场景):
adjusted_id = msg.arbitration_id & 0x7FF # 提取标准帧ID(仅当确认是标准帧被误识别为扩展帧时使用) try: decoded = db.decode_message(adjusted_id, msg.data) decoded_msg.append(decoded) except KeyError: print(f"未找到ID {msg.arbitration_id}的解码规则")
3. 添加异常处理避免程序崩溃
即使存在未定义的CAN ID,也可以让程序继续运行,跳过无法解码的帧:
修改原代码的循环逻辑:
with can.BLFReader(blf_file) as can_log: for msg in can_log: print(msg.arbitration_id) print(msg.data) try: decoded_msg.append(db.decode_message(msg.arbitration_id, msg.data)) except KeyError: print(f"警告:DBC无ID {msg.arbitration_id}的定义,跳过该帧")
内容的提问来源于stack exchange,提问作者Masoom Kumar
相关产品推荐
相关产品推荐

