مسیر یادگیری ROS 2  ·  کتاب آموزشی تصویری

فصل دهم: SLAM — ARCHO نقشه انبار را می‌سازد

وقتی هیچ نقشه‌ای وجود ندارد و ربات باید خودش بسازدش
پیش‌نیاز: فصل ۹ (Odometry)
پروژه پیوسته: ربات ARCHO
ابزار: SLAM Toolbox
زمان مطالعه: ۱۰۰ تا ۱۲۰ دقیقه
در این فصل چه می‌خوانیم ۱۰.۱یک سؤال اساسی: نقشه از کجا می‌آید؟ ۱۰.۲SLAM چیست: سه کار هم‌زمان ۱۰.۳دو حالت SLAM Toolbox: Mapping و Localization ۱۰.۴نصب و پیکربندی ۱۰.۵ساخت نقشه انبار ۱۰.۶ذخیره نقشه ۱۰.۷چرا نقشه‌ها خراب می‌شوند ۱۰.۸جمع‌بندی، واژه‌نامه و تمرین‌ها

۱۰.۱یک سؤال اساسی: نقشه از کجا می‌آید؟

در فصل نهم فرض کردیم یک نقشه از قبل وجود دارد و فقط باید موقعیت ARCHO را روی آن تخمین بزنیم. اما یک روز اول واقعی این‌طور نیست: ARCHO را از جعبه در می‌آوری، وارد یک انبار جدید می‌کنی که هیچ‌کس تا به‌حال نقشه‌اش را نکشیده. حالا چه؟

همین سؤال ساده، یکی از مهم‌ترین شاخه‌های کل رباتیک را به‌وجود آورده: SLAM (Simultaneous Localization and Mapping) — همزمان محیط را کشف کن، نقشه بساز، و موقعیت خودت را هم روی همان نقشه‌ای که داری می‌سازی پیدا کن.

🧠 چرا این یک مسئله سخت است

برای پیدا کردن موقعیتت، به یک نقشه نیاز داری؛ اما برای ساختن نقشه درست، باید بدانی خودت کجا هستی. این یک وابستگی دوطرفه به‌نظر غیرقابل‌حل است — دقیقاً مثل مرغ و تخم‌مرغ. SLAM این حلقه را با ترکیب هوشمند Odometry (که در فصل قبل ساختیم) و مقایسه پی‌درپی اسکن‌های LiDAR حل می‌کند.

۱۰.۲SLAM چیست: سه کار هم‌زمان

در این کتاب، از پرکاربردترین بسته LiDAR SLAM در ROS 2 استفاده می‌کنیم: SLAM Toolbox.

📖 SLAM Toolbox دقیقاً چه کاری می‌کند

از داده LiDAR استفاده می‌کند، هم‌زمان موقعیت ربات را تخمین می‌زند، نقشه می‌سازد، وقتی به یک مکان قبلاً دیده‌شده برمی‌گردد آن را تشخیص می‌دهد (Loop Closure)، تمام این تاریخچه را در یک ساختار به‌نام Pose Graph نگه می‌دارد، و در پایان نقشه را ذخیره و قابل بارگذاری مجدد می‌کند.

