Как определить, какие двигатели включить, чтобы вращать корабль?

47

Конфигурация корабля меняется динамически, поэтому я должен определить, какое подруливающее устройство включить, когда я хочу повернуть корабль по часовой стрелке или против часовой стрелки. Подруливающие устройства всегда выровнены по оси с судном (никогда не под углом) и включены или выключены. Вот одна из возможных настроек:

http://i.stack.imgur.com/GSBSH.png

До сих пор я пытался визуализировать вектор огня и вектор направления к центру масс корабля:

http://i.stack.imgur.com/ZzNzi.png

К сожалению, я не очень далеко с этим.

migimunz
источник
7
Вы движетесь в правильном направлении с векторами силы. Попробуйте найти формулы для УГЛОВОЙ скорости, поскольку вы пытаетесь вращать корабль вокруг центра масс.
Amplify91
Я забыл, как именно это сделать, но в основном это просто силы в каждой точке en.wikipedia.org/wiki/Center_of_mass и особенно en.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex
1
У меня была точно такая же идея! Один совет, который может упростить вам задачу, заключается в том, что вам нужно рассчитывать угловое и линейное ускорение только один раз для каждого двигателя, поэтому вычисления могут быть настолько сложными, насколько вы хотите.
Маркус фон Броади
@ Amplify91, ваш комментарий действительно помог мне разобраться, спасибо!
Migimunz
1
@migimunz Я скорее думал о расчете ускорений на двигатель, а не на нажатие клавиши (группа двигателей). Кроме того, предоставление игроку выбора, какие двигатели следует активировать, какая нажатая клавиша может быть интересной (некоторые люди будут торговать быстрее, вращаясь за вращение на месте)
Маркус фон Броади

Ответы:

22

Успех! Вот оно, и оно вращается так, как должно: введите описание изображения здесь

Я сделал следующее: для каждого двигателя я вычисляю величину крутящего момента по отношению к центру масс.

private function thrustTorque():Float
{
    // distToCom is the distance vector between the thruster and center of mass
    // fire angle is a unit vector representing the direction of the thruster
    var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
    var fireAngle = Math.atan2(dir.y, dir.x);
    var theta = fireAngle - distAngle;
    var torque = distToCOM.length * Math.sin(theta);
    return torque;
}

Уравнение для крутящего момента крутящего момента, согласно википедии, таково T = rF sin(theta), где:

  • r - расстояние между двигателем и COM
  • F - величина приложенной силы (я оставляю это, делая вид, что это всего лишь одна, потому что я забочусь только о знаке).
  • тета - угол между двумя векторами

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

Вероятно, это можно улучшить, используя точечное произведение для вычисления косинуса угла между векторами, но это придется подождать до завтра.

Наконец, вот живая демонстрация .

migimunz
источник
Почти там, я думаю. Кажется, что он не совсем в центре масс. Используя только стрелки влево / вправо, корабль может легко уйти с экрана. Очень близко, хотя. Возможно, точка, с которой вы измеряете, немного смещена. Или это может быть временная проблема, поскольку через некоторое время она, похоже, стабилизируется. Хорошая работа, хотя.
MichaelHouse
Я не думаю, что это как-то связано с этой логикой. Здесь нет ничего, чтобы гарантировать, что транспортное средство не получит чистую поступательную силу от запуска набора турбин, выбранных этим механизмом. Если не требуется поддерживать чистую поступательную силу, это потребует возможности модулировать силу отдельных движителей (и, вероятно, это станет гораздо более сложной проблемой для решения)
Тревор Пауэлл,
@TrevorPowell, точно. Для простоты (а также для забавы, поскольку то, насколько хорошо ваш корабль будет зависеть от того, насколько хорошо вы его спроектируете), я решил, что двигатели включены или выключены. Я, вероятно, включу пороговое значение, чтобы те, которые вызывают слишком маленький крутящий момент (и, следовательно, слишком большое боковое движение), не включались, но точно, сколько «слишком много / мало», вероятно, будет определяться методом проб и ошибок.
Migimunz
3
То, что вы хотите сделать, чтобы избежать вычисления угла, - это использовать произведение перпендикулярной точки (полученное из перекрестного определения крутящего момента T = r кросс F, если вы используете трехмерные векторы с z = 0). Вы берете вектор (-ry, rx), который перпендикулярен r с той же величиной, и вычисляете скалярное произведение этого вектора с F. В результате получается T = rx * Fy - ry * Fx. Тогда abs (T) - это величина крутящего момента, а его знак указывает направление: T> 0 против часовой стрелки, T <0 по часовой стрелке.
Джорен
1
Причину, по которой это работает, легко понять интуитивно: r dot F = r F cos θ. Если вы повернете r против часовой стрелки на 90 градусов и возьмете скалярное произведение, вы получите r F sin θ, потому что cos (θ - 90˚) = sin (θ).
Джорен
14

