软件背景

做汽车开发工作的应该大部分都知道 BLF (Binary Logging Format)文件。它是由Vector公司定义的用于记录总线数据的一种文件格式。在汽车开发的过程中,可能我们要录一段时间很长的数据,而CAN总线上有些数据是每隔10ms发送一次,有些是隔100ms,有些是隔1S发送一次的。而当我们要回放分析数据的时候,由于时间太长,导致电脑卡顿,导致需要很长的时间回放的数据。因此产生了一种想法:有时候我们并不需要特别精确的数据。而在分析数据的时候,如果把10ms一次的数据变为100ms一次。将会大的降低电脑的卡顿。因此希望能够使用软件处理一下BLF文件,在减少其中数据的同时,不会特别影响数据的内容。

这里我选用的编程语言为Python。选择它的理由很简单。因为它有丰富的库可以调用,因此我们并不需要特别深入的到底层。我的目的是能够快速的做出我达到功能需求的软件。

编程环境的搭建

首先给大家介绍一下我的编程环境:Win10+anaconda。安装anaconda后,可以使用jupyter在网页上进行编程。

在网上搜罗一番之后,我找到了能够满足我使用要求的库了:python-can。这个库的功能是驱动各种CAN盒,同时还带了解析记录文件的程序。安装指令为:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-can

需要注意的是库安装的位置为:盘符:\Anaconda\Lib\site-packages 。意思是当我们import的时候,就是从这里找到的python库。在后续的编程的时候,也需要去这个文件夹中找到源码,看库的使用方法。

在安装好这个库之后,我们就可以使用python测试是否正常工作,在python中输入以下指令运行,如果没有报错表示安装成功:

import can

在完成以上的工作之后,就开始自己正式的工作了。编程很多时候都是参考网上的例子,然后按照自己的需求在其基础上进行修改。下面我介绍一下自己在做这个工具的小想法:其核心功能是按照用户的需求降低文件内的CAN报文的帧数。假设用户所需的采样频率为n。

采样的计算方法

最开始的方案是读取CAN报文上的所有帧数,然后在读取帧的过程中,将这个数对n进行取模。判断余数为1时,便记录该帧报文到新的文件中去。但是实际效果不是很好。因为有的帧发送比较频繁,有的帧发送的比较慢。导致有的帧在整个采样周期中都没有被采集到,造成数据丢失严重。以下是将n设置为10时的程序。使用CANoe可以观察到输入文件与输出文件对比。发送频率比较低的报文丢失很多数据。复制以下代码,修改路径后可转换文件

from can.io import BLFWriter, BLFReader
logfile = r"输入文件.blf"
filename_out = r"输出文件.blf"
logger=BLFWriter(filename_out)
i = 0
with can.BLFReader(logfile) as reader:for msg in reader:i += 1if i % 10 == 1:logger.on_message_received(msg)
logger.stop()
print(i)

因此想到的新方法是首先要对CAN报文的数据进行分类。分类方法为按帧报文进行分类(在后续的开发中,发现还需按照channel进行分类)。然后统计每一类帧的出现的次数。然后用这个次数对n进行取模。判断余数为1后,将该帧记录到新的文件中。这样所有的报文都能按照n周期进行采样。也就不会丢失太多数据了。

from can.io import BLFWriter, BLFReader
logfile = r"输入文件.blf"
filename_out = r"输出文件.blf"
logger=BLFWriter(filename_out)
canid = {}
with can.BLFReader(logfile) as reader:for msg in reader:if msg.arbitration_id not in canid:canid[msg.arbitration_id] = 1else:canid[msg.arbitration_id] = canid[msg.arbitration_id] + 1if canid[msg.arbitration_id] % 10 == 1:logger.on_message_received(msg)logger.stop()
print(canid)

上面的那个程序还不是很完美,因为它对所有的报文都进行了一个采样。而大家的需求是:对于发送周期很短的报文的采样能够松一点,对于发送周期比较长的报文采样能够密一点。也就是能够手动调节每帧的采样周期 。但是这个功能是需要与软件界面进行配合,因此在这里不提供代码了。

GUI的开发

我的电脑安装好了Python。自然可以很方便的运行上面的程序了。当然也不是特别方便,因为它的路径是要手动输入进去的,复制粘贴路径的功夫,也是非常麻烦的。因此接下来的目标是为该软件写一个界面。并且打包成exe软件,当我同事想用的时候,也能方便快捷的打开使用。在网上搜索一番后,我选择使用Tkinter作为这软件的GUI库。选择的理由也很简单。因为自己的软件十分简单,不希望用其他库后,开发打包后的软件太大了。

