บทนำสู่ระบบปฏิบัติการหุ่นยนต์: สุดยอดกรอบงานแอปพลิเคชันหุ่นยนต์

เผยแพร่แล้ว: 2022-03-11

ระบบปฏิบัติการหุ่นยนต์ (ROS) ไม่ใช่ระบบปฏิบัติการจริง แต่เป็นเฟรมเวิร์กและชุดเครื่องมือที่ให้การทำงานของระบบปฏิบัติการบนคลัสเตอร์คอมพิวเตอร์ที่ต่างกัน ประโยชน์ของมันไม่ได้จำกัดแค่หุ่นยนต์ แต่เครื่องมือส่วนใหญ่ที่มีให้นั้นมุ่งเน้นไปที่การทำงานกับฮาร์ดแวร์ต่อพ่วง

ROS ถูกแบ่งออกเป็นมากกว่า 2,000 แพ็คเกจ แต่ละแพ็คเกจมีฟังก์ชันพิเศษ จำนวนเครื่องมือที่เชื่อมต่อกับเฟรมเวิร์กน่าจะเป็นพลังที่ยิ่งใหญ่ที่สุด

เหตุใดฉันจึงควรใช้ Robot OS

ROS ให้ฟังก์ชันการทำงานสำหรับการแยกฮาร์ดแวร์ ไดรเวอร์อุปกรณ์ การสื่อสารระหว่างกระบวนการต่างๆ บนเครื่องหลายเครื่อง เครื่องมือสำหรับการทดสอบและการแสดงภาพ และอื่นๆ อีกมากมาย

คุณสมบัติหลักของ ROS คือวิธีการทำงานของซอฟต์แวร์และวิธีการสื่อสาร ช่วยให้คุณออกแบบซอฟต์แวร์ที่ซับซ้อนได้โดยไม่ต้องรู้ว่าฮาร์ดแวร์บางตัวทำงานอย่างไร ROS เป็นวิธีเชื่อมต่อเครือข่ายของกระบวนการ (โหนด) กับฮับกลาง โหนดสามารถทำงานบนอุปกรณ์หลายเครื่อง และเชื่อมต่อกับฮับนั้นได้หลายวิธี

วิธีหลักในการสร้างเครือข่ายคือการให้บริการที่ร้องขอได้ หรือการกำหนดการเชื่อมต่อของผู้เผยแพร่/สมาชิกกับโหนดอื่นๆ ทั้งสองวิธีสื่อสารผ่านประเภทข้อความที่ระบุ บางประเภทมีให้โดยแพ็คเกจหลัก แต่ประเภทข้อความสามารถกำหนดโดยแต่ละแพ็คเกจได้

นักพัฒนาสามารถประกอบระบบที่ซับซ้อนโดยเชื่อมต่อโซลูชันที่มีอยู่สำหรับปัญหาเล็กน้อย วิธีการใช้งานระบบช่วยให้เราสามารถ:

  • เปลี่ยนส่วนประกอบด้วยอินเทอร์เฟซที่คล้ายกันได้ทันที ทำให้ไม่จำเป็นต้องหยุดระบบสำหรับการเปลี่ยนแปลงต่างๆ

  • เอาต์พุตมัลติเพล็กซ์ของส่วนประกอบหลายตัวเป็นอินพุตเดียวสำหรับส่วนประกอบอื่น ช่วยให้สามารถแก้ปัญหาต่างๆ ได้แบบคู่ขนาน

  • เชื่อมต่อส่วนประกอบที่สร้างขึ้นในภาษาการเขียนโปรแกรมต่างๆ โดยเพียงแค่ใช้ตัวเชื่อมต่อที่เหมาะสมกับระบบการส่งข้อความ ทำให้ง่ายต่อการพัฒนาซอฟต์แวร์โดยการเชื่อมต่อโมดูลที่มีอยู่จากนักพัฒนาต่างๆ

  • สร้างโหนดบนเครือข่ายของอุปกรณ์ โดยไม่ต้องกังวลเกี่ยวกับตำแหน่งที่รันโค้ดและนำระบบ Interprocess Communication (IPC) และ Remote Procedure Call (RPC) ไปใช้

  • เชื่อมต่อโดยตรงกับฟีดออนดีมานด์จากฮาร์ดแวร์ระยะไกลโดยไม่ต้องเขียนโค้ดพิเศษใดๆ โดยใช้สัญลักษณ์แสดงหัวข้อย่อยสองข้อก่อนหน้า

เราวางแผนที่จะแสดงให้เห็นว่ามีประโยชน์เพียงใดโดยการพัฒนาวิธีแก้ปัญหาง่ายๆ ซ้ำๆ มีข้อดีที่สำคัญหลายประการเมื่อเทียบกับวิธีอื่นๆ ROS มีการรองรับหลายแพลตฟอร์มและอนุญาตให้เชื่อมต่อระหว่างกระบวนการผ่านอุปกรณ์หลายตัวผ่านการเชื่อมต่อแบบเพียร์ทูเพียร์ที่ได้รับการจัดการเบื้องหลัง การออกแบบช่วยให้รองรับภาษาใดๆ โดยตัดคลาสการสื่อสาร C++ หรือพัฒนาคลาสด้วยตนเองสำหรับอินเทอร์เฟซภาษา

ROS สร้างขึ้นโดยชุมชนของตนเอง ซึ่งมีไว้สำหรับชุมชน หลังจากผ่านไปหลายปี ส่งผลให้มีแพ็คเกจที่นำกลับมาใช้ใหม่ได้จำนวนมากซึ่งง่ายต่อการรวมเข้ากับสถาปัตยกรรมของระบบ

