如何从Python海龟图形发送命令到EV3乐高积木?

9

针对T KINTER的编辑:

IDE是Visual Studio Code

Traceback调用在脚本下方打印

TkinterTest.py

#!/usr/bin/env python3

from tkinter import *
from tkinter import ttk
import Ev3_Motor

ev3 = Ev3_Motor.Ev3_Motor()

def calculate(*args):
    ev3.TestFunction("SUCCESSS YAHOOOOOO")
    print("command to robot >>>>")

root = Tk()
root.title("TEST TKINTER")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

ttk.Button(mainframe, text="TEST BUTTON", command=calculate).grid(column=3, row=3, sticky=W)

#ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

root.bind('<Return>', calculate)
root.mainloop()

Ev3_Motor.py

#!/usr/bin/env python3
from ev3dev.ev3 import *
import os
import sys
from time import sleep
import shutil 
import fileinput

os.system('setfont Lat15-TerminusBold14')

## FUNCTIONS ##

def __init(self):
    debug_print("Constructor Ev3")

def TestFunction(randomString):
    debug_print("Connection established: " + randomString)

TRACEBACK错误:

Starting: brickrun --directory="/home/robot/vscode-hello-python-master/Ev3" "/home/robot/vscode-hello-python-master/Ev3/TkinterTest.py"
Started.
----------
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 36, in <module>
    import _tkinter
ImportError: No module named '_tkinter'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/robot/vscode-hello-python-master/Ev3/TkinterTest.py", line 3, in <module>
    from tkinter import *
  File "/usr/lib/python3.5/tkinter/__init__.py", line 38, in <module>
    raise ImportError(str(msg) + ', please install the python3-tk package')
ImportError: No module named '_tkinter', please install the python3-tk package
----------
Exited with error code 1.

**原问题:我想做什么:**

我正在尝试创建一个程序设计,在其中使用Python中的Turtle Graphics库创建的UI程序直接通信与存在于LEGO EV3砖上的EV3 Python程序。

到目前为止:

  1. FrontEnd.py - 一个面向对象的程序,根据鼠标指针x和y以及用于绘制按钮状对象的形状感知唯一的按钮点击
  2. RobotInstruction.py - 根据函数调用转动电机的EV3程序

当我尝试让它工作时发生了什么:

似乎有依赖冲突。 就像龟和ev3不兼容。对我而言,FrontEnd.py文件似乎正在尝试加载到RobotInstruction.py文件中并最终在砖块上结束,这不是我想要的。

重要提示:

独立地,这些脚本都可以正常工作。例如,RobotInstruction.py可以接收键盘输入来操作电机。我只想从图形程序中获得“命令”

我的第一次尝试Janky Super Inefficient Workaround:

--现有代码摘录附在末尾--

使用FrontEnd.py将字符串命令写入文件,并使RobotInstruction.py不断读取该文件以获取命令,然后根据命令调用相应的函数以转动电机。

成功的部分:

可以成功从FrontEnd.py写入带有命令的文件

可以成功从同一文件中读取命令

但是

它不会实时发生。 我对Python的文件读取/写入并不是非常熟悉,所以很可能我在做一些尴尬的事情...

我的问题:

我正在尝试的东西是否可行? 您可以点击由turtle graphics创建的按钮以向ev3机器人发送命令吗?如果可以,我应该如何形成连接两个单独的脚本?

代码“摘录”

FrontEnd.py

def TurnTier(ButtonName):
   if ButtonName == "TurnT1":
      fileName = open("file1.txt", "w+")
      fileName.write("TurnT1")
      fileName.close()

RobotInstruction.py

while (not blnTierFound):
   # file1.txt is written to from FrontEnd.py through a button click
   # We are writing "TurnT1" into file1.txt
   # Here we are opening the same file for reading to check for changes

   fileName = open("file1.txt", "r+")
   ButtonName = fileName.read()
   fileName.close()

   ButtonName = str(ButtonName)
   if (ButtonName == "TurnT1"):
        blnTierFound = True
        strMotor = 'A'

   # In the main part of the code 
   motorLeft = fncStartMotor(strMotor)

