Quantcast
Channel: CAVEDU教育團隊技術部落格
Viewing all 678 articles
Browse latest View live

Raspberry Pi Pico W 與手機進行藍牙配對與無線通訊

$
0
0

前言

本文要感謝 Mason Chen 的 Github 並稍加修改之後才成功,已知陳老師已測試過 Raspberry Pi Pico W藍牙搭配 V7RC app Android 版的手機無法使用,所以筆者改用 “LightBlue® — Bluetooth LE” 手機應用程式,安裝在Android的手機來測試使用,之後會繼續嘗試 App Inventor 與 Raspberry Pi Pico W 來實現藍牙無線控制的專題。

上一篇” Raspberry Pi Pico W已新增藍牙無線功能” 已經介紹 Raspberry Pi Pico W 如何上傳藍牙的UF2韌體檔,如果要成功和手機藍牙連線,請先去看上述所提的部落格文章,新增藍牙的UF2韌體檔。

撰寫/攝影 許鈺莨 (ChatGPT協作編輯)
時間 30分鐘 材料表

 

難度 2(滿分5)

本文

下載Raspberry Pi Pico W BLE函式庫

若已經新增好藍牙韌體的Raspberry Pi Pico W後,還需要匯入函式庫到Raspberry Pi Pico W,這需要用到 ampy 套件。

0. 安裝 ampy 詳細作法請參考 “使用Raspberry Pi Pico W和MicroPython進行物聯網應用開發

1. 下載函式庫程式
請點我下載程式與函式庫,下載後請解壓縮至電腦。

2.   需匯入 ble_advertising.pyble_uart_v7rc.py 兩個函式庫

使用 ampy 的指令如下:

cd pico_w_ble
ampy --port COMX put ble_advertising.py
ampy --port COMX put ble_uart_v7rc.py

您可由 Thonny IDE 的檢視 --> 檔案

於其中查看已匯入 Raspberry Pi Pico W 的檔案

3.   執行Raspberry Pi Pico W BLE程式

程式名稱為pico_w_ble.py,在 Thony IDE 執行後,互動環境(Shell)會顯示 ble activated advertising... 訊息,代表 BLE 已啟用。

手機下載藍牙連線應用程式

本文將說明如何使用 Raspberry Pi Pico W 的藍牙功能與手機進行藍牙無線傳輸。請準備好已新增藍牙韌體的Raspberry Pi Pico W,以及一台支援藍牙的手機,作者以Android手機的操作為主。

1. 手機端下載 “LightBlue® — Bluetooth LE” app

2. 手機與Raspberry Pi Pico W藍牙連線溝通

app 端看見 pico_ble 的名稱,代表已啟用藍牙的 Pi Pico W 開發板,請按下CONNECT

可以看見 Thonny IDE 的 Shell 顯示連線成功相關訊息

接著選擇 Writable,代表允許 app 端對開發板寫入資料

● 選擇傳輸資料型態,這裡以 UTF-8 String (字串)為例,但藍牙通訊可支援的資料型態都可以選

● 輸入要傳出的訊息,可以任意輸入,完成之後按下 WRITE 就會對 Pi pico W 開發板送出這筆訊息

● 在Thonny IDE的Shell中,可以看見從手機接收到的字:(b'CAVEDU') 這段裡面的 ‘ ‘ 中的就是從手機端發送過來的訊息。

成果展示

完成,您可以使用 app 來與 Pi Pico W 進行各種藍牙通訊了,趕快打造您的小機器人吧~

 

Raspberry Pi Pico W 與手機進行藍牙配對與無線通訊〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。


Jetson Nano 內網固定IP連線方法,使用實體網路線

$
0
0

前言

在Jetson Nano中,通常我們可以使用USB線或Wi-Fi進行SSH遠端連線。另外,在RK-Jetbot競賽中,也有使用網路線共用網路的方法,以便透過網路線進行連線。不過,這些方法仍需要共用設定才能進行連線。

本文將說明如何使用固定有線網路的內網來設定特定IP。當您的筆電插上網路線後,就能直接使用這個 IP 來連到開發板,無需進行共用設定。這將讓連線更加便捷和直接。

撰寫/攝影 郭俊廷 (ChatGPT協作編輯)
時間 30分鐘 材料表

 

難度 2(滿分5)

本文

Jetson Nano是一款功能強大的單板電腦,常用於機器學習和人工智慧開發。在本篇文章中,我們將介紹如何在Jetson Nano上設定有線固定內網伺服器和DHCP,以便在內部網路中輕鬆連接和管理Jetson Nano。

在之前所執行的實體課程中,大部分都使用USB線以及Wi-Fi做為SSH遠端連線的方法,但最近發現大部分輕薄型筆電或使用WIN 11系統的筆電可能無法透過USB連線,而使用 Wi-Fi 連線大量裝置也可能造成網路不穩定。在RK-Jetbot競賽中,使用網路線來連線控制車子(請看以下影片)是一個常見的解決方案,但對於不熟悉網路共用的人可能會感到有些麻煩。

為了解決這個問題,我們將分享如何將Jetson Nano透過網路線固定IP的方式連線的方法。這將使連線變得更加穩定和便捷,並且無需網路共用的設定,這對於使用網路連線的人來說將是一個很實用的解決方案。

步驟 1:安裝isc-dhcp-server軟體

首先,在終端機中執行以下指令來安裝 isc-dhcp-server 軟體(這時候需要使用網路,如有更新系統或安裝過的人可以跳過這一步驟):

sudo apt-get update
sudo apt-get install isc-dhcp-server

步驟 2:編輯網路介面設定

使用以下指令編輯 /etc/network/interfaces 檔案:

sudo nano /etc/network/interfaces

在檔案中新增以下內容,存檔後關閉編輯器(Ctrl+X後YES後存檔):

auto eth0
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8

編輯新增前後請參考以下兩圖:

步驟 3:編輯DHCP伺服器設定

使用以下指令編輯 /etc/dhcp/dhcpd.conf 檔案:

sudo nano /etc/dhcp/dhcpd.conf

在檔案中新增以下內容,存檔後關閉編輯器:

subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.10 192.168.1.50;
    option broadcast-address 192.168.1.255;
    option routers 192.168.1.100;
    option domain-name-servers 8.8.8.8;
    option domain-name "example.com";
}

編輯新增前後請參考以下兩圖:

步驟 4:啟動DHCP伺服器並重新開機

使用以下指令啟動DHCP伺服器,並設定為開機自動啟動:

sudo systemctl enable isc-dhcp-server
sudo systemctl start isc-dhcp-server

接著,重新開機Jetson Nano:

sudo reboot

步驟 5:連接到Jetson Nano

使用RJ45有線網路來連接 Jetson Nano 與筆記型電腦或其他裝置。請再次檢查筆記型電腦或其他裝置的外部網路連線功能已經關閉,這樣才能進行內部網路測試。Jetson Nano的 IP 位址已透過上述步驟固定為 192.168.1.100。您可以直接用 Windows CMD 或任何喜歡的SSH遠端連線工具 (例如 MobaXterm 或 puTTy) 來連線,輸入正確的帳號密碼 (都是 jetson) 即可順利登入,如下圖:

開啟終端機透過以下命令進行SSH連線 (username是你Jetson裝置的使用者名稱):

ssh username@192.168.1.100
使用 CMD 進行 SSH 連線成功
使用 MobaXterm 軟體進行 SSH 連線成功

 

通過以上步驟,您可以成功在Jetson Nano上設定了有線固定內網伺服器和DHCP。可以直接透過192.168.1.100 這個 IP 透過有線網路來連線到 Jetson Nano,非常方便!

但請注意,如果要使用Wi-Fi對外部網路連線您的Wi-Fi路由器的IP設定,請不要與設定的IP在同一個網段,否則有可能造成Wi-Fi連線時無法對外連線的問題產生。

參考資料

  • https://blog.cavedu.com/?s=jetbot
  • https://blog.cavedu.com/?s=jetson

 

 

 

 

注記:本篇文章使用ChatGPT編輯協作。

 

 

Jetson Nano 內網固定IP連線方法,使用實體網路線〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

ADLINK (凌華科技) Pocket AI:輕巧、靈活、加速好幫手!

$
0
0

前言

更快、更方便,還要更靈活,是今天所有開發者對於 AI 產品的期望,但隨著大家對於 AI 服務的要求愈來愈高,”相同功能” 這句話所代表的意涵以及所需的算力其實是節節上升的。想想看大家現在對於 AI 算圖的解析度與細節要求,與去年同期相比,那水準可是高了好幾個數量級!

如果可以算力可以隨插即用?可以臨時擴充?如果算力可以分享給同事,那該有多好呀?

 

本文

就從某一天收到一個有趣的東西開始吧:ADLINK (凌華科技) Pocket AI,這是一款小巧的外接GPU,或稱呼它為攜帶式 AI 加速器吧,搭載了 NVIDIA RTX A500 GPU,為AI開發和圖形運算提供可靠的支援。Pocket AI 擁有4GB GDDR6 VRAM,為初學者提供了優秀的 AI 開發工具。不僅能滿足學生需求,RTX A500 還已針對 CAD 和 3D 渲染應用進行最佳化,專業人士也很合用。

連接方式輕巧簡單,尺寸只有 106 x 72 x 25 mm,重量 250 公克 [註1],透過 Thunderbolt 3 介面 [註2] 連接電腦就能使用,可為中階規格 PC 或筆記型電腦注入強勁的 AI 算力,適用於各種開發運算情境。根據 ADLINK 原廠表示,未來規劃加入更強大的MXM模組,為創作和開發提供更大的顯存容量。感謝 ADLINK 提供的樣品,以下針對實用、價格與特色三個面向和大家說明,下一篇文章就會實際測試它到底有多厲害

ADLINK Pocket AI 現已可購買,機器人王國已開預購,歡迎帶回家!https://robotkingdom.com.tw/product/Pocket-ai-a500-adlink/

實用:

  • 方便攜帶:Pocket AI的小尺寸和輕便設計,使其成為在不同場合隨身攜帶的理想選擇。不論是在學校、辦公室還是戶外,強大的 AI 算力讓您帶了就走。
  • 專業需求:雖然以初學者與彈性為主要訴求,但 Pocket AI 的 RTX A500 GPU 也能滿足CAD和3D渲染等專業應用。代表它不僅適用於學習,還能為專業人士提供高效工具。
  • 隨插即用:Pocket AI能夠輕鬆與您現有的筆記型電腦和PC連接,無需複雜的安裝過程。使用者可以迅速取得強大的運算能力,提升工作效率;還能連接不同電腦,靈活度大幅提升!

價格:

  • 售價合理:Pocket AI 在售價上找到了很不錯的切入點,使其在競爭激烈的GPU市場中具有一定的價格優勢。
  • 性價比高:考慮到其性能、攜帶方便性和價格,Pocket AI 提供了優越的性價比,能夠在有限預算下滿足使用者對AI和圖形運算需求。
  • 聰明選擇:對於尚未決定是否購入高階 GPU 的使用者來說,無須投入昂貴的整機配置,而可先添購 Pocket AI 來快速驗證想法,藉此降低初期投入成本。

特色:

  • 核心強大:Pocket AI 搭載了 NVIDIA RTX A500 專業級GPU,具有相當不錯的運算和圖形處理能力,為AI和圖形任務提供高效解決方案。
  • 連接方便: Pocket AI 採用 Thunderbolt 3 介面,不僅提供高速資料傳輸,還具備電源傳輸功能,整體配置更為簡潔方便。
  • 面面俱到:Pocket AI 作為初學者的AI學習工具,但同時還能滿足專業領域的需求,使其可以串連更多可能性。

限制

就產品規格以及操作情境來看,Pocket AI 自然也會有對應的限制,試列如下。

  • 記憶體有限:Pocket AI 4GB 記憶體在處理較大模型和資料集時會較為吃力,限制了其在某些高記憶體需求場景下的應用。
  • Thunderbolt 3 介面尚未普及:考量到攜帶性需求,但 Pocket AI 所指定的 通過Thunderbolt 3 介面目前尚未普遍見於各類主機,期待這個狀況在可預見的未來得以緩解。

結論

每項產品都有其自身定位與目標客群,請根據您的需求來挑選最適合的工具,如果以下使用情境是您的日常的話,那非常推薦 Pocket AI給您喔!

  1. AI 初學者: 對於初次涉足AI開發領域的人來說,Pocket AI是一個理想的起點。它具備高實用性、攜帶方便性、以及可滿足初階 AI專案的效能,而相對好入手的價格,也不會對預算造成過大壓力。
  2. 學生和教育機構:學生可以購買 Pocket AI 來進行學術研究、繪圖需求與專案開發。教育機構則可將其作為教學工具,不但配置有彈性,也有助於教室設備管理。
  3. 專業人士和創作者:需要在外出時保持高效生產力的專業人士可以考慮購買Pocket AI。無論是進行圖形設計、3D渲染還是輕量級 AI 任務,這款外接 GPU 都能提供相當不錯的運算能力。
  4. 小型辦公環境:對於辦公室或家庭辦公環境,可能沒有足夠的預算購買高性能工作站,但 Pocket AI 能為輕負載的AI和圖形任務提供一定程度的加速,進而提升生產力。
  5. 需要臨時GPU升級的使用者:對於尚未決定要投入昂貴的整機升級,但偶爾需要更強大GPU支援的用戶來說,Pocket AI 是非常經濟實惠且靈活度高的選擇。
  6. 研究人員和實驗室: 在實驗室和研究環境中,經常需要進行小規模的AI實驗和運算任務來進行可能性驗證。Pocket AI的效能和便攜性,便能成為處理這些任務的理想工具。

 

[註1] 目前行動電源重量約 200 – 500 公克,例如小米行動電源3 (20000 mAh),150 x 72 x 26。重量 502 公克。

[註2] 可由原廠網站的 compatibility list 查看目前支援的型號,但隨著電腦規格的推進,這類接頭應該會相當常見。例如阿吉老師的ASUS Zenbook S13 (UX5304V)筆記型電腦就有兩個 Thunderbolt 3,如下圖

ADLINK (凌華科技) Pocket AI:輕巧、靈活、加速好幫手!〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

Raspberry Pi Pico W 智慧淹水偵測系統,結合 Google 試算表與 LINE 通訊軟體

$
0
0

前言

本篇文章要來介紹的是使用 Raspberry Pico W 和 RS485 溫溼度感測器的淹水偵測裝置,為了因應最近強降雨的情形,怕地下室淹水所製作的,現在這套設備正在 CAVEDU 地下室服役中。

Pico W淹水偵測裝置功能如下:

➡每15分鐘會上傳資料點至Google Sheet雲端,以確保裝置運作中

