• اولین مرجع آموزش رآس در ایران
  • info@iranros.com
wikiros-minwikiros-minwikiros-minwikiros-min
  • ایران رآس
  • ROS
    • پیش نیازهای شروع ROS
      • بررسی مفاهیم، اطلاعات فنی
      • نصب ROS برای تمام توزیع‌ها
      • برای آموزش ROS از کجا شروع کنیم؟
      • آموزش ROS
      • واژه‌نامه ROS
    • آموزش گام به گام
      • پیش‌نیازهای ROS
      • آموزش مقدماتی ROS
      • آموزش سطح متوسط
    • .
    • .
  • Software
    • نمایشگر سه‌بعدی (Rviz)
    • شبیه‌ساز گزبو Gazebo
    • نرم افزار moveit
  • Robots
    • Robots
      • ربات‌های پرکاربرد در ROS
        • ربات‌های زمینی
      • حسگرهای پرکاربرد در ROS
      • موتورهای پرکاربرد در ROS
  • publications
  • ایران رآس
  • ROS
    • پیش نیازهای شروع ROS
    • آموزش گام به گام
    • .
    • .
  • Software
    • نمایشگر سه‌بعدی (Rviz)
    • شبیه‌ساز گزبو Gazebo
    • نرم افزار moveit
  • Robots
    • Robots
  • publications
گام هشتم : ایجاد فایل‌های msg و srv در ROS
دسامبر 21, 2018
گام دهم: مفهوم Publisher-Subscriber در ROS به زبان python
فوریه 2, 2019

گام نهم: مفهوم Publisher-Subscriber در ROS به زبان ++C

Categories
  • آموزش مقدماتی ROS
Tags
  • C++
  • publisher
  • subscriber

مفهوم Publisher و Subscriberدر ROS به زبان ++C

اگر کمی دقت کرده باشید باید متوجه شده باشید که یکسری پیام‌ از برخی نودها در حال انتشار و یکسری پیام دیگر در حال شنیده شدن هستند. هر نود می‌تواند هم شنونده و هم منتشرکننده‌ی یک پیام باشد.

در ROS به عمل شنیدن پیام به‌اصطلاح subscribe و به عمل انتشار پیام publish می‌گویند.

حال که با مفهوم منتشر کردن پیام در ROS آشنا شدید، بگذارید تا این مفهوم را با زبان ++C پیاده‌سازی کنیم تا خودمان را برای ارسال پیام در ROS آماده نماییم.

توجه: در ادامه برخی مفاهیم مرتبط با شئ گرایی در ++C گفته می‌شود. درصورتی‌که با این اصطلاحات آشنا نیستید نیاز هست تا کمی با برنامه‌نویسی با زبان ++C آشنا شوید.

منتشر کننده پیام، Publisher

منتشر کننده پیام، Publisher

در ROS برای زبان ++C مِتُدی تعریف شده است که این امکان را می‌دهد بعد از مشخص کردن یکسری پارامتر بتوانید پیام را از تاپیک خاص منتشر نمایید. نام این متد ()advertise است. advertise درواقع متد یک نود است که در برنامه تعریف می‌کنید.

با استفاده از این متد ما مشخص می‌کنیم که چه جنس پیامی را می‌خواهیم بر روی چه تاپیکی ارسال نماییم. همچنین اندازه پیام‌ها در حافظه را مشخص می‌کنیم تا در صورت سرعت بالای برنامه، دیتاها حذف نشوند و در بافر ذخیره شوند.

درواقع صفی از دیتاها را ایجاد می‌کند که این عدد تعداد صف را مشخص می‌کند. adverse شئ publisher بازمی‌گرداند؛ که در حین برنامه شما با استفاده از متد publish این شئ با ورودی پیام موردنظر خود می‌توان آن را منتشر نمایید.

خب به نظر می‌رسد که توضیح در مورد Publisher کافی باشد. بگذارید تا یک برنامه ساده برای ارسال پیام Hello World در ROS با کمک Publisher به زبان ++C بنویسم.
کد زیر درواقع این کار را برای ما انجام می‌دهد.

#include "ros/ros.h"
#include "std_msgs/String.h"

#include <sstream>

