python多线程处理ROS消息数据

本文介绍了一种利用Python多线程技术实时处理时间序列数据的方法。通过将数据获取、处理及绘图显示等步骤分配到不同的线程中,有效减少了数据处理的滞后性。文章详细展示了如何使用numpy和scipy库进行信号处理,并使用matplotlib实现实时绘图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近使用python处理时间序列数据,使用简单的串行输出结果会导致数据严重的滞后性,(matplotlib输出动态图片时会有短暂的pause),看了一些网上的方法,其中使用pyqt5进行输出时,由于ROS的msg送不到ndarrary中,导致数据不刷新(个人水平有限),如下使用多线程的方法,数据滞后性得到了明显的改善。

#!/usr/bin/env python
#coding=utf-8
from math import floor
from tokenize import single_quoted
import numpy as np
from numpy.fft import fft
import scipy.io
from scipy import signal
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
from mimetypes import init
import rospy
from gaitech_bci_bringup.msg import TransverseBipolar
import time
import threading

data_lenth = 500
list_o1_o2 = np.zeros(data_lenth)

def get_data(msg):
    global list_o1_o2
    
    list_o1_o2[:-1] = list_o1_o2[1:]
    list_o1_o2[-1]  = msg.o1_o2 



def data_make(msg):
    global list_o1_o2 , list1_o1_o2 , list2_o1_o2
    global t , f_oneside , X_oneside , max_indx
    
    get_data(msg)
    len_data = data_lenth
    Fs = 1000.0
    Ts = 1.0 / Fs
    t = (np.arange(0,len_data,dtype = float)) * Ts

    h_hz = 5
    wn_1 = 2*h_hz/1000.0
    b1,a1 = signal.butter(8,wn_1,'highpass')
    list1_o1_o2 = signal.filtfilt(b1 , a1 , list_o1_o2)

    l_hz = 30
    wn_2 = 2*l_hz/1000.0
    b2,a2 = signal.butter(8,wn_2,'lowpass')
    list2_o1_o2 = signal.filtfilt(b2 , a2 , list1_o1_o2)

    X = fft(list2_o1_o2)
    N = len(X)
    n = np.arange(N)
    T = N/Fs
    freq = n/T 
    n_oneside = N//2
    f_oneside = freq[:n_oneside]
    X_oneside =X[:n_oneside]/n_oneside

    max_indx = np.argmin(np.abs(X_oneside))


def figure_out(msg):
    global list_o1_o2 , list1_o1_o2 , list2_o1_o2
    global t , f_oneside , X_oneside , max_indx

    # plt.plot()
    # plt.clf()
    # plt.title('python-12hz')
    # plt.plot(f_oneside, np.abs(X_oneside))
    # plt.plot(f_oneside[max_indx],np.abs(X_oneside)[max_indx],'ks')
    # show_max='['+str(f_oneside[max_indx])+ '  ,  ' +str(np.abs(X_oneside)[max_indx])+']'
    # plt.annotate(show_max,xytext=(f_oneside[max_indx],np.abs(X_oneside)[max_indx]),xy=(f_oneside[max_indx],np.abs(X_oneside)[max_indx]))
    # plt.xlabel('Freq (Hz)')
    # plt.ylabel('FFT Amplitude |X(freq)|')
    # plt.xlim(0,30)
    # plt.pause(0.01)
    # plt.ioff()
    plt.clf()
    plt.plot(t , list_o1_o2)
    plt.pause(0.0000001)
    plt.ioff()


def Data_Callback(msg):
    # t0 = threading.Thread(target=get_data(msg))
    t1 = threading.Thread(target=data_make(msg))
    t2 = threading.Thread(target=figure_out(msg))

    # t0.start()
    t1.start()
    t2.start()






def Data_Suber():                                                
    rospy.init_node('gaitech_bci_device', anonymous=True)        
    rospy.Subscriber("/gaitech_bci_device_1/data_tb" , TransverseBipolar, Data_Callback)          
    rospy.spin() 

if __name__ == '__main__':
    Data_Suber()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值