ตอนที่ 4: การสื่อสารของหุ่นยนต์ผ่าน Topics และ Messages (Publish/Subscribe)

1. 🎯 ตอนที่ 4: Topics และ Messages การสื่อสารแบบไร้รอยต่อของหุ่นยนต์
สวัสดีครับน้องๆ ว่าที่วิศวกรหุ่นยนต์ทุกคน! ในตอนที่แล้วเราได้เห็นภาพรวมสถาปัตยกรรมของ ROS 2 กันไปแล้ว ว่ามันคือการแบ่งโปรแกรมก้อนใหญ่ๆ ให้กลายเป็นมดงานตัวเล็กๆ ที่เรียกว่า Node คำถามสำคัญที่ตามมาคือ… แล้วมดงานเหล่านี้มันส่งข้อมูลคุยกันได้อย่างไร?
วันนี้พี่จะพาไปเจาะลึกหัวใจสำคัญของการสื่อสารใน ROS 2 นั่นคือกลไก Publish / Subscribe ผ่านช่องทางที่เรียกว่า Topics และใช้ภาษากลางที่เรียกว่า Messages เตรียมตัวให้พร้อมครับ เพราะนี่คือพื้นฐานที่น้องๆ จะต้องใช้ในการเขียนโค้ดคุมหุ่นยนต์ไปตลอดชีวิต!
2. 📖 เปิดฉาก (The Hook)
ลองจินตนาการดูว่า น้องกำลังสร้างหุ่นยนต์เคลื่อนที่อัตโนมัติ หุ่นยนต์ตัวนี้มี “กล้อง” เป็นดวงตา และมี “สมองกล (Processor)” คอยประมวลผลเพื่อหลบหลีกสิ่งกีดขวาง ถ้าน้องใช้การเขียนโปรแกรมแบบเก่า สมองกลจะต้องไปสั่งกล้องว่า “เฮ้ย! ถ่ายรูปมาเดี๋ยวนี้ แล้วส่งมาให้ฉันวิเคราะห์” แล้วสมองกลก็ต้องนั่งรอ (Block) จนกว่ากล้องจะส่งรูปมาให้เสร็จ ถึงจะหันไปสั่งมอเตอร์ล้อให้หมุนได้… แบบนี้กว่าหุ่นยนต์จะขยับ คงเดินชนกำแพงไปแล้วใช่ไหมครับ?
ในโลกของ ROS 2 เราจะไม่ทำแบบนั้นครับ! เราจะให้กล้องทำงานของมันไป ถ่ายรูปเสร็จก็แค่ตะโกนประกาศออกไปเรื่อยๆ ส่วนสมองกลก็คอยเงี่ยหูฟังอย่างเดียว กลไกแบบนี้ช่วยให้ระบบทำงานขนานกันไปได้อย่างลื่นไหล ไม่ต้องมีใครมารอใคร นี่แหละครับคือพลังของระบบ Publish/Subscribe!
3. 🧠 แก่นวิชา (Core Concepts)
การสื่อสารแบบนี้ใน ROS 2 เปรียบเสมือนสถานีวิทยุกระจายเสียงครับ โดยมีองค์ประกอบหลักๆ 4 ส่วนดังนี้:
- Publisher (ผู้ประกาศ): คือ Node ที่ทำหน้าที่ส่งข้อมูลออกไป เช่น Node ของกล้องทำหน้าที่ส่งภาพที่ถ่ายได้ออกไปเรื่อยๆ โดยที่มันไม่สนใจเลยว่าจะมีใครรอรับภาพของมันอยู่หรือไม่ (Anonymous)
- Subscriber (ผู้ฟัง): คือ Node ที่คอยรับข้อมูล เช่น Node สมองกลประมวลผลภาพ (Computer Vision) ที่คอยเงี่ยหูฟังข้อมูลภาพ เมื่อมีภาพใหม่เข้ามา มันก็จะเรียกใช้ฟังก์ชัน Callback เพื่อนำภาพนั้นไปประมวลผลทันที
- Topic (คลื่นสถานีวิทยุ): คือ “ช่องทาง” หรือชื่อของท่อส่งข้อมูลที่ Publisher และ Subscriber ใช้เพื่อมาเจอกัน เช่น กล้องอาจจะส่งข้อมูลไปที่คลื่นชื่อ
/camera/image_rawสมองกลที่อยากได้ภาพก็ต้องจูนคลื่นมาที่/camera/image_rawให้ตรงกัน โดย Topic หนึ่งๆ สามารถมี Publisher และ Subscriber กี่ตัวมารุมส่งและรับข้อมูลก็ได้ (Many-to-Many) - Message (รูปแบบข้อมูล): คล้ายกับ “ภาษา” ที่ใช้คุยกันใน Topic นั้นๆ การที่ Node สองตัวจะคุยกันรู้เรื่อง ต้องใช้ Message Type เดียวกันเป๊ะๆ ตัว Message จะเป็นโครงสร้างข้อมูล (Data Structure) ที่กำหนดชนิดตัวแปรไว้ชัดเจน เช่น
int32,float32,stringหรือแม้แต่อาร์เรย์ (Array) โดยจะถูกนิยามไว้ในไฟล์นามสกุล.msg