➡可定時(如:每日7:00PM把目前偵測到的溫溼度發送到 LINE 通訊軟體

➡若濕度過高,則會立即通報LINE中。由於LINE可以把相關人員加入群組中,所以只要有人接到通報,就可以第一時間做處置。

撰寫/攝影 許鈺莨 (ChatGPT協作編輯)
時間 2 小時 材料表
難度 2(滿分5)

本文

智慧偵測淹水裝置接線圖

智慧偵測淹水裝置主要由下列元件所組成:

  • Raspberry Pi Pico W: 接收RS485感測器訊號,並上傳至雲端及LINE 訊息。
  • Raspberry Pi Pico W擴充板 : 擴充Raspberry Pi Pico W腳位,以方便將感測器腳位。
  • TTL轉RS485模組 : 可將RS485感測器訊號轉成TTL訊號,再讓Raspberry Pi Pico W接收
  • RS485溫溼度感測器:可以偵測室內的溫度及濕度。
  • LCD液晶螢幕: 主要顯示目前的溼度狀況與時間。
  1. Raspberry Pi Pico W擴充板與LCD 接線

  1. Raspberry Pi Pico W擴充板與TTL轉RS485模組接線

  1. TTL轉RS485模組接線與RS485溫濕度感測器接線

智慧偵測淹水裝置流程圖

系統流程圖如下 (點選看大圖)

 

智慧偵測淹水裝置匯入LCD函式庫

  1. 匯入 Raspberry Pi pico 函式庫的做法,請參考「使用 Raspberry Pi Pico W 和 MicroPython 開發物聯網應用
  2. 函式庫下載:https://reurl.cc/Dov54e
  1. 匯入檔案指令,匯入以上連結下載的 lcd_api.py 和 i2c_lcd.py
cd LCD_library
ampy --port COMX put lcd_api.py
ampy --port COMX put i2c_lcd.py
  1. 智慧偵測淹水裝置程式全貌

下列程式中需要 IFTTT 作為中介軟體來串接 pico W 與 LINE,相關IFTTT申請步驟,請參考 「LinkIt™ 7697空氣品質偵測並上傳Google表單(空氣盒子2.0)」。,並將申請到的 IFTTT 相關資訊填入以下 .py 檔之後上傳到 pi pico 開發板即可。

Alert_IFTTT_LINE_GOOGLE_settime_blog.py
import utime
import machine
import urequests
import ntptime
import network
from machine import I2C, Pin, RTC
from lcd_api import LcdApi
from i2c_lcd import I2cLcd

# IFTTT settings(需自行輸入IFTTT相關資訊)
IFTTT_GOOGLE_EVENT = "enter_your_google_event"
IFTTT_LINE_EVENT = "enter_your_line_event"
IFTTT_KEY= "enter_your_webhook_key"
IFTTT_URL_GOOGLE_SHEET ='https://maker.ifttt.com/trigger/'+IFTTT_GOOGLE_EVENT+'/with/key/'+IFTTT_KEY
IFTTT_URL_LINE ='https://maker.ifttt.com/trigger/'+IFTTT_LINE_EVENT+'/with/key/'+IFTTT_KEY

# WiFi settings(需自行輸入WIFI帳號和密碼)
wifi_ssid = "enter_your_wifi_ssid"
wifi_password = "enter_your_wifi_password"

# Initialize UART(初始化UART)
uart = machine.UART(1, baudrate=9600, tx=machine.Pin(8), rx=machine.Pin(9), timeout=1000)

uart.init(9600, bits=8, parity=None, stop=1)

# LCD initialization (LCD 初始化)
I2C_ADDR     = 0x3f
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)  

# Initialize RTC (RTC 初始化)
rtc = RTC()

# Connect to the WiFi (WIFI連線)
def connect_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        wlan.connect(ssid, password)
        while not wlan.isconnected():
            pass

# Update the time from NTP server (更新時間)
def update_time():
    ntptime.host = 'pool.ntp.org'
    ntptime.settime()
    tm = utime.localtime(utime.mktime(utime.localtime()) + 28800)
    rtc.datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))

# Get current time(取得目前時間)
def get_time():
    time = rtc.datetime()
    current_hour = time[4]
    current_minute = time[5]
    current_second = time[6]
    current_time = "{:02d}:{:02d}:{:02d}".format(current_hour, current_minute, current_second)
    return current_time, current_hour, current_minute

# Send data to IFTTT (傳資料到IFTTT)
def send_to_ifttt(url, soil_temp, soil_vwc, state):
    data = {'value1': str(soil_temp), 'value2': str(soil_vwc), 'value3': state}
    request_headers = {'Content-Type': 'application/json'}
    request = urequests.post(url, json=data, headers=request_headers)
    request.close()

# Sensor Access Function (RS485感測器回傳資料)
def Sensor_Access():
    Read_SOIL_TEMP_HUMI_Command = bytes([0x01, 0x03, 0x00, 0x06, 0x00, 0x02, 0x24, 0x0A])
    SOIL_buf = bytearray(11)
    Sensor_Delay_mS = 50
uart.write(Read_SOIL_TEMP_HUMI_Command)
    uart.readinto(SOIL_buf)
    utime.sleep_ms(Sensor_Delay_mS)

    SOIL_VWC_Data = (SOIL_buf[5] << 8) + SOIL_buf[6]
    SOIL_VWC_Value = int(SOIL_VWC_Data) / 1000
    SOIL_TEMP_Data = (SOIL_buf[3] << 8) + SOIL_buf[4]
    SOIL_TEMP_Value = int(SOIL_TEMP_Data) / 100
    return SOIL_TEMP_Value, SOIL_VWC_Value

# Print on LCD (顯示數值在LCD)
def lcd_print(current_time, soil_vwc):
    lcd.clear()
    lcd.putstr("TIME: {time}    VWC: {vwc:.1f}".format(time=current_time, vwc=soil_vwc))

def main():
    state = " Normal "
    connect_wifi(wifi_ssid, wifi_password)
    update_time() # update the time from NTP server at the start
    lcd.putstr("WIFI is connected!")

    # setting the initial time to a value that triggers the first send
    last_sent_hour = -1
    last_sent_minute = -1
   line_flag = False

    while True:
        current_time, current_hour, current_minute = get_time()
        # read sensor every 15 minutes  (每15分鐘上傳數值到Google Sheets)

        if current_minute % 15 == 0 and current_minute != last_sent_minute:
            soil_temp, soil_vwc = Sensor_Access()
        send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)

            last_sent_minute = current_minute

# send to LINE sheet once every day at 7:00pm (每晚七點上傳數值到LINE)
        if current_hour == 19 and current_minute == 0 and line_flag == False:
            soil_temp, soil_vwc = Sensor_Access()
          #send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)
            send_to_ifttt(IFTTT_URL_LINE, soil_temp, soil_vwc, state)
            line_flag = True

        # reset line_flag after 7:00pm (重置line_flag)

        if current_hour == 19 and current_minute > 0:

            line_flag = False

        # send to LINE when soil_vwc is between 0 and 10 (當淹水時會發緊報)

        soil_temp, soil_vwc = Sensor_Access()
        if 0 < soil_vwc <= 10:
            state = " ALERT!! "
            send_to_ifttt(IFTTT_URL_LINE, soil_temp, soil_vwc, state)
           send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)
        else:
            state = " Normal "

        # print on LCD every second (LCD每秒更新一次顯示畫面)
        lcd_print(current_time, soil_vwc)
        print(current_time, soil_vwc)
        utime.sleep(1)  # sleep for 1 second

# Run the main function (執行主程式)
main()
  1. 安裝位置

筆者將裝置設置在地下室容易淹水的地方,由於感測器很靈敏,所以使用海綿來吸水,到一定程度後感測器就會發出通報 (下圖左)。裝置運作時,可由外接 LCD 看到當下的時間和濕度。

6. 實際執行

執行影片如本文開頭,為了較快看到效果,筆者設計是每秒上傳一次資料到雲端,請根據實際狀況來修改這個更新頻率。

Raspberry Pi Pico W 智慧淹水偵測系統,結合 Google 試算表與 LINE 通訊軟體〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

Jetbot 升級新技能 : 結合紅外線感測器來循跡!

$
0
0

前言

Jetbot,作為一款基於NVIDIA Jetson Nano的開源機器人平台,以其強大的運算能力和靈活的擴展性受到了許多使用者喜愛。其內建的視覺處理能力使其在物體識別和路徑規劃方面都有出色的表現。但加入紅外線循跡感測器後,Jetbot的導航能力將得到進一步的提升。不再僅僅依賴視覺信息,Jetbot將能夠結合紅外線循跡感測器的資料,更為準確和迅速地進行路徑選擇和避障。

本文將深入探討如何為Jetbot加入紅外線循跡感測器,從理論到實踐,再到程式撰寫,無論你是初學者還是有經驗的開發者,相信這次的教學都能讓您收穫滿滿!

撰寫/攝影 許鈺莨 (ChatGPT協作編輯)
時間 2 小時 材料表
難度 2(滿分5)

本文

紅外線循跡感測器的工作原理

感測器的紅外發射二極體不斷發射紅外線,有以下兩種情形:

  • 當發射出的紅外線沒有被反射回來或被反射回來但強度不夠大時, 光敏三極體一直處於關斷狀態,此時模塊的輸出端為高電壓,板載指示LED處於熄滅狀態。
  • 被檢測物體出現在檢測範圍內時,紅外線被反射回來且強度足夠大, 光敏三極體飽和,模塊輸出低電壓,板載指示LED被點亮。

主要應用:本次運用於循跡車路線偵測,藉由紅外線被白色塊反射、黑色塊吸收減弱來偵測地上白線。 循跡模組感測器感應原理:

(1)利用顏色對光線的反射率,來檢測路徑,黑色吸收光線,感應器在 黑色線上時不會收到IR反射訊號 。

(2) 感應器背面LED指示燈,當LED燈亮起,表示接收到反射的紅外線。

Jetbot的循跡動作

1. 循跡感測器的模組訊號示意圖,L代表Left(左邊)、M代表Middle(中間)、R代表Right(右邊)。如下圖所示:

2. 循跡感測器控制 Jetbot 行為

若感測器偵測到白色,則訊號為1,若感測器偵測到黑色,則訊號為0。這樣會有八種排列組合並對應到 Jetbot 的某個動作。

循跡感測器腳位訊號
L (左側) C (中央) R (右側) Jetbot動作
0 0 0 停止
0 0 1 右轉
0 1 0 直走
0 1 1 右轉
1 0 0 左轉
1 1 0 左轉
1 1 1 停止

圖示說明

Jetbot直走
感測器偵測結果:010

 

Jetbot 停止
感測器偵測結果:000 感測器偵測結果:111

 

Jetbot 右轉,有兩種不同偏移程度,可藉此讓車子有不同的修正行為
感測器偵測結果:001 (車體相當偏左) 感測器偵測結果:011 (車體h稍微偏左)

 

Jetbot 左轉
感測器偵測結果:100 感測器偵測結果:110

 

程式執行與說明

    (1)  開啟程式

路徑位置在 /Jetbot 根目錄底下的 widget_linefollower_slider.ipynb

當您的 Jetbot SD 卡燒錄完成之後,Jetson Nano 開機之後會成為一個 Jupyter Lab伺服服器,請由網路端連入即可操作,請參考本篇教學

     (2)  程式執行

在工作列點選 Kernel Restart Kernel and Run All Cells

顯示使用者操作介面的區塊,出現操作介面,按下live即可啟動Jetbot

 

    (3)  程式撰寫說明

  1. 程式的第1格區塊

主要是匯入Jetbot 和使用者互動介面 widget 小工具的相關函式庫。

 

2. 程式的第2格區塊

設定紅外線感測器腳位,感測器L、C、R腳位分別接在 Jetbot 的17、27、22腳位。

3. 程式的第3格區塊

接感測器L、C、R 的Jetbot 的腳位,設定為輸入訊號。

4. 程式的第4格區塊

根據循跡感測器偵測到的訊號,去定義 Jetbot 的行為動作。

5. 程式的第5格區塊

使用按鈕、文字欄位和滑桿來建立使用者操作介面。

6. 程式的第6格區塊

定義 Jetbot 前進、停止、左轉、右轉。

7. 程式的第7格區塊

觸發 live 和 stop 按鈕的事件。

 

8. 程式的第8格區塊

顯示使用者操作畫面,stop 按鈕停止Jetbot ; live 按鈕啟動 Jetbot ; 三個滑桿來控制 Jetbot 的馬力。

  • 馬達前進動力滑桿,控制 Jetbot 走直線時的馬力,最小0,最大1,預設為0.8。
  • 左轉幅度滑桿,控制 Jetbot 左轉時的馬力,最小0.2,最大1,預設為0.8。
  • 右轉幅度滑桿,控制 Jetbot 右轉時的馬力,最小0.2,最大1,預設為0.8。
  • 文字方塊則可以看 Jetbot 動作。

實機展示

實際操作時可以看到,影片請回到本文一開始或點選本連結播放。後續還有繼續加入超音坡測距感測器為您的 Jetbot 加入更多豐富的功能!

Jetbot 升級新技能 : 結合紅外線感測器來循跡!〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

Jetbot 升級新技能 part 2:紅外線循跡與超音波測距實現多功能導航!

$
0
0

前言

在「Jetbot 升級新技能 : 結合紅外線循跡功能」的文章中,我們說明了如何在原有 Jetbot 的架構上加上基礎的紅外線循跡感測器。基於物體對紅外線的反射特性,能夠幫助 Jetbot 準確辨識和跟隨特定的路徑。而超音波偵測技術則為Jetbot提供了一個”眼睛”,讓它能夠偵測前方的障礙物,並做出迅速的反應。

本文要深入探討這兩種技術如何與Jetbot融合,從理論基礎到實際操作,將會為讀者帶來全新的篇章。

撰寫/攝影 許鈺莨 (ChatGPT協作編輯)
時間 2 小時 材料表
  • 一台連網的電腦
  • 欲購買RK-Jetbot可聯繫我們CAVEDU教育團隊
  • 連絡電話:(02) 2306-2900
    電子郵件:service@robotkingdom.com.tw
難度 2(滿分5)

本文

超音波感測器運作原理

超音波感測器是由超音波的發射器(T)、接收器(R)和控制電路所組成,經由計算發射後到接收的時間差來換算出與障礙物的距離。因此超音波感測器也是一個很容易且方便使用的距離感測器,所以我們可藉由超音波偵測距離而達到避障的功能。

左邊為發射器(Transmitter)標示為T,會發出 40 kHz 的聲波,由於這個聲波的頻率超過人類可聽見的 20 kHz,因此被稱為超音波。右邊為接收器(Receiver)標示為R,可以接收超音波。它可以感測的距離為 2cm到 400cm,感應角度為 15 度。

透過Trig和 Echo腳位,可維持 10 微秒以上的高準位訊號,便能觸發模組中的超音波發射器送出 8 個連續的 40KHz 超音波脈衝,接收器收到反射波後便會輸出一個與量測距離成正比的高準位脈衝。

超音波在空氣中傳播的速度為Vs =331+ 0.6 t (t為當時的溫度),傳播速度會受到當時溫度的影響,而且溫度愈高,傳播速度就愈快。 假設當時的溫度是 23℃,超音波行走 1cm 反射回來的時間 T ,表示超音波行走 1cm只需58微秒。

由公式表示: T=  ((1+1))/((331+0.6×23) )×100=58μs

HC-SR04 的 Echo訊號輸出的高位準脈衝,其時長即是超音波往返所花的時間,因此量出 Echo 的脈衝時間長,再除以 58,即可得到與反射超音波的障礙物之間的距離是幾公分了。

Jetbot超音波測距動作

本次實作是預設Jetbot距離障礙物15公分就會停止,但是使用者可以自由調整距離,最小為10公分,最大為50公分。

 

程式執行與說明

(1)  開啟程式

路徑位置在 /Jetbot 根目錄底下的 widget_linefollower_sonic_slider.ipynb

當您的 Jetbot SD 卡燒錄完成之後,Jetson Nano 開機之後會成為一個 Jupyter Lab伺服服器,請由網路端連入即可操作,請參考本篇教學

    (2)  程式執行

在工作列點選 Kernel Restart Kernel and Run All Cells

顯示使用者操作介面 這個 cell 執行之後會出現操作介面,按下live即可啟動Jetbot

(3)  程式撰寫說明

1.  程式的第1格區塊

