โปรเจกต์ วิธีเล่น Game ใดก็ได้โดยใช้ Time of Flight
เรียนรู้วิธีการใช้งาน pc keyboard ของคุณร่วมกับบอร์ด Arduino และเล่น Game โดยใช้ Time of Flight และ AI เพื่อส่ง inputs
เรียนรู้วิธีการใช้งาน pc keyboard ของคุณร่วมกับบอร์ด Arduino และเล่น Game โดยใช้ Time of Flight และ AI เพื่อส่ง inputs
สวัสดีและยินดีต้อนรับสู่บทช่วยสอนนี้! ในครั้งนี้ เราจะเรียนรู้วิธีการใช้งาน Time-of-Flight Sensor ร่วมกับ Edge AI เพื่อเล่นเกมโดยใช้การป้อนข้อมูลผ่าน Keyboard
เพื่อให้บรรลุเป้าหมายนี้ อันดับแรกเราจะเรียนรู้วิธีการใช้งาน Time-of-Flight Sensor จากนั้นทำการเก็บข้อมูล (collect data), ฝึกฝนโมเดล AI โดยใช้ NanoEdge AI Studio และสุดท้ายคือการดูวิธีควบคุม Keyboard เพื่อเล่นเกม
นี่คือลิงก์ของเกมที่ผมใช้: https://supermarioplay.com/fullscreen
Time-of-Flight (ToF) Sensor จะส่งค่าอาเรย์ (matrix) ของระยะทางออกมา คุณสามารถจินตนาการว่ามันเหมือนรูปภาพหนึ่งรูป แต่มีความละเอียดต่ำมาก (8x8 = 64 pixels)
Sensor เหล่านี้จะปล่อยลำแสงสั้นๆ (pulses) ซึ่งกินเวลาเพียงไม่กี่ nanoseconds และวัดเวลาที่แสงใช้ในการสะท้อนกลับมา เนื่องจากมันทำงานด้วยลำแสง จึงทำงานได้ดีในสภาวะมืดมากกว่าสภาวะที่มีแสงจ้า ระยะสูงสุดที่ Sensor สามารถวัดได้ในที่มืดคือประมาณ 3 เมตร ในขณะที่สภาวะแสงจ้ามาก Sensor อาจทำงานผิดพลาดหรือไม่ทำงานเลย
เมื่อทำการ Logging ข้อมูล คุณจะเห็นได้อย่างชัดเจนว่า Sensor ทำงานตามที่คาดหวังหรือไม่ แต่อย่าลืมใช้งานในสภาพแวดล้อมที่ไม่สว่างจนเกินไป

การ Logging ข้อมูลที่ดีด้วย ToF นั้นทำได้ยาก เพื่อให้ได้ข้อมูลที่ดี คุณจำเป็นต้อง:
ขั้นแรกให้เสียบ X-NUCLEO-53L5A1 เข้ากับ Arduino Uno R4 WiFi จากนั้นยึดชุดอุปกรณ์เข้ากับผนังโดยใช้ Blu Tack เป็นต้น
ในการเล่น Mario เราจำเป็นต้องสั่งการ 6 ท่าทาง:
ด้วยการใช้ distance matrix ที่เก็บมาจาก ToF Sensor เราสามารถระบุท่าทาง, ตำแหน่ง, ท่าโพสต์ หรือตัวบ่งชี้อื่นๆ ได้
ในกรณีของผม ผมพบว่าการยืนในโซนต่างๆ หน้า ToF Sensor นั้นได้ผลดี ดังที่แสดงในรูปภาพที่แนบมา:

Zone 1, 2 และ 3 จะอยู่ใกล้กับ ToF Sensor ในขณะที่ Zone 4, 5 และ 6 จะอยู่ใกล้กับพื้นหลัง
ตอนนี้เราต้องเริ่มเก็บข้อมูล
เมื่อทำงานกับ Time-of-Flight (ToF) Sensor คุณสามารถเลือกที่จะทำงานกับ matrix ระยะทางแบบเดี่ยวๆ หรือชุดของ matrix ต่อเนื่องกันเพื่อตรวจจับท่าทาง (gestures) ได้
ในกรณีนี้ เราต้องการให้การตอบสนองรวดเร็วที่สุดเท่าที่จะเป็นไปได้ ซึ่งหมายถึงการทำงานให้เร็วที่สุด ดังนั้นเราจะใช้เพียง matrix เดียว

