利用Python进行数据分析–CAN报文数据解析,生成折线图
在汽车开发工作过程中,需要经常对总线报文进行解析,并生成曲线做数据分析,定位以及对比。本文以车速报文为例,在不依托vector及其他CAN分析上位机的条件下,基于python工具对CAN报文进行解析,最终绘制信号折线图。
代码如下:
# *-* coding:utf8 *-*
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
# 函数作用:将ASC数据中的时间戳和车速信号原始值做筛选后,写入新的txt文件中
def SellectSignal_to_TxtFile(us_file_path, ID):
# 导入asc数据
data = open(us_file_path, "r")
readlines = data.readlines()
for line in readlines:
if line.__contains__(ID):
message = np.array(line)
with open("./Speed.txt", "a") as speed:
speed.write(str(message))
data.close()
# 函数作用:将新的txt文件中数据进行处理,拼接,保留时间戳和车速hex值
def ReadSignal(us_file_path):
# 导入txt文件
rawData = pd.read_csv(us_file_path, header=None)
# 拆分字符串
data = rawData[0].str.split(' ', expand=True)
# 提取指定列--时间,车速
data = pd.DataFrame(data, columns=[0, 10, 11])
# 修改列名--时间,速度低位,速度高位
data.columns =['time', 'speed_l', 'speed_h']
# 将两列速度列表拼接为speed原始值
data['speed'] = data['speed_h'] + data['speed_l']
# 保留时间和速度信息
data = pd.DataFrame(data, columns=['time', 'speed'])
# 将速度字符串数据转化为10进制数据
data['speed'] = data['speed'].apply(lambda x: int(x, 16))
# 将时间列表数据类型由object --> float64
data['time'] = pd.to_numeric(data['time'], errors='coerce')
return data
# 函数作用:根据offset和factor,计算车速物理值
def CalculatePhyValue(data, offset, factor):
# 求速度物理值
data['speed'] = (data['speed'] * factor) - offset
# 保留两位小数
# data['speed'] = data['speed'].apply(lambda x: format(x, '.2'))
# data['time'] = data['time'].apply(lambda x: format(x, '.2'))
pd.set_option('display.float_format', lambda x: '%.2f' % x)
return data
# 根据采样周期设置采样率,适当的步进长度显示报文的实际值与时间关系折线图
def plotFigure(data, CycleTimer):
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 根据报文周期取步长
step = int((1/CycleTimer) * 1000)
# 设置x和y,并取步长
x = data['time'][::step]
y = data['speed'][::step]
# 设置图形大小
plt.figure(figsize=(12, 6), dpi=80)
# 绘图
plt.plot(x, y, color='red') # 注意:需要添加图例才能显示label
# 设置x轴刻度
_xtick_labels = range(int(len(x)))[::3]
plt.xticks(x[::3], _xtick_labels, rotation=45)
# 添加描述信息
plt.xlabel("时间 单位(s)", fontsize=12)
plt.ylabel("车速 单位(km/h)", fontsize=12)
plt.title("车速与时间关系折线图", fontsize=20)
# 绘制网格
plt.grid(alpha=0.4, linestyle='-.') # 设置网格的透明度
# # 添加图例
# plt.legend(loc="upper left") # 通过查看legend方法源码修改图例位置
# 保存图片
plt.savefig("./Speed.png")
# 展示图像
plt.show()
# 主函数
if __name__ == '__main__':
# 原始数据路径/数据名,需要筛选的报文ID
SellectSignal_to_TxtFile("./left_can_alarm.asc", '11a')
# 筛选后的数据写入txt文件
speed = ReadSignal("./Speed.txt")
# 输入报文offset, factor
CalculatePhyValue(speed, 0, 0.001625) # 设定CAN数据的offset, factor信息
# 输入报文周期(ms)
plotFigure(speed, 5) # 报文周期5ms
数据筛选后效果
绘图效果:
以上数据和作图仅供参考,可在评论区交流!