Publisher و Subscriber در ROS به زبان python
در گام قبل با نحوه ساختن انتشاردهنده و شنونده پیام یا همان Publisher و Subscriber به زبان ++C آشنا شدید. در این گام قصد داریم تا نحوه ایجاد آنها به زبان پایتون را آموزش دهیم.
برنامهنویسان معمولاً برای اجرای کدهای خود ابتدا الگوریتم موردنظر خود را به زبان python مینویسند و بعد از تست و رفع مشکلات آن درنهایت برای افزایش کارایی و سرعت به زبان C++ بازنویسی میکنند. در ROS نیز همانطور که در آموزشهای قبلی نیز ذکر شد این امکان وجود دارد که برنامهنویسان بتوانند با استفاده از زبان python کد موردنظر خود را بنویسند.
توجه: در این آموزش این فرض در نظر گرفته شده است که خواننده با زبان python آشنا است.
در همین ابتدا باید بگوییم که ساختار و مفاهیم کلی دقیقاً مشابه بخش مفهوم Publisher و Subscriberدر ROS به زبان C++ است؛ اما تنها در نوع بیان کمی تفاوت وجود دارد. خب نوبت به بررسی کدهای مرتبط با شنوده و منتشرکننده پیام میرسد. قبل از هر چیزی ابتدا باید پوشهای به نام scripts در بستهای که قبلاً ایجاد نمودید، درست کنید.
کد مربوط به منتشرکننده پیام به زبان پایتون بهصورت زیر است:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
بخش اول:
ابتدا باید کتابخانههای مرتبط با ROS را فراخوانی کنید. برای این منظور کتابخانهی rospy برای تعریف نود و کتابخانهی std_msgs.msg بهمنظور مشخص کردن جنس پیام برای انتشار، فراخوانی خواهند شد.
بخش دوم:
در این بخش برنامهنویس یک تابع با نام talker ایجاد کرده است. این تابع به دلیل اینکه منتشرکنندهی پیام است، به کمک متد Publisher در rospy پیامی را بر روی تاپیک chatter از جنس رشته و با صفی بهاندازهی ۱۰ ارسال میکند. در ادامه این تابع نود را مقداردهی اولیه کرده و سپس نرخ حلقه را مانند حالت قبل برابر ۱۰ هرتز قرار میدهد. در آخر حلقهای ایجاد کرده با شرط اینکه ROS فعال و یا ترمینال بسته نشده باشد پیامی را نوشته و توسط متد publish انتشار دهد. در آخر تعریف این تابع نیز مانند حالت قبل از متد sleep استفاده کرده تا نرخ تنظیمشده رعایت شود.
بخش سوم:
قسمت اصلی برنامه در اینجا است. با استفاده از یک ساختار try-except تابع talker() فراخوانی شده و تا زمانی که با خطایی روبهرو نشده باشد این پیام منتشر میشود.
حال که از عملکرد این نود باخبر شدید کافی است تا فایلی با نام talker.py در پوشهی scripts که قبلاً ایجاد نمودهاید، درست کنید و سپس محتویات کد بالا در آن قرار دهید؛ و دستور زیر را وارد نمایید:
با این کار این نود قابلاجرا میشود.
برای این بخش ابتدا کد زیر را بررسی کرده و درنهایت آن را برای ROS قابلاجرا میکنیم.
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", String, callback)
rospy.spin()
if __name__ == '__main__':
listener()
تنها تفاوت این فایل با مورد بررسیشده برای C++ تنها در استفاده از rospy است. از این بخش به دلیل سادگی عبور میکنیم.
به پوشهی scripts که در بخش قبل ایجاد نمودید بروید و فایل با عنوان listener.py ایجاد کرده و سپس دستورات بالا را در آن قرار داده و درنهایت فایل را ذخیره نمایید.
حال این فایل را نیز دوباره باید قابلاجرا کنیم. برای این منظور از دستور زیر در خط فرمان استفاده میکنیم:
برای اجرای نودهای پایتون ایجادشده دقیقاً مشابه آموزش قبل از دستورات زیر استفاده نمایید:
یک ترمینال جدید باز کنید:
سپس یک ترمینال جدید دیگر باز کنید:
rosrun beginner_tutorials talker.py
اگر با خطایی روبهرو شدید در بخش پرسش و پاسخ مشکلاتتان را از تیم ایران رآس بپرسید.
سپس ترمینال دیگری باز کنید و دستور زیر را وارد کنید:
rosrun beginner_tutorials listener.py
درصورتیکه بخواهید این برنامهها را متوقف کنید تنها کافی است که دکمههای Ctrl+c را همزمان در ترمینال وارد کنید و یا ترمینال را ببندید. با این کار نودهای در حال اجرا حذف میشوند؛ و برنامه متوقف خواهد شد.