flowchart TB A["LiDAR
/scan"] --> B["SLAM Toolbox"] C["Odometry
/odometry/filtered"] --> B B --> D["/map"] B --> E["Transform: map → odom"] B --> F["Pose Graph"] D --> G["Navigation2"] style B fill:#eef0ff,stroke:#3d4bf5,color:#211f1a,font-weight:bold style G fill:#eafaf3,stroke:#0e9e6e,color:#211f1a
🌍 SLAM و robot_localization رقیب نیستند

نکته‌ای که خیلی‌ها گیج می‌شوند: SLAM Toolbox جایگزین کار فصل نهم نیست، بلکه از خروجی آن استفاده می‌کند. Odometry فیلترشده حرکت لحظه‌به‌لحظه را تخمین می‌زند؛ SLAM Toolbox از همین تخمین برای بهبود دقت مقایسه اسکن‌های متوالی (Scan Matching) استفاده می‌کند. این دو مکمل‌اند، نه رقیب.

۱۰.۳دو حالت SLAM Toolbox: Mapping و Localization

حالتوقتی استفاده می‌شودورودیخروجی
Mappingروز اول، محیط کاملاً ناشناخته استLiDAR + Odometryنقشه جدید (Occupancy Map)
Localizationنقشه از قبل ساخته و ذخیره شدهنقشه ذخیره‌شده + LiDARفقط موقعیت ربات روی نقشه

روند دو روز اول ARCHO در یک شعبه جدید انبار معمولاً این شکل است:

flowchart LR subgraph D1["روز اول"] A1["LiDAR"] --> B1["SLAM Toolbox
Mapping"] --> C1["Save Map"] end subgraph D2["روز دوم به بعد"] A2["Load Map"] --> B2["AMCL
Localization"] --> C2["Navigation2"] end style B1 fill:#eef0ff,stroke:#3d4bf5 style B2 fill:#eafaf3,stroke:#0e9e6e
⚠️ بزرگ‌ترین اشتباه مبتدی‌ها

خیلی‌ها فکر می‌کنند SLAM باید همیشه روشن بماند. در اکثر پروژه‌های صنعتی، نقشه فقط یک‌بار ساخته می‌شود، ذخیره می‌شود، و از آن به بعد فقط Localization (با AMCL، در فصل بعد) انجام می‌شود — هم سبک‌تر است، هم پایدارتر. استثنا محیط‌هایی است که دائماً تغییر می‌کنند، مثل یک انبار در حال بازسازی؛ آنجا ممکن است SLAM همیشه فعال بماند.

۱۰.۴نصب و پیکربندی

sudo apt install ros-jazzy-slam-toolbox
ورودی‌های اصلیخروجی‌ها
/scan/map
Transform: odom → base_linkTransform: map → odom
Transform: base_link → laser_linkPose Graph

فایل پیکربندی برای ARCHO:

# archo_slam/config/mapper_params.yaml
slam_toolbox:
  ros__parameters:
    use_sim_time: true
    mode: mapping
    map_frame: map
    odom_frame: odom
    base_frame: base_link
    scan_topic: /scan
    resolution: 0.05
    max_laser_range: 12.0
    minimum_time_interval: 0.2
    transform_publish_period: 0.05
    map_update_interval: 2.0
    minimum_travel_distance: 0.15
    minimum_travel_heading: 0.15
    use_scan_matching: true
    do_loop_closing: true
پارامترمعنی
resolutionاندازه هر سلول نقشه به متر — ۰.۰۵ یعنی هر پیکسل نقشه ۵ سانتی‌متر است
minimum_travel_distanceربات باید حداقل این‌قدر حرکت کند تا یک اسکن جدید در نقشه ثبت شود
do_loop_closingآیا وقتی به مکان قبلی برمی‌گردی، نقشه خودش را تصحیح کند یا نه

۱۰.۵ساخت نقشه انبار

برای ساخت نقشه، چهار ترمینال جدا لازم داری:

ترمینالکار
۱Gazebo + ARCHO (فصل ۷ و ۸)
۲SLAM Toolbox
۳Teleoperation (فرمان دستی حرکت)
۴RViz — با Fixed Frame روی map و Displayهای Map، LaserScan، TF، RobotModel، Odometry
🔧 چطور یک نقشه خوب بسازیم
  • آهسته حرکت کن — چرخش‌های سریع Scan Matching را خراب می‌کنند.
  • تمام راهروهای انبار را ببین، نه فقط مسیر مستقیم.
  • به نقطه شروع برگرد تا Loop Closure اتفاق بیفتد و خطای تجمعی تصحیح شود.
  • از نزدیک‌شدن بیش‌ازحد به قفسه‌ها یا سطوح شیشه‌ای (که بازتاب بدی به LiDAR می‌دهند) خودداری کن.

۱۰.۶ذخیره نقشه

وقتی از پوشش کامل انبار مطمئن شدی:

ros2 run nav2_map_server map_saver_cli \
  -f ~/archo_ws/src/archo_navigation/maps/warehouse

این دستور دو فایل می‌سازد:

فایلمحتوا
warehouse.pgmخود تصویر نقشه — یک تصویر خاکستری که دیوارها و فضای باز را نشان می‌دهد
warehouse.yamlاطلاعات نقشه: اندازه هر سلول، مبدأ، و آدرس فایل PGM
# warehouse.yaml
image: warehouse.pgm
mode: trinary
resolution: 0.05
origin: [-5.0, -5.0, 0.0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25

روز بعد، همین دو فایل توسط Map Server بارگذاری می‌شوند و به AMCL (فصل بعد) داده می‌شوند تا موقعیت ARCHO را بدون نیاز به ساخت دوباره نقشه پیدا کند.

۱۰.۷چرا نقشه‌ها خراب می‌شوند

علامتعلت‌های محتمل
دیوارها دوگانه یا محو دیده می‌شوندOdometry ضعیف، سرعت زیاد، لغزش چرخ، TF اشتباه، نرخ اسکن کم
نقشه می‌چرخد یا موج داردمحور Yaw اشتباه IMU، Timestamp نامعتبر، Scan Matching ضعیف
نقطه‌های اضافی روی نقشه می‌مانندانسان یا اشیای متحرک هنگام اسکن، محیط بیش‌ازحد پویا
📖 جمله طلایی این فصل

نقشه خوب فقط محصول یک الگوریتم خوب نیست؛ نتیجه Odometry مناسب (فصل ۹)، TF صحیح (فصل ۵)، حرکت آرام و مشاهده کافی محیط است. اگر فصل‌های قبل را با دقت طی نکرده باشی، هیچ تنظیم SLAM Toolbox نمی‌تواند این کمبود را جبران کند.

تمرین سخت‌تر

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

۱۰.۸جمع‌بندی فصل دهم

ARCHO حالا می‌تواند وارد یک انبار کاملاً ناشناخته شود و بدون هیچ نقشه از قبل آماده‌ای، هم‌زمان محیط را کشف کند، نقشه بسازد، و موقعیت خودش را روی همان نقشه در حال ساخت پیدا کند. این نقشه ذخیره‌شده، سکوی پرشی است که فصل بعد — Navigation2 — رویش بنا می‌شود.

✅ نقطه بازبینی یادگیری
  • می‌توانم توضیح دهم چرا SLAM یک مسئله «مرغ و تخم‌مرغ» است.
  • می‌دانم تفاوت حالت Mapping و Localization در SLAM Toolbox چیست.
  • می‌توانم بگویم چرا SLAM Toolbox و robot_localization مکمل هم‌اند، نه رقیب.
  • می‌دانم یک نقشه ذخیره‌شده از چه دو فایلی تشکیل شده و هرکدام چه نقشی دارند.
  • می‌توانم حداقل سه علت رایج خرابی نقشه را نام ببرم.
🌍 ارتباط با پروژه اصلی

پروژه ARCHO اکنون یک Package archo_slam با تنظیمات کامل Mapping دارد و اولین نقشه واقعی انبار (warehouse.pgm و warehouse.yaml) را ساخته و ذخیره کرده است.

فصل بعد چه چیزی اضافه می‌کند

در فصل یازدهم، همین نقشه ذخیره‌شده را بارگذاری می‌کنیم و وارد معماری کامل Navigation2 می‌شویم: Map Server، AMCL، Costmap، Global Planner و Local Controller — جایی که ARCHO برای اولین بار کاملاً خودکار در انبار مسیر پیدا می‌کند.

واژه‌نامه فصل دهم

SLAM
Simultaneous Localization and Mapping؛ ساخت هم‌زمان نقشه و تخمین موقعیت در یک محیط ناشناخته.
SLAM Toolbox
پرکاربردترین بسته LiDAR SLAM در ROS 2؛ نقشه، Pose و TF تولید می‌کند.
Loop Closure
تشخیص اینکه ربات به مکانی که قبلاً دیده برگشته، و تصحیح خطای تجمعی نقشه بر همان اساس.
Pose Graph
ساختار داده‌ای که تاریخچه موقعیت‌ها و ارتباط هندسی بین اسکن‌های متوالی را نگه می‌دارد.
Scan Matching
مقایسه دو اسکن LiDAR متوالی برای تخمین جابه‌جایی واقعی ربات بین آن‌ها.
Occupancy Map
نقشه‌ای که هر سلول آن اشغال، آزاد یا ناشناخته بودن یک نقطه از محیط را نشان می‌دهد.
map_saver_cli
ابزار خط فرمان برای ذخیره نقشه فعلی به دو فایل PGM و YAML.

خطاهای رایج فصل دهم — جمع‌بندی