You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取CAN .asc文件并绘制指定数据时无预期输出的问题求助

问题分析与解决方案

核心问题梳理

  • 循环逻辑完全失效:后续转换数据的for item in data循环根本不会执行,因为data初始是空列表。同时电压/电流的提取判断缩进错误,不在行数据拆分的有效块内,无法正确捕获每一行的目标数据。
  • 时间数据未收集:timestamps列表始终为空,绘图时没有有效的X轴数据。
  • 数据提取位置错误:从提供的文件片段看,你对1E3和4E3帧的十六进制数据位置判断错误,取到的不是目标电压/电流对应的字节。
  • 多余的文件操作:with open语句会自动关闭文件,后续的file.close()属于无效操作,还可能引发报错。

修正后的代码

import pandas as pd
import matplotlib.pyplot as plt

file_path = 'StartupElektroMode.asc'
timestamps = []
voltage_data = []
current_data = []

try:
    with open(file_path, 'r') as file:
        lines = file.readlines()
except FileNotFoundError:
    print(f"Error: The file '{file_path}' was not found")
    exit()

# 遍历有效行(跳过前6行表头)
for line in lines[6:]:
    parts = line.split()
    if len(parts) < 6:
        continue  # 跳过格式不完整的行
    
    timestamp = float(parts[0])
    can_id = parts[2]
    
    # 处理1E3帧:提取前两个数据字节计算电压(需根据实际协议确认字节位置)
    if can_id == '1E3' and len(parts) >= 14:  # 确保包含8个数据字节
        hex1, hex2 = parts[6], parts[7]
        voltage = (int(hex1, 16) * 256 + int(hex2, 16)) * 0.25
        timestamps.append(timestamp)
        voltage_data.append(voltage)
    # 处理4E3帧:提取对应数据字节计算电流(需根据实际协议确认字节位置)
    elif can_id == '4E3' and len(parts) >= 14:
        hex1, hex2 = parts[6], parts[7]
        current = (int(hex1, 16) * 256 + int(hex2, 16)) * 0.25
        timestamps.append(timestamp)
        current_data.append(current)

# 处理数据长度不一致的情况,填充缺失值为NaN
max_len = max(len(timestamps), len(voltage_data), len(current_data))
timestamps += [None] * (max_len - len(timestamps))
voltage_data += [None] * (max_len - len(voltage_data))
current_data += [None] * (max_len - len(current_data))

# 创建DataFrame并清理无效数据
data = {'Time': timestamps, 'Voltage': voltage_data, 'Current': current_data}
df = pd.DataFrame(data).dropna(subset=['Time'])

# 绘制子图展示数据
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))

# 电压曲线
ax1.plot(df['Time'], df['Voltage'], label='Voltage (1E3)', color='blue')
ax1.set_title('Voltage Over Time')
ax1.set_xlabel('Time (s)')
ax1.set_ylabel('Voltage (V)')
ax1.legend()
ax1.grid(True)

# 电流曲线
ax2.plot(df['Time'], df['Current'], label='Current (4E3)', color='red')
ax2.set_title('Current Over Time')
ax2.set_xlabel('Time (s)')
ax2.set_ylabel('Current (A)')
ax2.legend()
ax2.grid(True)

plt.tight_layout()
plt.show()

额外说明

  • 数据字节的提取位置需要根据实际CAN协议确认,如果你知道1E3和4E3帧中电压/电流对应的具体字节偏移,调整parts[X]的索引即可。
  • 如果电压和电流帧不是同步出现的,建议用字典按时间戳存储数据,再统一构建DataFrame,避免数据错位。

内容的提问来源于stack exchange,提问作者T3chWarri0r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:22:03