در فصل نهم فرض کردیم یک نقشه از قبل وجود دارد و فقط باید موقعیت ARCHO را روی آن تخمین بزنیم. اما یک روز اول واقعی اینطور نیست: ARCHO را از جعبه در میآوری، وارد یک انبار جدید میکنی که هیچکس تا بهحال نقشهاش را نکشیده. حالا چه؟
همین سؤال ساده، یکی از مهمترین شاخههای کل رباتیک را بهوجود آورده: SLAM (Simultaneous Localization and Mapping) — همزمان محیط را کشف کن، نقشه بساز، و موقعیت خودت را هم روی همان نقشهای که داری میسازی پیدا کن.
برای پیدا کردن موقعیتت، به یک نقشه نیاز داری؛ اما برای ساختن نقشه درست، باید بدانی خودت کجا هستی. این یک وابستگی دوطرفه بهنظر غیرقابلحل است — دقیقاً مثل مرغ و تخممرغ. SLAM این حلقه را با ترکیب هوشمند Odometry (که در فصل قبل ساختیم) و مقایسه پیدرپی اسکنهای LiDAR حل میکند.
در این کتاب، از پرکاربردترین بسته LiDAR SLAM در ROS 2 استفاده میکنیم: SLAM Toolbox.
از داده LiDAR استفاده میکند، همزمان موقعیت ربات را تخمین میزند، نقشه میسازد، وقتی به یک مکان قبلاً دیدهشده برمیگردد آن را تشخیص میدهد (Loop Closure)، تمام این تاریخچه را در یک ساختار بهنام Pose Graph نگه میدارد، و در پایان نقشه را ذخیره و قابل بارگذاری مجدد میکند.
نکتهای که خیلیها گیج میشوند: SLAM Toolbox جایگزین کار فصل نهم نیست، بلکه از خروجی آن استفاده میکند. Odometry فیلترشده حرکت لحظهبهلحظه را تخمین میزند؛ SLAM Toolbox از همین تخمین برای بهبود دقت مقایسه اسکنهای متوالی (Scan Matching) استفاده میکند. این دو مکملاند، نه رقیب.
| حالت | وقتی استفاده میشود | ورودی | خروجی |
|---|---|---|---|
| Mapping | روز اول، محیط کاملاً ناشناخته است | LiDAR + Odometry | نقشه جدید (Occupancy Map) |
| Localization | نقشه از قبل ساخته و ذخیره شده | نقشه ذخیرهشده + LiDAR | فقط موقعیت ربات روی نقشه |
روند دو روز اول ARCHO در یک شعبه جدید انبار معمولاً این شکل است:
خیلیها فکر میکنند SLAM باید همیشه روشن بماند. در اکثر پروژههای صنعتی، نقشه فقط یکبار ساخته میشود، ذخیره میشود، و از آن به بعد فقط Localization (با AMCL، در فصل بعد) انجام میشود — هم سبکتر است، هم پایدارتر. استثنا محیطهایی است که دائماً تغییر میکنند، مثل یک انبار در حال بازسازی؛ آنجا ممکن است SLAM همیشه فعال بماند.
sudo apt install ros-jazzy-slam-toolbox
| ورودیهای اصلی | خروجیها |
|---|---|
/scan | /map |
Transform: odom → base_link | Transform: map → odom |
Transform: base_link → laser_link | Pose 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 |
وقتی از پوشش کامل انبار مطمئن شدی:
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 — رویش بنا میشود.
پروژه ARCHO اکنون یک Package archo_slam با تنظیمات کامل Mapping دارد و اولین نقشه واقعی انبار (warehouse.pgm و warehouse.yaml) را ساخته و ذخیره کرده است.
در فصل یازدهم، همین نقشه ذخیرهشده را بارگذاری میکنیم و وارد معماری کامل Navigation2 میشویم: Map Server، AMCL، Costmap، Global Planner و Local Controller — جایی که ARCHO برای اولین بار کاملاً خودکار در انبار مسیر پیدا میکند.