4. 💻 ร่ายมนต์โค้ดและคำสั่ง (Show me the Code)
เรามาดูการใช้เครื่องมือผ่าน Terminal ของ ROS 2 กันก่อนครับ คำสั่งพวกนี้คือเครื่องมือหากินของวิศวกรเลยนะ:
# ขอดูหน่อยว่าตอนนี้ในหุ่นยนต์ มี "คลื่นสถานี (Topic)" อะไรกำลังออกอากาศอยู่บ้าง?
ros2 topic list #
# แอบฟังข้อมูลที่กำลังวิ่งอยู่ใน Topic /counter แบบ Real-time
ros2 topic echo /counter #
# ขอดูข้อมูลประจำตัวของ Topic /counter (เช่น ใครเป็นคน Publish, ใครเป็นคน Subscribe)
ros2 topic info /counter #
# ขอดูโครงสร้าง "ภาษา (Message Interface)" ที่ Topic นี้ใช้คุยกันหน่อย
ros2 interface show std_msgs/msg/Int32 #ทีนี้ลองมาดูตัวอย่างการร่ายมนต์โค้ด Python เบื้องต้นกันครับ พี่จะยกตัวอย่างการสร้าง Publisher และ Subscriber แบบง่ายๆ:
ฝั่ง Publisher (ส่งข้อมูล):
import rclpy
from rclpy.node import Node
from std_msgs.msg import String # นำเข้า Message ชนิด String (ข้อความ)
class SimplePublisher(Node):
def __init__(self):
super().__init__('talker_node')
# สร้าง Publisher ประกาศบนคลื่นชื่อ 'chatter' ด้วยภาษาแบบ String
# ตัวเลข 10 คือ Queue Size (ขนาดคิวรับฝากข้อความ)
self.publisher_ = self.create_publisher(String, 'chatter', 10)
# ตั้ง Timer ให้เรียกฟังก์ชัน timer_callback ทุกๆ 1 วินาที
self.timer = self.create_timer(1.0, self.timer_callback)
def timer_callback(self):
msg = String()
msg.data = "Hello, ROS 2!" # ยัดข้อความใส่ฟิลด์ data
self.publisher_.publish(msg) # สั่งส่งข้อความออกอากาศ!
self.get_logger().info(f'กำลังส่ง: "{msg.data}"') # ปริ้นต์ลงจอไว้ดูเล่นฝั่ง Subscriber (รับข้อมูล):
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class SimpleSubscriber(Node):
def __init__(self):
super().__init__('listener_node')
# สร้าง Subscriber จูนคลื่นไปที่ 'chatter' ด้วยภาษา String
# และผูกกับ Callback Function ชื่อ listener_callback
self.subscription = self.create_subscription(
String,
'chatter',
self.listener_callback,
10)
def listener_callback(self, msg):
# เมื่อมีข้อความวิ่งเข้ามาที่ Topic นี้ ฟังก์ชันนี้จะถูกเรียกอัตโนมัติ (Event-Driven)
self.get_logger().info(f'ได้รับข้อความแล้ว: "{msg.data}"')5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)
- เรื่องของ Queue Size สำคัญมาก: สังเกตตัวเลข
10ในโค้ดตอนสร้าง Publisher/Subscriber ไหมครับ? มันคือการกำหนดบัฟเฟอร์ (Buffer) สำรองข้อความ สมมติว่ากล้องส่งภาพเร็วมาก (Publisher ส่งไว) แต่สมองกลประมวลผลไม่ทัน (Subscriber ทำงานช้า) ภาพที่ล้นเข้ามาจะถูกเก็บไว้ในคิวนี้ ถ้าคิวเต็ม (เกิน 10) ภาพเก่าที่สุดจะถูกโยนทิ้งไป (Drop) เพื่อป้องกันไม่ให้เมมโมรี่คอมพิวเตอร์เต็มจนระบบแครชนั่นเองครับ - การแยกส่วนการทำงาน (Decoupling): ข้อดีของการสื่อสารแบบนี้คือ ต่อให้ Node สมองกลเกิดพังและดับไป Node กล้องก็ยังคงทำหน้าที่ส่งภาพไปที่ Topic ได้อย่างปกติไม่เกิด Error ค้าง ความยืดหยุ่นนี้ทำให้เราสามารถเขียนโค้ดชิ้นใหม่มาเสียบแทนชิ้นเก่าได้เลยโดยไม่ต้องแก้โค้ดที่ระบบอื่นเลยครับ
- ประสิทธิภาพผ่าน DDS: ใน ROS 2 ระบบเบื้องหลังของ Topic จะถูกขับเคลื่อนด้วย Middleware มาตรฐานอุตสาหกรรมที่เรียกว่า DDS (Data Distribution Service) ทำให้สามารถปรับแต่ง QoS (Quality of Service) ได้ว่าจะเน้น “ส่งข้อมูลให้เร็วที่สุด (Best Effort)” เหมาะกับข้อมูลเซ็นเซอร์ หรือ “ส่งให้ชัวร์ที่สุดห้ามตกหล่น (Reliable)” เหมาะกับข้อมูลสถานะหุ่นยนต์ครับ
6. 🏁 บทสรุป (To be continued…)
เห็นไหมครับว่าระบบ Topics และ Messages ของ ROS 2 นั้นถูกออกแบบมาให้จัดการข้อมูลแบบสตรีมมิ่ง (Streaming Data) เช่น ข้อมูลเซ็นเซอร์ หรือคำสั่งความเร็วมอเตอร์ ได้อย่างทรงพลังและเป็นอิสระต่อกัน
แต่ระบบ Topic เป็นเหมือนการ “กระจายเสียง” ฝ่ายเดียวครับ มันมีจุดอ่อนคือ เราจะไม่รู้เลยว่าผู้ฟังทำคำสั่งเราสำเร็จไหม? ถ้าเราต้องการส่งคำสั่งเช่น “ช่วยประมวลผลหน้าคนให้หน่อย แล้วส่งชื่อกลับมา” การใช้ Topic จะไม่ตอบโจทย์ ในตอนต่อไป พี่จะพาไปรู้จักกับระบบการสื่อสารแบบถาม-ตอบ (Request-Response) ที่เรียกว่า Services กันครับ รอติดตามได้เลย!
ต้องการที่ปรึกษาด้านการออกแบบสถาปัตยกรรมหุ่นยนต์ (Robotics) และระบบ Automation ให้กับองค์กรของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและพัฒนาซอฟต์แวร์แบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p