Try   HackMD

Python X Ev3 (EV3DEV)

使用 Python 來撰寫 EV3 程式~

tags: EV3 Python EV3DEV


參考資料:Program in Python with EV3 | www.ev3dev.org | ev3dev | EV3DEV API

介紹

Visual Studio Code

Visual Studio Code 是一款由微軟開發且跨平台的免費原始碼編輯器,支援語法突顯、程式碼自動補全、程式碼重構功能,並且內建了命令列工具和 Git 版本控制系統,也可以透過安裝額外套件增加功能,支援 Windows 、 MacOS 和 Linux 。

vscode-ev3dev-browser

與 LEGO® MINDSTORMS EV3Lab 的積木語言不同,使用 Visual Studio Code 進行編寫程式,安裝 EV3DEV 所推出的 vscode-ev3dev-browser 擴充插件後,可以直接上傳程式到 EV3 主機,也支援使用 SSH 等控制台。

EV3DEV

EV3DEV 是基於 Debain Linux-based 系統下運行,可在多個 LEGO® MINDSTORMS 兼容平台上運行,包括 LEGO® MINDSTORMS EV3 和基於 Raspberry Pi 的 BrickPi。

Python

Python 是一種高階程式語言,也是一種解釋型語言,強調程式碼的可讀性、簡潔的語法。Python為了讓程式碼具備高度的可閱讀性,在設計時盡量使用了其它語言常用的符號和英文單字。

Python 支援使用反斜槓作為行接續符,將多個物理行合成為一個邏輯行,作為通用型的程式語言,運用在 YouTube 、 Google 、 Yahoo! 、 Facebook 、 Dropbox 、Gmail 等等知名平台都在大量使用的程式語言,其特色是支援多種編寫方式,包括物件導向、命令式、函數式、程序式,也和Python和Ruby、Perl、Scheme一樣,擁有動態語法、強制縮排、Garbage Collection 和自動記憶體管理等等諸多的優勢,於未來的需求量也越來越多,涉獵的領域像是大數據分析、自動化腳本、人工智慧。

而 EV3DEV 所使用的 MicroPython 是一款小型的 Python 直譯器,它擁有自己的 Python 直譯器,在保留絕大部分 Python 的核心特色同時縮減周邊模組(函式庫),好讓 Python 這種出了名的吃記憶體的語言也能在像是 EV3 這樣的微控制板上運行。

安裝

EV3DEV

EV3DEV 是基於 Debain Linux-based 系統下的 MicroPython ,因此需要另外準備記憶卡當作系統碟,一般容量建議在 4GB 。

  1. 準備一張 microSD 記憶卡,建議容量 4GB 以下。

  2. 下載映像檔 EV3 MicroPython micro SD card image

  3. 下載燒錄軟體 Etcher

  4. 將記憶卡插入電腦後,依照下方步驟將映像檔燒錄至記憶卡。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  5. 燒錄完成後,確認 EV3 在關機狀態下將記憶卡插入到側邊的 MicroSD 插槽並開機。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

VScode 延伸模組

為了讓 Python 程式檔案可以傳送至 EV3 ,需要安裝額外的延伸模組。

  1. 點選左邊延伸模組商店,輸入 EV3 點選 LEGO® MINDSTORMS® EV3 MicroPython。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  2. 重啟 IDE。

  3. 安裝成功會在左側欄中出現擴充的延伸模組。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Python

和 MicroPython 語法基本一致,可以在燒錄記憶卡時先安裝在電腦上練習撰寫程式~

  1. 首先到官網下載 Python 的安裝檔。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  2. 點選 Downloads 進到下載頁面。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  3. 目前最新版本是 3.11,這邊是直接安裝此版本到環境中,因此如果有多個版本會需要額外設定,也有許多版本可下載,不同版本之間的語法有些小差異。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  4. 開啟安裝執行檔,並勾選 "Add python.exe to PATH" 自動設定路徑,並點選 Install Now 開始安裝。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  5. 安裝完後可以開啟 CMD ,並輸入 python ,如果安裝成功就可以進入到 Python,

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  6. 撰寫第一個程式來測試看看吧!

print("Hello World")

快看! 電腦在向世界說 Hello 呢! (@^0^)

連線 EV3

首先將 EV3 開機並且透過數據線連接至電腦,可以看見開機後的 EV3 主畫面也不同了,不過不用擔心,只要關機並且將記憶卡取出後再開機,就可以回到官方系統了。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

接著創建一個新的專案,並輸入檔名。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

接著左下方的可以看到我們剛剛所安裝的 EV3DEV Device Browser,點選 Click here to connect to a device 並選擇 ev3dev 。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

