บทนำ
โปรเจกต์นี้คือผลงานที่พี่ส่งเข้าประกวด Arduino / Distrelec Automattion Contest ปี 2018 นะน้อง มันพัฒนามาจากหุ่นยนต์สเก็ตที่พี่ออกแบบไว้ก่อนหน้านี้ พอดีมีไอเดียก็เลยเอามาทำต่อ สิ่งที่พี่ต้องทำมี "แค่" พัฒนาเวอร์ชันที่ควบคุมผ่าน Blynk ได้ แล้วค่อยเพิ่มฟีเจอร์อื่นๆ หลังจากที่ UI ใช้งานได้ดีแล้วน่ะ แต่มันก็ไม่ง่ายอย่างที่คิดหรอก เดี๋ยวพี่เล่าให้ฟังด้านล่าง
เป้าหมายเดิมคืออยากให้มันมีฟังก์ชันเพียบ เช่น โหมดอัตโนมัติ แต่พี่ต้องโฟกัสที่การทำให้หุ่นยนต์มันทำงานได้และจัดให้เรียบร้อยที่สุดก่อนต้นเดือนกันยา เพื่อให้ทันเดดไลน์ประกวด พี่เลยตัดสินใจเพิ่มฟีเจอร์ด้วยเซอร์โวกับเซ็นเซอร์อัลตราโซนิก และทำ UI ง่ายๆ ในแอป Blynk ของพี่แทน ส่วนการเคลื่อนที่อัตโนมัติไว้เป็นเรื่องต่อไปที่พี่จะลงมือทำต่อ พี่เชื่อว่าหุ่นยนต์ของพี่ในหลายๆ แง่มุมมันค่อนข้างพิเศษ และอาจจะแสดงให้เห็นวิธีหนึ่งในการผสมผสานการเดินกับการขับเคลื่อนด้วยล้อ
แนวคิดเบื้องหลัง
หุ่นยนต์มักจะแบ่งเป็นสองประเภทใหญ่ๆ นะน้อง คือแบบมีล้อ กับแบบเดิน แบบมีล้อออกแบบง่าย (ก็คือรถบังคับนั่นแหละ) และเคลื่อนที่เร็ว ส่วนหุ่นยนต์มีขานี่ท้าทายกว่าเพราะต้องเขียนโปรแกรมที่ซับซ้อนเพื่อควบคุมการเคลื่อนไหวของขา ความท้าทายนี่แหละที่เป็นหนึ่งในเหตุผลที่พี่พัฒนาหุ่น KITtyBot ขึ้นมา ข้อดีของแบบมีขาคือมันสามารถปีนข้ามสิ่งกีดขวางและเดินขึ้นลงบันไดได้ ซึ่งอาจจำเป็นสำหรับภารกิจกู้ภัยในอาคาร แต่บนพื้นเรียบ หุ่นยนต์เดินจะช้ากว่าแบบมีล้ออยู่แล้ว แน่นอนว่าเราสามารถผสมผสานทั้งสองแนวคิดเข้าด้วยกันเพื่อให้ได้ข้อดีจากทั้งสองโลก หุ่นยนต์ล้อที่มีระบบกันสะเทือนขั้นสูงสามารถจัดการกับสิ่งกีดขวางได้ และสุดท้าย "ระบบกันสะเทือน" นั้นอาจจะกลายเป็นเหมือน "ขา" และทำให้มันสามารถเดินหรือปีนได้บ้าง
โปรเจกต์ของพี่ทดสอบหุ่นยนต์ที่มีล้อแบบพาสซีฟ หมายความว่าล้อมันไม่มีระบบขับเคลื่อนนะ แต่พี่ใช้เซอร์โวเพื่อปรับมุมล้อแทน คล้ายๆ กับล้อหน้าของรถยนต์ การเคลื่อนที่ทำโดยการสเก็ต (หรืออาจจะเหมือนการพายเรือแคนู) คือใช้ประโยชน์จากการปรับมุมล้อแล้วดันตัวไปข้างหน้าด้วยการเคลื่อนไหวของขา วิธีนี้ทำให้เคลื่อนที่ได้ค่อนข้างเร็วและประหยัดพลังงาน อย่างน้อยก็เมื่อเทียบกับการเดินธรรมดา ข้อได้เปรียบเหนือหุ่นยนต์ล้อธรรมดาที่มี "ระบบกันสะเทือนแบบมีขา" คือไม่จำเป็นต้องมีมอเตอร์ขับเคลื่อนล้อ และหุ่นยนต์สามารถกลับมาใช้โหมดเดินได้ตลอดเวลา
การออกแบบส่วนใหญ่คล้ายกับหุ่นยนต์ KITtyBot ที่พี่เคยเผยแพร่ใน Project Hub มันใช้ Inverse Kinematics เดียวกันในการเคลื่อนที่เท้า และในโหมดเดิน มันก็ใช้ท่าเดิน (walking gaits) เดียวกันที่พี่พัฒนาสำหรับ KITtyBot ส่วนใหม่คือการเพิ่ม "รองเท้าสเก็ตล้อ" เข้าไปที่เท้า จุดสัมผัสของล้อจะอยู่ตรงตำแหน่งที่เคยเป็นปลายเท้าของ KITtyBot
เจาะลึกเทคนิค: Inverse Kinematics & ฮิวริสติกส์การสเก็ต
หุ่นยนต์ตัวนี้เป็นตัวอย่างที่เคร่งครัดของ Hybrid Robotic Locomotion นะน้อง มันใช้แบบจำลองทางคณิตศาสตร์ในการคำนวณมุมข้อต่อที่จำเป็น $(\alpha, \beta, \gamma)$ เพื่อวางตำแหน่งพิกัดของแต่ละเท้า $(x, y, z)$ ในพื้นที่สามมิติ Inverse Kinematics (IK) Logic-Engine นี้จะแปลค่าเวกเตอร์จากจอยสติกในแอป Blynk ให้เป็นค่าพิกัดเดลต้า สิ่งที่คิดค้นใหม่คือ "ท่าสเก็ต (Skate-Gait)" ซึ่งขาจะดันไปด้านข้าง ในขณะที่เซอร์โวที่เท้าจะปรับมุมล้อ สร้างโมเมนตัมให้เคลื่อนที่ไปข้างหน้าผ่านฟิสิกส์ของล้อพาสซีฟ เลียนแบบกลไกการสเก็ตน้ำแข็งของมนุษย์เลยล่ะ
การควบคุมเซอร์โวแรงบิดสูง MG996R ทั้ง 16 ตัว ใช้การสื่อสารผ่าน I2C ด้วยไดรเวอร์ PCA9685 จัดการให้เรียบร้อย การควบคุมเซอร์โว 16 ตัวแบบประสานงาน นี้ใช้ความละเอียด PWM 12-bit ของไดรเวอร์เพื่อความแม่นยำระดับองศาย่อยๆ เราใช้อาร์เรย์สำหรับปรับ "จุดศูนย์กลาง" ที่กำหนดในซอฟต์แวร์ $(\text{servodeg0}[16])$ เพื่อให้ทุกข้อต่อของหุ่นยนต์อยู่ในท่าพักที่ตรงกันเป๊ะ
ขั้นตอนประกอบหุ่นยนต์
ปริ้นชิ้นส่วนตามไฟล์ที่ให้มา ใช้เวลาสักนิดดูรูปภาพให้ดีก่อนเริ่มประกอบ จะได้เห็นภาพรวมว่าต้องทำยังไง
เริ่มจากประกอบข้อต่อสะโพกก่อนเลย พี่ออกแบบต่อยอดจาก KITtyBot โดยเพิ่มชิ้นส่วนพิมพ์ 3D เข้าไปบ้าง เลยต้องออกแบบตัวถังใหม่ด้วย เพราะข้อต่อสะโพกใหม่ต้องการพื้นที่มากกว่าเดิมนิดนึง ถ้าน้องบังเอิญมีชิ้นส่วนของ KITtyBot ค้างอยู่ หรืออยากดัดแปลงเจ้าเดิมมาเป็นหุ่นตัวนี้ก็ทำได้นะ พอประกอบเสร็จแล้วขนาดโดยรวมจะเท่าเดิม
ระวังให้ดีว่ามีชิ้นส่วนสองแบบนะ แบบ fl/rr (ซ้ายหน้า / ขวาหลัง) กับ fr/rl (ขวาหน้า / ซ้ายหลัง) ต้องใช้แต่ละแบบสองชิ้น เพื่อประกอบเป็นข้อต่อสะโพกสี่ชิ้น ตรวจสอบให้ชัวร์ว่าจัดชิ้นส่วนถูกแล้ว นอกจากนี้ยังต้องใช้สลักสี่อัน และตัวถังใหม่หนึ่งชิ้น ส่วนขาและกันชนจาก KITtyBot ตัวเดิมยังใช้ได้อยู่
รูปด้านล่างแสดงขั้นตอนประกอบข้อต่อ คำแนะนำทีละขั้นตอนในรูปด้านล่างแสดงวิธีประกอบข้อต่อแบบ fl/rr พอใช้ชิ้นส่วนไปครึ่งหนึ่งแล้ว ข้อต่ออีกแบบก็คงทำต่อได้ไม่ยากละ :)
ต่อไปเป็นข้อต่อเท้า ข้อต่อนี้ก็ประกอบด้วยชิ้นส่วนพิมพ์ 3D สองชิ้นและเซอร์โวสองตัวต่อหนึ่งข้อต่อ มีชิ้นส่วนอยู่สี่ชิ้น เรียกว่า foot first กับ foot second ชิ้นส่วนเหล่านี้ไม่ได้แบ่งเป็นแบบ fr/rl หรือ fl/rr เพราะจะถูกกำหนดโดยวิธีติดตั้งเซอร์โว รูปด้านล่างอธิบายลำดับการติดตั้ง
หลังจากทำขั้นตอนนี้แล้ว ก็สามารถประกอบขาให้เสร็จได้ ก่อนไปต่อ เป็นความคิดที่ดีถ้าจะตรวจสอบให้แน่ใจว่าเซอร์โวทั้ง 12 ตัวอยู่ที่จุดศูนย์กลางหมดแล้ว วิธีที่ดีที่สุดคือประกอบชุดอิเล็กทรอนิกส์ก่อน (ดูด้านล่าง) เชื่อมต่อเซอร์โวทั้งหมด แล้วอัพโหลดโค้ดลงไป พอ Arduino เริ่มทำงาน เซอร์โวทุกตัวจะกลับไปที่จุดศูนย์กลาง (รับสัญญาณคำสั่งที่ 90 องศา)
ชิ้นส่วนสำหรับขาส่วนบน (ต้นขา) และชิ้นส่วนที่ติดล้อ (เรียกว่า foot) มีร่องที่พอดีกับฮอร์นเซอร์โวที่มากับเซอร์โวปกติ ให้กาวฮอร์นเข้าไปในร่องเหล่านั้น ต้องแน่ใจว่าใช้กาวที่เหมาะสำหรับยึดวัสดุพิมพ์ 3D กับพลาสติกไนลอนของฮอร์น กาวปืนที่พี่ใช้ก็ใช้ได้ดี กาว CA คุณภาพดีบางยี่ห้อก็ใช้ได้เหมือนกัน
ขาแต่ละข้างที่ประกอบเสร็จแล้วต้องออกมาเหมือนในรูปพวกนี้นะจ๊ะ เริ่มจากเอาเซอร์โวสองตัวมาติดกับส่วนต้นขาก่อน ตั้งให้ต้นขาทำมุม 30 องศาจากแนวดิ่ง จะได้มุมนี้ก็ต่อเมื่อจุดศูนย์กลางของเซอร์โวล้อ (wheel servo) อยู่ในแนวเดียวกันกับจุดศูนย์กลางของเซอร์โวสะโพกส่วนล่าง (alpha servo) พยายามจัดให้ตรงกันให้มากที่สุด ส่วนการปรับแต่งตำแหน่งศูนย์กลางแบบละเอียดให้ไปปรับในโค้ดอีกทีหลังจากประกอบทุกอย่างเสร็จแล้ว (ดูด้านล่าง)
จากนั้นก็เอาเท้ามาต่อกับเซอร์โวของมัน ล้อทำมาจากขอบล้อที่พิมพ์จากเครื่อง 3D พร้อมกับโอริงเป็น "ยาง" ใช้สกรูและน็อต M3 ยึดล้อเข้ากับเท้า อย่าลืมใส่แหวนรอง (washer) สองอันระหว่างเท้ากับล้อด้วย จะได้กลิ้งได้ลื่นปรื๊ดๆ
ประกอบขาเข้ากับตัวลำตัวได้เลย ส่วนกันชน (bumper) ควรจะกาวเอาเซอร์โวฮอร์นติดเข้าไปในช่องของมัน วิธีที่ดีที่สุดคือใส่แกนขับของเซอร์โวเข้าไปในกันชนให้ใกล้กับมุมที่ต้องการมากที่สุด (ดูด้านล่าง) แล้วยึดด้วยสกรู กันชนที่ประกอบพร้อมขาสองข้างแล้วก็เอาไปติดกับตัวลำตัวได้ โดยยึดกันชนด้วยสกรูของเซอร์โว หมายเหตุ: สกรูทั้งหมดที่มากับเซอร์โวจะต้องถูกใช้เพื่อยึดเซอร์โวเข้ากับข้อต่อสะโพกและข้อเท้า เตรียมสกรูสำรองไว้บ้างก็ดีนะ เพราะเซอร์โวพวกนี้พังง่ายจะตายห่า
รูปด้านล่างคือหุ่นยนต์ที่ประกอบเสร็จแล้ว บอร์ดทดลอง (breadboard) สำหรับอิเล็กทรอนิกส์ควรวางพอดีบนตัวหุ่นยนต์ ติดแบตเตอรี่ไว้ใต้ "ท้อง" ด้วยแถบตีนตุ๊กแก จะได้ถอดออกไปชาร์จหรือเปลี่ยนเป็นอันใหม่ที่ชาร์จเต็มแล้วได้ และยังสามารถปรับจุดศูนย์ถ่วง (centre of gravity) โดยการขยับแบตเตอรี่ไปมาได้อีกด้วย
วิศวกรรมและการนำไปใช้: การวิเคราะห์โครงสร้างจากการพิมพ์ 3D
หุ่นยนต์ตัวนี้ใช้ข้อต่อสะโพกที่พิมพ์จากวัสดุความหนาแน่นสูง (รุ่น $fl/rr$ และ $fr/rl$) เพื่อรับแรงบิด (torque) จากเซอร์โว MG996R ซึ่งรวมถึงการเสริมความแข็งแรงด้วยสกรู M3 และการยึดด้วยกาว CA ระหว่างเซอร์โวฮอร์นไนลอนกับพื้นผิว PLA/PETG เพื่อป้องกันการเสียหายเชิงกลจากแรงเฉือน (mechanical shear) ภายใต้ความเค้น กระบวนการนี้เรียกว่า Hip-Joint Flex-Mitigation
การออกแบบนี้ช่วยให้ปรับจุดศูนย์ถ่วง (CoG) แบบไดนามิกได้ โดยการเลื่อนแบตเตอรี่ LiPo ไปตามส่วนท้องของโครง (ventral-chassis) โดยใช้แถบตีนตุ๊กแก การ Kinetic Balance Calibration นี้เกี่ยวข้องกับการตรวจสอบความสมมาตรของการก้าวขา (leg-extension gait) เพื่อให้แน่ใจว่าหุ่นยนต์เคลื่อนที่ไปในแนวเส้นตรงแบบฮาร์มอนิก (linear-harmonic vector) โดยไม่เกิดการหมุนรอบตัวเอง (yaw) ที่ไม่ต้องการ
เพิ่มเซนเซอร์อัลตราโซนิกและเซอร์โว
เป้าหมายของโปรเจกต์นี้คือให้มันเดินนำทางได้เองอัตโนมัติด้วยความช่วยเหลือจากเซนเซอร์อัลตราโซนิก HC-SR04 ซึ่งติดตั้งอยู่บนเซอร์โว ฮาร์ดแวร์ในส่วนของชิ้นส่วนที่พิมพ์ 3D นั้นพร้อมแล้ว และฟังก์ชันการทำงานก็ทดสอบกับวงจรอิเล็กทรอนิกส์เรียบร้อย เราแค่เพิ่มของพวกนี้เข้าไปตามที่มีตอนส่งประกวด deadline นะ ส่วนน้องจะเลือกประกอบมันแล้วลองเล่นดู หรือจะเขียนโค้ดให้มันเดินเองอัตโนมัติแล้วเอาไปเผยแพร่ต่อก็ตามสบายจ้า :)
กันชนด้านหน้าต้องถูกแทนที่ด้วยกันชนสำหรับอัลตราโซนิก (US bumper) และตัวยึดเซนเซอร์ควรประกอบอยู่บนเซอร์โวตัวที่ 17 ตัวเซอร์โวเองจะพอดีกับกันชนด้านหน้า พอทำทั้งหมดนี้ จุดศูนย์ถ่วงจะเคลื่อนไปด้านหน้า แนะนำให้ย้ายบอร์ดทดลอง (breadboard) บนตัวหุ่นยนต์ไปไว้ด้านหลังแทนจะดีกว่า
สำหรับโหมดอัตโนมัติ เราใช้เซ็นเซอร์ HC-SR04 ติดตั้งบนเซอร์โวโหนดตัวที่ $17$ หลักการ Acoustic ToF Navigation เนี่ย มันมีวงจรแบ่งแรงดัน (Voltage Divider) อยู่บนสัญญาณ Echo $(\text{5V ลงมาเป็น 3.3V})$ เพื่อปกป้องพอร์ตลอจิกของบอร์ด MKR1000 ของเรา ในขณะที่มันคำนวณระยะห่างจากสิ่งกีดขวางผ่านการวัดช่วงเวลาพัลส์แบบแม่นยำสุดๆ
จัดวงจรอิเล็กทรอนิกส์กันเถอะ
การต่อวงจรก็ตรงไปตรงมาอยู่แล้ว แต่มีบางจุดที่ต้องระวังหน่อย ก่อนจะไปต่อ ผมขอเตือนเรื่องแบตเตอรี่ LiPo ซักหน่อย (เหมือนที่เคยเขียนไว้ในโปรเจค KITtyBot รอบที่แล้วนั่นแหละ)
ผมใช้แบตเตอรี่ LiPo แบบไม่มีวงจรป้องกันในตัว มันอาจจะเสี่ยงนิดนึง อันตรายหลักคือการปล่อยประจุเร็วเกินไป หรือปล่อยจนแบตหมดเกลี้ยงเกินไป อันตรายแรกจะไม่เกิดถ้าเราไม่ทำให้มันลัดวงจรโดยบังเอิญ แบต R/C ทั่วไปมีอัตราการคายประจุ (Discharge Rate) 25 C ซึ่งในกรณีนี้หมายถึง 12 A ตัว UBEC สองตัวของเราจะป้องกันไม่ให้กระแสเกิน 2 ถึง 3 A ต่อตัวในทุกสถานการณ์ ส่วนอันตรายที่สองจะถูกป้องกันโดยตัว UBEC เอง มันจะหยุดจ่ายไฟให้เซอร์โวและบอร์ด MKR ถ้าแรงดันแบตตกถึง 6 V ซึ่งก็คือขีดจำกัดแรงดันต่ำพอดี เพื่อความชัวร์ เราก็มีตัววัดแรงดันในแอป Blynk ด้วย โปรเจค KITyBot รอบก่อนมีระบบเฝ้าระวังที่สั่งให้หุ่นหยุดทำงาน แต่คราวนี้ไม่จำเป็น เพราะหุ่นมันจะหยุดทำงานเองก่อนที่แรงดันจะตกต่ำเกินไปอยู่แล้ว
และสุดท้าย ผมต้องย้ำอีกครั้งว่า **ต้องชาร์จแบตเตอรี่ด้วยเครื่องชาร์จที่ออกแบบมาสำหรับมันโดยเฉพาะ** และดูแลรักษาให้ดี อย่าทิ้งไว้ชาร์จโดยไม่มีคนดูแล ควรถอดแบตออกจากหุ่น (ใช้ตีนตุ๊กแกยึดไว้ก็ได้) แล้วชาร์จในถุงกันไฟ หรืออย่างน้อยก็ให้ห่างจากวัสดุที่ติดไฟได้ง่าย เผื่อเกิดเหตุไฟลุกจะได้ไม่ลามไปที่อื่น และเก็บแบตเตอรี่ไว้ในที่ที่ปลอดภัยด้วย
ถ้ายังไม่คุ้นเคยกับแบต LiPo แนะนำให้ไปปรึกษาร้านขายของเล่น RC แถวบ้าน ซื้อแบตพร้อมกับเครื่องชาร์จที่เหมาะสม และอาจจะซื้อถุง/ภาชนะกันไฟสำหรับชาร์จและเก็บรักษาด้วย ของพวกนี้มักจะมีสัญลักษณ์เตือนเต็มไปหมด อ่านให้ดีและใช้วิจารณญาณของตัวเองด้วยนะครับ :)
ต่อ UBEC สองตัวเข้ากับสายแบตเตอรี่ แล้วก็ดึงสายไฟอีกสองเส้นตรงจากขั้วแบตออกมา ในกรณีของผม "สายสองเส้น" นี้คือสายเซอร์โวเก่าที่ตัดสายสัญญาณ (สีเหลืองหรือขาว) ออกไป มันจะได้เสียบลงบนเฮดเดอร์ male-male บนเบรดบอร์ดได้พอดี พอเสร็จแล้วมันก็จะดูคล้ายกับสายไฟเอาต์พุตจาก UBEC นั่นแหละ
ตามที่แสดงในแผนภาพ ไฟเลี้ยงจาก UBEC 1 จะไปเลี้ยงตัวควบคุมเซอร์โว (Servo Controller) ส่วนอีกตัวคือ UBEC2 จะต่อเข้ากับ "รางไฟด้านบน" บนเบรดบอร์ดเพื่อเลี้ยงบอร์ด MKR รางไฟเส้นนี้สามารถใช้เลี้ยงอุปกรณ์อื่นที่ต้องการไฟ 5 V ได้ในภายหลัง ส่วนไฟตรงจากแบตเตอรี่ (สายเซอร์โวที่ตัดแต่งแล้วในกรณีของผม) จะต่อเข้ากับรางไฟด้านล่าง จากรางไฟด้านล่างนี้ เราจะดึงไฟไปที่ขา A1 ผ่านตัวต้านทาน (Resistor) สองตัวเพื่อวัดแรงดันแบตเตอรี่ ผ่านตัวต้านทานสองตัวนี้ แรงดันแบตจะถูกแบ่งลงมา โดยที่ 10.6 V จะกลายเป็น 3.3 V ทำให้เรามีระยะห่างปลอดภัยจากแรงดันสูงสุดของแบตเตอรี่ที่ 8.4 V เยอะเลย
เจาะลึกเทคนิค: ความเสถียรของรางไฟและการวินิจฉัย IoT
การควบคุมเซอร์โว 16 ตัวในขณะที่หุ่นกำลังสเก็ตแบบโหลดสูงเนี่ย ต้องการพลัง