แนวทางทางเลือกเช่น MRPT, CARMEN, LCM, Player, Microsoft RDS และอื่นๆ มีคุณสมบัติเหล่านั้นบางส่วน แต่ไม่ใช่ทั้งหมด โดยส่วนใหญ่ ข้อเสียของการออกแบบคือข้อจำกัดในการสนับสนุนภาษา การสื่อสารระหว่างกระบวนการที่ไม่เหมาะสม หรือการขาดการสนับสนุนสำหรับอุปกรณ์ต่างๆ ซึ่งน่าจะเป็นปัญหาที่แก้ไขได้ยากที่สุด

เรากำลังจะสร้างอะไร?

เนื่องจากเรามุ่งเน้นที่เฟรมเวิร์กและไม่ใช่อัลกอริธึมที่แท้จริงสำหรับปัญหาเฉพาะ ปัญหาที่กำหนดจึงค่อนข้างง่าย เป้าหมายของเราคือการสร้างซอฟต์แวร์สำหรับคอมพิวเตอร์ออนบอร์ดที่ช่วยให้เราควบคุมและตรวจสอบหุ่นยนต์จากระยะไกล เชื่อมต่อกับเราผ่าน Wi-Fi โดยใช้แป้นเกมบนคอมพิวเตอร์ของเราและฟีดจากกล้องที่ติดตั้งบนหุ่นยนต์

ก่อนอื่น เราจะสร้างโปรแกรมง่ายๆ เชื่อมต่อกับการจำลองง่ายๆ เพื่อสาธิตหลักการพื้นฐานของ ROS เราจะแนบ gamepad เข้ากับคอมพิวเตอร์และพยายามออกแบบรูปแบบการควบคุมที่ดีสำหรับการเปลี่ยนอินพุต gamepad เป็นสัญญาณควบคุมสำหรับหุ่นยนต์

ภาษาหลักสำหรับการเขียนโค้ด ROS คือ C++ และ Python โดยควรใช้ C++ เนื่องจากประสิทธิภาพที่ดีขึ้น เราจะอธิบายตัวอย่างของเราใน Python เนื่องจากมีการสร้างโค้ดน้อยกว่าและไม่จำเป็นต้องสร้างอย่างชัดเจน

การติดตั้งและการกำหนดค่า

เวอร์ชัน ROS ถูกอ้างถึงตามชื่อ ณ วันที่นี้ รุ่นล่าสุดคือ Jade Turtle และ LTS เวอร์ชันล่าสุด Indigo Igloo ควรใช้เวอร์ชัน LTS และไม่รับประกันความเข้ากันได้แบบย้อนหลังใน ROS ดังนั้นตัวอย่างทั้งหมดจะถูกเขียนขึ้นสำหรับ Indigo

ROS พร้อมใช้งานบนแพลตฟอร์ม *NIX ต่างๆ เวอร์ชันที่รองรับอย่างเป็นทางการคือบน Ubuntu ชุมชนรองรับเวอร์ชัน OS X, Arch Linux, Debian, Raspbian และ Android

เราจะดำเนินการตามขั้นตอนการติดตั้งสำหรับ Ubuntu 14.04 บนเดสก์ท็อป กระบวนการสำหรับเวอร์ชันและแพลตฟอร์มที่รองรับทั้งหมดมีอยู่ในเว็บไซต์อย่างเป็นทางการ เครื่องเสมือนที่ติดตั้ง ROS ก็มีให้เช่นกัน

การติดตั้งขึ้นอยู่กับแพลตฟอร์ม (และแพลตฟอร์มส่วนใหญ่มีแพ็คเกจให้) แต่การกำหนดค่าพื้นที่ทำงานจะเหมือนกันสำหรับทุกแพลตฟอร์ม

การติดตั้งบน Ubuntu

ROS จัดเตรียมที่เก็บของตัวเอง ขั้นตอนแรกคือการเพิ่มพวกเขา

 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update

หลังจากนั้น คุณจะมีแพ็คเกจโฮสต์ทั้งหมดสำหรับเวอร์ชัน ROS ทั้งหมดที่มีให้สำหรับเวอร์ชัน Ubuntu ของคุณ ตัวอย่างเช่น Ubuntu 14.04 รองรับ indigo และ jade

การติดตั้งแพ็คเกจพื้นฐานบนเดสก์ท็อปมีหนึ่งในสามตัวเลือก:

  • sudo apt-get install ros-indigo-ros-base สำหรับการติดตั้งขั้นต่ำ

  • sudo apt-get install ros-indigo-desktop เพื่อให้มีเครื่องมือ GUI พื้นฐานเพิ่มเติม

  • sudo apt-get install ros-indigo-desktop-full เพื่อให้มีคุณสมบัติอย่างเป็นทางการทั้งหมด รวมถึงตัวจำลองและไลบรารีต่างๆ สำหรับการนำทางและการรับรู้

เพื่อประสบการณ์การทำงานที่ดีที่สุด ขอแนะนำให้ใช้ตัวเลือกเต็มรูปแบบ สำหรับการติดตั้งบนอุปกรณ์ที่จะใช้เพื่อเรียกใช้โหนดเท่านั้น เวอร์ชันพื้นฐานก็เพียงพอแล้ว ไม่ว่าคุณจะเลือกตัวเลือกใด คุณสามารถติดตั้งแพ็คเกจที่จำเป็นชื่อ package_name ได้โดยเรียกใช้:

 sudo apt-get install ros-indigo-<package-name>