对于GUI开发,其实就是几个按钮罢了。在这里我的界面的主要难度在于Tkinter中,能够为每类帧设置其采样周期。这里我使用了Treeview这个控件。但是这个控件并没有提供格子修改功能。因此需要我们自己写一个函数对其格子进行修改。

from tkinter import *
from tkinter import ttk
from tkinter.simpledialog import askinteger
root= Tk() root.title("BLF")
frame= Frame(root)frame.pack(padx=20,pady=20) #set areadef set_cell_value(event): # 双击进入编辑状态for item in tree.selection():#item = I001item_text = tree.item(item, "values")#print(item_text[0:2])  # 输出所选行的值column= tree.identify_column(event.x)# 列row = tree.identify_row(event.y)  # 行var_int = askinteger(title = "请输入一个整数",prompt = "整型变量x:")if int(var_int) > 0:tree.set(item, column=column, value=var_int)else:pass# 定义列的名称
columns = ("CHANNEL","ID", "OLD_NUM", "MULT","NEW_NUM")
tree = ttk.Treeview(frame, show = "headings", columns = columns, selectmode = BROWSE)
# 设置表格文字居中
tree.column("CHANNEL", anchor = "center")
tree.column("ID", anchor = "center")
tree.column("OLD_NUM", anchor = "center")
tree.column("MULT", anchor = "center")
tree.column("NEW_NUM", anchor = "center")
# 设置表格头部标题
tree.heading("CHANNEL", text = "通道数")
tree.heading("ID", text = "CAN ID")
tree.heading("OLD_NUM", text = "旧文件帧数")
tree.heading("MULT", text = "采样倍率")
tree.heading("NEW_NUM", text = "新文件帧数")
tree.grid(row=3,column=0,padx=35,pady=5,columnspan=2)
tree.bind('<Double-1>', set_cell_value) # 双击左键进入编辑tree.insert('', 1, values = (0,0,0,0,0))
root.mainloop()

使用Pyintaller打包软件

界面的编写是一个很机械重复的过程。勉勉强强做出来比较合适的界面后。就要对软件进行打包了。这时候该如何打包程序呢。百度了一番打包程序之后,发现程序打包还是一门很深的水。这也是我写这篇文章的主要目的了。也是我对python理解最深的地方了。最开始我使用的是pyinstaller进行打包。安装的指令为:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller

使用以下指令就能打包出想要的软件,并且能够正常运行

pyinstaller -Fw main.py

但是有个问题就是,打包的软件由于导入了其他软件库。导致软件有十五六兆的大小。这是最方便的也是最慢的软件。因为它使用的是Cpython。运行效率太低了。打开软件就需要10秒左右(打包为单个文件,当打包为多个文件的时候,启动为2S)。然后解析一个20Mb的文件需要30秒左右。对于这种使用场景下已经够用了。因为对时间并没有太高的要求。但是当文件有200Mb的时候,可以有预见性的认为时间需要五分钟,意味着速度会变得特别的长。接下来无聊我便专门的研究了一下python的数据打包。

使用Nuitka打包软件

参考知乎上推荐的Nuitka打包。安装起来比较麻烦,需要安装C语言编译器等等。其原理应该是把python转化为C语言,然后通过C语言编译成EXE文件。其打包还是非常有意思的。因为用Nuitka打包出来的软件不是多个文件,因此其启动速度还是非常快的。大概一两秒就能加载好了。然后解析的时间也要比pyinstaller打包的快一点点。可以说是有所提升,但是二十秒的时间也是有点慢了。我的期望以为打包出来的文件是C编译出来的,按道理应该是非常快的。距离我的期望还是有点距离。

使用pypy运行软件

可能是自己的程序优化不到位,但是我也不想去修改自己的程序提高程序的运行速度。一方面是因为改程序太麻烦了,另一方面也是因为不知道从何开始下手。在搜索一番资料后,发现可以pypy这个解释器的运行速度非常的强大,而我的库其实都是纯py文件的,因此也不需要做太多的设置。我甚至都不用去给它配置c语言编译器就能运行我的程序。在把自己的程序和库导入到pypy中后,运行速度打开速度非常的快,而且解析blf文件也是非常的快的。当200Mb的文件也就在30秒内能够解析完成。完全能够满足大文件的需求。

