Как предотвратить попадание самонаводящихся ракет на свои цели?

78

Я занимаюсь разработкой 2D-космической игры без трения, и мне очень легко сделать так, чтобы орбита самонаводящейся ракеты стала целью. Меня интересует антиорбитальная стратегия.

Простой пример - самонаводящаяся ракета, которая просто ускоряется прямо к своей цели. Если бы эта цель двигалась перпендикулярно траектории ракеты, а затем остановилась, ускорения ракеты к цели было бы недостаточно для преодоления ее собственной скорости, и ракета могла бы быть выведена на орбиту вокруг цели, как показано на рисунке:

Проблема орбиты

  • В кадре 1 ракета направляется прямо к цели, никаких проблем.
  • В кадре 2 цель переместилась на новую позицию, как показано. Ракета продолжает ускоряться прямо к цели (красным цветом), но все еще движется туда, где раньше была цель (черным цветом) из-за существующей скорости.
  • В кадре 3 скорость ракеты продолжает нести ракету вокруг стороны цели (черная), в то время как вектор ускорения отчаянно пытается тянуть ракету к цели.
  • В кадрах 4 и далее ракета попадает на потенциально устойчивую орбиту вокруг цели и никогда не достигает своей цели. Черные стрелки указывают вектор скорости, а красные линии - векторы ускорения в один и тот же момент времени.

Учитывая, что в космосе нет трения, нет ничего, что могло бы замедлить скорость ракеты и обрушить орбиту. Возможным решением было бы нацеливаться «за» целью, и это привело бы к закрытию орбиты, но как это сделать с точки зрения программирования?

Как заставить самонаводящуюся ракету достичь цели?

Джон Макдональд
источник
9
На самом деле это очень крутой способ вывести вещи на орбиту.
Дерек
Это напоминает мне об интеграции Эйлера. Все, что вам нужно сделать, это сделать ваш шаг времени бесконечно малым, проблема решена!
Джефф
Я хочу реализовать этот эффект в моей игре! : D
Zolomon
6
@ Деза Это само определение орбиты. Орбитальный объект ускоряется с помощью центростремительной силы по направлению к центру какого-либо другого объекта.
Бобобобо

Ответы:

49

Прежде всего, вы должны сделать все расчеты о том, что ускорение для применения в ракеты отсчёта (что, где ракета находится в неподвижном состоянии, а все остальное движется вокруг него, также часто называют «объектные координаты» или «локальные координаты» в игровых системах, хотя в нашем случае мы хотим, чтобы скорость была точно равна нулю).

Идея состоит не в том, чтобы стремиться к цели, а к месту, где цель будет находиться в предполагаемое время воздействия. Итак, общий алгоритм выглядит так:

  1. Оцените, сколько времени потребуется ракете, чтобы достичь цели. Если цель летит прямо на нее (помните, ракета неподвижна ), это может быть так же просто, как вычисление расстояния / скорости , в других случаях это может быть более сложным. Если цель может попытаться уклониться, вы все равно не сможете сделать точную оценку, так что все будет не очень точно.

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

  3. Рассчитайте ускорение, которое приведет к тому, что ракета будет находиться примерно в одном месте в одно и то же время.

  4. Перепроектируйте ускорение обратно от системы отсчета ракеты к глобальной, используйте это.

Важной частью здесь является получение оценки времени на приблизительном этапе и не забывать при этом возможности ускорения ракеты. Например, лучшая оценка для "цели прямо перед нами и полета в нашем направлении" была бы для решения уравнения ...

расстояние = скорость х время + 1/2 х ускорение х время 2

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

время = (√ ( скорость 2 + 2 x ускорение x расстояние ) - скорость ) / ускорение

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

Мартин Сойка
источник
Я думаю, что это именно то, что мне нужно. Я никогда не думал в местных координатах до сих пор.
Джон Макдональд
5
Отличный ответ. Как примечание стороны, многие ракеты слежения предназначены для автоматического взрыва в следующих условиях: 1) расстояние до пути и 2) расстояние до пути в настоящее время увеличивается. Это может добавить немного хорошего поведения при небольших затратах.
Патрик Хьюз
1
Это отличный ответ. В итоге я использовал постоянное ускорение для оружия (я подумал, что это было наиболее реалистично), рассчитал время, которое потребуется, чтобы прибыть (переставить d = v t + 1/2 * a t * t и решить для t). Секретный соус заключался в том, чтобы передать оценку времени, чтобы спроецировать, где цели будет дана ее текущая скорость и предполагаемое время удара. Работает хорошо.
Бобобобо
1
Я предполагаю, что это тип алгоритма
безрассудной
42

@ Мартин Сойка уже сказал вам, что делать. Вместо того, чтобы улучшить его ответ, я хочу предложить вам еще один более простой подход: DELOCK

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

Когда вы видите, что ваша цель входит в одну из таких рулевых теней, вы можете прекратить нахождение своей цели и удерживать другое направление в течение ограниченного периода времени.