ขีดล่างจะถูกแทนที่ด้วยยัติภังค์ในชื่อสุดท้าย ดังนั้น stage_ros จะอยู่ในแพ็คเกจ ros-indigo-stage-ros

ขั้นตอนต่อไปคือการเริ่มต้น rosdep แพ็คเกจใน ROS สามารถประกาศส่วนประกอบที่พึ่งพาได้ rosdep อนุญาตให้คุณคอมไพล์แพ็คเกจเหล่านั้นโดยไม่ต้องจัดการการพึ่งพาด้วยตนเองมากเกินไป ในการเริ่มต้นให้โทร:

 sudo rosdep init rosdep update

ROS มีตัวแปรสภาพแวดล้อมหลายอย่างที่ใช้โดยเครื่องมือ ด้วยการติดตั้งเริ่มต้น สคริปต์ทุบตีเพื่อเริ่มต้นจะอยู่ใน /opt/ros/indigo/setup.bash ต้องเริ่มต้นตัวแปรภายในทุกเซสชัน bash ดังนั้นทางออกที่ดีที่สุดคือการเพิ่มลงใน ~/.bashrc

 echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc source ~/.bashrc

แพ็คเกจบางตัวติดตั้งการพึ่งพาภายนอกผ่าน rosinstall ซึ่งมีให้ใช้งานเป็นแพ็คเกจและติดตั้งผ่าน sudo apt-get install python-rosinstall

นี่คือจุดสิ้นสุดของการติดตั้งบน Ubuntu ต่อไปนี้คือคำแนะนำสั้นๆ เกี่ยวกับการติดตั้งพื้นที่ทำงาน

การกำหนดค่า

นับตั้งแต่ Groovy Galapagos พื้นที่ทำงาน ROS ได้รับการจัดการผ่าน catkin เราจำเป็นต้องกำหนดไดเร็กทอรีสำหรับแพ็คเกจทั้งหมดที่เราโฮสต์ ภายในไดเร็กทอรี เราสร้างโฟลเดอร์ src และเรียก catkin_init_workspace form ภายในนั้น ซึ่งจะสร้างลิงก์สัญลักษณ์ต่างๆ ไปยังเวอร์ชัน ROS ที่มาจากปัจจุบัน ขั้นตอนต่อไปคือการเพิ่มพื้นที่ทำงานนี้ให้กับตัวแปรสภาพแวดล้อมด้วย

ในการกำหนดค่าเวิร์กสเปซทั้งหมดนี้ ให้เลือกไดเร็กทอรีว่างและรันคำสั่งต่อไปนี้:

 mkdir src cd src catkin_init_workspace cd .. catkin_make echo "source $(pwd)/devel/setup.bash" >> ~/.bashrc source ~/.bashrc

ตอนนี้คุณได้สร้างพื้นที่ทำงานซึ่งคุณสามารถสร้างแพ็คเกจ ROS ของคุณเองได้

ทำความคุ้นเคยกับเครื่องมือ

การสร้างรหัสใด ๆ เป็นการก้าวกระโดดครั้งใหญ่ มาทำความคุ้นเคยกับระบบบางอย่างที่ทำงานอยู่เบื้องหลังกันก่อน ขั้นตอนแรกของเราคือการเรียกใช้ GUI พื้นฐานและดูว่าข้อความใดที่สร้าง

ในการรันทุกอย่างใน ROS จำเป็นต้องเปิดใช้กระบวนการหลัก ง่ายเหมือนเปิดหน้าต่างเทอร์มินัลใหม่และพิมพ์:

 roscore

ในเครือข่ายอุปกรณ์ที่เชื่อมต่อทั้งหมดของคุณ roscore จะต้องเปิดใช้งานเพียงครั้งเดียวบนอุปกรณ์ที่จะโฮสต์ศูนย์กลางศูนย์กลางสำหรับการส่งการสื่อสาร

บทบาทหลักของ roscore คือการบอกโหนดว่าโหนดอื่นใดที่พวกเขาควรเชื่อมต่อและด้วยวิธีใด (ไม่ว่าจะผ่านทางพอร์ตเครือข่ายหรือหน่วยความจำที่ใช้ร่วมกัน) เป้าหมายคือการอนุญาตให้โหนดสนใจเฉพาะข้อมูลที่พวกเขาต้องการทราบ มากกว่าสิ่งที่โหนดต้องการเชื่อมต่อ ในขณะที่ลดเวลาและแบนด์วิดท์ที่จำเป็นในการสื่อสารทั้งหมด

rqt

หลังจากรัน roscore เราสามารถเปิดเครื่องมือ GUI หลักสำหรับ ROS: rqt สิ่งที่เราเห็นนั้นท่วมท้นมาก - หน้าต่างที่ว่างเปล่า rqt โฮสต์ปลั๊กอินมากมายที่สามารถกำหนดค่าในการกำหนดค่าภาพและจำนวนมุมมองที่กำหนดไว้ล่วงหน้า

สกรีนช็อตของหน้าต่าง GUI ว่างที่ชื่อว่า "Default - rqt" และด้วยเมนู File, Plugins, Running, Perspectives และ Help

