تصور کن قرار است یک ربات بسازی به اسم ARCHO (آرکو)؛ ربات کوچکی که باید بین قفسههای بلند یک انبار حرکت کند، مسیرش را با یک حسگر لیزری پیدا کند، و اگر انسانی جلویش سبز شد، بایستد. اولین وسوسه این است که یک فایل کد باز کنی و شروع کنی به نوشتن: بخوان از دوربین، پردازش کن، بفرست به موتور. بعد از چند ساعت متوجه میشوی همهچیز در یک فایل هزار خطی گیر کرده، هیچ بخشی را نمیتوانی جدا تست کنی، و اگر یک خط کد خراب شود، کل ربات یخ میزند. این دقیقاً همان مسیری است که بیشتر آموزشهای ROS 2 طی میکنند: مستقیم میروند سراغ دستورهای ترمینال — این را نصب کن، آن را اجرا کن — و یاد میگیری دستور بزنی، بدون اینکه بدانی چرا.
این کتاب، و این فصل بهطور خاص، مسیر دیگری را انتخاب میکند. قبل از اینکه حتی یک خط کد برای ARCHO بنویسیم، مینشینیم و نقشهاش را میکشیم: چه تکههایی لازم داریم، هرکدام چه کاری انجام میدهند، و چطور با هم حرف میزنند. این دقیقاً همان کاری است که یک مهندس رباتیک واقعی قبل از نوشتن اولین خط کد انجام میدهد. خبر خوب این است که کسانی که ROS 2 را ساختهاند، سالها پیش همین مسئله را حل کردهاند و تقریباً تمام سیستم — از یک ربات ساده جاروبرقی تا بازوی رباتیک صنعتی — را روی همین چند مفهوم بنا کردهاند:
اگر پنج مفهوم Node، Topic، Message، Service و Action را خوب یاد بگیری، حدود ۷۰٪ از ROS 2 را فهمیدهای. بقیه فصلهای کتاب فقط جزئیات و ابزارهای اطراف همین هسته هستند.
در پایان این فصل، این هفت مفهوم پایه را میشناسی و میتوانی برای هر Node در هر پروژهای این چهار سؤال را جواب بدهی:
نقشه یادگیری این فصل به این شکل است — هر جعبه روی جعبه قبلی خودش ساخته میشود:
در طول این کتاب، تمام مفاهیم را روی یک پروژه ثابت پیاده میکنیم: ARCHO، یک ربات متحرک ساده که قرار است در یک انبار بزرگ حرکت کند، محیط را با LiDAR ببیند و مسیر خودش را پیدا کند. هر فصل یک تکه از این ربات را کاملتر میکند. در همین فصل، فقط اسکلت ارتباطی ARCHO را طراحی میکنیم؛ هنوز کدی نمینویسیم.
برگردیم به ARCHO و همان فایل هزار خطی. فرض کن سه هفته روی آن کار کردهای: خواندن دوربین، پردازش تصویر، محاسبه مسیر، کنترل موتور، همه در یک برنامه، در یک پردازش (process). تا وقتی پروژه کوچک است همهچیز خوب پیش میرود. اما یک روز صبح، بخش پردازش تصویر کرش میکند و کل ربات یخ میزند — حتی موتورها هم دیگر جواب نمیدهند، چون همه در یک برنامه گیر افتادهاند. بدتر از آن، وقتی میخواهی فقط الگوریتم مسیریابی را تست کنی، مجبوری کل برنامه غولپیکر را کامپایل و اجرا کنی، فقط برای دیدن اینکه یک خط محاسبه درست کار میکند یا نه. این همان دیواری است که تقریباً هر کسی که بدون ROS شروع میکند، دیر یا زود به آن میخورد.
ROS این مسئله را با مفهومی به نام Node حل میکند. هر Node یک برنامه کوچک و مستقل است که فقط یک مسئولیت مشخص دارد. یکی فقط از دوربین میخواند، یکی فقط مسیر را محاسبه میکند، یکی فقط به موتورها فرمان میدهد.
Node یک پردازش (process) مستقل در ROS 2 است که یک وظیفه مشخص انجام میدهد و برای انجام آن با سایر Nodeها از طریق Topic، Service، Action یا Parameter ارتباط برقرار میکند.
یک رستوران را تصور کن. آشپز، گارسون، صندوقدار و ظرفشور هر کدام یک نفر مستقل هستند؛ هیچکدام کار دیگری را انجام نمیدهند، اما با هم هماهنگ کار میکنند تا رستوران بچرخد. اگر ظرفشور امروز نیاید، رستوران هنوز میتواند غذا سرو کند — فقط ظرفها جمع میشوند. دقیقاً همینطور، اگر Node دوربین یک ربات از کار بیفتد، بقیه Nodeها (مثلاً موتور یا LiDAR) هنوز زندهاند.
در یک ربات متحرک واقعی، معمولاً دهها Node بهصورت همزمان در حال اجرا هستند:
| Node | مسئولیت |
|---|---|
camera_node | خواندن تصویر از دوربین و انتشار آن |
lidar_node | خواندن داده فاصلهسنج لیزری |
slam_node | ساخت نقشه محیط از روی داده حسگرها |
navigation_node | محاسبه مسیر حرکت به هدف |
motor_controller_node | تبدیل فرمان سرعت به سیگنال موتور |
خیلی از تازهکارها فکر میکنند باید همه منطق ربات را در یک Node بزرگ بنویسند تا «سادهتر» باشد. نتیجه برعکس است: دیباگ کردن سخت میشود، تست کردن جداگانه هر بخش غیرممکن میشود، و اگر یک بخش کرش کند کل ربات از کار میافتد. قانون طلایی: هر Node، یک مسئولیت.
از دید معماری نرمافزار، Node در ROS 2 دقیقاً همان نقشی را دارد که یک microservice در معماری سرویسهای وب دارد: واحد کوچک، مستقل، قابل جایگزینی، با یک قرارداد ارتباطی مشخص با بقیه سیستم. این شباهت تصادفی نیست — هر دو برای حل یک مسئله مشترک طراحی شدهاند: کاهش وابستگی بین بخشهای یک سیستم بزرگ.
اگر بخواهی یک ربات ساده جاروبرقی طراحی کنی، چه Nodeهایی احتمالاً لازم داری؟ حداقل چهار مورد نام ببر و مسئولیت هرکدام را در یک جمله بنویس.
خب، حالا ARCHO را به چند Node مستقل تقسیم کردیم — یکی برای دوربین، یکی برای پردازش تصویر، یکی برای موتور. اما یک مشکل تازه پیدا شده: این Nodeها در دنیای خودشان تنها هستند. Node دوربین هر لحظه یک تصویر تازه میگیرد، اما اگر هیچ راهی برای رساندن آن به Node پردازش تصویر نداشته باشد، این تصویر همانجا در حافظه دوربین میماند و به دردی نمیخورد. باید راهی پیدا کنیم که این جزیرههای مستقل بتوانند با هم حرف بزنند. اولین و رایجترین راه ارتباط در ROS 2، Topic است.
Topic یک کانال نامگذاریشده برای انتقال داده است. یک Node میتواند روی یک Topic اطلاعات منتشر (Publish) کند و هر Node دیگری میتواند به همان Topic مشترک (Subscribe) شود و اطلاعات را دریافت کند. هر بسته دادهای که روی یک Topic فرستاده میشود را Message میگویند.
در یک رستوران، آشپز هر غذایی که آماده میشود را روی یک مانیتور نمایش میدهد. آشپز نمیداند چه کسی دارد نگاه میکند — شاید گارسون، شاید مدیر، شاید هیچکس. او فقط دائماً وضعیت را منتشر میکند. این دقیقاً رفتار یک Publisher روی یک Topic است.
چند نکته مهم درباره Topic که باید از همین ابتدا در ذهن بماند:
/image همیشه sensor_msgs/Image است.
در ربات ARCHO، Node مربوط به LiDAR روی Topic به نام /scan اطلاعات فاصله را با نوع پیام
sensor_msgs/LaserScan منتشر میکند. همزمان، هم Node نقشهسازی (SLAM) و هم Node تشخیص مانع
به همین یک Topic مشترک میشوند — بدون اینکه LiDAR اصلاً بداند چند نفر دارند به آن گوش میدهند.
بسیاری از تازهواردها فکر میکنند همه نوع ارتباط بین Nodeها باید از طریق Topic انجام شود. Topic فقط برای جریان پیوسته داده مناسب است. اگر بخواهی از یک Node چیزی بپرسی و منتظر یک پاسخ مشخص باشی، Topic ابزار درستی نیست — همانطور که در بخش بعد میبینیم.
فرض کن یک IMU (حسگر شتاب و جهت) روی ربات نصب کردهای که هر ۱۰۰ میلیثانیه یک بار داده جدید تولید میکند. آیا این یک Topic خوب است یا نه؟ دلیل خودت را در دو خط بنویس.
حالا که ARCHO دارد با Topic اطلاعات دوربینش را پخش میکند، یک اتفاق جالب میافتد: تیم توسعه، هیجانزده از این ابزار تازه، شروع میکند همهچیز را با Topic حل کردن. حتی برای ذخیره نقشه، حتی برای خواندن باتری. نتیجه؟ کانالهای بیشماری که هر لحظه پیامهای بیفایده میفرستند. برای فهمیدن اینکه چرا این اشتباه است، بیا وارد یک رستوران شویم. اگر بخواهی وضعیت آشپزخانه را بهصورت زنده ببینی، دقیقاً مثل یک Topic است — اطلاعات دائماً در حال پخش شدن است. اما اگر بخواهی بگویی «یک پیتزا لطفاً»، اتفاق دیگری میافتد: تو یک درخواست مشخص میفرستی و منتظر یک پاسخ مشخص میمانی. این دیگر Topic نیست؛ این یک درخواست و پاسخ (Request / Response) است. ROS برای دقیقاً همین کار، Service را ساخته است.
Service یک ارتباط دوطرفه است که در آن یک Node (Client) یک درخواست (Request) ارسال میکند و Node دیگری (Server) آن را پردازش کرده و یک پاسخ مشخص (Response) برمیگرداند.
| معیار | Topic مناسب است اگر... | Service مناسب است اگر... |
|---|---|---|
| نوع داده | دائماً در حال تغییر است (دوربین، LiDAR، IMU) | فقط هنگام نیاز خوانده یا اجرا میشود |
| الگوی زمانی | جریان پیوسته و تکرارشونده | یکبار، بر اساس درخواست |
| مثال | سرعت لحظهای، تصویر دوربین، Odometry | ذخیره نقشه، Reset کردن Encoder، خواندن درصد باتری |
| انتظار پاسخ | Publisher منتظر پاسخ نمیماند | Client منتظر Response مشخص میماند |
آیا لازم است ربات هر ثانیه درصد باتری خودش را برای همه منتشر کند؟ نه — این کار بیهوده است و پهنای باند
شبکه را اشغال میکند. بهجایش، وقتی لازم شد (مثلاً وقتی رابط کاربری باز میشود)، یک درخواست
Get Battery Status فرستاده میشود و Server یک بار پاسخ 78% را برمیگرداند.
در پروژه ARCHO، نمونههایی از Serviceهای واقعی اینها خواهند بود:
reset_encoder — صفر کردن شمارنده چرخهاcalibrate_imu — کالیبره کردن حسگر اینرسیsave_map — ذخیره نقشه ساختهشده روی دیسکget_battery_status — خواندن لحظهای درصد باتریوقتی وارد فصلهای عملی شویم، این دستورها روزمرهترین ابزار تو خواهند بود:
ros2 service list
ros2 service type /clear
ros2 interface show std_srvs/srv/Empty
ros2 service call /clear std_srvs/srv/Empty "{}"
خروجی std_srvs/srv/Empty فقط یک خط --- است، چون این نوع Service هیچ دادهای
در Request یا Response ندارد؛ فراخوانی آن فقط باعث اجرای یک عمل میشود، دقیقاً مثل فشردن یک دکمه.
در مقابل، example_interfaces/srv/AddTwoInts دو عدد صحیح میگیرد (a و b)
و مجموع آنها (sum) را برمیگرداند.
فرض کن به ربات میگویی «برو به اتاق شماره ۵». آیا این یک Topic است؟ آیا یک Service است؟ اگر جواب هر دو منفی است، فکر کن چرا — این سؤال دقیقاً ما را به بخش بعدی میبرد.
یک روز، یکی از اعضای تیم ARCHO یک سؤال ساده میپرسد که همه را برای چند دقیقه ساکت میکند: «اگر بخواهیم به ربات بگوییم برو به قفسه شماره ۵، از کدام ابزار استفاده کنیم؟» همه فکر میکنند جواب Service است — یک درخواست، یک پاسخ. اما وقتی دقیقتر نگاه میکنند، متوجه میشوند فرمان «برو به قفسه ۵» نه Topic است و نه Service. چرا؟ چون این کار ممکن است چند دقیقه طول بکشد: حرکت باید شروع شود، پیشرفت باید گزارش شود، احتمالاً در مسیر مانعی پیدا میشود، شاید لازم باشد عملیات لغو شود، و در پایان باید بدانیم موفق بوده یا نه. Service فقط یک پاسخ کوتاه میدهد و منتظر پایان یک کار طولانی نمیماند. برای این دسته از کارها، ROS 2 مفهوم سومی به نام Action را معرفی کرده است.
وقتی از یک اپلیکیشن تاکسی درخواست سفر میدهی، فقط یک پاسخ نمیگیری. اول میگویند راننده قبول کرد، بعد میگویند راننده ۳ کیلومتر با تو فاصله دارد، بعد میگویند راننده رسید، بعد سفر شروع میشود، و در پایان سفر تمام میشود. این دقیقاً همان چیزی است که Action در ROS 2 فراهم میکند: یک هدف، چند بهروزرسانی پیشرفت، و یک نتیجه نهایی.
Action یک عملیات طولانیمدت است که میتوان پیشرفت آن را در حین اجرا مشاهده کرد، در صورت نیاز آن را لغو کرد، و در پایان نتیجه نهایی را دریافت کرد. هر Action از سه بخش تشکیل شده است: Goal (هدف)، Feedback (گزارش پیشرفت) و Result (نتیجه نهایی).
شکل ۱.۳ — چرخه کامل یک Action: از Goal تا Result، با چند Feedback در میانه راه.
| بخش Action | نقش | مثال |
|---|---|---|
| Goal | هدفی که باید انجام شود | target_x: 5.2, target_y: 8.1 |
| Feedback | گزارش وضعیت در حین اجرا | distance_remaining: 2.3 |
| Result | نتیجه نهایی پس از پایان | success: true |
فرض کن بازوی ربات باید یک پیچ را ببندد؛ این کار ممکن است ۲۰ ثانیه طول بکشد. اگر از Service استفاده میکردیم،
فقط یک درخواست و یک پاسخ داشتیم و هیچ اطلاعاتی از وسط کار نمیدیدیم. با Action، مراحل را بهصورت زنده دنبال میکنیم:
Approaching → Aligning → Tightening → Finished. اگر شیء در میانه راه بیفتد، Result برابر
Failed برمیگردد — نه یک سکوت مبهم.
یکی از معروفترین Actionهای دنیای واقعی ROS 2، NavigateToPose در بسته Nav2 است.
تقریباً تمام رباتهای متحرک مبتنی بر Nav2 از همین Action برای رفتن به یک نقطه هدف استفاده میکنند:
Client میگوید «برو اینجا»، Server مراحل Planning… → Moving… → Avoiding Obstacle… → Arrived
را گزارش میدهد.
قابلیت مهمی که Action دارد و Topic و Service ندارند، امکان لغو (Cancel) است.
اگر ربات در حال حرکت باشد و ناگهان انسانی جلوی آن قرار بگیرد، میتوان همان لحظه Cancel Goal
فرستاد و ربات متوقف میشود. خیلی از طراحیهای ابتدایی این قابلیت را فراموش میکنند و بعداً برای اضافهکردن
«دکمه توقف اضطراری» به مشکل میخورند.
یک قهوهساز هوشمند را تصور کن. توضیح بده رفتار آن اگر با Topic ساخته شود چگونه است، اگر با Service ساخته شود چگونه است، و چرا Action بهترین انتخاب است. حداقل یک محدودیت هرکدام را بنویس.
یک تصویر ذهنی که باید همیشه یادت بماند: Topic مثل رادیو است، Service مثل تماس تلفنی با بانک، و Action مثل سفارش تاکسی آنلاین.
| معیار | Topic | Service | Action |
|---|---|---|---|
| الگو | Publish / Subscribe | Request / Response | Goal / Feedback / Result |
| مدت زمان | پیوسته | لحظهای و کوتاه | طولانی |
| گزارش پیشرفت | ندارد (خودش نوعی جریان است) | ندارد | دارد |
| قابل لغو | خیر | خیر | بله |
| مثال | دوربین، LiDAR، IMU | Reset، Save، Calibrate | Navigate، Pick Object |
| مناسب برای | حسگرها و جریانهای داده | عملیات آنی و تنظیمات | وظایف رباتیک بلندمدت |
وقتی داری معماری یک Node جدید طراحی میکنی، این سؤال را از خودت بپرس: «آیا این داده دائماً در حال تغییر است، یا فقط بر اساس یک محرک مشخص اتفاق میافتد؟» اگر پیوسته است → Topic. اگر لحظهای و کوتاه است → Service. اگر طولانی و نیازمند گزارش میانی است → Action. انتخاب اشتباه، معمولاً یا شبکه را با پیامهای بیفایده پر میکند (Topic بهجای Service) یا رابط کاربری را در حالت «قفلشده و بدون بازخورد» نگه میدارد (Service بهجای Action).
روی یک دوربین حرفهای، تنظیماتی مثل ISO، سرعت شاتر و دیافراگم وجود دارد. برای تغییر ISO لازم نیست فریمور دوربین را دوباره برنامهریزی کنی؛ فقط یک تنظیم را عوض میکنی. Parameter در ROS 2 دقیقاً همین نقش را دارد.
تیم ARCHO حالا میداند کِی از Topic استفاده کند و کِی از Service و Action. اما یک مشکل کوچکتر و آزاردهندهتر
هنوز باقی مانده. یکی از مهندسها سرعت پیشفرض ربات را مستقیم در کد نوشته: robot_speed = 0.5;.
یک ماه بعد، وقتی ربات را در یک راهروی باریکتر آزمایش میکنند، میخواهند این مقدار را به ۰.۷ تغییر بدهند. بدون Parameter باید فایل را باز کنی، کد را ویرایش کنی، دوباره Build کنی و دوباره اجرا
کنی — برای یک تغییر کوچک، کل چرخه توسعه تکرار میشود. با Parameter، کد ثابت میماند و فقط مقدار تنظیمات
عوض میشود.
Parameter یک مقدار قابل تنظیم است که رفتار یک Node را بدون تغییر کد کنترل میکند. Parameterها معمولاً در فایلهای YAML نگهداری میشوند تا بتوان یک نرمافزار را روی چند ربات مختلف، بدون بازنویسی کد، به کار برد.
# camera_params.yaml
camera_node:
ros__parameters:
fps: 30
width: 1280
height: 720
فرض کن همین نرمافزار حرکتی را روی سه ربات نصب میکنی: ربات کوچک با max_speed = 0.4،
ربات متوسط با max_speed = 0.8، ربات بزرگ با max_speed = 1.5. کد یکی است؛
فقط Parameter فرق میکند. در پروژه ARCHO، Node به نام motor_controller_node پارامترهایی مثل
wheel_radius، wheel_base و max_velocity دارد. اگر قطر چرخ عوض شود،
فقط مقدار wheel_radius را تغییر میدهیم؛ الگوریتم کنترل دستنخورده میماند.
یک تشبیه ساده: سرعت لحظهای ماشین (۸۰ کیلومتر بر ساعت) دائماً تغییر میکند — این مثل Topic است. اما تنظیم Cruise Control روی ۱۰۰ کیلومتر بر ساعت، شاید تا چند ساعت ثابت بماند — این مثل Parameter است. Topic داده جاری را منتقل میکند؛ Parameter تنظیمات نسبتاً ثابت را نگه میدارد.
ros2 param list
ros2 param get /camera_node fps
ros2 param set /camera_node fps 60
برای Node مربوط به LiDAR در ربات ARCHO، سه Parameter پیشنهاد بده که منطقی باشد (مثلاً محدوده تشخیص، نرخ اسکن). برای هرکدام بگو چرا این مقدار باید Parameter باشد، نه بخشی ثابت از کد.
هر روز صبح که سر کار میروی، چند برنامه را باز میکنی: مرورگر، ایمیل، ابزار پیامرسانی، ویرایشگر کد.
اگر هر روز یکییکی بازشان کنی، بعد از یک هفته خسته میشوی. بهجایش یک اسکریپت
(start_work.sh) میسازی که همه را با هم اجرا کند. Launch File دقیقاً همین
کار را برای ROS 2 انجام میدهد.
حالا ARCHO هفت، هشت Node مستقل دارد که هرکدام با Topic، Service، Action و Parameter خودشان کار میکنند.
روز آزمایش که میرسد، یکی از مهندسها باید هرکدام را در یک پنجره ترمینال جدا، دستی، اجرا کند: اول دوربین،
بعد LiDAR، بعد IMU، بعد SLAM، بعد ناوبری، بعد کنترلر موتور، بعد RViz. اگر ترتیب اجرا اشتباه شود یا یکی را
فراموش کند، ربات درست کار نمیکند. حالا تصور کن این عدد بهجای هفت، صد و پنجاه Node باشد — دقیقاً همین
اتفاق در یک ربات صنعتی واقعی میافتد. یک ربات واقعی معمولاً این Nodeها را همزمان لازم دارد: camera_node، lidar_node،
imu_node، slam_node، navigation_node، motor_controller و rviz.
اجرای دستی هرکدام با ros2 run برای یک ربات صنعتی با صدها Node عملاً غیرممکن است.
Launch File یک فایل پایتون است که مشخص میکند چه Nodeهایی، با چه Parameterهایی، در چه ترتیبی و تحت چه شرایطی اجرا شوند. Launch فقط یک اسکریپت اجرای پشتسرهم نیست؛ یک موتور (Engine) با منطق شرطی است.
یک فایل Launch میتواند موارد زیر را انجام دهد:
فرض کن پروژه هم حالت Simulation دارد و هم حالت اجرا روی ربات واقعی. با یک شرط ساده در Launch File،
اگر simulation = true باشد، Gazebo و RViz و یک کنترلر شبیهسازیشده اجرا میشوند؛
اگر simulation = false باشد، دوربین واقعی، LiDAR واقعی و درایور موتور واقعی اجرا میشوند —
همان پروژه، بدون تغییر کد.
# robot.launch.py (فقط برای آشنایی، جزئیات کامل در فصلهای عملی)
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(package="camera_driver", executable="camera_node"),
Node(package="lidar_driver", executable="lidar_node"),
Node(package="rviz2", executable="rviz2"),
])
و اجرای همه اینها با یک دستور:
ros2 launch my_robot robot.launch.py
وقتی داخل تقریباً هر پروژه حرفهای ROS 2 را باز کنی، همین الگو تکرار میشود:
my_robot/
├── launch/
│ ├── robot.launch.py
│ ├── simulation.launch.py
│ └── navigation.launch.py
├── config/
│ ├── controller.yaml
│ ├── nav2.yaml
│ └── camera.yaml
├── urdf/
├── rviz/
├── worlds/
├── src/
└── package.xml
این نکته را از همین فصل با خودت ببر: ROS فقط برنامهنویسی نیست. ROS ترکیبی است از معماری نرمافزار (Node، Topic، Service، Action)، ارتباطات (پیامرسانی بین فرایندها)، استقرار (Deployment) (Launch File) و پیکربندی (Configuration) (Parameter و YAML). کسی که فقط کد مینویسد ولی این چهار لایه را نمیشناسد، هیچوقت یک سیستم رباتیک واقعی را کامل نمیفهمد.
برای ربات ARCHO یک فهرست از Nodeهایی که باید در یک Launch File واحد اجرا شوند بنویس (حداقل پنج Node)، و مشخص کن کدامیک فقط در حالت Simulation و کدامیک فقط روی سختافزار واقعی باید اجرا شوند.
حالا که هر تکه را جداگانه دیدیم، بیایید همه را کنار هم بگذاریم. این نموداری است که باید تا آخر کتاب در ذهنت بماند — ستون فقرات ROS 2:
برای هر Node تازه که در پروژه ARCHO یا هر پروژه دیگری میسازی، این چهار سؤال را از خودت بپرس؛ اگر بتوانی جواب بدهی، معماری آن Node را واقعاً فهمیدهای:
تبریک — تو الان با هفت ستون اصلی معماری ROS 2 آشنا شدهای: Node بهعنوان واحد اجرایی مستقل، Topic و Message برای جریان پیوسته داده، Service برای درخواست/پاسخ لحظهای، Action برای عملیات طولانی و قابل لغو، Parameter برای تنظیم رفتار بدون تغییر کد، و Launch File برای راهاندازی کل سیستم با یک دستور. تا اینجا فقط نقشه شهر را یاد گرفتیم؛ هنوز وارد شهر نشدهایم.
پروژه ARCHO در این فصل فقط اسکلت ارتباطی ربات را روی کاغذ طراحی کردیم: کدام Node با کدام Node از طریق Topic حرف میزند، کدام کارها باید Service باشند، و کدامها Action. هنوز هیچ کدی ننوشتهایم و هیچ Nodeی روی سیستم اجرا نشده است.
از فصل ۲ به بعد وارد دنیای عملی میشویم: ساخت Workspace از صفر، بررسی ساختار آن، ساخت اولین Package، نوشتن اولین Node واقعی با Python، اجرای آن، و ساخت اولین Publisher و Subscriber با چشم خودمان. از آنجا به بعد، هر مفهومی که یاد میگیری بلافاصله روی سیستم خودت اجرا خواهی کرد — همانجاست که ROS 2 از یک مجموعه مفاهیم به یک ابزار واقعی برای ساختن ربات تبدیل میشود.