匯入Jetbot 和使用者互動介面 widget 小工具的相關函式庫。

2. 程式的第2格區塊

設定紅外線感測器及超音波感測器腳位,紅外線感測器L、C、R腳位分別接在Jetbot 的17、27、22腳位。超音波感測器的Trig和Echo腳位分別接在Jetbot的24和23腳位。

3. 程式的第3格區塊

接紅外線感測器L、C、R 的Jetbot 的腳位,設定為輸入訊號。
接超音波感測器的Trig腳位,設定為輸入訊號;Echo腳位,設定為輸出訊號。

4. 程式的第4格區塊

測量障礙物和 Jetbot (其實是超音波感測器) 的距離

5. 程式的第5格區塊

根據循跡感測器偵測到的訊號,去定義 Jetbot 的行為動作。
        6. 程式的第6格區塊

使用按鈕、文字欄位和滑桿來建立使用者操作介面。

7. 程式的第7格區塊

定義 Jetbot 前進、停止、左轉、右轉。

8. 程式的第8格區塊

觸發 live 和 stop 按鈕的事件。

9. 程式的第9格區塊

顯示使用者操作畫面,說明如下:

  • stop 按鈕停止Jetbot
  • live 按鈕啟動 Jetbot
  • 馬達前進動力滑桿,控制 Jetbot 走直線時的馬力,最小0,最大1,預設為0.8。
  • 左轉幅度滑桿,控制 Jetbot 左轉時的馬力,最小0.2,最大1,預設為0.8。
  • 右轉幅度滑桿,控制 Jetbot 右轉時的馬力,最小0.2,最大1,預設為0.8。
  • 與障礙物距離滑桿,可以調整 Jetbot 與與障礙物距離,最小10公分,最大50公分,預設為15公分。
  • 文字方塊,檢視目前超音波數值 (也就是距離 cm) ,和 Jetbot 當下正在執行的動作。

實機展示

實際操作時可以看到機器人應可根據循跡感測器來沿著白色軌跡線前進,請根據實際狀況來修改相關參數。機器人就是要不斷地調整才行呢!

影片請回到本文一開始或點選本連結播放。期待您也根據本文說明來為機器人加入更多豐富的功能。

 

 

 

 

 

Jetbot 升級新技能 part 2:紅外線循跡與超音波測距實現多功能導航!〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

[技術教學文] Raspberry Pi 4 樹莓派散熱套裝開箱及使用教學

$
0
0

前言

樹莓派在運作時熱呼呼嗎?來個 CAVEDU 為您精心挑選的散熱風扇吧,請由此購買喔:https://robotkingdom.com.tw/product/raspberry-pi-2fans/

撰寫/攝影 何卓君
時間 1 小時 材料表
難度 1(滿分5)

 

本文

開箱及硬體介紹

本款散熱套件內容包含:

  • 散熱風扇本體 x 1
  • 散熱片 x 3
  • 壓克力板,大小各 1
  • 螺絲起子 x 1
  • 螺絲螺帽 1批
  • 軟墊 1批

 

散熱風扇本體如下,可以看到兩個開關以及對應於 Pi 的  GPIO 接腳。

 

接著看到散熱片,請用隨附的導熱膠帶來貼上你所需要散熱的物件,讓散熱效果更好 (我也不知道這個顯微鏡效果是怎麼做到的QQ)。這個是很普遍可以買到的小東西,不小心不見也不用擔心。

 

安裝散熱片前

安裝散熱片後,可看到散熱片分別貼上了 Pi 的 CPU、RAM 與 USB 3.0 控制器晶片

風扇安裝好了!

接上電源後可以看到很西花的燈光 (後來發現這個功能很重要,甚至是賣點)

將風扇用套裝中提供的工具鎖好之後,我們就可以接上電源,使用右側的兩個開關就可以分別打開/關閉風扇或是LED燈。

這款風扇本身也有針腳,擴充板或是其他樹莓派小部件可以透過風扇連接至樹莓派本身,所以不會出現在裝上風扇後無法使用其他元件的情況。可看到風扇安裝之後,樹莓派仍可連接至擴充板。

總結

這類單板電腦如果在進行相關 AI 運算或高負載的應用時,散熱都是需要注意的問題。還是選一款不錯的散熱套件吧,涼快一點好做事~ 不但可以保證樹莓派的運行速度,還可以保護零件不會因為過熱而縮短壽命。

 

 

[技術教學文] Raspberry Pi 4 樹莓派散熱套裝開箱及使用教學〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

RK-micro:bit robot – assembly tutorial

$
0
0

Introduction

This step-by-step tutorial will show you how to assemble the RK-micro:bit robot, which is a differenial robot chassis with a micro:bit as its controller.

We will have another tutorial to inroduce how to program this robot using MakeCode

author 楊國立 (intern)
Time 1~ 2 hours BOM
Difficulty 3 / 5 

Content

First we check the meterial needs for this RK-micro:bit robot.

—Micro:bit*1
—L298n motor driver module*1
—TT Motor*2
—Ultrasonic(HC-SR04)*1
—Ball wheel*1
—65x15mm wheel*2
—9VBattery Holder with On Off switch*1
—Micro:bit Sensor shield module*1
—Micro USB Wire*1
—M3*8 Screw*2
—M3*12 Screw*10
—M3  Nut*12
—M2*20 Screw*4
—M2  Nut*4
—M3*6 Plastic Spacer*10
—M3*6 Plastic Screw*10
—M3  Plastic Nut*10
—Acrylic sheet*1
—10p Wire 

STEP 1  Attach the front wheel to the base board (Base Board x1,M3*8 Screw x2,M3 Nut x2) (It’s the same which side you attach)

STEP 2  Attach (m3x6)x4 to the base board(m3x6)x4 (Attention: Place it in the right direction, the screw is the same side with the ball wheel)

STEP 3  Attach the L298n motor driver module above the base board (Attention to the direction of the motor driver)

STEP 4  Attach the cables from 2 motors, 9V Battery Holder with On Off switch & Micro USB Wire
– Motor B {Left} the most left side is black cable and then the right one is red cable
– Motor A {Right} the most right side is black cable and then the left one is red cable
– Put the USB red cables in the middle on the most left side
– Put the battery red cables in the middle on the most right side
– At the middle of all of it put both battery & USB black cable together

STEP 5  Attach the Motors to the side acrylic (Aware fo the direction)

STEP 6  Attach the side body to the base acrylic (Attention: do not tighten the screws yet)

STEP 7  Attach the ultrasonic sensor to the Ultrasonic acrylic board. Use (m3x6) x2.

STEP 8  Attach the ultrasonic acrylic to the base acrylic (m3x12)x2 (Attention: Attach it ABOVE  the base acrylic, not under!!)

STEP 10  Put the 9VBattery Holder with On Off switch between the top acrylic (Open the battery holder first so it will fit)

STEP 11 Pull the USB cable over the top of the acrylic

STEP 12  Plug the cables based on the pictures

STEP 13 Pull the cables over the top of the acrylic based on the picture

STEP 14  Attach top board with (m3x6) x4

STEP 15  Attach the top acrylic to the rest of the body and lock all the screws firmly

STEP 16  Attach the above the micro:bit sensor shield module top acrylic (Aware of the direction of the micro:bit sensor shield module)

STEP 17  Attach the both wheels

 

Finished!

Feel free to adjust all the settings, add more of your own creativity to make it better! We will have another articale to show you how to control this robot by MakeCode graphical IDE.

 

 

 

 

RK-micro:bit robot – assembly tutorial〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。


Google Mediapipe 手勢偵測結合SVM模型進行多手勢識別

$
0
0

前言

CAVEDU 已寫過多篇 Google Mediapipe 的教學文,本文將說明如何搭配 SVM (支援向量機) 模型來讓你的手勢辨識模型更厲害!

撰寫/攝影 曾俊霖 aka Jack
時間 2~3 小時 材料
  • 桌上型電腦或筆記型電腦
  • webcam,例如羅技 C170 / C270
難度 3(滿分5)

內文

當我們想進行多手勢的辨識時,選擇僅用距離條件式的判斷相對於使用 SVM模型來說,存在一些明顯的限制和問題。以下是這兩種方法的比較:

  • 複雜性與可維護性:
    1. 距離條件式判斷:當手勢增多或變得複雜,你可能需要設定更多的條件和閾值。這不僅使得程式碼複雜、難以維護,而且很難確保每個條件都是正確的。
    2. SVM模型:透過機器學習,模型會從數據中學習如何正確區分手勢,而不是依賴手工設定的條件。
  • 泛化能力:
    1. 距離條件式判斷:可能只適用於特定的用戶和情境。例如,不同人的手大小、形狀不同,所以使用固定的距離閾值可能不適用於所有人。
    2. SVM模型:經過適當的訓練,模型可以學習到更普遍的、不依賴於特定人或情境的手勢特徵。
  • 容錯能力:
    1. 距離條件式判斷:僅基於距離的判斷可能非常敏感,一點點的誤差或變動都可能導致錯誤的分類。
    2. SVM模型:這些模型通常對於輸入的小變化有一定的容忍度,因此提供了更好的容錯能力。
  • 擴展性:
    1. 距離條件式判斷:若想新增手勢,你可能需要重新寫或調整大量的條件式,這是非常耗時和容易出錯的。
    2. SVM模型:只需增加新的訓練數據,然後重新訓練模型。
  • 動態和變異性:
    1. 距離條件式判斷:固定的條件很難捕捉手勢間的微妙差異或動態變化。
    2. SVM模型:可以捕捉和學習多種特徵的組合,並更好地處理手勢的動態和變異性。

儘管使用距離條件式判斷在某些簡單的情境下可能是可行的,但對於多手勢或複雜的手勢識別,使用 SVM模型是一種更為強大、靈活和可靠的方法。

SVM

SVM 是一個強大的機器學習模型,特別適合於分類問題。它的設計理念和數學基礎使其在許多情境下都能提供出色的性能,特別是當數據具有複雜的邊界或當需要進行多類別的分類時,針對「支援向量模型」SVM (Support Vector Machines) 模型的特點進行的概述:
一、 泛化能力:
SVM 被設計來找到最大的邊界,使其在多類別的數據集上具有很好的泛化能力。這意味著一旦模型經過適當的訓練,它可以有效地對新的、未見過的數據進行預測。

二、 容錯性:
SVM 透過找到最佳的超平面來分隔資料,這使得它具有一定的容錯性。也就是說,即使有一些數據點不完美地位於邊界的正確一側,SVM 仍然可以找到一個合適的超平面。

三、 處理高維數據:
SVM 可以有效地處理高維數據。在手勢識別的情境下,每一個手部標誌點可以提供多維的資料,而 SVM 能夠很好地處理這種情況。

四、 核技巧:
SVM 的一個重要特性是它可以使用所謂的核函數來處理非線性數據。即使數據在原始空間中不是線性可分的,SVM 仍然可以找到一個合適的邊界來分隔它。

五、 模型簡潔:
與某些其他的機器學習模型相比,SVM 傾向於產生比較簡潔的模型。這是因為 SVM 只依賴於支持向量(即那些位於邊界附近的數據點)來定義分隔邊界。

六、 可擴展性:
儘管 SVM 在非常大的數據集上可能比其他模型更加計算密集,但它仍然是可擴展的。當訓練集變得非常大時,還有一些優化的 SVM 變種可以使用。

MediaPipe 結合 SVM

使用 MediaPipe 來捕捉手部標誌點,再結合 SVM 進行手勢識別,具有以下優勢:

一、 即時性:
MediaPipe 是一個專為高效能而設計的框架,能夠即時捕捉和分析影像串流中的手部標誌點。

二、 SVM 是一個相對輕量級的模型,當訓練完畢後,對於新數據的預測是非常快速的。結合兩者,我們可以獲得實時且流暢的手勢識別。

三、 簡易性:
使用 MediaPipe 進行手部跟踪意味著不需要從頭開始訓練一個深度學習模型來識別手部或其標誌點,節省了大量時間和資源。

四、 SVM 是一個經典的機器學習模型,相對於深度學習模型,其原理和實現都更為簡單和直觀。

五、 靈活性:
MediaPipe 提供的手部標誌點數據可以轉化為多種特徵,例如指尖之間的距離、手部各部位的角度等。這些特徵可以容易地餵入 SVM 或其他模型進行學習。

六、低資源需求:
SVM 不需要像深度學習模型那樣的大量運算資源,對於邊緣設備或資源有限的情境,例如行動裝置,這是非常有益的。

七、可解釋性:
SVM,尤其是使用線性核的版本,提供了較好的解釋性。這意味著可以較容易地了解哪些特徵是對模型最有影響的,這對於了解和優化手勢識別過程是有價值的。

八、可擴充性:
如果在初步的研究或原型階段使用 MediaPipe 和 SVM 證明了手勢識別的有效性,那麼未來可以容易地升級到更複雜的深度學習模型,以提高精度或識別更多的手勢。

認識SVM模型

透過下圖來進行SVM模型特性的說明,我們假設紅色和藍色的數據點代表不同的手勢關節彎曲幅度的資料,由於手勢在攝影鏡頭前面的距離或位置不一定都是穩定的,因此會產生手勢關節座標的辨識誤差,但由於特定的手勢其關節彎曲幅度是有一定的趨勢規則,因此會產生測量數據的「群聚趨勢」,透過SVM模型建立的超平面區隔演算法,可以將紅色或藍色兩個不同手勢的群聚趨勢加以區隔,透過這樣的區隔演算法,在實際的影像辨識推論階段便可以透過區隔區域的差異或是群聚中心的距離,得知手勢的差異(群聚區域的不同),以及手勢辨識精確度(與群聚中心的距離),這樣的做法可以讓使用者不需要精確計算各手勢關節的座標相對關係,透過SVM模型便可以讓使用者更加彈性的操作,也因為這樣的操作便利性,讓使用者可以豐富多樣化想要辨識的手勢種類。

測試流程說明

接著來逐步說明如何完成本範例所需的各個功能吧,完成程式碼如本文最後

一、 蒐集訓練資料

輸入手勢類別標籤名稱。

按下空白鍵後開始蒐集手勢資料。

蒐集手勢資料10秒,畫面會出現倒數計時秒數。

針對各種手勢資料進行紀錄,檔案名稱就是手勢類別標籤名稱。

二、 SVM模型訓練

透過SVM線性分類模型開始進行模型訓練。

訓練完成後會產生SVM模型檔、比例記錄檔、類別名稱標籤檔,如下圖紅框。

三、 影像實際測試

識別出手勢:Six

識別出手勢:Fox

識別出手勢:Rocker

程式碼

安裝好相關套件之後,請於終端機中執行以下程式即可,分成三個步驟

  • Data_Collect_V3.py 收集資料
  • Train_Model_V3.py 訓練模型
  • Demo_V3_Multi.py 即時手勢辨識

Data_Vollect_V3.py

Data_Collect_V3.py (收集資料)
import cv2
import mediapipe as mp
import numpy as np
import time
import os

# Initialize mediapipe Hands
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()

def compute_distances(landmarks):
distances = []

# Define pairs for distance calculation
pairs = [(0, 1), (0, 2), (0, 3), (0, 4),
(0, 5), (0, 6), (0, 7), (0, 8),
(0, 9), (0, 10), (0, 11), (0, 12),
(0, 13), (0, 14), (0, 15), (0, 16),
(0, 17), (0, 18), (0, 19), (0, 20),
(4, 8), (8, 12), (12, 16), (16, 20)]