สำหรับการเริ่มต้น ให้เรียกใช้ปลั๊กอิน Robot Steering โดยเลือกใน Plugins > Robot Tools > Robot Steering สิ่งที่เราได้รับคือตัวเลื่อนสองตัว ซึ่งแสดงถึงการเคลื่อนที่เชิงเส้นและการหมุนที่เราต้องการให้หุ่นยนต์ของเรามี ที่ด้านบนของปลั๊กอิน เราจะเห็นกล่องข้อความที่มี /cmd_vel อยู่ในนั้น เราสามารถเปลี่ยนชื่อเป็นอะไรก็ได้ที่เราต้องการ แสดงถึงชื่อของหัวข้อที่จะเผยแพร่การบังคับบัญชา เครื่องมือเทอร์มินัลเป็นที่ที่ดีที่สุดในการดูว่าเกิดอะไรขึ้นในเบื้องหลัง

ภาพหน้าจอแสดงหน้าต่างเดียวกันกับก่อนหน้านี้ แต่มีอินเทอร์เฟซ Robot Steering—พร้อมไอคอน D, โหลดซ้ำ, ช่วยเหลือ, ย่อเล็กสุด, วงกลมและ X— อยู่ภายใน บรรทัดแรกจะมีกล่องข้อความที่มี "/cmd_vel" และปุ่มหยุด ด้านล่างเป็นแถบเลื่อนแนวตั้งที่มีศูนย์กลางในแนวตั้งซึ่งตั้งค่าไว้ตรงกลางที่ 0.0 m/s โดยมีปุ่มทางด้านซ้ายสำหรับ +, 0, และ - และตัวควบคุมตัวเลขด้านบนและด้านล่างที่อ่านว่า 1,00 และ -1,00 ด้านล่างเป็นแถบเลื่อนที่คล้ายกันซึ่งอยู่ในแนวนอนและวัดเป็น rad/s โดยตั้งค่าเป็น 0 ตรงกลาง โดยมีปุ่มควบคุมตัวเลขอยู่ที่ 3,00 ทางด้านซ้าย และ -3,00 ทางด้านขวา

เครื่องมือเทอร์มินัล

ROS มีเครื่องมือที่มีประสิทธิภาพหลายอย่างสำหรับตรวจสอบสิ่งที่เกิดขึ้นในระบบ เครื่องมือแรกที่เราจะแนะนำคือ rostopic ช่วยให้เราตรวจสอบหัวข้อที่โหนดสามารถสมัครและเผยแพร่ได้ การเรียกใช้ rostopic list จะให้ผล:

 /cmd_vel /rosout /rosout_agg

2 หัวข้อหลังทำงานอยู่เสมอและเกี่ยวข้องกับระบบ ROS ส่วนกลาง หัวข้อ /cmd_vel กำลังถูกเผยแพร่โดยการควบคุมของเรา การเปลี่ยนชื่อหัวข้อในการบังคับทิศทางจะเป็นการเปลี่ยนชื่อที่นี่เช่นกัน ตอนนี้ เราสนใจในสิ่งที่เกิดขึ้นภายในหัวข้อ การเรียกใช้ rostopic echo /cmd_vel จะไม่แสดงอะไรเลย (เว้นแต่คุณจะปรับแต่งแถบเลื่อน) กระบวนการทำงานจนกว่าเราจะยกเลิก ตอนนี้ให้เราเลื่อนตัวเลื่อนแนวตั้งไปที่ 20 ม./วินาที เมื่อพิจารณาจากเสียงสะท้อน เราจะเห็นสิ่งต่อไปนี้ซ้ำแล้วซ้ำเล่า:

 linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0

สแปมข้อความนี้บ่อยแค่ไหน? rostopic hz /cmd_vel พูดที่อัตราเฉลี่ย 10 Hz ฉันสามารถเรียกใช้หัวข้อเช่นนี้ผ่านการเชื่อมต่อ Wi-Fi ที่ช้าของฉันได้กี่หัวข้อ rostopic bw /cmd_vel ตรวจพบค่าเฉลี่ย 480 B/s

เท่านี้ก็เรียบร้อยและดีแล้ว แต่เราพูดถึงประเภทข้อความแล้ว ข้อมูลนี้ดีสำหรับมนุษย์ แต่แอปพลิเคชันต้องการข้อมูลดิบ และจำเป็นต้องทราบประเภทข้อความเพื่อให้สามารถตีความข้อมูลได้ สามารถกำหนดประเภทได้ด้วย rostopic type /cmd_vel โดยบอกเราว่ามันคือ geome_msgs geometry_msgs/Twist เครื่องมือเทอร์มินัล ROS ทั้งหมดที่เรียกโดยไม่มีอาร์กิวเมนต์จะส่งคืนข้อความช่วยเหลือมาตรฐาน

ROS Wiki นั้นดีพอที่จะทำให้การค้นหาเว็บสำหรับสตริงนี้ส่งผลให้เกิดคำอธิบายของ Wiki เกี่ยวกับสิ่งที่อยู่ภายในและโครงสร้างของมัน แต่เราไม่ต้องพึ่งมัน rosmsg เป็นเครื่องมือทั่วไปสำหรับประเภทข้อความ การเรียกใช้ rosmsg show geometry_msgs/Twist จะกลับมา:

 geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z

ข้อความประกอบด้วยเวกเตอร์ 3 มิติ 2 ภาพ ซึ่งแสดงถึงความเร็วเชิงเส้นและเชิงมุมในพื้นที่ 3 มิติ