Триггер разблокировки может быть легко вычислен путем приближения ваших торов с помощью (двойного) конуса *:

Триггер разблокировки

Вы должны просто вычислить скалярное произведение между вашим (нормализованным) вектором направления и вашим вектором смещения цели ( Target - Object / | Target - Object |).

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

* Если честно, это не конус ... это другой вид линейчатой ​​поверхности, образованной (полу) вращением двух непараллельных линий вокруг оси, проходящей через пересечение и перпендикулярной линии биссектрисы; Проекция на 2D-плоскость такая же, как у двойного конуса, но ось вращения перпендикулярна той, которая генерирует конус.

** Эта траектория вряд ли будет круговой, эллиптической или даже замкнутой. Скорее всего, траектория будет следовать траектории, подобной спирографу (гипотрохоиду) в 2D или даже других монстрах в 3 и более измерениях. Вы не можете достичь центра таких кривых в любом случае, и они выглядят как круги, так что "круговая" траектория.

FXIII
источник
+1 Хорошая идея для случая, когда вектор ускорения ракеты ограничен перпендикулярно направлению движения. Я не думаю, что это относится к этому вопросу, хотя.
Мартин Сойка
@Martin Sojka вектор ускорения можно даже разбить на две составляющие, одну радиальную, а другую - тангенциальную к направлению. Первый рассказывает, на сколько вы можете развернуться, второй - на сколько вы можете ускоряться / замедляться.
FxIII
1
Да, и если вы можете выбирать их относительные силы независимо друг от друга (то есть, если направление и сила вектора ускорения не зависят от вектора движения), ваши «круги исключения» исчезают.
Мартин Сойка
@ Мартин Сойка Нет ли ограничений на ускорение?
FxIII
1
+1 Это очень круто. Я никогда не думал об этом раньше. Я, вероятно, попытаюсь использовать это в сочетании с ответом @ Matin
Джон Макдональд
8

Ваша система наведения построена на предположении, что ускорение непосредственно к цели в конечном итоге приведет к столкновению объектов. Поскольку это предположение неверно, ИИ, основанный на этом предположении, также неудачен.

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

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

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

Николь Болас
источник
2
«Цели не особо проворные» .. не так ли?
Бобобобо
5

Самый простой и продвинутый метод для использования в играх (и в реальной жизни) - это Пропорциональная навигация.

Под Constant подшипник Уменьшение диапазона (CBDR) логики, когда два объекта (ракетные и целевые) путешествуют в том же направлении без изменения визирования между друг с другом, они будут сталкиваться.

Линия визирования, или Линия визирования (LOS) - это воображаемая линия между ракетой и целью - вектор между позицией ракеты и позицией цели. Скорость углового изменения этого LOS является Частотой вращения LOS.

Когда LOS Rotation Rate становится равной нулю, линия взгляда больше не меняется - два объекта теперь находятся на пути столкновения. Думайте о себе, как о том, что гонитесь за кем-то во время игры в футбол Если вы ведете его так, что его тело выглядит «замороженным» в вашем поле зрения (линия обзора между вами и ним больше не меняется), вы будете сталкиваться с ним до тех пор, пока сохраняете свое ускорение бега, чтобы его тело казалось застывшим в ваш взгляд.

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

Команда наведения ракеты должна быть представлена ​​следующим образом:

Ускорение = Скорость закрытия * N * Скорость LOS

Скорость LOS может быть легко получена путем измерения вектора LOS (положение цели - положение ракеты) и сохранения его переменной. Вектор LOS из нового кадра (LOS1) вычитается из вектора LOS из старого кадра (LOS0) для генерации дельты LOS - теперь у вас есть примитивная частота вращения LOS.

Чтобы упростить Closing Velocity, вы можете просто использовать текущий вектор LOS вместо него, таким образом:

Ускорение = (target_pos - missile_pos) * LOS_delta * N

N - это константа навигации - в реальном мире она обычно устанавливается в диапазоне от 3 до 5, но реальная работоспособная цифра в игре в некоторой степени зависит от частоты дискретизации, с которой вы выводите скорость / дельту LOS. Попробуйте случайное число (начиная с 3) и увеличивайте до 1500, 2000 и т. Д., Пока не увидите желаемый ведущий эффект в игре. Обратите внимание, что чем выше навигационная постоянная, тем быстрее ракета будет реагировать на изменения скорости LOS в начале полета. Если ваша имитационная модель самонаводящейся ракеты является несколько реалистичной, чрезмерная постоянная навигации может перегрузить аэродинамические возможности вашей ракеты, поэтому вы должны использовать сбалансированное число, основанное на методе проб и ошибок.

Джеймс Джун
источник
4

Как указывают другие ответы Мартина и Николя, вы, вероятно, хотите направить свою ракету не непосредственно на цель, а таким образом, чтобы впоследствии она столкнулась с целью. Однако метод, описанный Мартином, сложен, а метод, описанный Николом, неэффективен.