reference_pair = (0, 9)
p_ref1 = np.array([landmarks.landmark[reference_pair[0]].x, landmarks.landmark[reference_pair[0]].y])
p_ref2 = np.array([landmarks.landmark[reference_pair[1]].x, landmarks.landmark[reference_pair[1]].y])
reference_distance = np.linalg.norm(p_ref1 - p_ref2)

for pair in pairs:
p1 = np.array([landmarks.landmark[pair[0]].x, landmarks.landmark[pair[0]].y])
p2 = np.array([landmarks.landmark[pair[1]].x, landmarks.landmark[pair[1]].y])
distance = np.linalg.norm(p1 - p2) / reference_distance
distances.append(distance)

return distances

# Ask user for filename
filename = input("Please enter the filename for data: ")
save_path = "dataset_V3/" + filename

# Check if the 'dataset' directory exists, if not, create it
if not os.path.exists("dataset_V3"):
os.makedirs("dataset_V3")

cap = cv2.VideoCapture(0)
data_collection = []

collecting = False
start_time = None

while True:
ret, frame = cap.read()
if not ret:
continue

if not collecting:
cv2.putText(frame, "Press SPACE to start data collection", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
else:
elapsed_time = int(time.time() - start_time)
remaining_time = 10 - elapsed_time
cv2.putText(frame, f"Time left: {remaining_time} seconds", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
if elapsed_time >= 10:
break

rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(rgb_frame)

if results.multi_hand_landmarks and collecting:
for landmarks in results.multi_hand_landmarks:
distances = compute_distances(landmarks)
data_collection.append(distances)

cv2.imshow("Data Collection", frame)
key = cv2.waitKey(1)

if key == 32 and not collecting:
collecting = True
start_time = time.time()
elif key == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

# Convert the data_collection list to numpy array and save
np.save(save_path, np.array(data_collection))
print(f"Data saved to {save_path}")

Train_Model_V3.py

Train_Model_V3.py (訓練模型)
import numpy as np
import os
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
import joblib

dataset_path = "dataset_V3"
label_file = "labels_V3.txt"

# Fetch all .npy files from the dataset directory
files = [f for f in os.listdir(dataset_path) if f.endswith('.npy')]

X = []
y = []

labels = []

# Load data and labels
for idx, file in enumerate(files):
data = np.load(os.path.join(dataset_path, file))
X.extend(data) # Note: using extend instead of append
label = file.split('.')[0]
labels.append(label)
y.extend([idx] * data.shape[0])

X = np.array(X)
y = np.array(y)

# Save labels to labels.txt
with open(label_file, 'w') as f:
for label in labels:
f.write(label + "\n")

# Preprocess data
scaler = StandardScaler()
X = scaler.fit_transform(X)

# Train SVM model
clf = SVC(kernel='linear', probability=True)
clf.fit(X, y)

# Save the model and the scaler
model_filename = "svm_model_V3.pkl"
joblib.dump(clf, model_filename)
scaler_filename = "scaler_V3.pkl"
joblib.dump(scaler, scaler_filename)

print(f"Model saved to {model_filename}")
print(f"Scaler saved to {scaler_filename}")
print(f"Labels saved to {label_file}")

Demo_V3_Multi.py

Demo_V3_Multi.py (手勢辨識)
import cv2
import mediapipe as mp
import numpy as np
import joblib

# Initialize mediapipe Hands Detection
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()

# Load the SVM model and scaler
model_filename = "svm_model_V3.pkl"
clf = joblib.load(model_filename)
scaler_filename = "scaler_V3.pkl"
scaler = joblib.load(scaler_filename)

# Load labels
label_file = "labels_V3.txt"
with open(label_file, 'r') as f:
labels = f.readlines()
labels = [label.strip() for label in labels]

def compute_distances(landmarks):
# Define pairs for distance calculation
pairs = [(0, 1), (0, 2), (0, 3), (0, 4),
(0, 5), (0, 6), (0, 7), (0, 8),
(0, 9), (0, 10), (0, 11), (0, 12),
(0, 13), (0, 14), (0, 15), (0, 16),
(0, 17), (0, 18), (0, 19), (0, 20),
(4, 8), (8, 12), (12, 16), (16, 20)]

distances = []
reference_distance = np.linalg.norm(
np.array([landmarks.landmark[0].x, landmarks.landmark[0].y]) -
np.array([landmarks.landmark[9].x, landmarks.landmark[9].y])
)

for pair in pairs:
p1 = np.array([landmarks.landmark[pair[0]].x, landmarks.landmark[pair[0]].y])
p2 = np.array([landmarks.landmark[pair[1]].x, landmarks.landmark[pair[1]].y])
distance = np.linalg.norm(p1 - p2)
distances.append(distance/reference_distance) # Normalize the distance using the reference distance

return distances

cap = cv2.VideoCapture(0)

while True:
ret, frame = cap.read()
if not ret:
break

rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(rgb_frame)

if results.multi_hand_landmarks:
for index, landmarks in enumerate(results.multi_hand_landmarks):
# Distinguish between left and right hand
hand_label = "Right" if results.multi_handedness[index].classification[0].label == "Left" else "Left"

distances = compute_distances(landmarks)
distances = scaler.transform([distances])

prediction = clf.predict(distances)
confidence = np.max(clf.predict_proba(distances))

label = labels[prediction[0]]
display_text = f"{hand_label} Hand: {label} ({confidence*100:.2f}%)"

cv2.putText(frame, display_text, (10, 30 + (index * 40)), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)

# To visualize the landmarks of the hand
mp.solutions.drawing_utils.draw_landmarks(frame, landmarks, mp_hands.HAND_CONNECTIONS)

cv2.imshow('Demo', frame)

if cv2.waitKey(1) & 0xFF == 27: # ESC key
break

cap.release()
cv2.destroyAllWindows()

參考資料

 

 

 

Google Mediapipe 手勢偵測結合SVM模型進行多手勢識別〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

RK-micro:bit robot – line-following programming tutorial(MakeCode)

$
0
0

Introduction

This step-by-step tutorial will show you how to control the RK-micro:bit robot by MakeCode. For the assemly tutorial, please follow this link.

In this tutorial, the robot will follow the black track by its IR light sensor which is located in its front end. Check the video:

author 楊國立 (intern)
Time 1~ 2 hours BOM
Difficulty 2 / 5 

Content

How to control the motor and robot behavior

In RK-micro:bit Car, the two motor are placed back-to-back, we call this a differential drive platform, which means the robot behaviors are decided by the direction/speed of these two motors.

Since we are using a L298n motor driver module to control the two motors, we are acutually control four pins, two pins for one motor:

  • P1, P2 – the left motor
  • P14, P15 – the right motor

First we take a look of how to control one motor, if the motor rotate in the opposite direction, just switch the red/ black wire:

P1 – H P1 – L
P2 – H Brake (can NOT rotate the shaft) Rotate CW
P2 – L Rotate CCW Nothing (can rotate the shaft)

Combining two motors then we can make robot moving around, you can further adjust the motors’ speed to make more detailed contol of our robot:

Right motor – Forward Right motor – Backward
Left motor – Forward Robot moves forward Robot turns right
Left motor – Backward Robot turns left Robot moves backward

Makecode

We will use MakeCode graphical IDE to program RK-micro:bit Car. The code should be quite straight-forward and fun, enjoy!

STEP1: In the on start event, qw declare a variable for the motor speed and use it to P13 and P0.

  

STEP2: The code in forever will run continuously, which means that it will keep looping until you unplug the microbit. 

Since the IR light sensors is connected to P12, and it will return 1 and 0 when it detects the black track and white ground. We can take advantage of this to make a zigzag line-following robot.

In the video, you can see we put the robot (IR light sensor) at the left-hand side of the black track, this means the robot will move toward the front right to seek for black track. If yes, then it will move toward the front left a little bit -> these two-conditional pattern will repeat forever.

So when the light sensor detects the black track (digital read pin P12 = 1), the robot will move toward the front right, otherwise it will move toward the front left.

Note: please modify the motor parameters to make your robot move even better!

Resource

The complete code can be accessed at the following webpage or download the HEX file.

 

 

 

RK-micro:bit robot – line-following programming tutorial(MakeCode)〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

MyGPTs –做一個具備指定技能的專屬 ChatGPT 吧!

$
0
0

前言

本週 OpenAI dev day 所發表各項更新中,其中一項令人讚嘆的就是 GPTs,使用者可以自行客製化你所需要的 ChatGPT,從 GPTs 主頁已經可以看到 OpenAI 所給出的各種 GPTs,例如 Writing coach, tech advisor, Game Time 等等。代表任何人都可以透過 GPTs 來做出專屬的 GPT 應用。例如國內知名研究者,尹相志老師,就推出了一個 [視覺成像] GPTs,點擊以下連結就能體驗別人所設計的 GPTs,可能性真的是無限啊!

本文將說明如何使用 GPTs editor 來自行設計出您專屬的 ChatGPT

注意:

  1. CAVEDU GPTs 尚未公開,還在調整中
  2. GPTs 目前只針對付費訂閱用戶使用,也就是說您必須是付費帳號才能使用別人做好的 GPTs
  3. 本文引用了許多 Facebook 好友的寶貴意見,如有不妥請告知,會立刻處理。

 

 

本文

請由此進入 GPTs editor 頁面,並根據以下步驟操作

  1. 點選 Configure,填入相關資訊,上傳一張主視覺照片(很重要),也可以加入一些常問的問題。

  2. 往下拉,看到一些進階設定,Knowledge 可以上傳您希望這個 GPTs 知道的內容,這邊我上傳了一些關於 tinyML 的 pdf 文件上去,但其他格式的檔案應該也可以。但根據李慕約先生(請往下看)的測試,整本民法丟進去是沒問題的 (約 140k token)

    右側的 Preview 畫面是測試介面,您可以多多測試看他是否真的有學到你所上傳的內容。完成之後就點選右上角的 Save,首次發布之後則會變成 Update。您可以自行決定這個 GPTs 的公開程度:Only me (本人) / Only people with a link (知道連結的人) / Public (可在 Explore 中被找到)

  3. 這些設定在GPTs發布之後都可以更改,滿意之後就發布吧。之後就可以在您的 ChatGPT 左上角的 Explore 看到它了!成就感是不是滿滿啊?也可以把這個 GPTs 分享給您的朋友喔 (再次提醒,對方也必須是付費帳號才能使用您所建立的 GPTs,OpenAI 這招真的是合理的高招啊~)

  4. 完成了?就這樣?對,可怕的地方恰恰在於 “就這樣“。你只要專注在自身專業就好,甚至文件都不太需要整理,至於模型怎麼呼叫、怎麼訓練、當然還是要做,但從 0 到雛形這一段真的快太多了,之後就可以看到各種專業客製化的 GPTs 任君挑選了!真是令人期待又害怕呀

日後隨著 OpenAI 與其他平台的競爭,一定還會讓各種功能更往前推進。各平台的商業競爭自然不在話下,但藉由 GPTs,非程式背景人士也能快速將其自身競爭力與知識精煉並封裝起來,藉由一個小小的對話平台發揮想像不到的效益!

CAVEDU 這十多年來當然也有一些累積,我們會試著做出聰明又有趣的 GPTs,希望很快能和大家分享喔!

網路高手們的分享

李慕約 Facebook – 民法小幫手

劉詩雁先生 Facebook

林啟維先生 [角色設定產生器]

Link: https://chat.openai.com/g/g-StH7G0VE2-jiao-se-she-ding-chan-sheng-qi-gpt

尹相志老師 [視覺成像]

Link: https://chat.openai.com/g/g-qQzgIhqV7-shi-jue-cheng-xiang

參考資訊

➡ OpenAI GPTs: https://openai.com/blog/introducing-gpts

➡ OpenAI Dev Day: https://devday.openai.com/

MyGPTs – 做一個具備指定技能的專屬 ChatGPT 吧!〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

手指點球遊戲結合 Arduino – Google Mediapipe

$
0
0

前言

我們針對 Google Mediapipe 已經發表過多篇教學文章,這套裝置端的機器學習工具目前已支援視覺(分類、偵測與分割)、文字與聲音(分類)。本文要使用手部 api 做一個簡易的點球遊戲,畫面上會隨機出現不同顏色的球,點擊三次之後球消失,並撥放對應音效。並且可透過 USB 傳輸線來控制 Arduino 的 LED 亮起。

目前CAVEUE已發表的 Mediapipe 專題包含:

阿吉老師也很榮幸受邀到今年的 DevFest Taipei 2023 分享使用 Mediapipe 結合邊緣運算的小小心得,投影片如下,歡迎看看喔

本文

本專題分成兩端:Python 與 Arduino,依序說明如下:

python程式碼

您需要先安裝 mediapipe 與 pypserial 函式庫,請在終端機中輸入以下指令來安裝:

注意:如果您沒有 Arduino,只要把以下程式碼中的 ser 相關都註解掉就可以執行了,例如:

ser = serial.Serial(COM_PORT, BAUD_RATES)
pip install mediapipe

完整Python端程式碼如下,註解都在程式碼中,相當好理解。您可以參考 #164 開始的計算食指指尖位置與圓心之間距離 d,如果 d < r (圓半徑),代表碰到球了。

每次觸碰球就會修改球的透明度 ( alpha -= 0.33),並在碰觸到三次之後播放音效並發送指定給 Arduino ( ser.write(str(light).encode()) )

mediapipe hands api and send data to Arduino
import serial
import argparse
import cv2
import time
import numpy as np
import math
import mediapipe as mp
import random
import pygame

########## 手部追蹤偵測 #############
class handDetector():
def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):
self.mode = mode
self.maxHands = maxHands
self.detectionCon = detectionCon
self.trackCon = trackCon

self.mpHands = mp.solutions.hands
# self.hands = self.mpHands.Hands(self.mode, self.maxHands,
# self.detectionCon, self.trackCon)

self.hands = self.mpHands.Hands(self.mode, self.maxHands,
min_detection_confidence=self.detectionCon,
min_tracking_confidence=self.trackCon)

self.mpDraw = mp.solutions.drawing_utils
def findHands(self, img, draw=True):
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
self.results = self.hands.process(imgRGB)
# print(results.multi_hand_landmarks)

if self.results.multi_hand_landmarks:
for handLms in self.results.multi_hand_landmarks:
if draw:
self.mpDraw.draw_landmarks(img, handLms,
self.mpHands.HAND_CONNECTIONS)
return img

def findPosition(self, img, handNo=0, draw=True):

lmList = []
if self.results.multi_hand_landmarks:
myHand = self.results.multi_hand_landmarks[handNo]
for id, lm in enumerate(myHand.landmark):
# print(id, lm)
h, w, c = img.shape
cx, cy = int(lm.x * w), int(lm.y * h)
# print(id, cx, cy)
lmList.append( [id, cx, cy])
if draw:
cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
return lmList

def play_background_music():
pygame.mixer.music.load("bgm.mp3")
pygame.mixer.music.play(-1)

def play_good_sound():
good_sound = pygame.mixer.Sound("good.mp3")
good_sound.play()

def play_bad_sound():
bad_sound = pygame.mixer.Sound("bad.mp3")
bad_sound.play()

def main():

pygame.init()

# 設定音量(0.0 到 1.0 之間)
pygame.mixer.music.set_volume(0.8)

############## 各參數設定 ##################
pTime = 0
minPwm = 0
maxPwm = 255
briArd = 0
briBar = 400
briPer = 0

############## 指定WEBCAM和Arduino Serial Port編號的指令 ##################

parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--video', help='Video number', required=False, type=int, default=0)
parser.add_argument(
'--com', help='Number of UART prot.', required=False)
args = parser.parse_args()

COM_PORT = 'COM'+str(args.com)
BAUD_RATES = 9600
ser = serial.Serial(COM_PORT, BAUD_RATES)

args = parser.parse_args()


############## WEBCAM相關參數定義 ##################
height = 1080; width=1920
wCam, hCam = height, width
cap = cv2.VideoCapture(args.video) # 攝影機編號預設為0,也可以輸入其他編號!
cap.set(3, wCam)
cap.set(4, hCam)
detector = handDetector(detectionCon=0.7)

count=0
score=0
hp=3

circle_radius = 50
circle_y, circle_x=50,random.randint(circle_radius, (width - circle_radius)*0.6)
circle_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0,255))
finger_radius = 20
finger_touching=False
alpha = 0.99 # 設定透明度,這裡設定為50%
play_background_music()