等待出現綠色圓圈和 Status 可以顯示狀態就表示成功了!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

EV3DEV Device Browser 功能

尋找設備

自動發現任何連接的 ev3dev 主機,不需要額外設定。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

遠程瀏覽文件

每個設備的文件都列在 Brickman 中。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

將文件下載到設備

單擊一下即可將當前 VS Code 項目發送到 ev3dev 設備。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

遠程運行程序

單擊任何可執行文件以運行它。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

也可以右鍵點擊選擇 Run

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

錯誤消息將顯示在輸出窗格中。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

單擊一次(或 F5)即可構建、下載和運行

需創建一個 ev3devBrowser 的 launch.json 文件以使用此功能。

{ "version": "0.2.0", "configurations": [ { "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", "program": "/home/robot/${workspaceRootFolderName}/hello", "preLaunchTask": "build" } ] }

啟動遠程 SSH

可以通過右鍵單擊設備在控制台中啟動 SSH 。

sudo hostnamectl set-hostname <name>

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

營幕截圖

可以通過右鍵單擊設備輕鬆截取營幕。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

來撰寫 EV3 的第一個 Python 程式吧!

首先來介紹自動生成的 main.py ,這個檔案室 EV3 程式開始的地方,我們先來了解一下 Python 的語法以及這自動生成的程式碼是甚麼吧!

粉紅色框內所表示的是 from ... import ... 這段程式碼是代表匯入「函式庫」,函式庫像是外部的我們之前 EV3Lab 積木語言所學到匯入 MyBlock ,將外部的程式碼匯入就可以在這個檔案中的程式使用。

藍色框內所表示的是設定硬體的物件,當我們需要使用馬達或是感測器時,需要告訴 EV3 主機,我的硬體是插在哪個 port 。

黃色框內就是我們主要撰寫程式碼的地方了!

首先來撰寫我們在 EV3 上的第一個 Python 程式吧!

ev3.speaker.beep() 後方加上

print("Hello World")

接著點選左側邊欄中的偵測與執行,接著點選上方的開始鍵,就可以將剛剛所撰寫的程式下載至 EV3 並且執行。

可以看到下面的輸出欄位,印出了 Hello World ,這次換 EV3 打招呼了喔~

那有沒有辦法將 Hello World 顯示到 EV3 螢幕上呢?

試試看剛剛改成下方這段程式碼吧,並且下載到 EV3 執行看看。

ev3.screen.print("Hello World!") # 在螢幕上顯示 Hello World wait(5000) # 等待 5000 毫秒

成功了!

Q. 為甚麼要加上 wait(5000) ,等待 5000 毫秒呢?

A. 如果不加上的話,程式會印出Hello World! 結束,程式一結束便會回到主畫面,如此一來就來不及看到是否有印出了。

Python 流程控制

while

在Python中,while是一種迴圈語句,它允許在滿足特定條件的情況下重複執行程式碼塊。while語句的基本構造是:

while 條件: 程式碼

在這個語句中,當條件為True時,程式碼將被執行。每次執行完程式碼塊後,Python都會檢查條件是否仍為True,如果是,則再次執行程式碼。這個過程將繼續,直到條件變為False為止。

以下是一個while循環的簡單範例,該範例使用while循環顯示一系列數字,直到達到指定數字:

num = 0 while num < 5: print(num) num += 1

這段程式碼將從0開始顯示一系列數字,每個數字之間相差1,直到顯示數字5之前,因為條件“num < 5”仍然為True。在顯示數字5之後,條件變為False,因此while循環將停止執行。

需要注意的是,如果while循環的條件永遠不為False,則程式碼將陷入無限循環,這種情況應盡量避免。

小試身手

Q. 請使用 while 印出五個 Hello World! 在 EV3 螢幕上。

# ans num = 0 while num < 5: ev3.screen.print("Hello World!") # 在螢幕上顯示 Hello World num += 1 wait(1000) # 等待 1 秒

for

for 迴圈是一個重要的控制流程工具,與剛才介紹的 while 相似,新增了用於對序列物件(例如列表、元組、字串等)進行迭代的主要功能。

使用 for 迴圈的語法為:

for 變數 in 序列: # 程式碼

在上述語法中,變數是用來存放每次迭代中序列中的一個元素,而包裹其中的程式碼是在每次迭代時需要執行的一段程式碼。當迭代完成後,for 迴圈也就結束了。

以下是一個使用 for 迴圈遍歷列表的範例:

fruits = ['蘋果', '香蕉', '橘子'] for fruit in fruits: print(fruit)

在上述範例中,我們使用了一個名為 fruits 的列表,並使用 for 迴圈來遍歷這個列表中的每個元素。在每次迭代中,變數 fruit 會被賦值為列表中的一個元素,然後進入程式碼塊中執行 print 函式,將 fruit 輸出到螢幕上。