ถ้าเราต้องการหัวข้อที่โหนดเชื่อมต่ออยู่ rosnode info <node-name> จะให้ข้อมูลโดยละเอียดเกี่ยวกับโหนดนั้น เครื่องมือ rostopic , rosmsg และ rosnode เป็นเครื่องมือหลักในการตรวจสอบฟังก์ชัน ROS แบบดิบ ROS มี GUI และเครื่องมือเทอร์มินัลมากขึ้น แต่สิ่งเหล่านี้อยู่นอกขอบเขตของเราสำหรับการแนะนำนี้

เครื่องมือหลักสำหรับการรันโหนด ROS คือ rusrun และ roslaunch rosrun สามารถเรียกใช้โหนดผ่าน rosrun <package_name> <node_name> และ roslaunch จะรันโหนดตามไฟล์เรียกใช้งาน ซึ่งเราจะทำความคุ้นเคยในระดับเล็กน้อย เนื่องจากเป็นองค์ประกอบที่ซับซ้อนที่สุดของระบบอัตโนมัติ ROS

เราสามารถปิดทุกอย่างที่เราวิ่งเพื่อเริ่มทำงานกับโค้ดแรกของเรา สำหรับการอ้างอิงในอนาคต จะดำเนินการโดยไม่บอกว่าการเรียกใช้สิ่งใดก็ตามที่เกี่ยวข้องกับ ROS นั้นจำเป็นต้องมีอินสแตนซ์ของ roscore ที่ใช้งานอยู่ ปัญหามากมายที่คุณพบสามารถแก้ไขได้โดยปิดหน้าต่างเทอร์มินัลที่มีการเรียกใช้ roscore แล้วเปิดหน้าต่างใหม่เพื่อเปิดใช้ใหม่ สิ่งนี้จะอัปเดตการพึ่งพาทั้งหมดที่จำเป็นต้องโหลดซ้ำ ทั้งใน bash และ roscore

การสร้าง Gamepad Teleoperation

เป้าหมายแรกของเราคือเลียนแบบการทำงานของ Robot Steering โดยการสร้างโหนดที่เผยแพร่ข้อมูล geo_msgs geometry_msgs/Twist ไปยัง /cmd_vel ตามอินพุต gamepad จุดแรกของเราคือแพ็คเกจ joy

แพ็คเกจ joy

แพ็คเกจ Joy ให้ไดรเวอร์ ROS ทั่วไปสำหรับจ joy สติ๊กและเกมแพด ไม่รวมอยู่ในการติดตั้งเริ่มต้น จึงต้องติดตั้งผ่าน:

 sudo apt-get install ros-indigo-joy

หลังจากการติดตั้งเราสามารถเรียกใช้ rosrun joy joy_node ได้ การดำเนินการนี้จะเชื่อมต่อเรากับจอยสติ๊กหรือแป้นเกมเริ่มต้น การวิ่ง rostopic list แสดงให้เราเห็นว่าเรามีหัวข้อที่เรียกว่า /joy การฟังผ่าน rostopic echo จะแสดงข้อความในรูปแบบต่อไปนี้ให้เราทราบ (โปรดทราบว่าคุณต้องโต้ตอบกับแป้นเกมหรือจอยสติ๊กเพื่อเผยแพร่ข้อความ)

 header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

คุณสามารถละเว้นส่วนหัวได้ในตอนนี้ นอกจากนั้น เรามี axes และ buttons ซึ่งอธิบายอย่างชัดเจนถึงความหมายของมัน การเคลื่อนแกนและการกดปุ่มบนตัวควบคุมจะทำให้ตัวเลขเหล่านี้เปลี่ยนไป ด้วยเครื่องมือของเรา เราสามารถระบุได้ว่าข้อความประเภทใดคือ sensor_msgs/Joy และรูปแบบคือ:

 std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons

การสร้าง Teleoperation ของเรา

ขั้นตอนแรกในการเขียนโค้ดคือการสร้างแพ็คเกจ ภายในโฟลเดอร์ src ของเวิร์กสเปซ ให้รัน:

 catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs

ในที่นี้ เราระบุชื่อของแพ็คเกจที่เรากำลังสร้าง ตามด้วยแพ็คเกจที่เราวางแผนจะใช้ ไม่ต้องกังวล คุณสามารถอัปเดตการพึ่งพาได้ด้วยตนเองในภายหลัง

ตอนนี้เรามีโฟลเดอร์ toptal_tutorial ภายในโฟลเดอร์ ให้สร้างโฟลเดอร์ scripts ที่จะเก็บสคริปต์ Python ทั้งหมดของเรา

มาสร้างไฟล์ชื่อ teleop.py และในนั้นเราจะตั้งค่า:

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

เรายังต้องตั้งค่า chmod +x teleop.py เพื่อให้สคริปต์ทำงานได้ การเรียกใช้ rosrun joy joy_node ในเทอร์มินัลหนึ่งและ rosrun toptal_tutorial teleop.py ในเทอร์มินัลอื่นจะส่งผลให้เทอร์มินัลเอาต์พุตของ teleop.py เต็มไปด้วยข้อความ Joy

มาดูกันดีกว่าว่าโค้ดนี้ทำอะไรได้บ้าง