try:

while True:
success, img = cap.read()

img = cv2.flip(img, 1) # 加入這行進行左右翻轉

img = detector.findHands(img)
mask = np.zeros(img.shape, dtype=np.uint8)
lmList = detector.findPosition(img, draw=False)
#print(lmList)
light=0

# 畫圓點
circle_center = (circle_x,circle_y)
cv2.circle(mask, circle_center, circle_radius, circle_color, -1)
cv2.putText(mask, f'{count}', circle_center, cv2.FONT_HERSHEY_COMPLEX, 3, (255,255,255),3)
#圓點自由落體
circle_y+=3 #7

#掉到最下面
if circle_y>=(height - circle_radius)*0.7:
circle_y, circle_x=50,random.randint(circle_radius, (width - circle_radius)*0.6)
circle_color = (random.randint(100, 200), random.randint(100, 200), random.randint(100,200))
count=0
alpha=0.99
hp-=1
if hp>0:
play_bad_sound()

# 顯示文字
#cv2.putText(img,f'circle_position{circle_center}',(40,150), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0), 3)
#cv2.putText(img, f'alpha {alpha}', (40, 200), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0), 3)
#cv2.putText(img, f'count {count}', (40, 100), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0),3)
cv2.putText(img, f'Score: {score}', (40, 100), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 153, 255),3)
cv2.putText(img, f'HP: {hp}', (40, 150), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255),3)
#cv2.putText(img, f'color: {circle_color}', (40, 200), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255),3)

if len(lmList) != 0:
x,y=lmList[8][1],lmList[8][2]
finger_position=(x,y)
cv2.circle(img,finger_position,finger_radius,255,-1)
#cv2.putText(img,f'finger_position{finger_position}',(40,300), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0), 3)

# 計算食指位置和圓點位置的距離
distance = math.sqrt((finger_position[0] - circle_center[0])**2 + (finger_position[1] - circle_center[1])**2)
#cv2.putText(img, f'distance {distance}', (40, 250), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0),3)

#判斷是否碰觸
if distance < circle_radius + finger_radius and not finger_touching:
alpha -= 0.33
count += 1


finger_touching = True

elif distance >= (circle_radius + finger_radius)*2 and finger_touching:
finger_touching = False

# 碰三次
if count==3:
circle_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0,255))
#circle_y, circle_x=random.randint(circle_radius, (height - circle_radius)*0.7),random.randint(circle_radius, (width - circle_radius)*0.6)
circle_y, circle_x=50,random.randint(circle_radius, (width - circle_radius)*0.6)
circle_center = (circle_x,circle_y)

#time.sleep(0.5)
count=0
alpha=0.99
score+=1
light=1
play_good_sound()

#送出數值給Arduino
ser.write(str(light).encode())

#計算每秒跑幾張
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 3)

if hp<=0 :
result = np.zeros(img.shape, dtype=np.uint8)
cv2.putText(result, f'GAME OVER', (150, int(height*0.6/2)), cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 255), 3)
cv2.putText(result, f'Score: {score}', (540, int(height*0.6-200)), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 153, 255), 3)
pygame.mixer.music.stop() # 程式結束時停止背景音樂
else:
# 使用 addWeighted 函數混合圖像
result = cv2.addWeighted(img, 1, mask, alpha, 0)


#顯示畫面
cv2.imshow("HandDetector", result)

#按q停止程式
if cv2.waitKey(10) & 0xFF == ord('q'):
break
except KeyboardInterrupt:
ser.close()
cap.release()
cv2.destroyAllWindows()

if __name__ == '__main__' :
main()

Arduino 端程式

Arduino 端程式就更簡單了,等候來自另一端的指令,進行 ASCII code 處理之後,用於控制 LED 亮暗。在此保留之後的彈性所以使用 analogWrite(LEDPin, 255); 語法,效果等同於 digitalWrite(LEDPin, HIGH);

//Arduno digital 腳位
int LEDPin = 7;
String number = "";
int i = 0;
int pwm_val; // 改為整數類型

void setup()
{
//各協定通訊初始化
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
}

void loop()
{
//執行command副函式
command();
}

long command()
{
while (Serial.available())
{
if (i == 0)
{
number = "";
}
// 扣除ASCII碼值
number += Serial.read() - 48;
i++;
}
// 字串轉換成整數值
pwm_val = number.toInt();
i = 0;

Serial.println(pwm_val);

//PWM控制LED
if (pwm_val==1)
{
analogWrite(LEDPin, 255);
delay(1000);
analogWrite(LEDPin, 0);
}
}

執行

執行以下指令即可看到畫面,伸出您的手指來點點球吧!可在畫面左上角看到 FPS、Score 與 HP 三個遊戲參數。

python mp_finger.py

如果要搭配 Arduino,則請先燒錄好 Arduino sketch 之後並修改以下指令的 COM 號:

python mp_finger.py --com 3

手指點球遊戲結合 Arduino – Google Mediapipe〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

2024 = CAVEDU 15 / 2023年度報告

$
0
0

CAVEDU 15

各位好友們,今年是否也是豐收精彩的一年?CAVEDU 明年要邁入第十五年了,這個數字已超過我目前人生的1/3,我居然看著腦波弱老闆的大兒子上高中了!當年不是還那麼小跟在我們後面跑嗎?現在都比我高了。本文想和您分享 CAVEDU 在 2023 年的成果、2024 年的展望以及阿吉的一些心底話。

2023成果

    總結今年所涉獵的領域,可分成邊緣運算,系統整合課程活動等主要方面。說明如下。

1 邊緣運算方面:

單板電腦以NVIDIA Jetson 平台為主,另外也涵蓋了 Raspberry Pi、ASUS Tinker 與 Lattepanda 等。這類單板電腦可執行完整的作業系統,效能也比MCU更好。從Raspberry Pi 3 足以執行簡易的深度學習模型之後,我們就想為教學現場整合出一台合適的純視覺機器人平台,也在2018年與台灣微軟合辦了多次工作坊,使用 Azure 雲服務加速訓練神經網路模型,最後部署在 Raspberry Pi 小機器人上,可以循線並根據所看到的方向路牌來決定左轉右轉。相關成果已寫在 [實戰AI資料導向式學習|Raspberry Pi x 深度學習 x 視覺辨識] 一書中。

實際執行請參考以下影片:

自從 NVIDIA Jetson Nano 於2019年推出之後,我們發現邊緣運算 (或所謂  Edge AI) 會有全新的風貌,因此將火力集中在 Jetson 全家族,結合了 NVIDIA 深度學習機構所推出的認證課程 [Jetson Nano 上的人工智慧技術入門] 與 [在 Jetson Nano 邊緣端打造影像人工智慧應用程式]

我們可是一咖皮箱(裝著20套Jetson Nano)全台跑透透去上課呢,阿吉也因此連續兩年榮登 NVIDIA Jetson AI 白金級大使 (延伸閱讀)。除此之外,為了方便上課,我們也考量了上課可能的各種情境,包含教室螢幕VGA/HDMI甚至網路狀況,為的就是讓同學們能有最順暢的上課體驗。目前 CAVEDU 針對 Jetson 整合了非常多實用的內容。包含以下:

CAVEDU 把我們對於 Jetson Nano 的精華寫成本書 [ 初學Jetson Nano不說No-CAVEDU教你一次懂 ]。有點奇怪,正體中文就只有我們寫… 希望 2024 有機會改版囉

MCU開發板與微型機器學習:從Arduino、LinkIt 7697、Wio Terminal 到 Raspberry pi pico,各類 maker / 物聯網開發板,搭配好用的 IDE 以及豐富的周邊讓我們的創作多彩多姿。但我們想要的東西更多,所以運用微型機器學習 (tinyML) 技術來從傳統的感測器資料中獲得更多的資訊。我們已經針對這主題辦理過很多研習與直播,然後也帶入課程當中 (阿吉 2023 年在台科資工的學期課程 [嵌入式系統設計]),專題項目包含以下:電子鼻、電子舌、桌球姿態分析、腳踏車行為分類、震動異常偵測與智慧氣象站等。上課都是實作,連收資料都要自己來 (請參考以下照片)

阿吉也在 2022 年由 tinyML 基金會也曾於 2022 邀請阿吉分享 “Delivering ML concepts into K-12 curriculum“,並翻譯了 [TinyML經典範例集]。

物聯網屋:

這個有趣的小專題經過多年的改版之後,現在可是整合的很不錯,除了支援各式各樣的開發板之外,與雲服務也都整合的很好,包括LINE 、IFTTT、thing speak等等。針對這個主題寫了 [智慧物聯網大冒險 – 4P程式指南] 一書。

2 系統整合方面:

智慧農業:這是AIoT的一個重要應用場域,也是邊緣運算的一個重要的實踐的情境。等於場域中需要多個開發板各自連接不同的感測器,並且需要考慮到裝置執行時間的跨度以及與雲服務的整合程度。希望可以透過雲服務來控制開發板或是來接收並呈現各樣感測器讀數或開發板內部資料。實作資料請參考本文

5G 與 元宇宙  – 我們將 5G 視為基礎建設,只有在各項基礎建設都普及的情況下,將聯網應用帶入課程當中才成為可能。講師群也有執行與錄製相當多的課程

元宇宙方面,我們以ROS2自駕車模擬、5G基地台訊號強度模擬作為主要硬體結合軟體的評估項目。例如使用合成資料來訓練AI模型,或者是在虛擬平台中模擬機器人的行為等。

NVIDIA 相關資料中看到,這些應用目前已經有很落地的應用,或是我們可以把範圍聚焦到工業元宇宙結合數位雙生,應該更有感覺。今年也在高雄亞灣科學園區舉辦過兩場相關的研討會與工作坊,以及台中教師增能研習。

3 課程活動方面:

    老師與學生對於軟體硬體上的操作說明常有各種理解不同的狀況發生,實作教學在實務上還是有很多需要細細考量的地方,教學場域尤其如此。相關資料請參考 CAVEDU blogCAVEDU gitbook

  • AIGO高中職生扎根計劃這個活動已經參加第四年了,CAVEDU主要是負責實體課程與應用競賽。前兩年因為疫情的關係,我們與全台灣的學生們一起用線上課程的方式實施,這類課程執行起來有非常多的環節。前期需要預錄大量的課程影片以及各種滾動調整,我們也從中學到很多啊。

  • 科普環島列車:這是今年執行一個非常有趣的活動,我們教高中生成為活動的講師,讓他們在火車上帶小學生進行各式各樣的AI科普課程,火車在每一個站點的移動時間變成時作時間!我們完成使用各樣的移動設備、移動電源設計教學場域,啟動移動式實作教室。
  • NVIDIA Jetson DLI 課程,道路挑戰賽。從2020年台北教育博覽會開始辦理之後,我們每年都會辦理二到三場,而且是全台走透透去辦。從前期研習課程,到設備提供與諮詢,最後熱熱鬧鬧地辦一場比賽,這裡面真的很多要注意的環節。當然也歡迎與我們洽詢來辦理各種有趣的比賽喔。

https://blog.cavedu.com/2022/01/05/2021-rk-jetbot-competition/

https://blog.cavedu.com/2022/06/21/2022-rk-jetbot-competition/

https://blogs.nvidia.com.tw/2021/05/03/a-16-year-old-high-school-girl-win-robot-contest-by-jetson-nano/ 

4 一些有趣的數字

    以下是我在整理今年成果的時候,發現了一些有趣的數字:

  • > 300 場研習,總時數 > 1200 小時 -> 請掌聲鼓勵

 

  • 1本翻譯書,今年是CAVEDU從2009年以來,首次沒有自行出版書籍的一年。前幾天和出版社的業務聊到,當年出版 CAVEDU 第一本書 (猜猜看是哪一本?) 的時候居然是2012年,那個時候對於書架構的考量還有鋪陳都很初步,真的是要很感謝當時出版社同仁們的包容與鼓勵。講歸講,我還是很喜歡文字工作的,所以翻譯了[凡人也能懂的白話人工智慧演算法(2022)] 

  • 100場生成式AI研習:從律師事務所、會計師事務所、設計工作室到全台北市的校長資訊組長們,我都有分享過這個主題。大家問的問題五花八門,但都想知道這類 AI 工具如何讓我們的生活更好或是如何把這些帶到教學現場中(教學樣態如何變化?)
  • 40 場直播,主題涵蓋了生成式AI、邊緣運算、物聯網智慧農業、機器人。我們維持每個禮拜一到二場的的頻率周期性的分享相關的主題。有新的主題,我們就初步玩玩看,有趣就直播,直播完再測試並整合到我們現有的服務或是產品線。

  • 第一名的 NVIDIA Jetson AI 白金大使。今年成績是 440 取得認證 / 694 上課人次,但根據”內參資料”,數量應已超過1000人!) 。這不但讓阿吉成為白金級大使,而且是白金第一名!歡迎加入 Jetson AI Certification Program,您也可以!

  • 一次 App Inventor 正體中文翻譯大更新:這真的一年一次就夠惹… 要自誇一下,在完全無償的情況下還能夠多年投入這麼多心力的話,一方面是愛,一方面就真的是覺得 App Inventor 很棒,值得我們用各種方式來支持它(如果真的要拉關係的話,可以說敝團隊從當年樂高 RCX 開始就已經非常感謝MIT了) 。歡迎多多使用 App Inventor 中文學習網喔!

2024展望

  • 課程活動

      莫忘初衷,CAVEDU 會繼續提供優質的課程與諮詢服務,這是我們的強項也會持續推進!

  • 系統整合:

            我們沒有辦法影響商品的售價,但可以想辦法讓你使用得更久也更容易。做法就是豐富使用情境,完善技術文件,讓任何有心想要學習的人看著我們的文件都可以跟著完成。按圖施工,保證成功,一直都是我們的目標!這可不是隨便說說。例如 [RK-NVIDIA® JETSON Nano™ 2GB 開發套組-配件],為了配無線網路網卡、記憶卡與電源,我們可是把市面上找得到的規格都測試一遍,也寫了相當完整的技術文件喔。

            當然這一類東西變化的是很快的,以往能夠執行的語法或是範例,某一天(可能就是上課當天QQ) 可能沒有辦法執行了,所以我們時不時都要回頭去重新修改一下相關的工具以及教學的內容。多虧了ChatGPT,這件事情以往做起來很痛苦,但是現在就變得輕鬆多了。

  • Youtube 頻道

           CAVEDU YouTube 頻道以往就是拿來做上課紀錄,但隨著我們對於製作線上課程的影片更加熟悉之後,預計2024年會投注更多心力在這裡,請各位先訂閱起來囉!

  • 發揮影響力