Общее выражение для 3D крутящего момента является кросс - продукт смещения и силы: Т = гР . В двух измерениях будет достаточно скалярного значения для крутящего момента, и, учитывая только четыре ортогональных ориентации для двигателей, мы можем записать в кусочной форме:

  • Сила в направлении + x: T = F * (-ry)
  • Сила в направлении -x: T = F * (ry)
  • Сила в направлении + y: T = F * (rx)
  • Сила в направлении -y: T = F * (-rx)

Здесь F - величина силы, создаваемой двигателями, rx и ry - x- и y-компоненты вектора от точки поворота до двигателя. Положительные моменты имеют тенденцию вращать корабль против часовой стрелки. Используя четыре формулы, приведенные выше, тривиально определить знак крутящего момента, создаваемого каждым двигателем.

Для скромно точного представления физики вам нужно знать не только знак тяги, но также ее общую величину и инерцию вращения. Более того, вы можете не просто активировать все правильно настроенные двигатели для вращения.

Космический корабль

Как показано, полная мощность двигателей B, D и E увеличит скорость вращения, но также ускорит движение корабля вправо. Выключение D предотвратит это. Если вместо этого предусмотрено ускорение вправо, а вращение по часовой стрелке - нет, то наиболее эффективный способ - включить C и F на две трети полной мощности вместе с D.

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

Маркс Томас
источник
7

Несколько разных вещей. Во-первых, мы должны признать, что это недостаточно ограниченная проблема. То есть существует множество различных комбинаций движителей, которые могут стрелять, приводя к вращению в одном направлении. Я предполагаю, что в вашей ситуации есть только два состояния для двигателей: «включено» и «выключено», и все двигатели выдают одинаковую силу.

Во-вторых, глядя на вашу модель, похоже, ваш «центр масс» на самом деле не является вашим центром масс. К счастью, это не повлияет на ваши расчеты крутящего момента. Однако это повлияет на ваши расчеты смещения центра масс. Я не уверен, если вы заботитесь о точности на этом уровне, так как ваш «центр масс», по крайней мере, ближайший квадрат к истинному центру масс.

В-третьих, если вы хотите рассчитать, как определенное подруливающее устройство повлияет на вращение, у вас все правильно, хотя вы используете неэффективную формулу. Крутящий момент можно рассчитать как r x F, который имеет величину r*F*sin(theta). Однако вычисление углов в этом случае является неэффективным методом. Вместо этого вы должны использовать перекрестное определение крутящего момента напрямую, поскольку это будет намного проще, если использовать ваши представления. Поскольку все ваши векторы не имеют z-компонента, формула для перекрестного произведения значительно упрощается.

Не изменяя результаты ваших вычислений, мы можем просто обновить ваш код

private function thrustTorque():Float
{
    var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
    return torque;
}

Это намного лучше (и быстрее).

Вы предлагаете в своем ответе, что ваше решение состоит в том, чтобы запустить все двигатели с крутящим моментом в правильном направлении. Теперь это в значительной степени решает вопрос, который вы задали. Тем не менее, я ожидаю, что в некоторой точке вдоль линии вы обнаружите, что ваша стратегия не столь удовлетворительна, если пользователь удерживает нажатой кнопку «Поворот», а все двигатели с положительным крутящим моментом вращаются, потенциально перемещая их сверху. вращать их (я не уверен в уровне детализации вашего моделирования, если вы действительно рассчитываете силы от движителей, или если вы просто визуально показываете их выстрелы, а затем вращаете вашу модель с постоянным ускорением или что-то в этом роде. Кстати, вы хотите, чтобы двигатели запускались хотя бы приблизительно точно).

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

Кроме того, если бы вы могли представить себе дополнительный регулятор «громкости двигателя», который одновременно влияет на мощность всех двигателей, то вы можете установить этот элемент управления так, чтобы два ваших решения имели одинаковый крутящий момент, и вы видите, что второе решение может иметь только меньшее смещение, чем первое. Тем не менее, мы должны помнить, что если возможно запустить двигатели, чтобы вы только вращались и вообще не двигались, то оба решения будут одинаковыми.

Итак, мы собираемся перейти ко второму решению, основанному на аргументах предыдущего абзаца. Теперь, анализируя общую силу, мы можем просто отметить, что двигатели могут указывать только в четырех направлениях. Таким образом, общее усилие в направлении x - это просто количество движителей, указывающих влево, минус число, указывающее вправо, а также в направлении y.

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

Джереми Салвен
источник
Спасибо за ответ (и более быстрое и чистое решение для расчета крутящего момента). Красный круг - это не COM корабля, а ядро ​​питания. Я использую физический движок и просто прикладываю локальный импульс к кораблю. Я согласен с тем, что решение не идеальное, так как очень интересно поиграть с разными конфигурациями, но я бы хотел знать, что вы придумали.
Migimunz
1
Вы можете рассчитать крутящий момент из произвольной точки отсчета. Полученное число изменится, но пока вы вращаете корабль вокруг этой точки, которая не обязательно должна быть центром масс, физическое поведение не изменится. Фактически, без информации о распределении масс центр масс сам по себе произвольный и не может быть рассчитан как таковой.
Маркс Томас