ขั้นแรก เรานำเข้า rospy ซึ่งโฮสต์ไลบรารีสำหรับการโต้ตอบกับเฟรมเวิร์ก ROS แต่ละแพ็คเกจที่กำหนดข้อความมีแพ็คเกจย่อย msg พร้อมคำจำกัดความของข้อความ เรากำลังนำเข้า Joy เพื่อจัดการกับอินพุต ไม่จำเป็นต้องนำเข้าประเภทข้อความที่ฝังไว้ (เช่น Header จาก std_msgs.msg ที่อยู่ในข้อความ Joy ) เว้นแต่เราต้องการกล่าวถึงอย่างชัดเจน

ขั้นตอนแรกของเราคือการเริ่มต้นโหนดด้วยชื่อเฉพาะ (ในกรณีนี้ เราเรียกว่า "teleop") หลังจากนั้น เราสร้างสมาชิกที่สมัครรับหัวข้อ "joy" ของประเภท sensor_msgs.msg.Joy และจัดการแต่ละข้อความโดยเรียกใช้ฟังก์ชัน joy_callback โทรกลับได้รับหนึ่งพารามิเตอร์ ข้อมูลจากข้อความ การเข้าถึงสมาชิกของข้อมูลนั้นง่าย หากเราต้องการพิมพ์สถานะของแกนแรก หากเราจำประเภทข้อความได้ เราจะเรียก print data.axes[0] และจะเป็นแบบทศนิยม การวนซ้ำที่ส่วนท้ายจะวนซ้ำจนกว่า ROS จะปิดตัวลง

ขั้นตอนต่อไปของเราคือการจัดการข้อมูลของเราอย่างใด เราควรสร้างข้อความ Twist ที่เปลี่ยนแปลงตามอินพุต จากนั้นเราจะเผยแพร่ไปยังหัวข้อ cmd_vel

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

ขั้นแรก เราเพิ่มข้อความ Twist และเราเพิ่มการรองรับอาร์กิวเมนต์ของฟังก์ชันการโยงผ่าน functools.partial เราสร้างผู้เผยแพร่ pub ที่เผยแพร่ข้อความประเภท Twist ไปยัง cmd_vel เราผูกมัดผู้เผยแพร่นั้นกับการโทรกลับ และทำให้เผยแพร่ข้อความ Twist ในทุกอินพุตด้วยความเร็วที่แสดงโดยสองแกนแรก รหัสนี้ทำในสิ่งที่เราคาดหวัง และเราสามารถเห็นผลลัพธ์ที่ได้ผ่าน rostopic echo /cmd_vel

เรายังมีปัญหาอยู่อย่างหนึ่ง หัวข้อ /joy สามารถเผยแพร่ได้ในอัตราที่ดี หากเราตรวจสอบ rostopic hz /cmd_vel และย้ายแท่งอนาล็อกเป็นวงกลม เราจะเห็นข้อความจำนวนมาก ไม่เพียงแต่ส่งผลให้เกิดการสื่อสารจำนวนมากเท่านั้น แต่กระบวนการที่ได้รับข้อความเหล่านี้ยังต้องดำเนินการกับแต่ละข้อความด้วย ไม่จำเป็นต้องเผยแพร่ข้อมูลนั้นบ่อยๆ และเราควรจะเผยแพร่ที่อัตรา 10 Hz ที่เสถียร เราสามารถทำได้ด้วยรหัสต่อไปนี้

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()

เราแก้ไขการเรียกกลับเพื่อรับวัตถุ Twist ที่เปลี่ยนแปลงได้และแก้ไขภายในลูป ฟังก์ชั่น sleep จาก rospy.Rate รักษาความถี่เอาต์พุตที่เสถียร

โค้ดสุดท้ายจะส่งผลให้หัวข้อ /cmd_vel ได้รับคำสั่ง velocity ที่ 10 Hz เลียนแบบเอาต์พุตของปลั๊กอิน Robot Steering rqt

ใช้งานระบบจำลอง

จำลองโลก

เป้าหมายแรกของเราคือการสร้างสภาพแวดล้อมที่เราสามารถจำลองสถานการณ์ที่เราต้องการบรรลุได้ โหนด stageros ภายในแพ็คเกจ stage_ros ช่วยให้เราสามารถเรียกใช้โรบ็อตหนึ่งตัวภายในสเตจ 2 มิติที่กำหนดผ่านรูปภาพ มีไวยากรณ์ทั้งหมดที่อธิบายไว้ในแพ็คเกจ stage_ros สำหรับไฟล์โลกและวิธีสร้างไฟล์เหล่านั้น มันค่อนข้างง่าย แต่อยู่นอกขอบเขตของเรา โชคดีที่แพ็คเกจนี้มาพร้อมกับโลกสาธิตมากมาย ขั้นแรก ไปที่ไดเร็กทอรีของไฟล์โดยเรียกใช้:

 roscd stage_ros cd world

ภายในโฟลเดอร์มีหลายไฟล์ มาวิ่งกัน

 rosrun stage_ros stageros willow-erratic.world

สิ่งนี้สร้างหลายหัวข้อ ความหมายของแต่ละสิ่งมีบันทึกไว้ในแพ็คเกจด้วย ส่วนที่สำคัญคือมี cmd_vel

ภาพหน้าจอของหน้าต่างชื่อ Stage: willow-erratic.world ป้ายสถานะเขียนว่า "0m 20s 300msec (1.0)" มีมาตราส่วนทางด้านขวาวิ่งจาก 18 ที่ด้านล่างถึง 30 ที่ด้านบน โดยเพิ่มขึ้นทีละหนึ่ง ภาพหลักคือกระดานหมากรุกที่มีจุดและเส้นสีดำหลักกระจายอยู่ทั่ว บวกกับสี่เหลี่ยมสีน้ำเงินที่อยู่ตรงกลาง และสี่เหลี่ยมสีแดงที่ใหญ่กว่าเล็กน้อย และอีกสองสามตารางกระดานหมากรุกอยู่ห่างจากภาพนั้น