int main(int argc, char **argv)
{
 ros::init(argc, argv, "talker");
 ros::NodeHandle n;
 ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
 ros::Rate loop_rate(10);
 int count = 0;

 while (ros::ok())
 {
 std_msgs::String msg;
 std::stringstream ss;

 ss << "hello world " << count;

 msg.data = ss.str();
 ROS_INFO("%s", msg.data.c_str());

 chatter_pub.publish(msg);
 ros::spinOnce();

 loop_rate.sleep();

 ++count;
 }
 return 0;
}

ابتدا اجازه دهید تا به‌صورت خلاصه کد بالا را توضیح دهیم.

بخش اول:

هدرهای موجود در خطوط اول برنامه به ترتیب

ros/ros.h درواقع شامل تمام هدرهایی ضروری است که مرتبط با ROS است.

std_msgs/String.h: این هدر درواقع به‌صورت خودکار توسط فایل String.msg در بسته تولید شده است. برای اطلاعات بیشتر msg را مطالعه نمایید.

sstream: این کلاس برای کار کردن با رشته در ++C استفاده می‌شود. در اینجا برای رشته Hello World استفاده می‌شود.

بخش دوم:

مقداردهی اولیه به ROS ‌می‌باشد. با استفاده از متد init در ROS علاوه بر مقداری دهی می‌توانید نام نود خود را نیز مشخص نمایید. البته توجه داشته باشید که این نام باید به‌صورت یکتا باشد. در این مثال نام نود talker است. حال برای کنترل و مقداردهی اولیه به نود باید شئ از کلاس NodeHandle ایجاد نمایید. در اینجا شئ n ایجاد شده است.

ros::init(argc, argv, "talker");
 ros::NodeHandle n;

بخش سوم:

در این بخش برای تعریف Publisher در مستر از دستور زیر استفاده می‌کنیم:

ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

این بخش به‌صورت کامل در بالا توضیح داده شد.

بخش چهارم:

در ROS این امکان وجود دارد که بتوانید در حلقه نرخ اجرا را مشخص نمایید. برای این منظور فرض کنید که می‌خواهید حلقه با فرکانس ۱۰ هرتز اجرا شود. برای این منظور، شئ از کلاس Rate با ورودی ۱۰ باید مطابق زیر ایجاد نمایید.

ros::Rate loop_rate(10);

بخش پنجم:

حلقه‌ی ‌اصلی اجرایی برنامه با یک حلقه‌ی While ایجاد می‌شود شرط این حلقه به کمک متد ok از ROS بررسی می‌شود. این متد زمانی مقدار false را بازمی‌گرداند که در ترمینال Ctrl+c را بزنید و یا زمانی که نود دیگر با همین نام اجرا شود و یا در بخش دیگر برنامه متد shutdown() از ROS فراخوانی شود.

بخش ششم:

در این بخش پیام خود را ایجاد می‌کنیم. این بخش شئ از کلاس String ایجاد و سپس رشته‌ی ایجادشده را به متد data از شئ msg انتساب می‌دهد. تا درنهایت این شئ را توسط منتشرکننده ارسال نماید.

بخش هفتم:

ارسال پیام، اگر دقت کرده باشید. شئ chatter_pub برای ارسال پیام توسط متد advertise ایجاد شد. این شئ دارای متدی به نام Publish است. این متد درواقع پیام را ارسال می‌کند.

 chatter_pub.publish(msg);

بخش هشتم:

در این بخش نمایش پیام در همین ترمینال فعلی توسط ابزار ROS_INFO انجام می‌شود. همچنین متد spinOnce() نیز نوشته شده است، البته این متد برای این نود که ساده است کاربرد ندارد زیرا زمانی که نیاز است تا توابع callback فراخوانی شوند از این متد استفاده می‌شود.

قسمت آخر این برنامه مربوط به شئ loop_rate ایجاد شده است. برای اینکه نرخ تنظیم‌شده توسط شما در حلقه رعایت شود متد sleep از این شئ فراخوانی می‌شود این متد کمک می‌کند تا زمانی که برنامه سریع‌تر از نرخ تنظیم‌شده توسط شما انجام شد، منتظر باقی بماند؛ و سپس دوباره حلقه اجرا شود.

شنوده پیام، Subscriber

شنوده پیام، Subscriber