文字的力量是很大的,傳遞正確的資訊更是有價值的事情。CAVEDU 當年就是從 Yahoo 奇摩部落格開始紀錄對於機器人的點滴成果,慢慢累積就會被看見。你願意的話,今天就可以開始!本團隊除了阿吉以外,還有多位講師都取得了 NVIDIA Jetson AI 專家的資格以及其他平台的專業證照。許多開發者社群或是競賽評審也看得到我們的身影喔!

另一方面,我們也有 LINE 社群與 Facebook 粉絲頁,歡迎加入喔!

一些心底話  

一些淺見,大家勿笑。都是一些微不足道的小事情,但今年水到渠成的感覺特別明顯。

  • CAVEDU已到非常有默契的水準:都是小事但很順,很感謝我有許多優秀的同事們攜手前進 ,包含資訊流通、活動支援後勤規劃等等。
  • 心境上的轉變
    • 本身的感受力、素養(或經歷):自己唱過一陣子合唱團,明白音樂是否動聽,並不全然在於歌唱者或演出者本身的技巧,反而是觀眾比較容易被演出者的人生歷練或經歷所感動,所以常常聽一些樂團或是媽媽團演出時會非常感動,應該就是這個原因吧。
    • 換成最近很熱門的 AI 圖片生成,如果我想要描述天空,但詞彙只有 beautiful sky,那效果會比 magnificant 或 spectacular 遜色不少。這牽涉到自身對周遭世界的觀察與體認。
  • 自己如何使用ChatGPT這些工具:自從 ChatGPT 從 2022/11月底發布以來,各類生成式AI的應用已在我們的生活、工作各層面產生了相當大的影響,我們也看到了更多挑戰與機會。生成式AI這類工具的進步一日千里,但我們對於工具的期望也日益增高,你是否也感受到了 ChatGPT 的不足之處?大家必然同意,問對問題,才有機會得到好的答案。那麼 “如何問對問題?”,這個問題早在生成式AI之前就是所有人都要面對的課題了,對吧?
  • 維持可管控的進度:做就對了,運用各種方式記錄下來,讓自己維持在一個有進度的情況下。這些東西其實都是老生常談,但是如何做得好、做得穩、做得久才是關鍵。所以我很喜歡用各種方式紀錄自己的進度,例如發文幾篇、翻譯幾頁、上了幾小時的課等等。
  • 良好作息:今天做不完?那就去睡覺啊,如果長期處於被進度追著跑,我會和同事們討論是否一開始估計時程或自身產能就不對了?可以熬夜一天,不可能熬夜一週。健康第一!
  • 千里之行,始於足下
    • GTC21 有一場線上分享
    • 以及在 2023 Computex 把我們所寫的 Jetson Nano 書拿給黃仁勳先生簽名。
    • 這些都需要累積,就看您什麼時候開始。我們可以,您也沒問題!

 

2024 = CAVEDU 15

不論是按讚分享、參加課程或購買任何商品服務,對我們來說都是非常大的支持。感謝有您,CAVEDU才能成長茁壯,提供更棒的教學內容!所有新消息,請密切關注CAVEDU相關頻道!感謝您一直以來的支持,預祝新年快樂!

重要連結

除了文章中已經做好的超連結之外,以下是CAVEDU的重要資訊:

 

 

 

 

2024 = CAVEDU 15 / 2023年度報告〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

NVIDIA®Jetson Nano™ 8小時線上課程,完成可拿證書喔!

$
0
0

有興趣的朋友請由此報名,需要註冊帳號,再由註冊的email 來開始上課(建議直接使用GOOGLE帳號直接登入註冊,由信箱註冊密碼長度及安全性須設定複雜較容易忘記)。

根據網站表示完成課程者可取得證書,一起來挑戰吧!

本課程有中文以及英文版本使用 RK-NVIDIA® JETSON Nano™ 2GB 開發套組以及RK-NVIDIA® Jetson Nano™ B01套件大全套 皆可執行此課程:

透過 Jetson Nano 開發人工智慧應用

https://courses.nvidia.com/courses/course-v1:DLI+S-RX-02+V2-TW/

Getting Started with AI on Jetson Nano

https://courses.nvidia.com/courses/course-v1:DLI+S-RX-02+V2/

阿吉老師小提醒:課程硬體購買連結都使用 Amazon,但機器人王國商城都幫大家測試過也準備好了,RK-NVIDIA® Jetson Nano™ B01套件大全套。當然您還是可以在Amazon上面購買沒問題喔。

以下內容翻譯自報名網站


學習目標

透過NVIDIA Jetson Nano Developer Kit,maker、自學開發者以及嵌入式科技狂熱者已經能掌握AI所展現的強大威力了。這片易用且威力無窮的單板電腦可以同時直行多個神經網路,用途超廣!包括影像分類、物件偵測、物件分割與語音處理等等。本課程將在您個人的 Jetson nano 使用Jupyter iPython notebooks 來打造一個電腦視覺模型來完成深度學習影像識別專題。

您會學到的內容:

  • 設定 Jetson Nano 單板電腦與攝影機
  • 收集分類模型所需的影像資料
  • 標註用於迴歸模型的影像資料
  • 根據您的資料訓練神經網路並建立模型
  • 在Jetson Nano上使用您所建立的模型進行推論

完成本課程之後,您將有能力使用Jetson nano 完成一個深度學習分類與迴歸模型。

課程細節

  • 基礎:對Python的基礎理解 (有很好,但並非必須)
  • 要用到的軟硬體:PyTorch, Jetson Nano 單板電腦
  • 證書:
  • 考試方式:選擇題

需要的硬體

NVIDIA Jetson nano 大全套

  • NVIDIA Jetson Nano Developer Kit
  • High-performance microSD card:至少32GB
  • 5V 4A 電源供應器,2.1mm 圓形接頭 (購買)
  • 2-pin jumper (買我們的套件包就送給您一個!):需安裝於 Jetson Nano 板子上才能用圓形接頭供電 (請參考這裡)
  • Logitech C270 USB Webcam,也可改用 Raspberry Pi Camera Module v2 (購買)
  • USB cable:Micro-B To Type-A 資料傳輸線 (購買)
  • 可上網的電腦,用於下載 img 檔並燒錄SD卡

更多資訊請參考:NVIDIA Deep Learning Institute.

 

2024/01/04 更新課程資訊等連結

NVIDIA®Jetson Nano™ 8小時線上課程,完成可拿證書喔!〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔

$
0
0

大家好,如果您是對於AI有興趣,想要跨入AI領域的初學者,或是教育單位,那麼您一定要來看本篇文章!!

 

本篇要來帶大家進入NVIDIA Jetson Nano 2GB(以下簡稱Jetson Nano 2GB)的世界裡面,Jetson Nano 2GB提供了一個適合於AI教育和初學者的學習平台,讓各位可以輕鬆接觸並學習AI的基本知識和技能。

 

在這篇部落格中,我們將從映像檔燒錄開始,後續系列文將一步步指導您如何設置您的Jetson Nano 2GB,並且不需接上螢幕、鍵盤、滑鼠的方法,讓我們一起開啟學習之旅吧!

撰寫/攝影 許鈺莨
時間 1 小時 材料表
難度 1(滿分5)

從映像檔燒錄開始,到最後的硬體設定,會分成下列幾個步驟說明。

 

1、Jetson Nano 2GB 的規格介紹

2、燒錄映像檔

3、硬體設定

 

1、Jetson Nano 2GB 的規格介紹

  • Jetson Nano 2GB 的硬體規格簡介

以下為Jetson Nano 2GB 硬體規格介紹

 

上述的規格中,MicroUSB的部分需要注意,其設備是只能跟電腦連接時的訊號輸出孔,而不具備電源輸入的。因為Jetson Nano 4GB的MicroUSB是可以當作5V的電源輸出的。

2、燒錄映像檔

  • 下載映像檔

網站下載 Jetson Nano 2GB映像檔,連結:

https://www.dropbox.com/scl/fo/x0ajlvzr3xhej0f7hx05u/h?rlkey=gect3acstt6l5zveafj2ovni0&dl=0

 

請下載檔名為2GNANO_DLI_BuildingVideoAI_240110_有線共用.zip,檔案過大請耐心下載。

  • 準備 SD 卡和讀卡機

建議初學者購買RK-NVIDIA® JETSON Nano™ 2GB 開發套組,裡頭就有包含三星128GB容量的SD卡。

 

另外請準備SD卡讀卡機,如果是筆記型電腦應該有內建的讀卡器。

  • 使用映像檔燒錄工具

這邊建議使用balenaEtcher (較優)映像檔燒錄軟體,因為可以快速偵測到SD卡的磁碟區,再來不需解壓縮檔案就可以直接燒錄。

當然您也可以使用另一套常用的Win32Diskimager ,但需要將映像檔先解壓縮再燒錄。

balenaEtcher有提供Windows、macOS以及Linux系統版本,請按照您電腦適合使用的版本進行安裝,本篇以Windows x64 安裝版為例。

 

  • 燒錄映像檔到 SD 卡,詳細步驟說明

開啟軟體後,先點擊Select image,選擇剛剛下載的Jetson Nano 2GB映像檔案。

 

將SD卡插入讀卡機,在軟體中點擊  Select drive,選擇SD卡的磁碟機編號,點擊Continue後,再點擊Flash就開始在SD卡安裝作業系統。

(題外話,我用其他的映像檔燒錄軟體時,因為沒有軟體標示儲存空間,所以不小心選到1TB外接式行動硬碟的磁碟區,導致硬碟資料誤刪,結果檢測結果需要花費快萬元,流淚~)

 

軟體開始燒錄映像檔至SD卡,燒錄完畢會出現Validating(驗證中) 。根據經驗燒錄SD卡完成後就可以使用了,可以勇敢地把驗證的過程取消。

 

請注意,映像檔燒錄完畢後,SD卡會新增許多磁區,WINDOWS作業系統會跳出需多磁區畫面(平常有更新Windows的電腦不會發生),並要使用者格式化SD卡,這步驟是因為SD卡的內容已變成Linux Ubuntu作業系統了,所以Windows作業系統無法正常顯示SD卡磁區內容,可放心將SD卡退出,並將micro SD卡接在Jetson Nano 2GB上即可。

 

如果點擊 “Flash“後一直無法燒錄,請到Windows Defender允許使用balenaEtcher ,您若不希望更改設定,也可以使用Win32DiskImager。

 

4、硬體設定

  • 插入燒錄好的 SD 卡

接上安裝好作業系統的SD卡,Jetson Nano 2G的SD卡插槽是彈跳式的,插入SD卡後不會凸出來。

 

  • 使用Type-C變壓器供電

Type-C變壓器接上之後,在Micro USB孔附近的綠色燈號會亮起,代表已經開機。

 

  • 接上Micro USB訊號線

首先是透過Micro USB 遠端連線,當開機時在Micro USB孔接上Micro USB線,另一頭接上電腦,如下圖所示。

 

若映像檔燒錄成功,接上Micro USB線時,在電腦的資料夾中左邊會出現L4T-README的磁碟機,當然有的電腦會自行跳出來,如下圖所示。

 

本篇Jetson Nano 2GB 燒錄映像檔先分享這邊,下一篇要分享Jetson Nano 2GB三種遠端連線的方式,我們下篇見!

取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。


取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法

$
0
0

 

大家好,之前有分享過透過映像檔燒錄軟體,來燒錄  Jetson Nano 2GB的映像檔,本篇將進一步探討「NVIDIA Jetson Nano 2GB 與電腦進行遠端連線控制的三種方法」。這將涵蓋如何從電腦遠端控制 Jetson Nano 2GB,包括不同情形和方法,這對初學者或教育領域的使用者是必備知識,以下就開始吧!

 

撰寫/攝影 許鈺莨
時間 1 小時 材料表
難度 1(滿分5)

本篇主旨在於建立遠端連線,會分成下列幾個步驟說明。

  1. 透過 Micro USB 遠端連線:設定使用 Micro USB 遠端連線
  2. 網路有線連線:使用網路線和 Jetson Nano 2GB遠端連線
  3. 網路無線連線:使用無線網卡(WI-FI dongle)和 Jetson Nano 2GB網路連接
  4. 關機

 

以下分享3種電腦和Jetson Nano 2GB連線的方式,但是以下方法的共通點,就是取得Jetson Nano 2GB 的IP,和使用遠端連線軟體。

所以需先下載遠端連線軟體—MobaXterm,下載軟體連結: https://mobaxterm.mobatek.net/download-home-edition.html

 

選擇並下載Portable edition 免安裝版本。

 

解壓縮後,開啟MobaXterm_Personal_23.6.exe

 

第一次使用會出現安全性警訊,請選允許存取

 

進到以下畫面就可以先直接進行下個有線或無線遠端連線步驟。 

但最後登入Jetson Nano 2GB並輸入帳號和密碼的步驟,這三種方法都是一致的,最後會在統一說明。

 

透過 Micro USB 遠端連線:設定使用 Micro USB 遠端連線

1.接上Micro USB訊號線

首先是透過Micro USB 遠端連線,當開機時在Micro USB孔接上Micro USB線,另一頭接上電腦,如下圖所示。

 

在電腦的資料夾中左邊會出現L4T-README的磁碟機,當然有的電腦會自行跳出來,如下圖所示。

 

2.使用遠端登入軟體

Nvidia 官方在設計使用Micro USB線連接時,會用預設的192.168.55.12的 IP。接下來,就接續前面使用MobaXterm遠端連線軟體的步驟。

按下 Session

 

再按下SSH

 

再到Remote host* 欄位,填入192.168.55.1

 

看到以下畫面,就已經連線到Jetson nano 2GB。

 

輸入Jetson Nano 2GB的帳號和密碼,帳號和密碼皆為jetson,且密碼不會顯示出來

密碼不會顯示出來!!!

密碼不會顯示出來!!!

密碼不會顯示出來!!! 連游標都不會動,很重要所以要說三次!!!

 

輸入完帳密後,見下圖所示

 

是否要記住密碼,按YES記住,下一次就不用輸入。反之,按NO後,下次登入要再次輸入。

 

成功登入畫面

 

網路有線連線:使用網路線和 Jetson Nano 2GB遠端連線

1.接上網路線

和Jetson Nano 2GB遠端連線的其中一種方式是藉由網路線連接,如下圖所示

 

另外電腦端需要有網路孔,網路線另一頭接至電腦

 

若像輕薄型筆電就要外接RJ-45轉接頭,見下圖。

 

2.電腦端設定共用

由於Jetson Nano 2GB本人沒有無線網卡,所以需要電腦分享IP給Jetson Nano 2GB。以下又分幾個步驟:

2-1開啟網路連線視窗

開啟後,會出現乙太網路  無法辨識的網路,那個圖示就是Jetson Nano 2GB的有線網路,筆者出現的是網路2。

 

2-2開啟WI-FI共用

對Wi-Fi的圖示按右鍵->內容

 

2-3選取家用網路連線

在Wi-Fi內容中,選共用分頁,在家用網路連線選擇乙太網路2,再選允許其他網路使用者透過這台電腦的網際網路連線來連線。

 

3.使用IP搜尋軟體

使用網路連線,不像接Micro USB一樣預設就有固定IP,所以要使用IP搜尋軟體,

筆者常用的軟體為Wireless Network Watcher (按我連結)。

解完壓縮後執行程式,下列也分成下列步驟:

 

3-1 到進階選項設定

選項->進階選項

 

3-2選擇乙太網路的選項

先勾選使用下列網路卡,再選乙太網路的選項

 

3-3開始搜尋Jetson Nano 2GB的IP

按下綠色撥放鍵,就會開始搜尋Jetson Nano 2GB的IP。

 

可以點兩下,可把IP複製起來。

 

