Реализация простой пропорциональной навигации для самонаводящейся ракеты

8

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

Итак, у меня есть двумерная ракета, движущаяся с постоянной скоростью в направлении, в котором она находится, которая может вращаться с постоянной скоростью, и каждый интервал я обновляю ракету чем-то вроде:

Position += VectorProduct (Direction * Speed * TimePassed)

PreviousTargetBearing = TargetBearing
TargetBearing = AngleBetween(TargetPosition, Position)
TargetBearingDelta = TargetBearing - PreviousTargetBearing

If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed

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

Как проще всего решить эту проблему? Я уверен, что упускаю что-то простое.

Связанный вопрос StackOverflow: Как создать «ракету-перехват» для игры?

Повторюсь, я заинтересован именно в реализации алгоритма пропорциональной навигации , а не в алгоритмах самонаведения в целом.


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

e100
источник

Ответы:

1

Шаг 1) Рассчитать время до цели, если идти по прямой

Шаг 2) Рассчитайте, где будет цель с ее текущим курсом в это время.

Шаг 3) Установите курс ракеты, чтобы быть этим местом.

Шаг 4) Обновите при необходимости

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

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

И для этой части:

If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed

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

Azaral
источник
Это не похоже на использование метода пропорциональной навигации?
e100
Нет, но это должно иметь примерно такой же эффект. Это наметит курс перехвата между ракетой и целью. Цель навигации состоит в том, чтобы ракета перехватила цель. Вышеуказанный процесс должен сделать это. Вы хотели просто.
Азарал
Справедливо, +1 к вам
e100
Если вы попробуете, дайте мне знать, как это происходит. Это был мой план самонаведения ракеты в моей игре; Я просто еще не успел запрограммировать ракету.
Азарал
Я реализовал этот метод на данный момент, и он работает хорошо. Я не думаю, что смогу принять этот ответ, так как он недостаточно близок к тому, чем я хочу закончить, но большое спасибо.
e100
4

Как говорит Нейлер, вы можете каким-то образом ограничить изменение движения.

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

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

Valmond
источник
Я вижу, что мне нужна некоторая форма замкнутого контура управления обратной связью, когда ракета отслеживает цель, но я думаю, что у меня есть более простая начальная проблема, поскольку ракета просто колеблется в начальном направлении запуска. Просто чтобы подчеркнуть, я определенно хочу использовать алгоритм пропорциональной навигации.
e100
Хотя PID - хороший инструмент, его сложно настроить ... но как только три параметра (если требуется три) найдены, у вас есть решение для этого конкретного механизма. +1 с моей стороны.
Теодрон
спасибо teodron ;-) @ e100: если вы хотите, чтобы ракета двигалась "прямо вперед", когда расчеты выполнены, и цель находится в постоянном движении, посмотрите на пример "кривой собаки", так как он это делает. В противном случае ваш «TurnRate» равен «P» (IIRC) в PID, вы можете рассчитать его «на лету», скажем, 10% от разницы, а не фиксированное значение. Если вы отклонены от курса на 2 °, вам не нужно вносить такие же изменения, как если бы вы отклонились на 20 °.
Valmond
1

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

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

PS. Суть в том, что мы переносим собственный вектор ракеты на вектор направления (чтобы попасть) относительно некоторого небольшого лага во времени.

haxpor
источник
Обратите внимание, что хотя этот подход может давать результаты, он даст ракете постоянное время разворота (а не постоянную скорость поворота ) - если только вы не пересчитаете частоту интерполяции каждого кадра на основе расстояния поворота, которое еще предстоит пройти, чтобы получить постоянная скорость поворота.
doppelgreener
Мне нужно искать на "lerping"!
e100
1

Пропорциональная навигация проста для реализации в играх.

Пример реализации в игре:

Требуемое ускорение = LOS * LOS_Rate * NC + APN_bias

LOS = Vector3 (TargetPosition) - Vector3 (MissilePosition)

NC = множитель постоянной навигации (в зависимости от частоты кадров)

APN_bias = LOS_Rate / delta_T * (NC / 2)

LOS_Rate = LOS Rotation Rate - угловая скорость изменения линии визирования между ракетой и целью. Это измеряется путем записи положения вектора ракеты и цели в каждом кадре в delta_T и вычитания каждого, чтобы получить разницу. Delta_T - это временная привязка (то есть частота кадров), с которой ваша самонаводящаяся ракета запускается в игре.

Чтобы получить LOS_Rate, просто сделайте свой цикл наведения ракеты для каждого кадра следующим образом (delta_T):

// New LOS rate

LOS_Delta = Vector3( LOS ) - Vector3( LOS_previous_frame ) 

LOS_Rate = LOS_Delta.Vector3Length()

// Update LOS before we finish

LOS_previous_frame = Vector3( LOS )

Вы можете найти больше информации о том, как мы реализовали PN для игры World in Conflict, по следующим ссылкам ниже. Надеюсь, вы найдете это полезным.

http://www.moddb.com/mods/wicmw/features/flint-lead-pursuit-guidance-principles

http://download.wicmwmod.com/Fun_Mod/presentations/FLINT%20Jul%202012.pdf

-blahdy

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

Разве вы не можете просто ограничить скорость поворота, чтобы она никогда не могла превзойти TargetBearing в одном кадре?

Если из-за поворота ракета пройдет мимо своей цели, вы просто устанавливаете новую опору равной цели.

Имеет ли это смысл?

гвоздильщик
источник
Нет, я так не думаю. Идея заключается не в том, чтобы повернуть ракету в направлении TargetBearing, а в том направлении, в котором меняется TargetBearing.
e100
Хорошо. Я думаю, что я неправильно понял.
Nailer