1
如果您在同一设备上运行这两个脚本,为什么不包含第三个脚本,以编程方式将这些命令从您的UI传递到RobotInstruction.py?在这里读写文件并不是正确的工具... - Henry Prickett-Morgan
1
使用海龟绘图有特定的要求吗?我的意思是,我相信还有其他库可以完成这项工作。例如,使用 tkinter 库可以设计带有按钮的桌面应用程序。每个按钮都可以调用 RobotInstruction.py 中的相应函数。我也同意上面的评论,对于这种用例,您不需要文件读写。 - amanb
1
你也可以查看python-ev3dev库。 - amanb
1
你可以使用pip安装ev3模块。确保库和其依赖项已安装。如果您能够分享您尝试过的代码片段以及Trace back错误,那么调试和解决此问题将更容易。 - amanb
1
你需要安装python3-tk,运行sudo apt-get install python3-tk,然后再试一次。来源:https://askubuntu.com/questions/815874/importerror-no-named-tkinter-please-install-the-python3-tk-package - amanb
显示剩余6条评论
1个回答

3

重要信息:

通常情况下,EV3使用乐高的基于块的编程语言进行编程。默认操作系统也是使用这种语言编写的。如果想要使用像Python这样的基于文本的编程语言与机器人进行通信,则必须安装一个名为ev3dev的新操作系统,该操作系统是基于Linux的,并使用双引导SD卡。完整的设置说明可在此处找到。在运行以下脚本之前,这个设置是必需的。

通过评论部分的讨论,我已经为您提供了可能适用的解决方案。这利用了问题中的Tkinter脚本(已经经过测试)和已修改的Ev3_Motor脚本,其中包括了一个Ev3_Motor类(使得导入脚本并创建此类对象变得容易)。然而,这个脚本没有经过测试,可能会产生其他错误,因为我没有一个Ev3机器人。这些错误可以稍后进行调试。请确保Ev3_Motor.py与TkinterTest.py位于同一目录中。

Ev3_Motor.py

#!/usr/bin/env python3
from ev3dev.ev3 import *
import os
import sys
from time import sleep
import shutil 
import fileinput
import debug_print

os.system('setfont Lat15-TerminusBold14')

## Main Ev3 Motor Class ##
class Ev3_Motor:

    def __init__(self):
        debug_print("Constructor Ev3")

    def TestFunction(randomString):
        debug_print("Connection established: " + randomString)

TkinterTest.py

#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
import Ev3_Motor

ev3 = Ev3_Motor.Ev3_Motor()

def calculate(*args):
    ev3.TestFunction("SUCCESSS YAHOOOOOO")
    print("command to robot >>>>")

root = Tk()
root.title("TEST TKINTER")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

ttk.Button(mainframe, text="TEST BUTTON", command=calculate).grid(column=3, row=3, sticky=W)

#ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

root.bind('<Return>', calculate)
root.mainloop()

我仍在努力连接电机。你把我的最后一次编辑发布为答案,但它还不是完全可行的答案。我仍在进行一些测试,并会在取得更多进展后及时报告。感谢你迄今为止的帮助,但将其作为答案发布可能会对任何看到这个问题的新手有点困惑。 - shecodesthings
你编辑的tkinter脚本运行良好,我已经测试过了。然而,可能存在更简单的实现方式。Ev3电机脚本需要一些修改,我希望在那之后它能够正常工作。问题本身应该被编辑为:将Ev3机器人连接到具有前端控制的Python脚本。由于你更了解这个问题,让我来编辑问题是不合适的。Python错误信息非常详细,如果你粘贴Trace back,我们可以尝试进行调试。我们也可以在聊天中继续交流。 - amanb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接