فرض کن روی نسخهای از ARCHO کار میکنی که علاوهبر چرخها، یک بازوی برداشت هم دارد — برای برداشتن جعبه از قفسه. تا الان با Nav2 دیدیم چطور ARCHO در فضا حرکت میکند. اما وقتی نوبت حرکتدادن بازو میرسد، مسئله کاملاً فرق دارد: اگر Nav2 مغز حرکت ربات متحرک است، MoveIt 2 مغز بازوی رباتیک است.
اگر فقط بگویی «نوک بازو باید اینجا باشد» بدون هیچ بررسی دیگری، بازو ممکن است در مسیر رسیدن به آن نقطه، به میز، قفسه یا حتی به خودش برخورد کند. MoveIt دقیقاً همین ریسک را حذف میکند — قبل از هر حرکت واقعی، تمام مسیر را در ذهن (در حافظه) شبیهسازی و بررسی میکند.
فرض کن این بازو را داری:
Base → Joint1 → Joint2 → Joint3 → Gripper
حالا یک سؤال ساده: اگر زاویه هر سه مفصل را بدانم، نوک بازو (Gripper) دقیقاً کجای فضا قرار دارد؟
اگر زاویه شانه، آرنج و مچ دستت را بدانم، میتوانم محل دقیق نوک انگشتت را حساب کنم — این دقیقاً همان FK است. این محاسبه ساده است چون فقط «جلو میرویم»: زاویه موتور → زاویه لینک → موقعیت لینک → نوک بازو. همیشه دقیقاً یک جواب وجود دارد.
FK همانجایی است که TF2 (فصل ۵) واقعاً از آن استفاده میکند: وقتی TF میگوید «جوینتها این زاویهها را
دارند»، این FK است که موقعیت واقعی gripper_link یا camera_link را در فضا
محاسبه میکند. RViz، Gazebo و Collision Detection همگی دائم از FK استفاده میکنند.
حالا سؤال را برعکس کن: اگر بدانم نوک بازو باید کجا باشد (مثلاً X=0.50، Y=0.20، Z=0.80)، هر مفصل باید چند درجه بچرخد؟
وقتی میگویی «لیوان روی میز را بردار»، مغزت خودش زاویه شانه، آرنج و مچ را محاسبه میکند — این IK است. اما بر خلاف FK، IK ممکن است چند جواب داشته باشد (مثلاً آرنج بالا یا آرنج پایین، هر دو به هدف میرسند)، هیچ جوابی نداشته باشد (هدف خارج از دسترس)، یا حتی بینهایت جواب داشته باشد.
چرا IK از FK مهمتر است؟ چون انسان (یا اپراتور خط تولید) همیشه هدف را مشخص میکند — «این پیچ را ببند»، نه «Joint1 را ۱۳ درجه بچرخان». MoveIt این ترجمه از هدف به زاویه مفصلها را برای تو انجام میدهد.
| Forward Kinematics | Inverse Kinematics | |
|---|---|---|
| ورودی | زاویه مفصلها | موقعیت هدف (Pose) |
| خروجی | موقعیت نوک بازو | زاویه مفصلها |
| تعداد جواب | همیشه دقیقاً یکی | صفر، یک، چند، یا بینهایت |
| سختی محاسباتی | ساده و مستقیم | معمولاً نیازمند حلکننده عددی |
| استفاده رایج | RViz، TF، Robot State، Gazebo | MoveIt، Pick & Place، Manipulation |
در بازوهای ۶ یا ۷ محوره واقعی، معمولاً فرمول بسته سادهای برای IK وجود ندارد و از حلکنندههای عددی مثل KDL، TRAC-IK یا IKFast استفاده میشود که MoveIt میتواند هرکدام را بهعنوان پلاگین به کار ببرد.
فکر نکن FK یعنی «حرکتدادن بازو» یا IK یعنی «حرکتدادن موتور». هیچکدام این کار را نمیکنند — اینها فقط محاسبه میکنند. اجرای واقعی حرکت کار ros2_control و Controllerها (فصل ۸) است.
Workspace یعنی تمام نقاطی که بازو واقعاً میتواند به آنها برسد. اگر هدف بیرون این محدوده باشد، IK پاسخ میدهد: Unreachable — یعنی رسیدن اصلاً امکانپذیر نیست، صرفنظر از اینکه مسیر چقدر باز باشد.
وقتی بازو کاملاً کشیده و صاف میشود، حرکت در بعضی جهتها ناگهان سخت یا حتی غیرممکن میشود — به این وضعیت Singularity میگویند. MoveIt سعی میکند مسیرهایی که به این وضعیت نزدیک میشوند را دور بزند.
| حالت IK | علت |
|---|---|
| چند جواب (مثلاً آرنج بالا/پایین) | هندسه بازو اجازه چند وضعیت متفاوت برای رسیدن به یک هدف را میدهد |
| بدون جواب (No IK Solution) | هدف خیلی دور، Joint Limit اجازه نمیدهد، یا مانعی سر راه است |
اگر MoveIt فقط IK داشته باشد، ممکن است بهترین جواب ریاضی را انتخاب کند — حتی اگر مسیرش از وسط یک جعبه روی میز عبور کند. سؤال اینجاست: MoveIt از کجا اصلاً میفهمد آن جعبه وجود دارد؟
Planning Scene یک مدل دیجیتالی کامل از دنیایی است که ARCHO در آن حرکت میکند: خود ربات، میز، کف، دیوار، جعبهها، ابزار، انسان، تجهیزات ثابت، قفسهها و نوار نقاله. MoveIt همیشه، قبل از هر حرکت، این دنیا را در حافظه بررسی میکند.
فرض کن یک کارگر یک جعبه جدید روی میز کنار ARCHO میگذارد. Planning Scene بلافاصله بهروزرسانی میشود و از همان لحظه، مسیرهای جدید MoveIt خودکار آن جعبه را دور میزنند — بدون اینکه کسی خط جدیدی کد بنویسد.
وقتی ARCHO یک جعبه را برمیدارد، از آن لحظه جعبه عملاً جزئی از خود ربات محسوب میشود — به این Attached Object میگویند. اگر MoveIt این را فراموش کند، ممکن است فکر کند بازو هنوز باریک است، در حالی که با جعبه در دست، عرض واقعیاش مثلاً از ۴۰ سانتیمتر به ۸۰ سانتیمتر رسیده — و همین باعث برخورد جعبه با دیوار میشود، حتی اگر خود بازو کاملاً سالم از کنارش رد شده باشد.
MoveIt قبل از اجرای هر مسیر میپرسد: «آیا بازو در هیچ لحظهای از این مسیر به چیزی برخورد میکند؟» و این بررسی فقط ابتدا و انتهای مسیر نیست — در صدها یا هزاران نقطه میانی مسیر هم انجام میشود. اگر ابتدا و انتها سالم باشند اما وسط مسیر برخورد رخ دهد، آن مسیر رد میشود.
| نوع Collision | معنی | مثال |
|---|---|---|
| Self Collision | ربات به خودش برخورد میکند | Gripper در اثر خمشدن زیاد آرنج به Upper Arm میخورد |
| World Collision | برخورد با محیط | میز، دیوار، انسان، جعبه، قفسه |
دو مفصل مجاور مثل Joint1 و Joint2 طبیعتاً همیشه به هم نزدیکاند و بررسی مداوم برخوردشان بیفایده و کند است. MoveIt یک Self-Collision Matrix میسازد که مشخص میکند کدام جفتها اصلاً نیاز به بررسی ندارند — و همین محاسبات را بهطرز چشمگیری سریعتر میکند.
یادت هست در فصل ۴ گفتیم URDF دو بخش visual و collision دارد؟ MoveIt فقط از
بخش collision استفاده میکند — یک جعبه ساده بهجای پیچ، لبه و لوگوی دقیق مدل بصری، چون
برای بررسی برخورد کافی و بسیار سریعتر است.
گاهی برخورد کاملاً طبیعی و لازم است — مثلاً Gripper باید به جسم برخورد کند تا بتواند آن را بگیرد.
MoveIt این استثناها را با یک ماتریس مشخص میکند: Gripper ↔ Object → Allowed، اما
Gripper ↔ Table → Not Allowed.
| نوع Constraint | مثال |
|---|---|
| Orientation Constraint | لیوان آب همیشه باید عمودی بماند |
| Position Constraint | بازو فقط داخل یک محدوده مشخص حرکت کند |
| Joint Constraint | Joint3 هرگز از ۹۰ درجه بیشتر نشود |
| Workspace Constraint | بازو فقط داخل یک حجم مشخص اجازه حرکت دارد |
فرض کن بازوی ARCHO ۶ مفصل دارد و هر مفصل فقط ۱۰۰ حالت مختلف داشته باشد. اگر MoveIt بخواهد همه ترکیبها را امتحان کند، باید ۱۰۰⁶ یعنی یک تریلیون حالت را بررسی کند — کاملاً غیرممکن.
خیلیها فکر میکنند MoveIt مسیر را داخل فضای سهبعدی اتاق پیدا میکند. اشتباه است. MoveIt در واقع داخل Configuration Space (C-Space) — فضای زاویه مفصلها — جستجو میکند. اگر ۶ مفصل داشته باشی، هر وضعیت بازو یک نقطه در یک فضای ۶ بعدی است، نه یک نقطه در اتاق.
داخل C-Space، بعضی نقاط Free Space (مجاز و بدون برخورد) هستند و بعضی Collision Space (غیرمجاز چون به میز، دیوار یا خود بازو برخورد دارند). هدف Motion Planner پیدا کردن مسیری از نقطه Start تا نقطه Goal است که کاملاً داخل Free Space باقی بماند.
Open Motion Planning Library — MoveIt خودش الگوریتم مسیریابی نمینویسد، بلکه از این کتابخانه متنباز استفاده میکند. ورودی OMPL: Planning Scene + Robot Model + Goal. خروجی: یک Trajectory.
بهجای بررسی کل فضا، RRT مثل ریشه یک گیاه یک درخت را از نقطه شروع رشد میدهد. هر شاخه جدید یک وضعیت تصادفی جدید از بازو است. اگر شاخهای به مانع بخورد، حذف میشود و درخت از مسیر دیگری رشد میکند. وقتی یک شاخه به Goal برسد، همان شاخه تبدیل به مسیر نهایی میشود.
نسخه بهتر: بهجای یک درخت، دو درخت همزمان رشد میکنند — یکی از Start و یکی از Goal. وقتی این دو درخت به هم برسند، مسیر پیدا شده است. این معمولاً سریعترین Planner موجود در MoveIt است.
ابتدا هزاران نقطه تصادفی در C-Space تولید و به هم وصل میشوند — مثل ساختن یک نقشه جاده. بعد فقط مسیر مناسب روی همان جاده انتخاب میشود.
| RRT / RRTConnect | PRM | |
|---|---|---|
| روش | هر بار از صفر شروع میکند | اول یک «جاده» ثابت میسازد، بعد از همان استفاده میکند |
| مناسب برای | محیط دائماً در حال تغییر | محیط ثابت و تکراری |
Planner فقط یک Path پیدا میکند — دنبالهای از زاویههای مفصل بدون هیچ اطلاعاتی درباره زمان. این مسیر خام معمولاً گوشههای تیز دارد که برای اجرای فیزیکی مناسب نیست، پس MoveIt آن را با Path Smoothing نرم میکند.
Path فقط مسیر است. Trajectory یعنی مسیر + زمان — مثلاً «ثانیه صفر: Joint1=0°، ثانیه یک: Joint1=20°، ثانیه دو: Joint1=35°». این Trajectory نهایی است که Controller (فصل ۸) واقعاً اجرا میکند.
در ساخت Trajectory نهایی، MoveIt چند محدودیت را هم رعایت میکند:
| محدودیت | معنی |
|---|---|
| Velocity Limit | سرعت هیچ مفصلی از حد مجاز بیشتر نشود |
| Acceleration Limit | شتاب ناگهانی نداشته باشد |
| Jerk | حتی تغییر ناگهانی شتاب هم در رباتهای صنعتی حرفهای محدود میشود |
مرکز اصلی این هماهنگی، Node معروفی بهنام move_group است:
RRT و RRTConnect یک مسیر خوب و امن پیدا میکنند، نه لزوماً بهترین مسیر ریاضی دنیا —
چون یافتن مسیر مطلقاً بهینه ممکن است ساعتها طول بکشد. MoveIt یک Planning Time محدود
دارد (مثلاً ۵ ثانیه)؛ اگر تا آن زمان مسیری پیدا نشود، پاسخ Planning Failed برمیگردد.
حالا میدانی وقتی ARCHO دستش را برای برداشتن یک جعبه بلند میکند، پشت صحنه چه اتفاقی میافتد: FK محاسبه میکند بازو الان کجاست، IK محاسبه میکند برای رسیدن به هدف مفصلها چه زاویهای لازم دارند، Planning Scene دنیای اطراف را در حافظه نگه میدارد، Collision Detection مسیر را تأیید ایمنی میکند، و OMPL در فضای چندبعدی Configuration Space یک مسیر امن پیدا میکند که در نهایت به یک Trajectory قابل اجرا تبدیل میشود.
پروژه ARCHO اکنون یک پیکربندی کامل MoveIt دارد که با استفاده از Planning Scene، Collision Detection و الگوریتم RRTConnect میتواند بازوی برداشتش را برای گرفتن جعبه از قفسه، بدون برخورد با محیط، هدایت کند.
در فصل چهاردهم از یک ARCHO تنها فاصله میگیریم و وارد دنیای چند رباتی میشویم: Namespace، TF Prefix و هماهنگی چند ARCHO که همزمان در یک انبار کار میکنند.