Как сделать самонаводящуюся ракету

Добавил пользователь Skiper
Обновлено: 04.10.2024

люди)помогите ,как напиать код для движения самонаводящейся ракеты,если известны координаты персонажа и координаты противника?

устанавливай ракете направление на цель и двигай ее вперед

Yazephyr
Все просто.

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

Следующий уровень сложности. Если например у тебя авиасим и нужны все таки нормальные самонаводящиеся ракеты, которыми можно сшибать самолеты(сопоставимые по скорости с ракетами).
Ракета все так же пытается лететь по вектору цели, с постоянной скоростью(линейное ускорение всегда равно нулю) но теперь у нас есть предельная угловая скорость поворота ракеты. Берем какое нибудь значение максимальной перегрузки, ну скажем 50g (тоесть 490 м/c^2).
Центробежное ускорение равняется произведению двух скоростей - линейной и угловой.
Тоесть максимальную угловую скорость рассчитали как константу и не превышаем её. Такая ракета уже будет достаточно похожа на настоящую, но асы обзовут её тупой коровой.

Level up.
С угловой скоростью все то же самое, но теперь мы будем лететь не в центр обьекта а по упреждению. Тут всё тоже не очень сложно - постоянно рассчитываем предполагаемое время до столкновения и на основании скорости и ускорения обьекта предполагаем его положение в момент столкновения. И туда пытаемся лететь.

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

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

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

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

Я пользуюсь такой формулой:

только недостаток этого способа в том что чем дальше ракета от объекта тем быстрее она будет двигаться(для устранения этого недостатка и нужно замедление) и физики здесь никакой.

красиво и почти просто: учитывать скорость поворота ракеты. находишь косинус синус по формулам выше, находишь из арктангенса угол, химичешь так как там будут проблемы со знаком +/-, сравниваешь с настоящим углом ракеты и ищешь, куда ближе поворачивать, поворачиваешь на скорость поворота, продолжаешь движение. если, например, не взрывать ракеты над целью, то они начнут выделывать восьмерки над объектом

Yazephyr
> Yazephyr
google -> SteeringBehavior -> pursuit

А препятствия в расчет не берем совсем шоле?

El Zee Sheppard
> А препятствия в расчет не берем совсем шоле?
у ракеты. препятствия.

El Zee Sheppard
> А препятствия в расчет не берем совсем шоле?
Воздух? ^_^

ну прям не ракета, а поезд, сошедший с рельс, из голого пистолета.

Ну а вдруг речь идет об аркадной ракете, которая найдет цель даже в заднице у дьявола?

Dervinar
> Если у тебя ракета летит много быстрее, чем может двигаться цель(ну например по
> танку жахаешь ракетами) то вполне достаточно просто тупо лететь по вектору к
> цели.

Подозреваю что военные инженеры сделали несколько более умно. Ракета должна лететь на упреждение.
У меня в свое время была даже книжка для 10-класников с дифференциальными уравнениями по теме.
Называлась "программирование игр" но кроме как обсасывания оптимизации движения ракеты с упреждением ничего не писалось.
Похоже это был левак от одной "шаражек". :)

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

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

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

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

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

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

@ Деза Это само определение орбиты. Орбитальный объект ускоряется с помощью центростремительной силы по направлению к центру какого-либо другого объекта.

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

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

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

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

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

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

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

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

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

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

Отличный ответ. Как примечание стороны, многие ракеты слежения предназначены для автоматического взрыва в следующих условиях: 1) расстояние до пути и 2) расстояние до пути в настоящее время увеличивается. Это может добавить немного хорошего поведения при небольших затратах.

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

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

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

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

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

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

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

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

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

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

+1 Хорошая идея для случая, когда вектор ускорения ракеты ограничен перпендикулярно направлению движения. Я не думаю, что это относится к этому вопросу, хотя.

@Martin Sojka вектор ускорения можно даже разбить на две составляющие, одну радиальную, а другую - тангенциальную к направлению. Первый рассказывает, на сколько вы можете развернуться, второй - на сколько вы можете ускоряться / замедляться.

+1 Это очень круто. Я никогда не думал об этом раньше. Я, вероятно, попытаюсь использовать это в сочетании с ответом @ Matin

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

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

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

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

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

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

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

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

Ускорение = Скорость закрытия * 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 в начале полета. Если ваша имитационная модель самонаводящейся ракеты является несколько реалистичной, чрезмерная постоянная навигации может перегрузить аэродинамические возможности вашей ракеты, поэтому вы должны использовать сбалансированное число, основанное на методе проб и ошибок.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Читайте также: