інверсна кінематика


Переклад здійснив Pavel A. Chuvanov, учасник проекту Almighty.

Кінематика - є процес обчислення позиції в просторі для кінця взаємозалежної структури при заданих кутах повороту всіх шарнірних точок (Joints). Це легко здійснюється, якщо є тільки одне рішення. Інверсна кінематика робить протилежне. Для даної кінцевої точки обчислюються необхідні кути повороту шарнірів таким чином, щоб вдалося досягти цієї кінцевої точки. При цьому можуть виникнути труднощі, якщо є багато або нескінченно багато рішень.

Даний процес надзвичайно корисний в робототехніці. Наприклад, ви захотіли, щоб рука робота потягнулася і взяла об'єкт. Якщо програма знає місце розташування об'єкта щодо плечового суглоба, то їй досить розрахувати кути повороту шарнірів щоб досягти об'єкта. Також інверсна кінематика корисна в 3D іграх. Візьмемо для прикладу дракона з дуже довгою шиєю. Дракон повинен реалістично зігнути шию і зжерти гравця стоїть на підлозі. Або гравець захотів підняти з підлоги якийсь об'єкт або натиснути на кнопку. Користувач побачить на екрані як гравець потягнеться і торкнеться об'єкта, замість того щоб просто махнути рукою десь поблизу об'єкта (як наприклад в Alone In The Dark).

Я написав невелику демку під DOS ілюструє механізм інверсної кінематики. Скріншот показує як змійка намагається торкнутися невеликого обертового кубика. Ви можете переміщати мета використовуючи клавіатуру. У демке на змійку діє гравітація і вона має невелику еластичність, тому можливо буде рухатися і після того як знайде мета, намагаючись досягти більш комфортного положення. Модель змійки знаходиться в файлі tail.cfg. Ви можете виправити його щоб створити який-небудь інший об'єкт.

Існує багато випадків, коли пов'язана структура не в змозі досягти мети. Наприклад ви не можете торкнутися ліктем однієї руки зап'ястя тієї ж руки. Або дістати з землі до верхівки високого дерева.

У разі якщо є два рішення, то повинна існувати техніка вибору, яке з рішень більше відповідає поточному стану структури.

Коли використовується більше двох шарнірів, часто трапляється, що існує багато рішень задачі. Тим не менш, деякі рішення є краще за інших. Якщо ваша структура являє, наприклад, руку то деякі рішення більш зручні, інші дуже неприродні. Часто є оптимальне рішення.

Я прийшов до методу інверсної кінематики після деяких роздумів, проб і помилок. Немає сумнівів, що є багато алгоритмів вирішення проблем інверсної кінематики, але тут я опишу тільки один.

Цей алгоритм не відразу знаходить рішення. Це не проста функція де ви задаєте місце призначення і отримуєте кути. Це ітеративний алгоритм, що робить алгоритм більш реалістичним в програмах, особливо в іграх, де ви наверяка хочете, щоб об'єкти рухалися згладжено.

Рішення знаходиться за рахунок віртуального застосування сили до кінця ланцюжка і перетягування кінця ланцюжка в кінцеву позицію. Сила діє на кожне зчленування і рухає структуру трохи ближче до кінцевої точки. Так що навіть якщо рішення немає, ланцюжок наблизиться до кінцевої точки так близько, наскільки це можливо. Так як шарніри розраховуються окремо, то ви можете задати їм різні властивості, такі як жорсткість, еластичність і т.д. Кожен з шарнірів також може мати оптимальну позицію, яку алгоритм буде намагатися досягти так близько, як тільки це можливо.

Інверсна кінематика в 2D

Почнемо з одного шарніра. В даному випадку він може обертатися навколо тільки однієї осі (напрямок проти годинникової стрілки виберемо як позитивне). Вектор R діє під прямим кутом до кістки. Вектор сили F діє від кінцевої точки в напрямку мети. Кут між R і F є a. Тепер все зовсім просто. Швидкість, з якою ви повинні повертати шарнір, пропорційна скалярному добутку (dot product) векторів R і F. Дотримуючись точки зору, що скалярний добуток двох векторів позитивне число, і, звичайно ж, шарнір повинен обертатися в позитивному напрямку, щоб максимально наблизиться до мети . Якщо кут між R і F прямий, то шарнір повернувся так, щоб кістка була максимально близько до мети і тому шарнір не повинен більше повертатися. У цій точці скалярний добуток двох векторів дасть нуль.

Ну ось, приїхали. Випадок важче. Надалі, все буде просто різновидом даного випадку. Коли ви маєте більше однієї кістки ви просто повинні повторити вищеописаний алгоритм для кожного шарніра по черзі.

Почнемо з шарніра найближчого до мети:
1. Обчислимо вектор сили (від кінцевої точки до мети)
2. Обчислимо скалярний твір вектора сили і вектора, перпендикулярного кістки.
3. Помножимо скалярний твір на невелике число (наприклад 0.01)
4. Додамо його до кута шарніра.

Робимо так для всіх шарнірів послідовно.

Інверсна кінематика в 3D