برای شنیدن پیام از یک تاپیک خاص شما باید از متد subscribe استفاده کنید. با استفاده از این متد شما بعد از مشخص کردن نام تایپک ارسال‌کننده پیام، تعداد پیام موجود در صف و همچنین تابع callback، شئ از کلاس Subscriber را ایجاد و به آن انتساب می‌دهید. با این کار در هر حلقه شما در صورت وجود داشتن پیامی در تاپیک آن را به کمک تابع callback دریافت می‌کنید.

درواقع شما باید متد callback را به‌گونه‌ای تعریف کنید که می‌خواهید از پیام دریافت شده استفاده نمایید. مثلاً ما در این مثال می‌خواهیم این پیام را در ترمینال نمایش دهیم برای این منظور متد callback را به کمک ابزار ROS_INFO تعریف می‌کنیم تا پیام ورودی را در ترمینال چاپ کند.

کد زیر را در نظر بگیرید:

#include "ros/ros.h"
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
 ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{

 ros::init(argc, argv, "listener");
 ros::NodeHandle n;
 ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
 ros::spin();

 return 0;
}

کد بالا یک شنوده‌ی پیام است. این نود پیام را توسط دستور زیر می‌شوند.

 ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

دستور بالا درواقع شنوده است. این شونده به کمک تابع callback تعریف‌شده پیام را دریافت و در ترمینال نمایش می‌دهد. تفاوت شنوده با دریافت‌کننده پیام در تابع callback است. این تابع توسط متد spin موجود در هر بار اجرای حلقه فراخوانی می‌شود. درواقع متد spin منتظر باقی می‌ماند تا یک پیام برسد.

توجه: در اینجا فرض می‌شود که خواننده با تعریف تابع به زبان ++C آَشنا است از این‌رو تابع chatterCallback موردبررسی قرار نمی‌گیرد.

خب کدهای مرتبط با شنوده و دریافت‌کننده را به ترتیب در فایل‌هایی به نام های listener.cpp و talker.cpp قرار دهید سپس این فایل‌ها در پوشه‌ی catkin_ws/beginner_tutorials/src قرار دهید.

اجرای نودهای شنوده و دریافت‌کننده

اجرای نودهای شنوده و دریافت‌کننده

اگر به یاد داشته باشید با استفاده از دستور catkin_create_pkg در آموزش‌های قبلی یک بسته ایجاد نمودید. این دستور یک فایل xml و Cmake ایجاد کرده است. این فایل‌ها برایتان ایجاد شده است تا بتوانید نودهایی که شما ایجاد کرده‌اید را در آن تعریف کنید تا قابل‌اجرا شود.

به‌منظور تعریف نود شنوده و دریافت‌کننده قبلی که ایجاد کردید دستورات زیر را به فایل cmake خود اضافه کنید.

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

درصورتی‌که بخواهید هر نود دیگری نیز اضافه کنید باید این دستورات را برای آن نیز در فایل Cmake اضافه نمایید.

خب تا اینجا شما نودها را تعریف و فایل Cmake را نیز متناسب با نودهای تعریف‌شده اصلاح نمودید. حال برای اینکه این فایل‌ها Build شوند و یا اصطلاحاً قابل‌اجرا شوند. دستورات زیر را به ترتیب وارد نمایید.

cd ~/catkin_ws
 catkin_make

دستور اولی خط فرمان را به پوشه‌ی catkin_ws منتقل می‌کند؛ و به کمک catkin_make نودهای ایجادشده را کامپایل و سپس Build می‌کنید. خب در این گام می‌خواهیم تا این نودها را اجرا نماییم.

ابتدا دستور زیر را در ترمینال خود وارد نمایید. تا رآس مستر اجرا شود.

roscore

حال یک ترمینال جدید باز کنید و دستورات زیر را وارد نمایید.

cd ~/catkin_ws
source ./devel/setup.bash

سپس دستور زیر را برای اجرای نود مربوط به فرستنده‌ی پیام در ترمینال وارد نمایید:

rosrun beginner_tutorials talker

که در ترمینال خود پیام Hello World را مشاهده خواهید کرد. با این کار شما نود مربوط به منتشرکننده پیام را فعال کرده‌اید.

ترمینال دیگری باز نمایید؛ و مانند مرحله بالا به ترتیب دستورات زیر را وارد نمایید:

cd ~/catkin_ws
source ./devel/setup.bash
rosrun beginner_tutorials listener

اگر همه چیز را به‌درستی انجام داده باشد شما باید در این ترمینال پیام منتشرشده در تاپیک را مشاهده نمایید.

درصورتی‌که در هر یک از این مراحل با مشکلی همراه شدید به بخش پرسش و پاسخ تیم ایران رآس رجوع و سؤالات خود را در آنجا از متخصصین سایت ایران رآس بپرسید.

Share
6

Related posts

مارس 16, 2020

نصب ROS بر روی ویندوز ۱۰


Read more
سپتامبر 20, 2019

گام سیزدهم: نوشتن یک service و client ساده (Python)


Read more
سپتامبر 19, 2019

گام دوازدهم: نوشتن یک service و client ساده (C++)


Read more

1 دیدگاه

  1. fleck water گفت:
    آوریل 9, 2020 در 11:10 ق.ظ

    Hello There. I found your weblog using msn. This is a very well
    written article. I will be sure to bookmark it and return to read extra of your useful information. Thank you for the post.

    I will definitely return.

    پاسخ

دیدگاهتان را بنویسید لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

آموزش سیستم عامل رباتیک ROS

  • پیش‌نیازهای شروع ROS
    • نصب Ubuntu در کنار ویندوز به صورت Dual Boot
    • نحوه نصب اوبونتو بر روی VMware در ویندوز ۱۰
    • اشتراک اطلاعات بین ویندوز و ماشین مجازی(VMware)
    • راه اندازی و تنظیمات اولیه Ubuntu جهت کار با ROS
    • نصب ROS
  • آموزش مقدماتی ROS
    • گام اول: نصب و پیکربندی محیط ROS
    • گام دوم: آدرس دهی در ROS
    • گام سوم: ایجاد بسته در ROS
    • گام چهارم :مفهوم Node در ROS
    • گام پنجم : مفهوم تاپیک در ROS
    • گام ششم : مفهوم service و parameters در ROS
    • گام هفتم : مفهوم launch فایل‌ها در ROS
    • گام هشتم : ایجاد فایل‌های msg و srv در ROS
    • گام نهم: مفهوم Publisher-Subscriber در ROS به زبان ++C
    • گام دهم: مفهوم Publisher-Subscriber در ROS به زبان python
    • گام یازدهم: ضبط و بازپخش داده‌ها در ROS
    • گام دوازدهم: نوشتن یک service و client ساده (C++)
    • گام سیزدهم: نوشتن یک service و client ساده (Python)
  • آموزش سطح متوسط ROS
    • ساخت یک پکیج به صورت دستی
    • مدیریت وابستگی‌های سیستم
    • تعریف پیام های سفارشی در ROS
    • مقدمه‌ای بر شبیه‌ ساز گزبو Gazebo
    • مقدمه‌ای بر RVIZ نمایشگر سه‌بعدی

ربات‌ها

  • ربات‌های زمینی
    • ربات TIAGo
    • TurtleBot
  • ربات‌های هوایی
  • بازوهای رباتیک
  • ربات‌های دریایی

برچسب‌ها

  • ;hvhdd fhgh
  • A Gentle Introduction to ROS
  • actor
  • actor_Gazebo
  • ajk nv vhs
  • bash
  • C++
  • ca tvhsd v
  • catkin
  • chmode

Google-fomrs

ایران رآس، اولین مرجع آموزش و توسعه ROS در ایران

سایت ایران رآس با بهره گیری از متخصصین حوزه رباتیک به تولید محتوای آموزشی پرداخته و آنها را در اختیار کاربران قرار می­دهد . همچنین متخصصین ما این آمادگی را دارند تا به موسسات و مراکزی که قصد ورود به دنیای رآس را دارند مشاوره های تخصصی داده و برای آنها دوره های آموزشی خصوصی برگزار کند.


درباره ما تماس با ما قوانین و مقررات ثبت شکایات
  • پیش نیازهای ROS
  • آموزش مقدماتی ROS
  • آموزش سطح متوسط ROS
  • کتاب آموزش ROS
  • نرم افزارها
  • ربات‌ها
© تمام حقوق مادی و معنوی برای ایران رآس محفوظ است.
  • No translations available for this page