利用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

数据筛选后效果 

绘图效果:

        以上数据和作图仅供参考,可在评论区交流! 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>