Динамічне врівноваження космічного корабля


14

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

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

Корабель

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

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

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

a - вектор положення для рушія a b - вектор положення до тяги b v1 - сила від виштовхувача a v2 - сила від тяги b

ефективністьDelta = a.cross (v1) / | v1 | - (a.cross (v1) + b.cross (v2)) / | v1 + v2 |

в основному "a.cross (v1 * t) / | v1 |" повинна бути ефективність повороту. А потім ми віднімаємо його за коефіцієнтом повороту рушіїв разом, щоб побачити, чи варто запускати новий тяга.

Проблема виникає, коли я розумію, що тяги не підлягають включенню / вимкненню, але можуть змінювати їх тягу від 0 до 1. І як рухатись, коли гравець хоче, щоб корабель рухався вперед. Звичайно, потрібно було б встановити баланс того, скільки потрібно обертати / рухати.

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

Дякую, що знайшли час! / Кім


3
Я почав тим самим шляхом, але з багатьма конфігураціями неможливо і обертати, і не перекладати. То ви забираєте обертання? Або ви дозволяєте переклад? Зрештою, користувач проектує судно. Для демонстрації цього я підробив це. Пов'язаний: gamedev.stackexchange.com/questions/58216 / ... , gamedev.stackexchange.com/questions/40615 / ...
MichaelHouse

Я пішов схожим шляхом і закінчив писати демонстрацію на цій сторінці . Коли ви рухаєте штовхачі навколо (перетягуєте їх на кораблі, щоб встановити положення та потужність), він малює три форми. Інтуїція полягає в тому, що ви можете думати про всі можливі рухи як точку в 3d-просторі (x, y, обертання), а обмеження 0-1 є обмеженням у цьому просторі. Отже, у вас виходить 3d форма, яка містить усі можливі рухи. Якщо вам не потрібна лінійна швидкість, ви дивитесь на рядок (x = 0, y = 0) у цьому просторі (Q, W, E, S всі 0 у моєму демонстрації)
amitp

Відповіді:


7

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

Кожен тяги буде виробляти два впливи на рух корабля: лінійний та кутовий. Їх можна розглядати самостійно. Якщо тяга виробляє силу fв напрямку dirі зміщується з центру маси вектором r(а не геометричним центром або центром спрайта!), То вплив на лінійну складову:

t = f * dir // f is a scalar, dir is unit length

Вплив на кутову швидкість надає крутний момент:

tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product

t- вектор сили (тобто лінійна тяга). tauявляє собою підписаний скаляр, який при поділі на момент інерції маси дасть кутове прискорення. Важливо, що dirіr обидва в тому ж просторі координат, тобто як в локальних координатах або як в світових координатах.

Загальне лінійне прискорення корабля задається сумою t's для кожного тяги, поділеної на масу корабля. Аналогічно, кутове прискорення - це лише сума крутних моментів, поділена на масовий момент інерції (що є ще одним скаляром). Якщо сумарний крутний момент дорівнює нулю, корабель не повернеться. Так само воно не рухатиметься, якщо загальна тяга дорівнює нулю. Нагадаємо, крутний момент є скалярним, але тяга (сума t's) - двовимірний вектор.

Суть цієї експозиції полягає в тому, що тепер ми можемо записати свою проблему як лінійну програму . Скажіть спочатку, що ми хочемо, щоб наш корабель повернувся без руху . У нас є змінна для кожного тяги, $ x_1, x_2, ... $, яка є величиною тяги, яку забезпечить тяга. Один набір обмежень:

0 <= x_i < fmax_i  //for each i

де fmaxмаксимальна сила для цього тяги (це дозволяє нам мати сильніші або слабкіші). Далі ми говоримо, що обидві рівності:

0 = Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y

Це кодує обмеження, що ми не будемо застосовувати лінійне прискорення, кажучи, що загальна тяга дорівнює нулю (тяга - вектор, тому ми просто скажемо, що кожна частина дорівнює нулю).

Тепер ми хочемо, щоб наш корабель повернувся. Імовірно, ми хочемо зробити це якомога швидше, тому ми хочемо:

max (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>

Рішення для x_i 's, задовольняючи вищезгадані нерівності та рівності, при цьому максимізуючи підсумок вище, дасть нам бажану тягу. Більшість мов програмування мають бібліотеку LP для них. Просто покладіть на нього вищевказану проблему, і вона дасть вашу відповідь.

Подібна проблема дозволить нам рухатися, не повертаючись. Скажімо, ми переписуємо свою проблему в систему координат, в якій ми хочемо рухатись у позитивному напрямку x. Тоді обмеженнями є:

0 <= x_i < fmax_i  //for each i
max Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y
0 = (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before

З обмеженням того, що тяги можуть створювати тягу тільки в одному напрямку, існують обмеження щодо виду обертання та лінійних швидкостей, яких ви зможете досягти. Це виявиться як рішення 0 = x_1 = x_2 = ... = x_n, яке є , а це означає, що ви нікуди не потрапите. Щоб пом'якшити це, я пропоную додати пару маленьких, слабких (скажімо, 5% або 10%) штовхачів для кожного гравця, розміщеного тяга під 45 градусами з обох боків. Це дасть рішенню більшу гнучкість, оскільки вони можуть бути використані для протидії слабким вторинним ефектам основних рушіїв.

Нарешті, для наближення, можливо, 100 поштовхів, рішення LP дуже швидко, щоб зробити це на кадр. Однак, оскільки рішення не залежить від місця розташування або поточного стану, ви можете попередньо обчислити рішення для кожної розумної вхідної комбінації контролера щоразу, коли форма змінюється (це включає додавання не-тяжів, які змінюють момент інерції або масу корабля, бо тоді штовхачі знаходяться в іншому місці відносно центру маси!). Це 24 можливості (тобто 8 разів вказівки (лівий віджим, відсутність обертання, правий віджим)).


Дуже добре пояснено!
Кім

1
Що Sum_iозначає в цьому контексті?
S. Tarık Çetin

1

Моя перша думка була суто емпіричним рішенням, тобто імітувати бурову установку в середовищі пісочниці для різного ступеня тяги, щоб визначити, як вона поводиться. Замість того, щоб збалансувати багато складної математики в пошуку детермінованого рішення, ви можете досягти його чисельно, наприклад, використовуючи метод Ньютона. Приклад:

Діапазон тяги - від 0 до 1000, де 1000 - АЛО.

Крок 1

Моделюйте довіру (0 + 1000) / 2 = 500. Результат: занадто велика довіра

Крок №2

Діапазон тепер 0 до 500 Моделюйте довіру (0 + 500) / 2 = 250. Результат: занадто велика довіра

Крок №3

Діапазон тепер 0 до 250 Моделюйте довіру (0 + 250) / 2 = 125 Результат: занадто мало довіри

Крок №4

Діапазон тепер становить від 125 до 250 Моделюйте довіру (125 + 250) /2=187.5 Приведіть занадто багато довіри

Крок №5 Діапазон тепер становить від 125 до 187,5. Моделюйте довіру (125 + 187,5) /2=156,25 Результат - це занадто мало довіри

Крок # 6 Діапазон тепер 156,25 до 187,5 Діапазон нижче порога 35 , що означає , що вона є досить гарною оцінкою

Кінцевий результат = (187,5 + 156,25) / 2 = 171,875

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.