ภายในเวทีที่แสดง จะมีสี่เหลี่ยมสีน้ำเงิน แสดงถึงหุ่นยนต์ที่คุณควบคุม โดยใช้รหัสของเราหรือ Robot Steering เราสามารถควบคุมหุ่นยนต์ตัวนี้ได้ ลองดูสิ

การตั้งค่าระบบของเราผ่านไฟล์เรียกใช้งาน

มาสร้างโฟลเดอร์เรียก teleop.launch งานกันภายในแพ็คเกจของเรา และภายในนั้นให้สร้างไฟล์ชื่อ launch โครงสร้างโฟลเดอร์สุดท้ายควรมีลักษณะดังนี้:

 toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src

ภายในไฟล์ teleop.launch เราจะกำหนดชุดของโหนดและการเชื่อมต่อระหว่างกัน

 <launch> <arg name="world_file" default="$(find stage_ros)/world/willow-four-erratics-multisensor.world" /> <node pkg="stage_ros" type="stageros" name="simulated_world" args="$(arg world_file)"></node> <group ns="robot_0"> <node pkg="joy" type="joy_node" name="joy_input"></node> <node pkg="toptal_tutorial" type="teleop.py" name="joy_convert"></node> </group> </launch>

โลกใหม่ประกอบด้วยหุ่นยนต์สี่ตัว และแต่ละหัวข้อมีคำนำหน้าของ robot_<n> ดังนั้น หมายเลขโรบ็อต 0 จึงมีหัวข้อคำสั่งความเร็วที่เรียกว่า robot_0/cmd_vel นั่นคือเหตุผลที่เราใส่การควบคุมของเราไว้ในเนมสเปซที่เรียกว่า robot_0 เพื่อปรับชื่อให้เป็นรูปแบบใหม่ ในแง่นั้น คุณสามารถนึกถึงชื่อหัวข้อเป็นโฟลเดอร์ในระบบไฟล์ได้

ไดอะแกรมที่มีสองส่วน คือ simulated-world และ /robot_0 หลังมีกล่องและฟองอากาศทั้งหมดที่ขึ้นต้นด้วย /robot_0/ อดีตมีฟองที่มีป้ายกำกับ /simulated-world เชื่อมต่อกับฟอง cmd_vel ของหลังซึ่งรวมกล่อง joy_convert ซึ่งรวมกล่องความสุขซึ่งรวมฟอง joy_input /simulated-world ยังเชื่อมต่อกับกล่องสี่กล่องใน /robot-0 ได้แก่ image_1, depth_0, depth_1 และ image_0

ในการเรียกใช้ไฟล์เรียกทำงาน ไม่จำเป็นต้องมี roscore ในแง่หนึ่ง roscore เป็นเพียงกรณีพิเศษของไฟล์เรียกใช้งานที่ไม่ทำอะไรเลย หาก roscore หายไป เฉพาะไฟล์เรียกทำงานแรกที่เปิดตัวเท่านั้นที่จะเรียกใช้คอร์ ในขณะที่ส่วนที่เหลือจะเชื่อมต่อกับไฟล์นั้น ตอนนี้ เราเปิดตัวด้วย:

 roslaunch toptal_tutorial teleop.launch

หากทั้งหมดถูกต้อง จะส่งผลให้มีหุ่นยนต์จำลอง 4 ตัว ซึ่งหนึ่งในนั้นควบคุมด้วยแป้นเกมหรือจอยสติ๊กของเรา โลกนี้มีมากขึ้นภายใต้ประทุนมากกว่าโลกก่อน หุ่นยนต์สี่ตัวแต่ละตัวมี:

 /robot_<n>/base_pose_ground_truth /robot_<n>/base_scan_0 /robot_<n>/base_scan_1 /robot_<n>/camera_info_0 /robot_<n>/camera_info_1 /robot_<n>/cmd_vel /robot_<n>/depth_0 /robot_<n>/depth_1 /robot_<n>/image_0 /robot_<n>/image_1 /robot_<n>/odom

เราแทนที่ <n> ด้วย 0, 1, 2 หรือ 3 สิ่งนี้นำเราไปสู่หัวข้อสุดท้ายของเรา

การดูข้อมูลของเราด้วย rqt

เราไม่ได้เจาะลึกเกินไป rqt แต่เป็นเครื่องมือที่สมบูรณ์แบบสำหรับการดูข้อมูลที่ซับซ้อนมากขึ้น คุณสามารถทดลองกับหัวข้อทั้งหมดได้ แต่เราจะเน้นที่ image_0 , image_1 , depth_0 และ depth_1

เริ่มต้น rqt และลบปลั๊กอินที่เปิดอยู่ ตอนนี้เราจะเปิดตัวสร้างภาพ 4 ภาพ ( Plugins > Visualization > Image View ) และวางไว้ในรูปแบบตาราง 2x2 สุดท้าย ที่มุมซ้ายบนของแต่ละมุมมอง มาเลือกหนึ่งในสี่หัวข้อที่ระบุไว้สำหรับ robot_0