4、使用遠端登入軟體

前面步驟相同,故從輸入Jetson Nano 2GB的IP開始,

Remote host* 欄位,貼入剛剛搜尋到的IP後按下Enter即可。

連線成功。

 

網路無線連線:使用無線網卡(Wi-Fi dongle)和 Jetson Nano 2GB網路連接

這步驟在最後一段才提,是因為使用者沒接螢幕的情形之下,需要先借助前面透過 Micro USB 遠端連線 網路有線連線 這兩種方法來設定,請繼續往下看。

 

筆者一樣分成幾個步驟:

1、外接Wi-Fi dongle

Jetson Nano 2GB 外接Wi-Fi dongle

 

2.手動連接Wi-Fi訊號

前段內文提到,需要Jetson Nano 2GB的IP才能夠連線。但由於考慮使用者第一次接無線網卡而且尚未接螢幕、鍵盤和滑鼠的做法,但又要Wi-Fi無線遠端連線,那要如何取得IP呢?

請使用者透過前面透過 Micro USB 遠端連線 網路有線連線 的方法遠端連線先登入Jetson Nano 2GB。以下是透過Micro USB已經登入的畫面。

 

在裡面輸入指令sudo nmtui,再按Enter

 

輸入密碼 jetson,密碼一樣不會顯示出來,打錯密碼會提醒你

 

啟用連線

 

無線網路選擇環境的Wi-Fi訊號名稱(SSID)。對了,Jetson Nano 2GB也可以接收到5G訊號。

 

輸入密碼,注意是Wi-Fi密碼,不是Jetson Nano 2GB的密碼jetson。

 

顯示連接中

 

連接完畢,用方向鍵選到<Back>,按Enter

 

到主頁選離開

 

接下來用指令去查Wi-Fi IP,輸入ifconfig,輸入後按下Enter

可以往下滑,找到wlan0的地方,有顯示IP

 

3.使用IP搜尋軟體

可以用Wireless Network Watcher來驗證,在選項->進階選項,勾選使用下列網路卡,再選擇Wi-Fi的選項

 

 

6、使用遠端登入軟體

前面步驟相同,故從輸入Jetson Nano 2GB的IP開始,

Remote host* 欄位,填入搜尋到的IP

 

連線成功

 

7、輸入Jetson Nano 2GB帳號密碼

步驟和透過 Micro USB 遠端連線相同,在此不贅述。

 

5.如何關機

遠端關機:透過遠端連線下指令關機 

在裡面輸入 sudo shutdown -h now,按Enter

 

 

 

再輸入密碼jetson,就會開始關機(一樣密碼不會顯示)

 

 

 

再來就可以看見Jetson Nano 2GB電源燈已關閉,把Type-C電源拔掉即可。

 

Jetson Nano 2GB的基本連線操作到這邊,想必各位會開始慢慢熟悉Jetson Nano 2GB,下一篇要分享的是透過Jetson Nano 2GB,開啟NV DLI 證書的專案,我們下次見囉~

 

 

 

取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

取得NVIDIA AI認證之前該做的二三事(下) – JetsonNano 2GB 開啟範例實作

$
0
0

本篇為<取得NVIDIA AI認證之前該做的二三事>的第三部曲,本篇是分享Jetson Nano 2GB如何開啟<透過 Jetson Nano 開發人工智慧應用>的範例實作,若讀者是剛剛入手Jetson Nano 2GB,或是要操作Jetson Nano 2GB,請先閱讀以下兩篇文章喔~

 

剛購入的新手看此篇—–<取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔>

 

Jetson Nano 2GB遠端連線操作看此篇—<取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法>

 

以下本篇開始。

 

撰寫/攝影 許鈺莨
時間 1 小時 材料表
難度 1(滿分5)

 

<透過 Jetson Nano 開發人工智慧應用>課程概覽

此課程將在您個人的 Jetson nano 使用Jupyter notebook 來打造一個電腦視覺模型來完成深度學習影像識別專題。

 

您會學到的內容:

  • 設定 Jetson Nano 2GB單板電腦與攝影機
  • 收集分類模型所需的影像資料
  • 標註用於迴歸模型的影像資料
  • 根據您的資料訓練神經網路並建立模型
  • 在Jetson Nano 2GB上使用您所建立的模型進行推論

完成本課程之後,您將有能力使用Jetson Nano 2GB完成一個深度學習分類與迴歸模型。

 

由於此課程在開始前,必須NVIDIA網站註冊,有關詳細內容介紹請看此部落格

<NVIDIA®Jetson Nano™ 8小時線上課程,完成可拿證書喔!>

 

Jetson Nano 2GB開啟範例

在此篇<取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法> 中已經有分享三種遠端連線Jetson Nano 2GB的方法,本篇由以下已經登入到Jetson Nano 2GB的畫面開始說明。

 

首先,確定是否有顯示jetson@jetson-2gNANO:~$ , 要開啟範例,就在$後面要打指令。

 

Jetson Nano 2GB接上Webcam

要在開啟專案之前,在Jetson Nano 2GB的USB孔必須要接上Webcam,下圖為C270網路攝影機(購買連結請按我)。

 

如下圖所示。

注意是Jetson Nano 2GB接上Webcam,不是接在電腦上!!

 

 

輸入指令

Jetson Nano 2GB的USB孔接上Webcam後,指令輸入: ./docker_dli_run.sh

 

接下來輸入密碼jetson,密碼一樣不會顯示,如下圖所示。

 

若密碼輸入正確,需等幾秒鐘後會顯示IP位址。如下圖所示。

因為是開啟Docker,所以會看見登入的身分變成root@jetson-2gNANO:/nvdli-nano#

 

 

開啟Jupyter notebook

上圖訊息顯示的IP不一定是正確的,所以注意以下說明。

 

開啟Jupyter notebook需用電腦的瀏覽器(建議用Google Chrome),在瀏覽器的網址列輸入<localhost:8888>,這邊的localhost有三種情形:

如果讀者是透過Mirco USB是遠端連線,則localhost為192.168.55.1

如果讀者是透過網路線,則localhost為192.168.1.100。

如果讀者是透過無線網卡,則localhost為IP掃描軟體

 

這邊以Mirco USB遠端連線的IP為例,在電腦的瀏覽器輸入192.168.55.1:8888

 

密碼輸入dlinano

 

成功開啟Jupyter notebook

 

 

開啟圖像分類(Image Classification)

路徑classification -> classification_interactive.ipynb

 

開啟圖像迴歸(Image Regression)

路徑regression -> regression_interactive.ipynb

 

 

如何跳出範例程式

在MobaXterm中先輸入exit,jetson nano 2GB 也會用粉紅的字回應,

之後身分又會返回jetson@jetson-2gNANO:~$。

 

接下來就看讀者要執行其他專案或關機就都可以囉~

 

關機指令忘了嗎?再複習一下:

輸入 sudo shutdown -h now,按Enter即可。

 

再輸入密碼jetson,一樣不會顯示出來

 

本篇的開啟<透過 Jetson Nano 開發人工智慧應用>範例實作分享就到這邊,我們下次見!!

 

相關文章與資源連結

<取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔>

 

<取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法>

 

<NVIDIA®Jetson Nano™ 8小時線上課程,完成可拿證書喔!>

取得NVIDIA AI認證之前該做的二三事(下) – JetsonNano 2GB 開啟<透過 Jetson Nano 開發人工智慧應用>範例實作〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

取得NVIDIA AI認證之前該做的二三事(番外篇) – JetsonNano 2GB 更新遠端網路線連線方法和開啟/關閉圖形化介面指令

$
0
0

本篇為<取得NVIDIA AI認證之前該做的二三事>的番外篇,主要是我們在透過有網路線連線的方式做了一些更動,還有分享如何遠端開啟Jetson Nano 2GB的圖形化介面。

 

若讀者是剛剛入手Jetson Nano 2GB取得NVIDIA AI認證,請先閱讀以下兩篇文章喔~

剛購入的新手看此篇—–<取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔>

Jetson Nano 2GB遠端連線操作看此篇—<取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法>

 

撰寫/攝影 許鈺莨
時間 1 小時 材料表
難度 2(滿分5)

 

透過網路線遠端連線

 

使用掃描IP軟體找出Jetson Nano 2GB IP

由於有些Jetson Nano 2GB映像檔有做更新,所以在有線網路連接時步驟有更新,可直接輸入固定IP就可以遠端操作連線,就免去電腦設定網路共用等複雜步驟,步驟如下。

當讀者使用遠端網路線連線,網路線接上電腦和Jetson Nano 2GB。

 

再來讀者的電腦需先取消共用。也就是共用分頁,然後允許其他網路使用者透過這台電腦的網際網路連線來連線的空格”不要”勾選。

 

注意:若讀者之前沒有開啟網路共用,則這步可以略過

 

再使用Wireless Network Watcher IP掃描軟體找出Jetson Nano 2GB 的IP位置。

要用有線網路的模式掃描,在選項>進階選項

 

勾選使用下列網卡>[192.168.1.XXX]乙太網路

 

掃描結果,會出現192.168.1.100的IP,點選兩下可以得知這是Jetson Nano 2GB的IP。

 

啟用遠端連線軟體

如果忘了登入步驟,這邊大致再說明連線方法。

開啟MobaXterm軟體,選Session

 

再按下SSH

 

再到Remote host* 欄位,填入192.168.1.100

 

筆者遇到登入MobaXterm時發生連線警告,內容是伺服器身分改變。有可能是筆者之前是為了測電腦的網路連線分享所用的映像檔,現在換新的映像檔而出現MobaXterm連線警告。不過出現按即可。

 

如果讀者沒出現以上訊息,略過即可。

 

 

輸入帳號和密碼,皆是jetson,密碼一樣不會顯示出來。

 

輸入帳密正確,會顯示是否要記憶密碼。按Yes,下次登入不用輸入;NO,則是下次還會輸入一次。

 

成功登入畫面。

 

 

此Jetson nano 2GB的網路線連線方式,多了一個可以直接不需要透過電腦的網路分享,而是直接把Jetson nano 2GB設定成伺服器端(Server),所以相對電腦變成用戶端(Client),使Jetson nano 2GB主動發IP給電腦。設計這種連線模式的好處是,之後連線IP會是固定的,且不限用戶端電腦。

 

開啟/關閉圖形化介面指令

由於Jetson nano 2GB的效能問題,這個段落就來分享開啟/關閉圖形化介面前後的記憶體效能,及開啟/關閉圖形化介面的指令。

使用者所拿的映像檔,是將圖形化介面關掉的,若接上螢幕,會看見以下畫面。

 

 

查詢記憶體效能和相關訊息指令

若要看記憶體效能,或相關訊息,可以在MobaXterm中輸入指令:

  • jtop

 

圖中可以看見沒開圖形化介面,記憶體效能已啟用了306M (約0.3G)。

若要看其他資訊,可以按數字1~7,按Q跳出。

 

開啟圖形化介面指令

接下來開啟圖形化介面,之後開機都會開啟圖形化介面,指令為(一樣要輸入密碼):

  • sudo systemctl set-default graphical.target

 

設定後要重開機,重開機指令(一樣要輸入密碼):

  • sudo reboot

 

讀者可以接螢幕看看是否有開啟桌面,會呈現綠色眼睛的圖示。

 

接下來一樣用jtop指令來看,開啟圖形化介面的記憶體效能。

 

以上圖所示,記憶體光是開圖形化介面就啟用了636M(約0.6G)。其實就已經占用快1G的效能了,剩餘記憶體約為1.4G可以用。

 

關閉圖形化介面指令

關閉圖形化介面,改回開機後直接進到命令列。

指令(一樣要輸入密碼):

  • sudo systemctl set-default multi-user.target

 

重開機:

  • sudo reboot

 

重開機後,接上螢幕就會出現指令列的畫面,和剛開始的一樣囉~

 

總結

本篇分享了透過固定IP來進行有線遠端連線,讓連線流程可以簡化,進而順利開啟範例程式。也分享了開啟/關閉圖形化介面指令,來比較開啟圖形化桌面的記憶體效能前後差異,其實大部分的範例都是可以用指令輸入後開啟程式。因效能有限,所以都是預設關閉圖形化桌面,而為了將效能有更有效的發揮。

 

<取得NVIDIA AI認證之前該做的二三事(上)- 在Jetson Nano 2GB 燒錄系統映像檔>

<取得NVIDIA AI認證之前該做的二三事(中)- NVIDIA Jetson Nano 2GB 遠端連線控制的三種方法>

<NVIDIA®Jetson Nano™ 8小時線上課程,完成可拿證書喔!>

 

 

取得NVIDIA AI認證之前該做的二三事(番外篇) – JetsonNano 2GB 更新遠端網路線連線方法和開啟/關閉圖形化介面指令〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

RK-JETBOT 避開障礙物功能多類別辨識教學 –收集資料篇

$
0
0

前言

NVIDIA JetBot 是基於NVIDIA Jetson Nano的一個開源自主機器人平台,而 Jetson Nano 是NVIDIA 推出的邊緣運算裝置之一,專為運行現代 AI 任務而設計,針對不同的算力需求提供儒門到高階的 Jetson 規格。JetBot結合了Jetson Nano的這些特點,使其成為進行AI實驗和開發的理想平台,特別是在機器人學、自動駕駛、機器視覺等領域。

本文將延伸 Jetbot 原廠教學,讓機器人可以辨識更多類別且可自行定義的障礙物!

CAVEDU 教育團隊針對 Jetbot 已辦理過多次 Jetbot 道路識別競賽,有興趣的單位歡迎洽詢,我們可提供研習、師資訓練與比賽相關設備!

本文

JetBot 原廠教學中已說明如何偵測自定義的物體,並根據偵測結果來執行不同的動作,簡單來說就是避開障礙物啦。但這份教學中只教了如何辨識兩種類別,如果要辨識更多類別並有著不同的行為,應該怎麼做呢?

撰寫/攝影 郭俊廷
時間 2 小時 (看要花多少時間收集資料) 材料表
難度 3(滿分5)

由於 JetBot 是一台純視覺的機器人,換言之,它對於環境的理解全部來自於攝影機,並經由自身的神經網路模型推論出它所看到的當下畫面屬於哪個類別,再讓 JetBot 執行對應的動作,例如前進、轉彎或停止等等。這些功能並非開箱即用,必須經過資料搜集、訓練模型之後,執行程式才會有避障的效果。

首先來看看訓練好的成果是如何呢?以這次蒐集的資料為例,機器人看到灰色的地板會直走 (代表無障礙物),看到紅色或藍色三角錐就會左轉或右轉 (代表兩種不同的障礙物,執行的動作也不同)。

深度學習

深度學習是機器學習的一個分支,它是以神經網路為架構對資料進行特徵學習的演算法。機器學習則是從過往資料和經驗中學習並找到其運行規則,而人工智慧則是包含所有機器學習和深度學習的範疇,期望能讓機器展現人類的智慧可以感知、推論、交流、學習、行動。

下圖是人工智慧、機器學習、深度學習的關係圖,這類圖片在網路上相當常見,可以自行搜尋一下或問問 chatGPT 囉。

 

