gpt4 book ai didi

Python实时绘制ROS数据

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:28 25 4
gpt4 key购买 nike

我正在尝试使用 python 绘制进入计算机的实时数据。数据来自 ROS 主题,我使用“rospy”订阅该主题以获取数据。这是我写的代码

import rospy
from sensor_msgs.msg import ChannelFloat32
import matplotlib.pyplot as plt

N = 200
i = 0

topic = "chatter"

x = range(N)
lmotor = [0]*N
rmotor = [0]*N

plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim([0,N])
ax.set_ylim([-1,1])

line1, = ax.plot(lmotor, 'r-')
line2, = ax.plot(rmotor, 'g')

def plotThrottle(data):
global x, lmotor, rmotor, i

[x[i],lmotor[i],rmotor[i], tmp] = data

line1.set_ydata(lmotor)
line1.set_xdata(x)
line2.set_ydata(rmotor)
line2.set_xdata(x)

fig.canvas.draw()

def callBack(packet):
data = list(packet.values)
plotThrottle(data)


def listner():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber(topic, ChannelFloat32, callBack)
rospy.spin()

if __name__ == '__main__':
listner()

我的问题是,当我使用从 rostopic 获得的数据调用 plotThrottle() 时,出现以下错误。

[ERROR]
[WallTime: 1454388985.317080] bad callback: <function callBack at 0x7f13d98ba6e0>
Traceback (most recent call last):
File "/opt/ros/indigo/lib/python2.7/dist-packages/rospy/topics.py", line 720, in _invoke_callback
cb(msg)
File "dummy2.py", line 41, in callBack
plotThrottle(data)
File "dummy2.py", line 37, in plotThrottle
fig.canvas.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 349, in draw
tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/tkagg.py", line 13, in blit
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
RuntimeError: main thread is not in main loop

但是,如果我使用相同的函数并传递代码中生成的一些数据(一些随机数据),绘图就可以正常工作。我绝对是 python 的初学者。我搜索了这个错误,它说这是因为一些线程问题。但我不明白如何修复这段代码。如果有人可以解释问题并帮助修复此代码,我将不胜感激。

最佳答案

这里有两个线程在运行,rospy.spin() 和 top.mainloop()(来自 Tkinter,在您的例子中是 matplotlib 的后端)。

来自 this answer :

The problems stem from the fact that the _tkinter module attempts togain control of the main thread via a polling technique whenprocessing calls from other threads.

Your Tkinter code in Thread-1 is trying to peek into the main threadto find the main loop, and it's not there.

来自 this answer :

If there is another blocking call that keeps your program running,there is no need to call rospy.spin(). Unlike in C++ where spin() isneeded to process all the threads, in python all it does is block.

因此您可以使用 plt.show(block=True) 来防止您的程序关闭,在这种情况下您将使用 Tkinter mainloop,重绘 Canvas 没有问题。

监听函数应该是这样的:

    def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber(topic, ChannelFloat32, callBack)
# rospy.spin()
plt.show(block=True)

无论如何,这似乎是其他替代方案的一种解决方法,请再次查看 this answer或者简单地使用单独的节点进行绘图,即 ros 建议的工具,如 rqt_graph .

关于Python实时绘制ROS数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35145555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com