ภาพหน้าจอแสดงอินเทอร์เฟซการบังคับเลี้ยวของหุ่นยนต์ โดยมีกล่องข้อความและแถบเลื่อนที่กล่าวถึงก่อนหน้านี้ แต่กล่องข้อความอ่านว่า "/robot_0/cmd_vel" ด้านขวามีมุมมองภาพสี่ภาพ สองอันดับแรก (image_0 และ image_1) แสดงกล่องสีน้ำเงินสองกล่องและกล่องสีแดงในแบบ 3 มิติ สองด้านล่าง (deep_0 และ depth_1) แสดงภาพที่คล้ายคลึงกันที่ด้านบน แต่ในโทนสีเทา และโดยเฉพาะอย่างยิ่ง กล่องสีพื้นหน้าที่นี่จะปรากฏเป็นสีเทาเข้มกว่าวัตถุในพื้นหลัง

สิ่งที่เราได้รับคือการมองเห็นแบบสเตอริโอพร้อมการรับรู้ความลึกด้วยกล้องความละเอียดต่ำ จำไว้ว่าเราอาจได้รับผลลัพธ์นี้ด้วยซ้ำหากไม่มีระบบอินพุตของเรา หากเราเรียกใช้สิ่งนี้ (จากภายในโฟลเดอร์ stage_ros/world ):

 rosrun stage_ros stageros willow-four-erratics-multisensor.world

และเพิ่มปลั๊กอิน Robot Steering ด้วยหัวข้อที่เรียกว่า /robot_0/cmd_vel เราจะได้รับผลลัพธ์เช่นเดียวกันกับการควบคุมที่เป็นแถบเลื่อนบนหน้าจอ

การนำผลลัพธ์ไปใช้กับระบบจริง

ฮาร์ดแวร์จำนวนมากได้รับการสนับสนุนอย่างเต็มที่สำหรับ ROS ซึ่งมักมีให้โดยอาสาสมัครบุคคลที่สาม แพลตฟอร์มหุ่นยนต์จำนวนมากมีไดรเวอร์ที่สร้างข้อความประเภทนี้ และ ROS มีโหนดที่ใช้เว็บแคมและเผยแพร่ฟีดรูปภาพ

แม้ว่าผลลัพธ์สุดท้ายจะเป็นการจำลองสิ่งที่เราต้องการบรรลุ แต่ก็สามารถทำได้เช่นเดียวกันโดยการปรับเปลี่ยนต่อไปนี้:

  • ติดตั้ง ROS บนคอมพิวเตอร์ออนบอร์ดของหุ่นยนต์ของคุณ
  • สร้างไฟล์เรียกทำงานสำหรับคอมพิวเตอร์ออนบอร์ดที่เชื่อมต่อ ROS กับแพลตฟอร์มพื้นฐานและเซ็นเซอร์ระดับสูงทั้งหมด เช่น กล้อง เครื่องค้นหาระยะด้วยเลเซอร์ และอื่นๆ โหนดที่จำเป็นสามารถมีอยู่แล้ว หรือสามารถนำไปใช้ได้โดยการสร้างผู้เผยแพร่/สมาชิกใน ROS ที่ด้านหนึ่ง และไดรเวอร์สำหรับการสื่อสารแบบอนุกรมในอีกด้าน
  • ให้ไฟล์เรียกทำงานเมื่อเริ่มต้น
  • บนคอมพิวเตอร์ระยะไกลของคุณให้เพิ่ม export ROS_MASTER_URI=http://<robot_hostname>:11311/ เพื่อเริ่มต้น bash ของคุณทำให้คอมพิวเตอร์ระยะไกลค้นหา roscore บนชื่อโฮสต์และพอร์ตที่ระบุ
  • เรียก rqt และ/หรือสคริปต์ใดๆ สำหรับตรวจสอบและควบคุมโรบ็อต

สิ่งที่เกิดขึ้นจริงคือการส่งออกตัวแปรสภาพแวดล้อมที่เหมาะสมบนอุปกรณ์ระยะไกล และส่วนที่เหลือจะจัดการเอง การเรียกใช้ ROS บนคอมพิวเตอร์คลัสเตอร์ต้องการเพียงขั้นตอนเดียวที่ทำกับทุกเครื่อง

บทสรุป

เราได้แสดงให้เห็นแล้วว่า ด้วยการเข้ารหัสเพียงเล็กน้อย คุณสามารถมีระบบตัวแปรที่ซับซ้อนซึ่งคุณสามารถจัดการได้ตามต้องการ ระบบผู้เผยแพร่/สมาชิกที่เรียบง่ายช่วยให้คุณพัฒนาขั้นตอนซอฟต์แวร์ที่ประมวลผลข้อมูลในกลุ่มคอมพิวเตอร์ได้อย่างรวดเร็ว โดยไม่ต้องกังวลกับการใช้งานองค์ประกอบบางอย่าง

ในขณะที่เราใช้เครื่องจำลองอย่างง่าย เครื่องจำลองที่ซับซ้อนมากขึ้น เช่น gazebo (รวมถึงในเวอร์ชันเดสก์ท็อปเต็มรูปแบบด้วย) ช่วยให้คุณสร้างโลก 3 มิติด้วยฟิสิกส์และเซ็นเซอร์ที่ซับซ้อน และสามารถให้ประสบการณ์ผลลัพธ์สุดท้ายและผลิตภัณฑ์แก่คุณก่อนที่จะพัฒนา

การแนะนำนี้เป็นพื้นฐานเบื้องต้น แต่หวังว่าคุณจะสนใจทำงานกับกรอบการทำงานที่หลากหลายนี้มากขึ้น