الـTopics في ROS 2، وnodes النشر (Publisher) والاشتراك (Subscriber)
مقدمة: نموذج الـTopics وPub/Sub
في ROS 2، تتواصل الـnodes مع بعضها باستخدام نموذج النشر/الاشتراك (publish/subscribe أو pub/sub) عبر الـTopics. فالـPublisher يرسل رسائل إلى topic معين، والـSubscriber يستقبل الرسائل من ذلك الـtopic. هذا الأسلوب يفصل الـnodes عن بعضها البعض (decoupling) ويتيح تواصلاً مرناً بينها.
مثال كلاسيكي: nodes الـTalker والـListener
مثال "talker" و"listener" هو أبسط توضيح عملي لنموذج pub/sub.
1. شغّل node الـTalker
node الـtalker ينشر رسائل إلى topic باسم /chatter.
ros2 run demo_nodes_py talker2. شغّل node الـListener
node الـlistener يشترك في topic باسم /chatter ويطبع الرسائل المستقبَلة.
ros2 run demo_nodes_py listener3. افحص الـTopics
- عرض قائمة الـtopics النشطة:
ros2 topic list - عرض الرسائل الواردة على
/chatterلحظيًا (echo):ros2 topic echo /chatter
Turtlesim: عرض مرئي للـTopics
turtlesim هي أداة رسومية لتصور الـtopics ونموذج pub/sub أثناء عمله فعليًا.
1. شغّل turtlesim_node
ros2 run turtlesim turtlesim_node2. تحكّم بالسلحفاة عبر teleop
ros2 run turtlesim turtle_teleop_key- node التحكم عن بعد (teleop) ينشر أوامر السرعة إلى
/turtle1/cmd_vel. - node الـturtlesim يشترك في
/turtle1/cmd_velويحرّك السلحفاة بناءً عليها.
3. افحص topics الخاصة بـturtlesim
- عرض قائمة الـtopics:
ros2 topic list - عرض أوامر السرعة لحظيًا:
ros2 topic echo /turtle1/cmd_vel
4. معلومات الـTopic ونوع الرسالة
للحصول على معلومات عن topic ونوع الرسالة الخاص به:
ros2 topic info /turtle1/cmd_velمثال على المخرجات:
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 1لرؤية بنية نوع الرسالة:
ros2 interface show geometry_msgs/msg/Twistوهذا يُعبّر عن السرعة في الفضاء الحر مقسّمة إلى جزئها الخطي (linear) وجزئها الزاوي (angular):
# This expresses velocity in free space broken into its linear and angular parts.
Vector3 linear
float64 x
float64 y
float64 z
Vector3 angular
float64 x
float64 y
float64 zمثال: node ناشر (Publisher) لـturtlesim
لنشر أوامر السرعة إلى turtlesim، تحتاج إلى إضافة هذه الاعتماديات (dependencies) في ملف package.xml الخاص بحزمتك:
<depend>rclpy</depend>
<depend>geometry_msgs</depend>
<depend>turtlesim</depend>إليك node ناشر بسيط يجعل السلحفاة تتحرك في مسار دائري عن طريق نشر رسائل من نوع Twist إلى /turtle1/cmd_vel:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
class DrawCircleNode(Node):
def __init__(self):
super().__init__("draw_circle")
self.cmd_vel_pub = self.create_publisher(Twist, "/turtle1/cmd_vel", 10)
self.timer = self.create_timer(0.5, self.send_velocity_command)
self.get_logger().info("Draw circle node has been started")
def send_velocity_command(self):
msg = Twist()
msg.linear.x = 2.0
msg.angular.z = 1.0
self.cmd_vel_pub.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = DrawCircleNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == "__main__":
main()- يتم إنشاء الـPublisher لـtopic باسم
/turtle1/cmd_velباستخدام نوع الرسالةTwist. - المؤقّت (timer) يستدعي بشكل دوري الدالة
send_velocity_command، والتي تنشر أمر سرعة يحرّك السلحفاة في مسار دائري.
مثال: node مشترك (Subscriber) لموضع (Pose) السلحفاة
للاشتراك في موضع (pose) السلحفاة، استخدم الاعتماديات التالية في ملف package.xml الخاص بك:
<depend>rclpy</depend>
<depend>turtlesim</depend>الـtopic باسم /turtle1/pose يستخدم نوع الرسالة turtlesim/msg/Pose. يمكنك فحصه بالأمر:
ros2 topic info /turtle1/pose
ros2 interface show turtlesim/msg/Poseبنية الرسالة:
float32 x
float32 y
float32 theta
float32 linear_velocity
float32 angular_velocityإليك node مشترك بسيط لـ/turtle1/pose:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from turtlesim.msg import Pose
class PoseSubscriberNode(Node):
def __init__(self):
super().__init__("pose_subscriber")
self.subscription = self.create_subscription(
Pose,
"/turtle1/pose",
self.pose_callback,
10)
self.subscription # prevent unused variable warning
self.get_logger().info("Pose subscriber node has been started")
def pose_callback(self, msg):
self.get_logger().info(
f"x: {msg.x}, y: {msg.y}, theta: {msg.theta}, "
f"linear_velocity: {msg.linear_velocity}, angular_velocity: {msg.angular_velocity}"
)
def main(args=None):
rclpy.init(args=args)
node = PoseSubscriberNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == "__main__":
main()- الـSubscriber ينصت إلى
/turtle1/poseويطبع موضع السلحفاة وسرعتها.
تشغيل nodes الـPublisher والـSubscriber
###->>> لا تنسَ إضافة الـnodes كملفات تنفيذية (excutables) <<<-
-
ابنِ مساحة العمل الخاصة بك:
colcon build --symlink-install source install/setup.bash -
شغّل node الـPublisher:
ros2 run my_first_py_pkg draw_circle -
شغّل node الـSubscriber (في نافذة طرفية (terminal) منفصلة):
ros2 run my_first_py_pkg pose_subscriber
تصور (Visualizing) الـTopics
- استخدم
rqt_graphلتصور الـnodes والـtopics. - عرض قائمة الـtopics النشطة:
ros2 topic list - عرض الرسائل على topic معين لحظيًا:
ros2 topic echo /topic
مرجع
- راجع
01/Readme.mdللاطلاع على إعداد مساحة العمل والحزمة.
يشرح هذا الدليل كيفية استخدام الـtopics وإنشاء nodes للنشر (publisher) والاشتراك (subscriber) في ROS 2، بناءً على الأساسيات المذكورة في القسم 01. وهو يتضمن الآن مثالَي talker/listener الكلاسيكيين ومثال turtlesim، إضافةً إلى فحص معلومات الـtopic ونوع الرسالة، ونماذج عملية لـnodes النشر والاشتراك في turtlesim باستخدام geometry_msgs/msg/Twist وturtlesim/msg/Pose.