【问题标题】:Python Tkinter canvas plotting stream of serial data (Math problems)Python Tkinter 画布绘制串行数据流(数学问题)
【发布时间】:2020-05-06 06:33:50
【问题描述】:

我正在尝试可视化来自来回旋转 180 度的声纳传感器的数据。

在读取传感器数据并使用正则表达式对其进行处理后,变量“dist”包含一个表示距离(以厘米为单位)的浮点数。 变量“angl”包含一个介于 0 和 180 之间的整数,表示旋转状态。

到目前为止一切都很好,但我无法完全理解如何使用 Tkinter 在画布上表示它。我一直在尝试各种事情,但我已经为这个线程清理了一点代码。

目标是以画布上的点 (1000, 1000) 为中心,并将绿色圆圈移动到相应缩放的 (x, y) 坐标。

这是来自终端的示例读数

角度:174
距离:208.11
X:-72.99856014995218
Y:-194.88710146142
角度:175
距离:161.67
X:96.75694368800949
Y:-129.51943000243384
角度:176
距离:100.88
X:100.62718668260311
Y: 7.13748557578522
角度:177
距离:43.61
X:20.907170903220738
Y: 38.27169064496002

import serial
import re
import math
import tkinter
import time

w_width = 2000
w_height = 1000


def create_animation_window():
    window = tkinter.Tk()
    window.title("WALL-E SONAR")
    window.geometry(f'{w_width}x{w_height}')
    return window

def create_animation_canvas(window):
    canvas = tkinter.Canvas(window)
    canvas.configure(bg="black")
    canvas.pack(fill="both", expand=True)
    return canvas


ser = serial.Serial('/dev/ttyACM0', 9600)
strPort = '/dev/ttyACM0'
def animate_sonar(window, canvas):
    intercept = canvas.create_oval(0,0,20,20, fill="green")

    while True:
        rawData = ser.readline() # rawData input example: b'D:140.98A:57\r\n
        decodedData = rawData.decode("utf-8")
        line = re.search(r'D:(.*)A:(.*)\r\n', decodedData)

        if line:
            dist = float(line.group(1))
            angl = int(line.group(2))


            print(f"ANGLE:  {angl}")
            print(f"DISTANCE: {dist}")
            x = dist * math.cos(angl)
            y = dist * math.sin(angl)
            print(f"X:  {x}")
            print(f"Y:  {y}")

            canvas.moveto(intercept, x,y)

            window.update()



animation_window = create_animation_window()
animation_canvas = create_animation_canvas(animation_window)
animate_sonar(animation_window, animation_canvas)

【问题讨论】:

  • 'Canvas' object has no attribute 'moveto' 你有没有试过在开始制作动画之前先画一些东西
  • 什么意思?我使用 canvas.moveto() 没有问题
  • 你必须有一些我没有的东西,因为这是我在运行你的代码的控制台上遇到的错误
  • 不,没有这样的问题。让我头疼的是数学和映射值。

标签: python canvas tkinter coordinates trigonometry


【解决方案1】:

我看到的东西很少:

  • 在 sin 和 cos 中使用的角度应该是弧度
  • 您必须使用相对于画布的位置

我会这样做:

import math
import tkinter
import time

window = tkinter.Tk()
window.title("WALL-E SONAR")
window.geometry(f'2000x1000')

canvas = tkinter.Canvas(window)
canvas.configure(bg="black")
canvas.pack(fill="both", expand=True)


def animate_sonar(window, canvas):
    dist = 200
    for angl in range(180, 360):
        rad = angl * math.pi / 180
        x = dist * math.cos(rad) + 300
        y = dist * math.sin(rad) + 300

        canvas.delete("all")
        canvas.create_oval(x-10, y-10, x+10, y+10, fill="green")
        canvas.create_line(300, 300, x, y, fill="red")
        window.update()
        time.sleep(0.05)


animate_sonar(window, canvas)
window.mainloop()

如果你运行它,你应该会看到类似:

我的代码中的 300 只是用来放置一些东西,但您必须调整窗口和画布的尺寸才能将其正确放置在您想要的位置。

        rad = angl * math.pi / 180
        x = dist * math.cos(rad) + 300
        y = dist * math.sin(rad) + 300

从非常简单的事情开始,模拟数据,这将使其他人更容易复制您的代码,然后合并您的传感器。当我第一次阅读我几乎关闭页面的问题时,我的第一个想法是没有那个传感器我无法重现这个......

我还使用了canvas.delete("all") 你的canvas.moveto 给了我错误,但如果它对你完美,请以与我的示例类似的方式使用它。

希望你能走上正确的道路......

【讨论】:

  • 非常感谢您的帮助!我应该能够解决其余的问题,并且我会牢记您的建议,并在下次寻求帮助时更加详细。
  • 如果这解除了您的阻止,请不要忘记投票并接受答案
猜你喜欢
  • 2011-05-16
  • 2020-07-10
  • 2017-11-14
  • 2011-09-08
  • 2018-03-05
  • 2017-01-10
  • 2011-02-08
  • 2012-04-22
  • 1970-01-01
相关资源
最近更新 更多