for 迴圈也可以和其他控制流程結構(例如 if、else 等)結合使用,來實現更複雜的邏輯運算。使用 for 迴圈,可以輕鬆地對序列物件進行迭代,讓我們可以更加靈活地處理大量資料。

if else

if else 是最常見的條件判斷工具,可以用來根據不同的條件執行不同的程式碼。使用 if else 的語法為:

if 條件1: # 條件1成立時要執行的程式碼 else: # 條件1不成立時要執行的程式碼

條件1 是一個 bool 布林值(True 或 False),如果條件1 為 True,則執行 if 後的程式碼,否則執行 else 後的程式碼。

以下是一個使用 if else 判斷 Touch Sensor 是否按下的程式。

btn = TouchSensor(Port.S1) # 創建一個連結在Port.S1的TouchSensor while True: # 使用無限迴圈讓程式持續執行 if btn.pressed(): # 當按鈕按下 ev3.screen.print("btn pressed") else: ev3.screen.print("btn not pressed")

程式實作

馬達緩加減

首先我們先來拼裝出簡單的循跡車

模型下載連結 | PDF組裝說明書

馬達緩加減是指讓馬達在啟動或停止的時候,逐漸地加速或減速,不是瞬間就開始或停止。這樣做的原因是因為如果馬達瞬間啟動或停止,會對機器和電子元件產生很大的應力,導致損壞或壞掉,更會導致馬達的精準度不佳。

EV3 的輪型機器人上則是會輪子的打滑,起步和煞車如果過快,機器會因慣性和摩擦力導致行走起來不完整。

  • 緩減速
bMotor = Motor(Port.B) target = 1000 # 目標角度 bMotor.reset_angle(0) # 將現在的角度歸零 while bMotor.angle() < target: # 當現在的角度小於目標角度時 speed = (target - bMotor.angle()) * 0.5 # 計算速度 if speed > 100: # 限制速度在 10~100 之間 speed = 100 elif speed < 10: speed = 10 bMotor.dc(speed) # 設定速度 ev3.screen.print(bMotor.angle()) # 顯示現在的角度 bMotor.hold() # 停止馬達
  • 緩加減速
# 緩動函數 cos def easeInOutSine(x): return -(math.cos(math.pi * x) - 1) / 2 # 彈跳函數 def easeOutBounce(x): n1 = 7.5625 d1 = 2.75 if x < 1 / d1: return n1 * x * x elif x < 2 / d1: x -= 1.5 / d1 return n1 * x * x + 0.75 elif x < 2.5 / d1: x -= 2.25 / d1 return n1 * x * x + 0.9375 else: x -= 2.625 / d1 return n1 * x * x + 0.984375 # 映射區間 def mapping(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min # 緩加減速 def smoothMove(time, distance, minSpeed, maxSpeed): i = 0 step = time / 100 / 2 target = bMotor.angle() + distance while i <= 1: t_angle = mapping(easeInOutSine(i), 0, 1, 0, target) error = t_angle - bMotor.angle() t_speed = error * 1.5 bMotor.dc(t_speed) i += 0.01 wait(step) while bMotor.angle() < target: bMotor.dc(20) bMotor.stop() bMotor.hold() # 使用範例 在3秒內移動到1000度 smoothMove(3000, 1000)

循跡

# 初始化馬達 left_motor = Motor(Port.B) right_motor = Motor(Port.C) # 初始化顏色感應器 line_sensor = ColorSensor(Port.S3) # 初始化Drive robot = DriveBase(left_motor, right_motor, wheel_diameter=55.5, axle_track=104) # 計算反射光閥值 BLACK = 9 WHITE = 85 threshold = (BLACK + WHITE) / 2 # 設定移動速度為每秒 100 毫米。 DRIVE_SPEED = 100 # 設定比例控制器的增益。這意味著對於每一個光強度百分比偏離閥值, # 我們就將駕駛座的轉向速度設置為 1.2 度/秒。 # 例如,如果反光值偏離閥值 10,則機器人的轉向速度為 10*1.2 = 12 度/秒。 PROPORTIONAL_GAIN = 1.2 # 開始無限地跟隨線條。 while True: # 計算光線強度與閥值之間的偏差。 # 加負號可以走在線的另一邊 deviation = line_sensor.reflection() - threshold # 計算轉向速度。 turn_rate = PROPORTIONAL_GAIN * deviation # 設置駕駛座速度和轉向速度。 robot.drive(DRIVE_SPEED, turn_rate) # 您可以在此循環中等待一小段時間或做其他事情。 wait(10)