用Python做小工具——精简blf文件相关推荐

  1. 【Python实用小工具】PDF文件快速拆分

    """ 需要先安装:pip/pip3 install PyPDF2==3.0.0python3版本:3.10.6PyPDF2版本:PyPDF2-3.0.0执行命令:pyt ...

  2. 12岁的少年教你用Python做小游戏

    首页 资讯 文章 频道 资源 小组 相亲 登录 注册 首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 -首页最新文章经典回顾开发- Web前端- Py ...

  3. 用Python编写小工具下载OSM路网数据

    文章来源于Python大数据分析,作者费弗里 本文对应脚本已上传至Github仓库: https://github.com/CNFeffery/DataScienceStudyNotes[1] 1 简 ...

  4. python 处理数据小工具_用Python这个小工具,一次性把论文作图与数据处理全部搞定!...

    原标题:用Python这个小工具,一次性把论文作图与数据处理全部搞定! 一入科研深似海-- 随着大学纷纷开学,"防脱发用生姜还是黑芝麻?", 研究僧们又开始为自己所剩无几的头发发愁 ...

  5. Python解析CANoe录制的blf文件asc文件通用方法

    Python解析CANoe录制的blf文件&asc文件通用方法 一.背景     由于很多时候我们在录制日志文件的时候更愿意选择BLF文件,至少目前我见到的很多公司都是使用的BLF文件来作为最 ...

  6. 有关Python的小工具 - picture

    有关Python的小工具 - picture 读取图片 通过cv2.imread读取图片 通过cv2.imread读取比特流 通过Image.open读取图片 通过io.BytesIO读取比特流 保存 ...

  7. Java 文件传输小工具,网络传输文件,内网传输

    文件传输小工具,网络传输文件,内网传输 换了一台电脑,想把一台电脑的资料放到另一太电脑上,由于没有太大的U盘就动手用Java写了个小工具.有需要的朋友下载使用! 运行环境 运行环境需要安装JDK,并配 ...

  8. 将py文件转换成html,(2条消息)自制 Python小工具 将markdown文件转换成Html文件

    今天看到了一个Python库,名为markdown.瞬间就给了我一个灵感,那就是制作一个将markdown文件转换成html文件的小工具. 我的实验环境操作系统: Windows 7 64位 旗舰版 ...

  9. python 上传excel_简历批量合并Python+VBA小工具

    每年的校招,才是对招聘系统体验的真正大考. 如何帮HR快速标记.筛选成千上万的简历? 如何快速应答同学们的问询? 群面如何签到?如何自动分组? 怎样让候选人清楚面试流程与候场时间? 如何让面试官方便地 ...

最新文章

  1. TEASOFT 关于远程WEICHAT命令
  2. 台湾高校首创气体灭火数位实境教育馆
  3. Rocket - tilelink - FIFOFixer
  4. docker重启mysql数据丢失_mysql如何确保数据不丢失的?我们借鉴这种设计思想实现热点账户高并发
  5. 布局 线宽 间距 走线 泪滴 过孔 【快速提升PCB板Layout质量的6个细节】
  6. 微信开发者工具 wxmi修改模版颜色_网站建设公司讲解:微信小程序的开发者工具界面...
  7. 判断输入的IP地址是否合法
  8. 查看Jar包中Class类的编译环境jdk版本
  9. 【李宏毅2020 ML/DL】P76 Generative Adversarial Network | Unsupervised Conditional Generation
  10. 入门嵌入式HTML/CSS/脚本引擎 sciter(问题篇)
  11. 阿帕奇服务器配置站点,Apache的基本服务器配置
  12. retina 显示屏详细理解
  13. word中如何将所有同一级标题统一格式
  14. 【短视频运营】查找对标账号 ( 关键词搜索 | 第三方工具查找 | 对标账号学习 | 视频文案 | #话题 | 评论内容 | 历史视频 )
  15. spark(scala) shell 里面输入多行代码
  16. [JAVA冷知识]动态加载不适合数组类?那如何动态加载一个数组类?
  17. Markdown 编辑器设置字体大小颜色
  18. [python爬虫]喜马拉雅音乐
  19. Rman配置DataGuard using Backup-based duplication with a target connection with filesystem
  20. get a foot in the door 迈出第一步

热门文章

  1. java财务管理项目_基于jsp的个人财务管理-JavaEE实现个人财务管理 - java项目源码...
  2. 三轮全向底盘实现SLAM导航功能
  3. 177m²美式轻奢,简约时髦的色调,又不失高雅范儿
  4. int main(void)和int main()的区别
  5. ZABBIX监控DM数据库
  6. Java static与final使用陷阱
  7. 有哪些适合程序员的兼职?
  8. 找出所有不是这两个数组共有的元素
  9. Win10企业版任务栏上搜索功能失效的解决方法
  10. UCloud“安全屋”数据流通平台:隐私计算市场的“隐形冠军”