У тривимірному просторі обчислення будуть не набагато складніше. Є три можливих осі, навколо яких шарнір може обертатися. Я спробував застосувати вищеописаний метод в тривимірному просторі, але результати були не дуже хорошими. Я не до кінця зрозумів чому. Проте ця математика безумовно працює. Є щось, що вимагає великої кількості змін установок, щоб все працювало, безумовно, правильно.

Ну, що ж, рухаємося далі.

Ось шарніра перпендикулярна кістки

Спершу давайте спробуємо приклад, наведений вище, але в цей раз в 3D. Це система з двома шарнірами і ми спершу візьмемо перший шарнір.

Дамо назви векторах
a - Вектор уздовж осі шарніра.
b - Вектор уздовж кістки.
r - Вектор перпендикулярний a і b.
f - Вектор сили (чинний від кінцевої точки до мети).

Якщо вектор сили буде паралельний a, шарнір НЕ буде обертатися. Якщо він паралельний b, то ви просто тягнете кістка, шарнір НЕ буде обертатися. Озброївшись даними пустулатамі, я вирішив що обертає момент повинен бути пропорційний синусу кута між a і f і синусу кута між b і f.

Якщо кінцева точка прийшла в точку цілі, то ви не хочете, щоб структура рухалася, але якщо кінцева точка далеко від цілі, то ви хочете, щоб структура рухалася швидко. Отже, крутний момент повинен бути пропорційний довжині вектора сили.

Є тільки одна річ, яку не можна зрозуміти з вищеописаного - напрямок в якому повинен обертатися шарнір. Нехай шарнір повинен вращатсья в позитивному напрямку якщо вектор сили направлений уздовж r, і в протилежному напрямку в разі якщо вектор сили направлений протилежно r.

Склавши всі воєдино отримаємо:

torque = Mag (f) * SinVect (a, f) * SinVect (b, f) * sign (CosVect (r, f)) * Sensitivity

У цій формулі SinVect і CosVect повертають відповідно синус і косинус кута між векторами. Mag повертає довжину вектора, і sign повертає знак числа. Sensitivity - це просто невелика скалярная константа.

Тепер ви можете рухатися до наступного шарниру в структурі. Обчислимо нові значення векторів a, b і f, і обчислимо крутний момент для шарніра 2. Обчислимо крутний момент для всіх шарнірів в структурі і додамо до кута кожного шарніра по його крутним моментом. Кінцева точка повинна тепер бути ближче до мети. Безперервно повторюючи процес ми зможемо наблизити кінцеву точку структури до мети максимально близько чи навіть торкнуться мети.

Ось шарніра спрямована уздовж кістки

Добре, давайте поглянемо на більш важкий випадок. Але тут немає нічого нового. Тут ви бачите пов'язану структуру що складається з чотирьох шарнірів. Шарнір номер два, проте, може обертатися навколо осі своєї кістки. Це схоже на вигин вашого зап'ястя. І звичайно цей шарнір найбільш важливий. Як і в попередньому випадку, вектор a буде проходити уздовж осі шарніра, але в цьому випадку це ще й уздовж кістки. Вектор b зараз йде від шарніра до кінцевої точки. Вектор r як і раніше перпендикулярний обом.

Щоб досягти мети шарнір 2 повинен повернутися на 90 градусів (див. Праву картинку).

І закінчимо тим, що вектор b різний для шарнірів чия вісь обертання паралельна кістки.

Тепер, коли ви освоїли базу інверсної кінематики, є ще завдання регулювання системи, щоб задати її поведінку в різних ситуаціях. Як я говорив до цього, є багато різних рішень. Деякі краще, деякі гірше. Розрізняються тим як вони виглядають, величиною витрачених рухів або зручністю.

Реальна змійка на реальній анімації рідко коли заплутується сама в собі. Вона має тенденцію образоввивать досить гладкі криві. Змійка в демке зроблена з пар шарнірів осі, які перпендикулярні один одному. Спочатку написана змійка рухалася не дуже реалістично. Тому я додав їй трохи еластичності в шарнірах. Через це шарніри пручаються вигину. Чим більше ви їх сгибаете, тим більше вони чинять опір. Ефект від цього такий, що вигин разпространяется по шарнірам.

Давайте поглянемо на динозавра. Він дуже товстий в тілі, але стає більш тонким і гнучким в шиї. Ця властивість може бути симулювати пов'язаної структурою, зчленування якої все більше і більше еластичність до кінця.

Кінцівки воліють знаходиться в зручному положенні. Це може бути виконано новим додаванням еластичності шарнірам. Проте в цьому випадку може бути найкращим мати певний ряд положень для кожного шарніра в якому немає опору. Цей ряд може бути рассмот як зручний. Після того як шарнір залишає зручне положення він буде сопротівлятся все сильніше і сильніше поки зовсім не відмовиться обертатися.

Також може бути бажано тримати кінцівку максимально низько. Люди рідко довго тримають свої руки на вазі більш, ніж це необхідно. Тому положення вибирається виходячи з мінімальної енергії вимагається для утримування положення.

Схожі статті