ขอบเขตงาน
โปรเจคนี้ใช้ Arduino, Python และ OpenCV ในการแก้รูบิคสครับ เป้าหมายหลักคืออยากได้หุ่นยนต์ราคาประหยัดที่แก้รูบิคได้ภายในไม่เกินหนึ่งนาที
แต่ว่า... ต้องบอกก่อนว่ามีไอเดียเสริมคืออยากออกแบบเสื้อทีเชิร์ตที่มีมุกให้คุยกับคนอื่นด้วย—เพราะงั้นโปรเจคนี้ต้องเข้าใจคณิตศาสตร์พื้นฐานนิดหน่อย และฝึกฝน Python กับ OpenCV ให้คล่องด้วยนะ
แรงบันดาลใจทางเทคนิค
ตอนนั้นกำลังดูหุ่นยนต์แก้รูบิคอยู่ แล้วก็ติดใจความเจ๋งของหุ่นยนต์ LEGO ที่ชื่อ SpinnerCube ขึ้นมาเลย
ภาพรวมโปรเจค
"SpinnerCube" คือระบบเมคคาทรอนิกส์ขั้นสูงที่ผสมผสาน Computer Vision, อัลกอริทึมคณิตศาสตร์ความเร็วสูง และการควบคุมการเคลื่อนไหวแม่นยำ เพื่อแก้รูบิคสครับให้เสร็จภายใน ไม่เกิน 18 วินาที โปรเจคนี้เป็นการแสดงฝีมือข้ามสาขาวิศวะชัดๆ โดยใช้ Python กับ OpenCV สำหรับประมวลผลภาพแบบเรียลไทม์ และ Arduino UNO สำหรับควบคุม มอเตอร์สเตปเปอร์แบบไบโพลาร์ ในระดับล่าง ด้วยการตาม อัลกอริทึม Kociemba หุ่นยนต์จะคำนวณเส้นทางที่ดีที่สุดไปสู่สถานะที่แก้ได้แล้ว (ปกติประมาณ 20-27 ท่า) และทำตามลำดับนั้นด้วยความแม่นยำระดับไมโครวินาที แสดงให้เห็นถึงการทำงานร่วมกันระหว่างคอมพิวเตอร์ระดับเดสก์ท็อปและฮาร์ดแวร์ฝังตัว
ลงลึกเรื่องเทคนิคและลอจิกการควบคุม
- กระบวนการ Computer Vision (OpenCV): ระบบ Vision ต้องรับมือกับสภาพแสงและเฉดสีที่หลากหลาย โดยใช้เว็บแคม สคริปต์ Python จะทำ การกรองด้วย HSV (Hue, Saturation, Value) เพื่อระบุสติกเกอร์ทั้ง 9 อันบนแต่ละหน้า จากนั้นสติกเกอร์จะถูกแมปไปเป็นสตริงที่แทนสถานะของลูกบาศก์ (เช่น สัญลักษณ์ URFDLB) การแปลง "ภาพเป็นพีชคณิต" นี้คือส่วนที่ใช้พลังการคำนวณมากที่สุดในขั้นตอนการแก้
- อัลกอริทึมสองเฟสของ Kociemba: เมื่อรู้สถานะของลูกบาศก์แล้ว Python backend จะรันอัลกอริทึม Kociemba อัลกอริทึมค้นหานี้แบ่งปัญหาออกเป็นสองเฟส: เริ่มจากลดสถานะลูกบาศก์ให้อยู่ในกลุ่มย่อยที่สามารถแก้ได้ด้วยท่าที่จำกัด จากนั้นจึงหาคำตอบสุดท้าย กลยุทธ์ทางคณิตศาสตร์นี้รับประกันเส้นทางแก้ปัญหาที่เกือบจะดีที่สุด ช่วยลดการสึกหรอทางกลของมอเตอร์สเตปเปอร์
- โปรโตคอลการสื่อสารแบบอนุกรม: คำตอบ (ชุดท่าเช่น
R2 U' L) จะถูกส่งจาก Python ไปยัง Arduino ผ่าน Serial UART จากนั้น Arduino จะแยกคำสั่ง ASCII เหล่านี้ออกเป็นลำดับพัลส์ที่ประสานกันสำหรับ ไดรเวอร์สเตปเปอร์ A4988 - การปรับแต่งมอเตอร์สเตปเปอร์: เพื่อให้ถึงเวลา 18 วินาที เฟิร์มแวร์บน Arduino ต้องใช้ การเพิ่มและลดความเร็วแบบมีขั้นบันได (ramping) การเริ่มต้นทันทีทันใดจะทำให้มอเตอร์สเตปเปอร์ลื่นไถลเพราะความเฉื่อยของลูกบาศก์ ด้วยการใช้โปรไฟล์ความเร็วแบบสี่เหลี่ยมคางหมู (trapezoidal) หุ่นยนต์จึงรักษาแรงบิดสูงสุดไว้ได้ในขณะที่ไปถึงความเร็วเชิงมุมสูงระหว่างการหมุน $180^\circ$
Engineering & Hardware Insights
- A4988 Driver Tuning: ตัวขับ A4988 นี่ต้องปรับแต่งด้วยมัลติมิเตอร์เพื่อตั้งค่า Current Limit (Vref) กันหน่อย วิธีนี้จะทำให้มอเตอร์สเตปเปอร์แบบไบโพลาร์มีแรงบิดพอจะเอาชนะแรงเสียดทานภายในของลูกบาศก์ได้ โดยไม่ทำให้ตัวขับหรือขดลวดมอเตอร์ร้อนจัดจนพัง
- Flexible Shaft Couplers: การใช้ Flexible Couplers ต่อระหว่างเพลามอเตอร์กับแขนจับลูกบาศก์นี่สำคัญมากนะตัวนี้ มันช่วยชดเชยการติดตั้งที่อาจจะเบี้ยวๆ นิดหน่อย ป้องกันไม่ให้ระบบกลไกติดขัด และทำให้การหมุนลื่นไหลและแม่นยำซ้ำๆ ได้
- Power Management: เวลาแก้บาศก์เนี่ย มอเตอร์ทั้งสามตัวต้องการกระแสสูงพร้อมกันเป็นช่วงๆ โปรเจกต์นี้เลยใช้ ตัวเก็บประจุแบบ decoupling ขนาดใหญ่ (10µF+) บนสายไฟหลัก เพื่อป้องกันไม่ให้แรงดันตกจน Arduino รีเซ็ตตัวกลางคันตอนที่มอเตอร์ทำงานเร็วๆ
- Open-Source Philosophy: GUI และเฟิร์มแวร์ของโปรเจกต์นี้ออกแบบมาให้เป็นโมดูลาร์ เปิดโอกาสให้นักพัฒนาคนอื่นๆ มา upgrade โมเดลการมองเห็นหรือปรับโค้ดให้เข้ากับโครงสร้างกลไกแบบอื่นๆ ได้ (เช่น จาก 3 มอเตอร์เป็น 6 มอเตอร์) จัดไปวัยรุ่น!
Operation
หุ่นยนต์ตัวนี้ใช้สเตปเปอร์มอเตอร์ 3 ตัวในการหมุนหน้าทุกด้านของลูกบาศก์ (URFLDB) ขั้นตอนการทำงานมีดังนี้:
- จับสีสติกเกอร์ทีละหน้า ตามลำดับที่กำหนด
- ประมวลผลแต่ละหน้าโดยใช้ Python เพื่อหาตำแหน่งเริ่มต้นที่สลับสีของลูกบาศก์
- แก้บาศก์ด้วยอัลกอริทึม Kociemba
- ส่งคำตอบจาก Python ไปยัง Arduino ผ่านพอร์ตอนุกรม
- จากนั้น Arduino จะทำการหมุนทุกครั้งให้ เร็วและแม่นยำที่สุด เท่าที่จะทำได้!!! สู้งานนะน้อง
เวลาที่ทำได้ดีที่สุด
ถ้าอยากได้สถิติเวลาดีๆ สำหรับหุ่นยนต์ที่ใช้สเตปเปอร์มอเตอร์แบบนี้ มี ทริคง่ายๆ อย่างนึงคือใช้วิธี Inverse Sequence แต่วิธีนี้ก็ดูออกง่ายๆ อยู่แล้ว เพราะปกติ Kociemba จะแก้บาศก์ได้ใน 20 ถึง 27 ท่า ส่วนวิธีอื่นอย่าง Fridrich หรือ CFOP มักจะใช้ท่ามากกว่านั้น อย่างไรก็ตาม เป้าหมายหลักของพี่ไม่ใช่การทำลายสถิติ แต่คือการเรียนรู้ แต่การลองหาขีดจำกัดทางกายภาพของระบบ โดยไม่ใช้ทริค ก็เป็นแบบฝึกหัดที่ดี ทำให้เรามีความอดทนในกระบวนการปรับแต่งหรือ Fine Tuning นั่นเอง
เพราะฉะนั้น แต่ละรุ่นหุ่นยนต์ก็จะมีขีดจำกัดทางกายภาพของมัน ในกรณีนี้ สเตปเปอร์มอเตอร์มีแรงบิดเพียงพอที่จะหมุนหน้าบาศก์ได้ และมีค่าความเร็วและความเร่งสูงสุดที่กำหนดไว้ อย่างไรก็ตาม ความล่าช้าระหว่างการหมุนแต่ละครั้ง และการหมุนแบบ U(up), D(down), B(back) ก็เป็นข้อจำกัดเหมือนกัน
พี่เคยเห็นหุ่นยนต์ Spinner Cube ที่ใช้ Servo ทำงาน ความเร็วในการแก้ก็จะดีกว่า ในอนาคตอันใกล้นี้ พี่จะมาแชร์โปรเจกต์ที่ใช้ Servo ให้ดูกันนะ
สำหรับตัวนี้ พี่ลองปรับแต่งค่ากันจนได้เวลาต่ำสุดที่ 18 วินาที
ในวิดีโอนี้จะเห็นว่าหลังจากลองปรับหลายรอบ ก็ได้ 18 วินาที (ตำแหน่งสลับสีต่างกัน แต่ใช้ค่าปรับแต่งเดิม):
Developer
พี่แบ่งให้ดูโค้ดทั้งหมดเลยน้อง งานนี้โอเพ่นซอร์สจัดไปวัยรุ่น
เราเขียนแอปด้วย Arduino กับ Python เพื่อให้โปรแกรมทำงานร่วมกัน แก้รูบิค และควบคุมหุ่นยนต์ ช่วยให้เราทดสอบและทำให้การป้อนสถานะลูกบาศก์กับถ่ายรูปมีประสิทธิภาพขึ้น
แอปตัวนี้ใช้กลยุทธ์การโปรแกรมจากนักพัฒนาคนอื่นๆ ที่แชร์โค้ดไว้ แล้วพี่ก็ต้องปรับแต่งอยู่เป็นสัปดาห์ เพื่อสอนให้ระบบมันดูและแยกสีสติกเกอร์ออกมาให้ได้ ห้ามช็อตนะตัวนี้
ทำไปทำไม?
คำตอบของคำถามนี้จะมาให้อ่านกันในไม่ช้า ตอนนี้อาจจะตอบว่าเพื่อพัฒนาผลิตภัณฑ์สำหรับคนกลุ่มเล็กๆ ที่ชอบเล่นรูบิค ไหนๆ ลองดูซิว่าจะเกิดอะไรขึ้น สู้งานนะน้อง