บทนำสู่ระบบปฏิบัติการหุ่นยนต์: สุดยอดกรอบงานแอปพลิเคชันหุ่นยนต์
เผยแพร่แล้ว: 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
โฮสต์ปลั๊กอินมากมายที่สามารถกำหนดค่าในการกำหนดค่าภาพและจำนวนมุมมองที่กำหนดไว้ล่วงหน้า
สำหรับการเริ่มต้น ให้เรียกใช้ปลั๊กอิน Robot Steering โดยเลือกใน Plugins > Robot Tools > Robot Steering
สิ่งที่เราได้รับคือตัวเลื่อนสองตัว ซึ่งแสดงถึงการเคลื่อนที่เชิงเส้นและการหมุนที่เราต้องการให้หุ่นยนต์ของเรามี ที่ด้านบนของปลั๊กอิน เราจะเห็นกล่องข้อความที่มี /cmd_vel
อยู่ในนั้น เราสามารถเปลี่ยนชื่อเป็นอะไรก็ได้ที่เราต้องการ แสดงถึงชื่อของหัวข้อที่จะเผยแพร่การบังคับบัญชา เครื่องมือเทอร์มินัลเป็นที่ที่ดีที่สุดในการดูว่าเกิดอะไรขึ้นในเบื้องหลัง
เครื่องมือเทอร์มินัล
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
ภายในเวทีที่แสดง จะมีสี่เหลี่ยมสีน้ำเงิน แสดงถึงหุ่นยนต์ที่คุณควบคุม โดยใช้รหัสของเราหรือ 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
เพื่อปรับชื่อให้เป็นรูปแบบใหม่ ในแง่นั้น คุณสามารถนึกถึงชื่อหัวข้อเป็นโฟลเดอร์ในระบบไฟล์ได้
ในการเรียกใช้ไฟล์เรียกทำงาน ไม่จำเป็นต้องมี 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
สิ่งที่เราได้รับคือการมองเห็นแบบสเตอริโอพร้อมการรับรู้ความลึกด้วยกล้องความละเอียดต่ำ จำไว้ว่าเราอาจได้รับผลลัพธ์นี้ด้วยซ้ำหากไม่มีระบบอินพุตของเรา หากเราเรียกใช้สิ่งนี้ (จากภายในโฟลเดอร์ 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 มิติด้วยฟิสิกส์และเซ็นเซอร์ที่ซับซ้อน และสามารถให้ประสบการณ์ผลลัพธ์สุดท้ายและผลิตภัณฑ์แก่คุณก่อนที่จะพัฒนา
การแนะนำนี้เป็นพื้นฐานเบื้องต้น แต่หวังว่าคุณจะสนใจทำงานกับกรอบการทำงานที่หลากหลายนี้มากขึ้น