機器學習可以分成三大分類,如下圖 (圖片來源),分成:

  • 監督式學習 (Supervised learning)
  • 非監督式學習 (Unsupervised learning)
  • 增強式學習 (Reinforcement learning)
  1. 監督式學習是有標準答案、標註 (Annotation),所有資料都加註了標籤(標註, labeled),每個標籤提供機器相對應的值來讓機器學習輸出時判斷誤差使用,常見應用以視覺來看的話,包含了視覺分類與物件偵測等等,當然學習的效果就取決於資料集品質囉。JetBot使用的是監督式學習,把搜集到的資料標註到相對應的類別,執行相對應的動作。
  2. 非監督式學習則是沒有標準答案,常見的應用包含分群、找關聯、編碼、異常檢測
  3. 增強式學習則是專注於如何讓智能代理(agent)在環境中採取行動來最大化獎勵。不同於監督學習,強化學習不依賴於預先標記的輸入/輸出對,而是通過智能體與環境的互動學習策略,從成功和失敗的經驗中學習。常見應用包含遊戲、機器人等等。

額外延伸還有自監督式學習,讓系統根據歷史資料產生答案,對部分資料進行標籤,電腦只透過有標籤的資料找出特徵並對其它的資料進行分類。

機器學習跟一般傳統程式學習的差別

傳統程式是使用規則加上資料,經過邏輯判斷之後得出答案,機器學習則是資料搭配正確答案,模型經過訓練後找出兩者之間的規則來處理後續新的資料
深度學習神經網路模型建立流程

深度學習通用的神經網路模型建立流程可以分為九個步驟:

  • Step 1. 定義問題
  • Step 2. 建立資料集
  • Step 3. 選擇評量的成功準則
  • Step 4. 根據資料量決定驗證方法
  • Step 5. 資料預處理
  • Step 6. 建立並訓練模型
  • Step 7. 開發出Overfitting的模型
  • Step 8. 粗胚的精雕細琢 – 調整參數使其變成通用模型
  • Step 9. 應用

JetBot 則把上述簡化為三大步驟:

  1. 資料搜集 (Data Collection)
  2. 訓練模型 (Train Model)
  3. 應用範例 (Live Demo)

接著要依序介紹這三大步驟如何操作使用,以及如何將原本的兩個類別改為三個類別的分類避開障礙物。考量到篇幅,本文只介紹到資料收集,接著會另寫一篇文章來介紹。

Jetbot 開機並連入其 jupyter notebook 介面之後,在以下路徑  home > jetbot_CAVEDU/collision_avoidance 可以看到以下檔案,如下圖紅框處。

其中以C3結尾的檔案,就是由原本雙類別避障功能修改過後的三種類別另存新檔後避開障礙物的檔案

  • data_collectionC3.ipynb (三種類別資料蒐集)
  • live_demoC3.ipynb (三種類別應用範例)
  • train_modelC3.ipynb (三種類別訓練模型)

Collision Avoidance – Data Collection  資料收集

首先點選 home > jetbot_CAVEDU/collision_avoidance/data_collectionC3.ipynb,就能打開以下的JupyterLab 的 Collision Avoidance – Data Collection 畫面。

data_collectionC3 這個檔案可以在收集資料後歸類到三種類別中,您可根據實際需要來修改相關設定,目前試過最多五種類別都沒問題。

第1個區塊設定要蒐集資料夾的命稱,更改 ‘   ‘ 引號裡面的紅字資料夾名稱例如我目前是三種類別的資料取名為class3

第2~3個區塊是設定功率模式與開啟風扇,這個的程式碼不需要也不建議修改,設定功率模式到10W可以加快系統的效能。

執行第4個區塊,該區塊程式會建立一個 224×224 像素的方塊來即時顯示攝影機畫面。

第5個區塊,原本的教學是建立一個 dataset 資料夾,裡面有 blockedfree 兩個資料夾,用來儲存後續要拍照分類的照片。

但本範例要調整為三個類別,所以改用 a b c三個資料夾來命名(請取名a b c因為這在之後辨識lable的時候會使用英文字母順序來辨識不同的標籤,後續會再說明),並且下面的建立資料夾指令也要呼叫OS指令建立三個對應的資料夾(如下圖紅框處)

第6個區塊,新增了按鈕來建立三個類別的圖片(按鈕上的文字可自行修改,例如我們有other、blue、red就可以寫上add這三個類別的說明),並顯示該類別有幾張照片的數量。請注意,此時只是建立元件,尚未決定按下按鈕後的行為,所以按鈕不會有任何反應,修改的地方如下圖紅框處,從原本的兩個類別變成三個。

第7個區塊將定義並連結按下上述三個按鈕所要執行的動作,按下add otheradd blueadd red按鈕會使用uuid1的命名格式,將圖片以 jpg 檔儲存到對應的資料夾中。通用唯一辨識碼(英語:Universally Unique Identifier,縮寫:UUID)

第8個區塊負責顯示攝影機的最新畫面,並顯示add otheradd blueadd red按鈕與相片數量的視窗,此時按下按鈕,就會拍照並儲存到相對應的資料夾。

第9個區塊,會斷開攝影機,代表不會再更新攝影機影像啦。請注意不要一口氣或從頭到尾一直執行所有區塊,這會導致攝影機連結中斷,請在資料收集完畢之後不再需要攝影機時,再執行此區塊。

第10個區塊會把所收集的資料壓縮成 .zip檔,預設檔名為 dataset.zip。請根據您執行的日期或場景來修改檔名,後續才不會搞混喔!更改以下dataset.zip的名稱來更改為壓縮的檔名,更改以下dataset名稱為我們預設使用的 class3。

第11個區塊執行後會關閉風扇,風扇將會慢慢減速不會瞬間關閉請耐心等候。

蒐集資料的方法

本範例將所要辨識的類別從原本的兩種,再多加了一種。您可根據實際需要來擴充更多類別,當然啦更多資料也會需要更多的訓練時間才能完成喔!

無障礙物(other)

這裡的照片會被歸類到 dataset/other 資料夾中。正前方無障礙物的場地上(各種光影角度跟位置),我知道看起來差不多,但收集資料就是要耐心囉~

藍色障礙物(blue)

這裡的照片會被歸類到 dataset/blue 資料夾中。請注意本範例的影像分類屬於一張圖一個標籤( one image one label),所以請不要在同一個畫面中同時出現兩種障礙物。更進階的物件偵測模型或甚至影像分割模型就能做到更好的偵測結果,但不是本範例所要討論的內容。

紅色障礙物(red)

這裡的照片會被歸類到 dataset/red 資料夾中。

關閉檔案和kernel

執行完這個 ipynb 檔案之後記得關閉 kernel 和使用視窗,即點選正在使用的視窗上的叉叉還有左邊目錄第二個小圖示,按SHUTDOWN關閉正在使用的所有kernel才可執行下一個檔案,才不會發生攝影機被占用等錯誤訊息。接下來執行完每個檔案都要這樣做,不然 Jetson Nano 的記憶體會被吃光喔 (原本就不多了呀)

總結

本文根據 JetBot 原廠教學,將原本的雙類別辨識擴充為多類別。由於篇幅考量,本文只介紹到收集資料,下一篇再介紹訓練模型與實際展示。

更多內容請點我,

 

RK-JETBOT 避開障礙物功能多類別辨識教學 – 收集資料篇〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

RK-JETBOT 避開障礙物功能多類別辨識教學 –訓練模型與下場比賽篇

$
0
0

前言

前一篇介紹了如何將 NVIDIA Jetbot 原廠避障範例從雙類別改為多類別,由於篇幅關係只講到收集資料,本文接續把後續兩大步驟,也就是訓練模型與實際展示一口氣講完喔!來看看 CAVEDU YTshort 吧,歡迎按讚訂閱分享開啟小鈴鐺喔

CAVEDU 教育團隊針 對 Jetbot 已辦理過多次 Jetbot 道路識別競賽,有興趣的單位歡迎洽詢,我們可提供研習、師資訓練與比賽相關設備!

本文

本文接續 [RK-JETBOT 避開障礙物功能多類別辨識教學 – 收集資料篇],介紹訓練模型與實際展示兩大階段,希望各位都能從中體驗機器人的魅力!

撰寫/攝影 郭俊廷
時間 2 小時 材料表
難度 3(滿分5)

訓練模型

在畫面左側的畫面中,開啟 home > jetbot_CAVEDU/collision_avoidance/train_modelC3.ipynb,這個檔案負責把前一個步驟所收集的資料集訓練成 pytorch 模型檔 (.pth)。

以下區塊是解壓縮資料集壓縮檔,如果不需要解壓縮的話可以跳過這一步驟。更改以下語法中的 dataset.zip 檔名來對應到您實際的檔案名稱。預設是註解掉程式無法執行,如要執行請取消註解即可。

第1個區塊設定訓練用資料集的資料夾名稱,更改底下的 class3 來對應實際名稱。

第2個區塊設定訓練後的模型檔名稱,請自由更改 ‘ ‘ 中內容來對應您要的模型檔名。第3個區塊設定訓練回合數預設是20回合,建議也訓練20回合以上。

執行第4個區塊,匯入PyTorch, NumPy, Python Imaging Library等函式庫,在此無需修改,日後等您對於程式架構更佳掌握之後再回頭試試看吧!

第5、6個區塊設定功率模式以及開啟風扇,這裡的語法同樣不需要也不建議修改。設定功率模式為 5W,是因為當訓練時Jetson Nano功率會使用到最大功率,如果使用MICRO USB供電時會因為輸出功率不足而斷電,如果改用 DC接頭供電就可以使用10W功率訓練。

第7個區塊會建立一個 dataset 實例,把 dataset 資料夾中的資料使用 torchvision.datasets 套件包與 torchvision.transforms數據包來分類跟轉換資料。

第8個區塊將資料集拆分為訓練集和測試集。

第9個區塊設定訓練集和測試集的參數

第10個區塊是定義神經網路,在此使用 alexnet 模型,初次使用會下載alexnet模型,實際下載時間根據您的網路速度而異,請耐心等候,並區塊前面顯示*號。(如果是使用 CAVEDU 所提供的映像檔,則都已經預先下載好囉!)

第11個區塊是將 alexnet 模型原本的1000個類別標籤輸出,改為3個。之所以為 3 是因為本範例共要辨識三個不同的障礙物,如果您希望辨識更多類別則請修改這個數字。

第12個區塊是將模型搬到在GPU上執行。

第13個區塊即開始將資料集訓練成模型檔,預設訓練20回合,根據建議各類別100張左右的照片訓練時間大約為十分鐘。訓練完成會產生一個一開始設定好名稱best_model3class.pth的模型檔(訓練完成後會如下圖所示顯示Done!)

最後一個區塊執行後會關閉風扇。

Live Demo 下場試車啦

這是一系列範例中的第三個 ipynb,也是最後一個,您的車子會使用先前所訓練好的 .pth 模型檔來執行視覺辨識任務。

在畫面左側的畫面中,開啟 home >jetbot_CAVEDU/collision_avoidance/live_demoC3.ipynb,就能看到 Collision Avoidance – Live Demo 畫面。

這份程式負責執行訓練好的模型檔,也就是根據攝影機畫面進行推論為某個類別,並做出您所設定的動作。

請注意:在此需要有相對應的模型檔才可以執行該檔案,換言之,如果您已經有現成模型的話,就可以直接開車啦!實際跑車時,場地的背景跟燈光不能與收集資料集的狀況差異太多,否則視覺辨識的效果會不好喔。

第2個區塊使用 best_model_3class.pth 這個模型,請自行修改為您實際的檔名。

第2個區塊定義馬達參數,CAVEDU 目前採用 DFRobot 馬達驅動板所以不需要修改,如果您使用其他板子例如 waveshare 請自行修改。
執行後看到下圖 board begin success 代表馬達驅動板正常啟動,如果顯示失敗請檢查板子有無正確插上Jetson Nano上的GPIO以及正確接上電源。

第3、4個區塊設定功率模式以及開啟風扇,設定功率模式到 10W 可以提高系統效能。

第5個區塊是設定 PyTorch 的 alexnet 模型參數,請注意下圖數字 3 需對應先前所訓練模型的資料類別,如果您希望更多類別則記得要修改為對應的數字。

第6個區塊是載入模型檔,第7個區塊是把模型權重從 CPU 記憶體搬到 GPU 來執行。

第8個區塊是定義影像預處理方法,依序執行了以下內容

  • 從BGR轉換為RGB模式
  • 從HWC佈局轉換為CHW佈局
  • 使用與訓練期間相同的參數進行正規化(攝影機像素範圍是[0,255],因此要 / 255 將其調整到範圍內的值,並在[0,1]範圍內訓練加載的圖像,因此我們需要縮放255.0
  • 將資料從 CPU 搬到 GPU
  • 針對批 (batch) 新增一個維度

第9個區塊建立一個大小為 224 * 224 的攝影機畫面,並針對每一個類別都有一個對應的滑桿,以視覺效果來呈現攝影機目前畫面所對應的類別機率 (機率值為 0~1 之間的小數),如下圖。

根據之前蒐集的資料分為a b c三個滑桿對應other blue red 三種類別的機率
a_slider = widgets.FloatSlider(description='other', min=0.0, max=1.0, orientation='vertical')
b_slider = widgets.FloatSlider(description='blue', min=0.0, max=1.0, orientation='vertical')
c_slider = widgets.FloatSlider(description='red', min=0.0, max=1.0, orientation='vertical')

並且在最後顯示出來的畫面也需要對應:
display(widgets.HBox([image, a_slider, b_slider, c_slider]))

第10個區塊,執行後機器人就會動了,請注意不要將JetBot放在桌上或是容易摔落撞到的地方(心疼)。修改程式碼說明如下:

首先在全域變數宣告,把新增的prob_a , prob_b, prob_c, a_slider, b_slider, c_slider變數跟滑桿都加上 global:
global robot, prob_a , prob_b, prob_c, a_slider, b_slider, c_slider

接著宣告 prob_a , prob_b, prob_c是對應系統陣列裡的哪個參數。float(y.flatten()[0])、float(y.flatten()[1])、float(y.flatten()[2])排序是根據蒐集類別名稱的英文字母順序,如果是按照類別取名稱可能會造成排序錯亂,建議是按照英文字母順序取名。接著讓三個 slider.value 對應到各自的機率值。

prob_a = float(y.flatten()[0])
prob_b = float(y.flatten()[1])
prob_c = float(y.flatten()[2])

a_slider.value = prob_a
b_slider.value = prob_b
c_slider.value = prob_c

最後是修改程式碼將對應類別執行對應的動作,如下方程式會執行以下動作,您可以根據實際使用情境來修改機率門檻值與機器人動作:

  • 當判斷類別a(other)的機率大於0.5的時候就以40%的速度前進
  • 當判斷類別b(blue)的機率大於0.7就以70%的速度左轉
  • 當判斷類別c(red)的機率大於0.7就以70%的速度右轉

if prob_a > 0.5:
    robot.forward(0.4)
elif  prob_b > 0.7:
    robot.left(0.7)
elif  prob_c > 0.7:
    robot.right(0.7)

第11個區塊會更新攝影機畫面,如果沒有執行這一步驟,攝影機的畫面將無法同步,執行完這個區塊請往上拉回到第9個區塊來看看 JetBot 避障的效果如何。

第12個區塊,這裡會停止同步畫面,JetBot也會停止。第13個區塊是中斷攝影機的連結。

第14個區塊執行後會關閉風扇,風扇將會慢慢減速不會瞬間關閉請耐心等候。

總結

本文根據 JetBot 原廠教學,將原本的雙類別辨識擴充為多類別。機器人在製作過程有許多要注意的細節,幸好 NVIDIA Jetson 與 Jetbot 專案已經幫我們打通很多關節,期待您與我們分享您的機器人最新功能喔!

RK-JETBOT 避開障礙物功能多類別辨識教學 – 訓練模型與下場比賽篇〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。

Viewing all 678 articles
Browse latest View live