Более простой способ - но все же довольно эффективный - направлять ракету путем регулировки ее угла в соответствии с изменением угла между ракетой и целью. На каждом тике вы рассчитываете угол от ракеты до цели и сравниваете его с углом от предыдущего тика. Разница - это именно то, что вы хотите сделать под углом ракеты. Таким образом, если угол был 0,77 в одном тике и 0,75 в следующем, вы хотите отрегулировать угол наклона ракеты на -0,02. Этот метод прост, и пока цель находится «перед» ракеты, она очень эффективна с точки зрения выбранного маршрута. Это также относится к любому количеству измерений, а не только в 2d.

Имейте в виду, хотя:

  • Этот метод ломается, если ракета и цель имеют одинаковую скорость и движутся параллельно. Ну, теоретически он все еще составляет курс столкновения для ракеты, это просто занимает бесконечное время :) на практике ракета всегда должна быть быстрее цели, но если они имеют одинаковую скорость, вам нужно добавить угловой случай, чтобы определить, параллельны ли они ,

  • Метод ломается, если цель и ракета летят по одной и той же линии, но в противоположных направлениях. Это не может произойти в реальном мире, но не так уж редко встречается в дискретной игре. Вы должны добавить проверку угловых случаев в вышеупомянутый алгоритм, чтобы проверить это.

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

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

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

дуб
источник
1

Несколько простых опций, которые были сочтены «достаточно хорошими» для игр, над которыми я работал в прошлом:

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

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

2) Если вы обнаружите, что ваша ракета находится под прямым углом к ​​вашей цели, это может быть точка, в которой замок «ломается», и ракета просто движется прямо, если цель снова не окажется «перед» ракеты.

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

Надеюсь это поможет.

Джеймс
источник
0

Как уже было сказано, вы должны направить ракету туда, где ожидаемая цель будет, когда вы туда доберетесь, а не туда, где цель находится сейчас. Это предотвратит выход ракет МОСТ на орбиту, но орбита все еще возможна, если цель уклоняется точно. Это законная тактика, используемая пилотами самолетов для уклонения от поступающих ракет - поскольку ракета движется гораздо быстрее, чем у вас, у нее будет больший радиус поворота, и резкий рывок в нужный момент заставляет ее идти дальше. (Хотя вы все еще можете подвергнуться риску от детонации близости.)

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

Однако я не согласен с его решением проблемы. Вместо этого я бы запрограммировал ракеты так:

если ракета сместилась на 90 градусов к линии движения на 360 градусов, вы находитесь на орбите. Отрегулируйте тягу на 120 градусов от линии движения. Орбита ракеты будет расширяться, поскольку она не поворачивается так сильно, но ракета также замедлится, что позволит ей лучше маневрировать. Когда дальность до цели открывается до 1,25-кратного диаметра мертвой зоны (обратите внимание, что этот диаметр основан просто и только на скорости ракеты, во время выполнения никаких сложных вычислений не требуется), ракета возвращается к своему нормальному поведению слежения.

В качестве альтернативы используйте тупые искатели голов - когда дальность до цели перестает отсчитывать, вы детонируете.

Лорен Печтель
источник
0

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

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

Вот рабочий пример, который я реализовал сегодня утром, в моем случае для ИИ игрока в спортивной игре-симуляторе, где игрок пытается преследовать своего противника. Движение регулируется стандартной моделью «удар-дрейф», в которой ускорения применяются в начале временного шага для обновления скоростей, а затем объекты дрейфуют с этой скоростью на протяжении временного шага.

Я бы опубликовал вывод этого, но я обнаружил, что на этом сайте не поддерживается математическая разметка. Бу! Вы просто должны поверить, что это оптимальное решение, учитывая, что у меня нет ограничений по направлению ускорения, что не относится к объектам ракетного типа, поэтому для этого потребуются некоторые дополнительные ограничения.

Код написан на python, но должен быть читаемым на любом языке. Для простоты я предполагаю, что каждый временной шаг имеет длину 1 и выражаю скорость и ускорение в соответствующих единицах, чтобы отразить это.

self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)

Обратите внимание, что функция atan2 (a, b) вычисляет обратный tan для a / b, но гарантирует, что углы находятся в правильном квадранте круга, что требует знания знака как a, так и b.

В моем случае, когда у меня есть ускорение, я применяю его, чтобы обновить скорость

vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)

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

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

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

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

Более реалистичным подходом для системы наведения было бы изменение скорости поворота с обратно пропорциональным расстоянием до цели (меньшее расстояние -> большая скорость поворота). Это дало бы спираль, а не орбиту, и гарантировало бы столкновение с более медленной целью.

Это также дает гораздо более реалистичную траекторию полета. Постоянная скорость поворота неестественно идеальна. Вы также можете добавить случайные изменения в скорость поворота, чтобы моделировать турбулентность. Опять же, гораздо более реалистично, и на самом деле можно избежать сценариев стационарного орбиты.

Нет необходимости в частных уравнениях.

Доминик Черизано
источник