读取传感器数据并通过画图实时动态展示数据变化

需求:读取传感器数据并通过画图实时展示出来
我用的是python2.7,传感器是Yost Labs的惯性导航传感器:3 space sensor Data Loging,读取传感器数据用的是Threespace包,因为threespace只能在python2.x下面使用(虽然threespace的文档中有说也支持python3.x,但是我试过,3.x版本是不行的),所以我使用了python2.7.
整个代码写下来,就是在实时展示数据的实时性和读取数据不丢包之间取得平衡。
读数据:from threespace import threespace_api as tsapi
imu = tsapi.TSDLSensor(com_port=‘COM3’, baudrate=115200) //创建IMU对象
imu.startStreaming() //开启流读数据,通过流读数据相当于是传感器每隔一定时间会自动传送数据过来,效率高于问答模式
imu.setStreamingSlots(slot0=‘getTaredOrientationAsQuaternion’, slot1=‘null’,slot2=‘null’, slot3=‘null’, slot4=‘null’, slot5=‘null’, slot6=‘null’, slot7=‘null’)
//设置你想要读取的数据,具体函数介绍可以通过传感器的用户使用手册了解
while True:
data.append(imu.getStreamingBatch(timestamp=False))
time.sleep(0.1) //每隔0.1秒去拿数据,并保存在全局数组变量data中
展示数据
展示数据方法,首先用的是matplotlib中的plot方法,且是单线程,效果见下图:

存在问题:
程序为单线程,因为是用matplotlib实现的动态图,必须要有plt.pause(time)单位为s,才能实现数据图动态刷新,才会有图中的动态效果图。但是plt.pause()比较耗时,又因为是单线程,就导致读数据时存在丢包现象,具体表现为传感器的数据缺少变化的过程,比如当传感器运动时,图中曲线应该有一个渐变的过程,但现在渐变过程不明显,几乎直接达到峰值。所以可以知道,这个代码存在丢包现象。
改进方案一:
引进多线程和改用python的其他有效实现动态图的方法
一:改用多线程
思路:一个线程用来读数据,另一个线程用来实时动态展示数据
import threading
t1 = threading.Thread(target=getData)
t1.start()
t2 = threading.Thread(target=main)
t2.start()
存在问题:查找资料发现,python的多线程实际是伪线程,因为有GIL的存在,python实际同时只能有一个线程运行。具体介绍可以参考:https://www.cnblogs.com/SuKiWX/p/8804974.html。那么文中也提到,python一般会用多进程来代替多线程,但是多进程的引进也会带来很多不便,因为进程间是不共享数据的,所以我们得通过共享内存、队列或者管道来处理共享数据,这在一定程度上会使程序的实现存在很大不便。
经过查资料,发现python中matplotlib中的animation模块和pyqt5可以实现快速动态绘图功能,绘图效率要高于matplotlib的plot.pause().下面分别介绍这2种方法及在实现时遇到的问题。
matplotlib中的animation模块:
读取传感器数据并通过画图实时动态展示数据变化_第1张图片
可以看到该图有很好的实时性,那么也意味着读取数据比较准确。以下是关于FuncAnimation的官方文档,可以了解一下:https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation。但是,用animation的FuncAnimation方法来画动态图有一些局限性,比如它必须设置XY轴的坐标范围,否则不能画出曲线图,而我们需要实时展示传感器数据,并不能确定x轴范围,如果设置过大,观察曲线变化则会不明显,如果设置太小,超出x轴范围,曲线将不会再显示。而且在一个图里,只能展示一条曲线。所以该方法也不能解决问题。
pyqt5可以实现快速动态绘图功能

由图可以看到,基本上能实现实时动态展示,数据也比较完整。
本段代码是双线程+pyqt5实现的
总结:基本实现需求,但上面的程序在刚开始时,数据曲线能做到实时,但是运行一段时间后,展示曲线的程序耗时逐渐增加,就会有一定的延时。所以最好是用c++来实现,c++的多线程+MFC的Hight-Speed Charting,可以实现实时动态展示。我在查找资料的时候,发现也有人遇到和我一样的问题,他们的解决方法就是用c++或c#来实现展示数据。

你可能感兴趣的:(读取传感器数据并通过画图实时动态展示数据变化)