ผมใช้เครื่องมือ NanoEdge AI Studio เพื่อสร้าง Code สำหรับการเก็บข้อมูล ToF ตัว Code แนบมาให้ด้านล่าง แต่ถ้าคุณต้องการสร้าง Code แบบเดียวกัน ให้ทำดังนี้:
ผมใช้พารามิเตอร์ดังต่อไปนี้:
คลิก Generate Data Logger แล้วคุณจะได้ไฟล์ .zip ที่มีไฟล์ .ino ซึ่งเป็น Code ที่พร้อมจะอัปโหลด (flash) ลงบน Board
คำเตือน:
ตอนนี้เราจะสร้างโปรเจกต์ใน NanoEdge AI Studio เพื่อเก็บข้อมูลและสร้างโมเดลที่สามารถแยกแยะโซนต่างๆ ที่ผมไปยืนอยู่ เพื่อนำไปใช้เล่น Mario:
ในส่วนของ Project settings:

ตั้งแต่เวอร์ชัน 4.5 เป็นต้นมา การตั้งค่าโปรเจกต์มีการเปลี่ยนแปลงเล็กน้อย คุณต้องเลือกว่าคุณกำลังทำงานกับข้อมูลประเภท Time series หรือ Cross sectional โดยพื้นฐานแล้วคือข้อมูลของคุณประกอบด้วยหลายตัวอย่างในช่วงเวลาที่ต่างกันหรือไม่ ในกรณีของเรา เราใช้เพียงเฟรมเดียว/matrix เดียว ไม่เกี่ยวข้องกับเวลา ดังนั้นเราจึงใช้ข้อมูลแบบ Cross sectional
ในส่วนของ Signals:

ตอนนี้เราจะเก็บข้อมูลสำหรับแต่ละโซนผ่านการสื่อสารแบบ Serial
คุณควรเก็บข้อมูลให้มีความหลากหลายมากที่สุดเท่าที่จะเป็นไปได้ ตัวอย่างเช่น เมื่อเก็บข้อมูลการเลื่อนไปทางขวา (ใน Zone 4) คุณควรเคลื่อนตัวเล็กน้อยภายในโซนเพื่อจำลองตำแหน่งต่างๆ ที่ต้องถูกจำแนกเป็น Zone 4 ยืนในจุดต่างๆ ของโซน เช่น ทางขวา, ขวามากหรือน้อยลงหน่อย, ใกล้หรือไกลจาก ToF Sensor เล็กน้อย เป็นต้น
เมื่อเล่นเกม คุณจะสลับไปมาระหว่างโซน และคุณจะไม่อยู่ในจุดเดิมเป๊ะๆ ตลอดเวลา
พยายามหลีกเลี่ยงการมีข้อมูลที่ทับซ้อนกันในคลาสที่ต่างกัน ตัวอย่างเช่น อย่าไปยืนในจุดเดียวกันขณะที่เก็บข้อมูลสำหรับคลาส Standing และ Moving to the left มิฉะนั้น โมเดลจะแยกแยะข้อมูลได้ยาก ส่งผลให้การควบคุมผิดพลาดขณะเล่นเกม
ขั้นตอนการเก็บข้อมูล:
ทำแบบนี้ให้ครบทั้ง 6 โซน
ในส่วนของ Benchmark:
Benchmark คือหัวใจสำคัญของ NanoEdge AI Studio ในส่วนนี้เราจะใช้ข้อมูลทั้งหมดที่เก็บมาเพื่อค้นหาการผสมผสานระหว่างการประมวลผลข้อมูลเบื้องต้น (preprocessing) และโมเดลที่ดีที่สุดที่สามารถแยกแยะข้อมูลได้
Benchmark จะพยายามทดสอบการผสมผสานระหว่าง Preprocessing และ Model กับข้อมูลซ้ำไปซ้ำมาเพื่อประเมินประสิทธิภาพ โดยมีการแบ่งข้อมูลเป็นชุด Training และ Testing หลายครั้งเพื่อให้ได้ผลลัพธ์ที่แม่นยำ (robust)
Benchmark อาจใช้เวลาหลายชั่วโมงขึ้นอยู่กับปริมาณข้อมูลที่ใช้ หากคะแนนถึง 90% หรือมากกว่า คุณสามารถกด Pause/Stop และดำเนินการต่อได้ Benchmark จะพยายามปรับจูนโมเดลให้ดีที่สุดเท่าที่จะทำได้ แต่คุณสามารถหยุดมันได้เมื่อพอใจกับผลลัพธ์แล้ว

