简体   繁体   English

使用Python进行粒子过滤的Gui

[英]Gui for Particlefilter with Python

I'm trying to implement a particle filter and I chose python for it because I kinda like python. 我正在尝试实现粒子过滤器,因此选择了python,因为我有点喜欢python。 By now i have written my gui using tkinter and python 3.4. 现在,我已经使用tkinter和python 3.4编写了我的GUI。

I use the tkinter.canvas object to display a map (png image loaded with PIL) and then i create dots for each particle like: 我使用tkinter.canvas对象显示地图(已加载PIL的png图像),然后为每个粒子创建点,例如:

dot = canvas.create_oval(x, y, x + 1, y + 1) 点= canvas.create_oval(x,y,x + 1,y + 1)

When the robot moves I calculate the new position of each particle with the control command of the robot, the particles position and the particles alignment. 当机器人移动时,我会根据机器人的控制命令来计算每个粒子的新位置,粒子位置和粒子对齐方式。 To move the particle tkinter.canvas has two methods: 移动tkinter.canvas粒子有两种方法:

canvas.move() canvas.move()
canvas.coords() canvas.coords()

But both methods seem to update the gui immediately which is OK when there are about 100 particles but not if there are 200 - 5000 (what I actually should have in the beginning for the global localization). 但是这两种方法似乎都可以立即更新gui,这在有大约100个粒子的情况下是可以的,但如果有200-5000个则不行(对于全局本地化,我实际上应该有什么)。 So my problem is the performance of the gui. 所以我的问题是gui的性能。

So my actual question is: Is there a way in tkinter to stop the canvas from updating the gui, then change the gui and then update the gui again? 所以我的实际问题是:tkinter中是否有办法阻止画布更新gui,然后更改gui,然后再次更新gui? Or can you recommend me a module that is better than tkinter for my use-case? 还是可以为我推荐一个比我的用例更好的模块?

Your observation is incorrect. 您的观察不正确。 The canvas is not updated immediately. 画布不会立即更新。 The oval isn't redrawn until the event loop is able to process events. 在事件循环能够处理事件之前,椭圆不会重绘。 It is quite possible to update thousands of objects before the canvas is redrawn. 在重新绘制画布之前,很可能会更新数千个对象。 Though, the canvas isn't a high performance tool so moving thousands of objects at a high frame rate will be difficult. 但是,画布并不是一种高性能的工具,因此以高帧频移动成千上万个对象将非常困难。

If you are seeing the object being updated immediately it's likely because somewhere in your code you are either calling update , update_idletasks , or you are otherwise allowing the event loop to run. 如果您看到该对象立即被更新,则可能是因为您在代码中的某个位置调用了updateupdate_idletasks ,否则您将允许事件循环运行。

The specific answer to your question, then, is to make sure that you don't call update or update_idletasks , or let the event loop process events, until you've changed the coordinates of all of your particles. 那么,对该问题的具体答案是确保在更改所有粒子的坐标之前,不要调用updateupdate_idletasks ,或者让事件循环处理事件。

Following is a short example. 以下是一个简短的示例。 When it runs, notice that all of the particles move at once in one second intervals. 运行时,请注意所有粒子每隔一秒便一次移动。 This is because all of the calculations are done before allowing the event loop to redraw the items on the canvas. 这是因为所有计算都在允许事件循环在画布上重画项目之前完成。

import Tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.canvas = tk.Canvas(self, width=500, height=500, background="black")
        self.canvas.pack(fill="both", expand=True)

        self.particles = []
        for i in range(1000):
            x = random.randint(1, 499)
            y = random.randint(1, 499)
            particle = self.canvas.create_oval(x,y,x+4,y+4,
                                               outline="white", fill="white")
            self.particles.append(particle)

        self.animate()


    def animate(self):
        for i, particle in enumerate(self.particles):
            deltay = (2,4,8)[i%3]
            deltax = random.randint(-2,2)
            self.canvas.move(particle, deltax, deltay)

        self.after(30, self.animate)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM