เขียน Publisher และ Subscriber ด้วยภาษา Python

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

Topic ก็เหมือนกับหัวเรื่องที่เราไว้คุยกัน พูดง่ายๆคือ Publisher Node จะ Publish Message ของตัวเองขึ้นไปที่ Topic แล้วจะมี Subscriber Node มารอรับ Message ที่ส่งมาทาง Topic ที่มีชื่อเดียวกัน

เวลาพูดว่า Publisher หมายถึงการที่ Node จะส่ง Message ออกไปที่ Topic โดยไม่สนใจว่าจะมี Node รอรับอยู่รึเปล่า Node 1 ตัวสามารถ Publisher Message ออกไปได้หลายๆ Topics

Message : ข้อความ ค่ามาตรฐาน (จำนวนเต็ม, จุดลอย, บูลีน, ฯลฯ ) ข้อมูลอาร์เรย์ทั่วๆไป รวมไปถึงข้อมูลอาร์เรย์ที่มีความซับซ้อน

1 : เขียน Node ภาษา Python แบบ OOP


เขียน Node ภาษา Python แบบ OOP ตามขั้นตอนลิงค์ด้านล่าง


2 : เปิด Terminator 4 หน้าต่าง


3 : เขียน Publisher ด้วยภาษา Python


เขียนโหนดส่งข้อความ Publisher ด้วยภาษา Python

โดยไปที่ ไปที่ หน้าต่างที่ 1 ใช้คำสั่งเข้าไปใน โฟลเดอร์ที่ต้องการสร้างไฟล์

cd ros2_ws/scr/my_py_pkg/my_py_pkg

ls


สร้างไฟล์ robot_news_station.py

touch robot_news_station.py


คำสั่ง chmod คำสั่งใช้เปลี่ยนสิทธิของไฟล์ ตัวอักษร x มาจาก Execute หมายถึง ประมวลผล

chmod +x robot_news_station.py

ls

ใช้ Visual Studio Code เปิดไฟล์ robot_news_station.py เขียนโค้ด + Save ตามโค้ดด้านล่าง

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from example_interfaces.msg import String


class RobotNewsStationNode(Node):
    def __init__(self):
        super().__init__("robot_news_station")

        self.robot_name_ = "C3PO"
        self.publisher_ = self.create_publisher(String, "robot_news", 10)
        self.timer_ = self.create_timer(0.5, self.publish_news)
        self.get_logger().info("Robot News Station has been started")

    def publish_news(self):
        msg = String()
        msg.data = "Hi, this is " + \
            str(self.robot_name_) + " from the robot news station."
        self.publisher_.publish(msg)


def main(args=None):
    rclpy.init(args=args)
    node = RobotNewsStationNode()
    rclpy.spin(node)
    rclpy.shutdown()


if __name__ == "__main__":
    main()


เปิดไฟล์ setup.py เพิ่ม จุลภาค หรือ ลูกน้ำ ( , ) หลังบรรทัด 23 แล้ว เพิ่มโค้ดบรรทัดที่ 24 ล่าง ด้วยโค้ดด้านล่าง

"robot_news_station = my_py_pkg.robot_news_station:main"


เปิดไฟล์ package.xml เพิ่มโค้ดบรรทัดที่ 11 ด้วยโค้ดด้านล่าง

 <depend>example_interfaces</depend>


กลับสู่ Home เพื่อจะ Build แพ็กเกจ my_py_pkg

cd

cd ros2_ws/


คำสั่ง Build เฉพาะ แพ็กเกจ my_py_pkg

colcon build --packages-select my_py_pkg --symlink-install

ไปที่ หน้าต่างที่ 2 โดยเราจะต้องทําให้ Terminator รู้จักคําสั่งของ ROS2 ด้วย คําสั่ง

source ~/.bashrc


เรียกใช้งาน robot_news_station ด้วย ROS2

ros2 run my_py_pkg robot_news_station

ไปที่ หน้าต่างที่ 4 ให้แสดง Node ที่กำลังทำงานอยู่

ros2 node list


แสดง Topic ที่กำลังทำงานอยู่

ros2 topic list

แสดงข้อมูลที่ส่งออกมาจาก topic robot_news

ros2 topic echo /robot_news


4 : เขียน Subscriber ด้วยภาษา Python


Subscriber หมายถึงการที่ Node จะรับ Message จาก Topic ที่ตัวเองรอรับอยู่ Node 1 ตัวสามารถ Subscriber Message ที่มาจากหลายๆ Topic ได้

เขียน โหนด รับข้อความ Subscriber ด้วยภาษา Python โดยกลับไปที่ หน้าต่างที่ 1  ใช้คำสั่งเข้าไปใน โฟลเดอร์ที่ต้องการสร้างไฟล์

cd scr/my_py_pkg/my_py_pkg

ls


สร้างไฟล์ smartphone.py

touch smartphone.py


คำสั่ง chmod คำสั่งใช้เปลี่ยนสิทธิของไฟล์ ตัวอักษร x มาจาก Execute หมายถึง ประมวลผล

chmod +x smartphone.py


ใช้ Visual Studio Code เปิดไฟล์ smartphone.py เขียนโค้ด + Save ตามโค้ดด้านล่าง

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node

from example_interfaces.msg import String


class SmartphoneNode(Node):
    def __init__(self):
        super().__init__("smartphone")
        self.subscriber_ = self.create_subscription(
            String, "robot_news", self.callback_robot_news, 10)
        self.get_logger().info("Smartphone has been started.")

    def callback_robot_news(self, msg):
        self.get_logger().info(msg.data)


def main(args=None):
    rclpy.init(args=args)
    node = SmartphoneNode()
    rclpy.spin(node)
    rclpy.shutdown()


if __name__ == "__main__":
    main()




เปิดไฟล์ setup.py เพิ่ม จุลภาค หรือ ลูกน้ำ ( , ) หลังบรรทัด 24 แล้ว เพิ่มโค้ดบรรทัดที่ 25 ล่าง ด้วยโค้ดด้านล่าง

"smartphone = my_py_pkg.smartphone:main"



ไปที่ หน้าต่างที่ 1 กลับสู่ Home เพื่อจะ Build แพ็กเกจ my_py_pkg

cd

cd ros2_ws/


คำสั่ง Build เฉพาะ แพ็กเกจ my_py_pkg

colcon build --packages-select my_py_pkg --symlink-install


ไปที่ หน้าต่างที่ 2 โดยเราจะต้องทําให้ Terminator รู้จักคําสั่งของ ROS2 ด้วย คําสั่ง

source ~/.bashrc



เรียกใช้งาน smartphone ด้วย ROS2 จะแสดงการรับ Message จากที่ส่งออกมาจาก topic robot_news

ros2 run my_py_pkg smartphone