ในส่วนของ Validation:
ในระหว่างกระบวนการ Benchmarking ทุกครั้งที่พบ Library ที่ดีกว่าตัวเดิม มันจะถูกเพิ่มเข้ามาในขั้นตอน Validation
เมื่อคุณมี Library ที่ดีแล้ว คุณสามารถทดสอบการทำงานแบบ Real-time ได้เสมือนว่ามันถูกติดตั้งลงบน Microcontroller เพื่อดูว่าใช้งานได้ดีหรือไม่
วิธีการคือ คลิกปุ่ม Play ในคอลัมน์ Serial Emulator เลือก COM Port ที่ถูกต้อง แล้วคลิก Start จากนั้นคุณจะสามารถทดสอบโมเดลและดูประสิทธิภาพของมันได้
หากคุณสังเกตเห็นว่าบางคลาสถูกระบุได้ยาก คุณสามารถกลับไปที่กระบวนการ Logging และทำ Benchmark ใหม่ได้ ตัวอย่างเช่น ผมเคยมีปัญหากับคลาส "Standing" และ "Moving to the Right" เมื่อผมยืนอยู่ใกล้รอยต่อระหว่างสองโซน ดังนั้นผมจึงบันทึกข้อมูลใหม่เพื่อให้แน่ใจว่าไม่ได้ยืนในที่เดียวกัน
ในส่วนของ Compilation:
เพียงคลิก Compile เพื่อรับโมเดลที่ฝึกสอนแล้ว คุณจะได้ไฟล์ .zip ที่ประกอบด้วยทุกสิ่งที่จำเป็นสำหรับขั้นตอนถัดไป
ในการเล่นเกม เราจะใช้ Library ของ NanoEdge AI Studio เพื่อจำแนกท่าทางที่ต้องการ และใช้ Library Keyboard ของ Arduino เพื่อส่งข้อมูลไปยัง PC และควบคุมเกม
การใช้ Keyboard ร่วมกับ Board อาจทำให้ควบคุม PC ของคุณได้ยากเมื่อ Board เริ่มส่งข้อมูล เพื่อความสะดวก ผมได้ตั้งค่า Delay ไว้ที่ส่วนท้ายของฟังก์ชัน setup() ซึ่งจะช่วยให้คุณมีเวลาแก้ไข Code และอัปโหลดลง Board ได้โดยไม่ถูกรบกวนจากการส่งข้อมูลที่เกิดขึ้น
ฟังก์ชันสำหรับ Keyboard Input:
เราจะใช้ฟังก์ชันดังต่อไปนี้เพื่อส่งข้อมูล:
เพื่อให้เล่นเกมได้อย่างมีประสิทธิภาพ เราต้องเลี่ยงการส่งปุ่ม 'a' (เลื่อนซ้าย) เพียงแค่ครั้งเดียว เพราะการทำเช่นนั้นจะทำให้ Mario ขยับไปทางซ้ายเพียงเล็กน้อยทุกครั้งที่มีการประมวลผล (classification) ซึ่งขัดขวางการเคลื่อนที่ต่อเนื่องหรือการกระโดด แทนที่จะทำแบบนั้น เราจะใช้ Keyboard.press ร่วมกับ Delay แล้วจึงปล่อยปุ่ม
เราจะกดเพียงสามปุ่ม:
ในการกระโดดไปทางซ้ายหรือขวา เราจะกดสองปุ่มพร้อมกัน การตั้งค่า Delay ไว้ที่ 500ms ก่อนจะปล่อยปุ่มจะช่วยให้ Mario กระโดดได้สูงสุด
เราจะใช้คำสั่ง switch() เพื่อกดปุ่มที่ถูกต้องตามคลาสที่คาดการณ์ไว้
ตรวจสอบให้แน่ใจว่าคลาสและการเคลื่อนที่ใน Code ตรงกับลำดับของไฟล์ของคุณ ซึ่งลำดับนี้จะถูกอธิบายในขั้นตอนถัดไป การตรวจสอบลำดับใน Library ของคุณจะมีการอธิบายไว้ในหัวข้อถัดไปเช่นกัน
ในการเพิ่ม AI ลงใน Code Arduino ของเรา สิ่งที่ต้องทำมีดังนี้:
เพียงเท่านี้เอง!
การเพิ่ม Library ลงใน Arduino IDE:
ขั้นแรกเราต้อง Import Library เข้าสู่ Arduino IDE เพื่อหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้นหากคุณเคย Import Library ของ NanoEdge AI ตัวเก่ามาแล้ว นี่คือวิธีที่ปลอดภัยที่สุด:
คำอธิบาย Code ที่แนบมา:
นี่คือสิ่งที่ทำใน Code ที่แนบมา:
นี่คือส่วนที่เพิ่มเข้ามา:
#include "NanoEdgeAI.h"
#include "knowledge.h"
#include <Keyboard.h>
/* Global variables definitions */
static uint8_t neai_code = 0;
static uint16_t neai_ptr = 0;
static float neai_buffer[SENSOR_FRAME_RESOLUTION * SENSOR_FRAMES] = {0.0};
/* NEAI library variables */
uint16_t id_class = 0; // Point to id class (see argument of neai_classification fct)
float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER]; // Buffer of input values
float output_class_buffer[CLASS_NUMBER]; // Buffer of class probabilities
const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name
"unknown",
"dm_jumpcenter",
"dm_jumpleft",
"dm_jumpright",
"dm_left",
"dm_right",
"dm_stand",
};
void setup() {
//some code
//initialize the keyboard usage
Keyboard.begin();
/* Initialize NanoEdgeAI AI */
neai_code = neai_classification_init(knowledge);
if (neai_code != NEAI_OK) {
Serial.print("Not supported board.\n");
}
}
/* Main function: Code run indefinitely */
void loop() {
//classification
neai_classification(neai_buffer, output_class_buffer, &id_class);
//actions to perform based on id_class (the detected class)
switch (id_class) {
case 6:
//stand
Keyboard.releaseAll();
break;
case 4:
//move left
Keyboard.press('q');
break;
case 5:
//move right
Keyboard.press('d');
break;
case 1:
//jump
Keyboard.press(0x20);
break;
case 2:
//jump left
Keyboard.press(0x20);
Keyboard.press('q');
break;
case 3:
//jump right
Keyboard.press(0x20);
Keyboard.press('d');
break;
}
delay(500);
Keyboard.releaseAll();
}
การแทนที่ id2class:
ใน Code จะมี Variable ชื่อ id2class ที่ระบุชื่อคลาสและลำดับของคุณ
คุณต้องแทนที่ตัวแปรใน Code ที่แนบมาด้วยตัวแปรของคุณที่อยู่ใน NanoEdgeAI.h ภายในไฟล์ .zip:
โดยเฉพาะในบทช่วยสอนนี้ คุณยังต้องแก้ไข switch() ในส่วนของ loop() เพื่อสร้างคำสั่งการกระทำ ใน Code ด้านบน คุณสามารถตรวจสอบได้ว่าคลาสต่างๆ ตรงกับการกระทำของมันหรือไม่ ตัวอย่างเช่น ใน switch ตัวเลือกแรกคือ case 6 เพราะคลาสใน id2class ที่ตรงกับ stand คือตัวสุดท้าย (โดยเริ่มนับจาก 0)
หมายเหตุ:
หากคุณพบข้อผิดพลาดเกี่ยวกับ RAM อาจเป็นเพราะ Library ใน NanoEdge ให้กลับไปที่ขั้นตอน VALIDATION ใน NanoEdge แล้วเลือก Library ที่เล็กลง (คลิกรูปมงกุฎทางด้านขวา) จากนั้นจึงทำการ Compile ใหม่และนำไปแทนที่ใน Arduino IDE
ด้วยบทช่วยสอนนี้ คุณได้เรียนรู้วิธีการใช้ NanoEdge AI Studio ร่วมกับ Time of Flight เพื่อเล่นเกมโดยใช้ Keyboard ของเครื่อง PC
การสั่งการผ่าน Keyboard นั้นค่อนข้างพื้นฐาน คุณสามารถปรับปรุง Code เพื่อให้เล่นได้ดีขึ้นตามต้องการ
ขอบคุณที่อ่านจนจบ คุณอาจต้องการลองดูโปรเจกต์อื่นๆ ของผมที่แสดงวิธีอื่นๆ ในการใช้งาน NanoEdge AI Studio!
สนับสนุนเพื่อรับ Source Code หรือแอปพลิเคชันสำหรับโปรเจกต์นี้
Verified user reviews
ล็อกอินด้วยบัญชีบนเว็บนี้แล้วให้คะแนนหรือคอมเมนต์ได้เลย ระบบเก็บผ่าน Supabase ไม่ต้องใช้ GitHub แล้ว
ยังไม่มีรีวิวที่อนุมัติแล้ว เป็นคนแรกที่มาให้ความเห็นได้เลย