Скажем, у меня есть движущийся циркуляр, target
определенный как:
Vector2 position;
Vector2 velocity;
float radius;
И вращающийся turret
(установленный на движущемся транспортном средстве), определенный как:
Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second
(Или что-то в этом духе. Обратите внимание, что положение и скорость обоих контролируются в другом месте - предположим, что скорость постоянна, а положение изменяется в зависимости от скорости.)
Я пытаюсь написать две связанные функции AI для определения в данном кадре:
Какое угловое ускорение (и в каком направлении) применить к углу башни, чтобы башня была направлена на цель?
Если цель в данный момент находится в поле зрения, можно ли ее (любую часть в пределах ее радиуса) держать в поле зрения в течение
x
нескольких секунд, гдеx
будет доля секунды? (Альтернативно: есть ли другая стратегия, чтобы убедиться, что цель на самом деле «зафиксирована», а не просто летит через прицел?)
И я мог бы использовать некоторую помощь ...
Ответы:
Сначала вам нужно определить разницу в угле между направлением башни и направлением на цель.
Как только у вас есть эти величины, вы можете установить выражение второй степени для угла револьверной головки. Вы должны вычислять это при каждом обновлении, чтобы всегда использовать самые последние данные о позициях и скоростях.
Здесь первый член (нулевой градус) в выражении ускорения заставит турель начать поворачиваться к цели. Однако это не остановится во времени, а скорее колеблется назад и вперед по этому. Чтобы остановить его, нам нужен второй член демпфирования (первая степень), который вызывает высокую скорость поворота, противоположную высокому ускорению.
Теперь положительные константы (не обязательно программные константы) должны быть определены и сбалансированы, чтобы система работала хорошо.
C0
является основным элементом управления скоростью системы. Высокое значение дляC0
даст быструю скорость поворота, а низкое значение даст низкую скорость поворота. Фактическое значение зависит от многих факторов, поэтому вы должны использовать метод проб и ошибок здесь.C1
контролирует величину демпфирования. Дискриминант квадратного уравнения говорит нам , что еслиC1*C1 - 4*C0 >= 0
мы имеем систему , не колеблющийся.Вы, вероятно, должны выбрать
C1
немного больше, чем это по численным причинам, но не слишком большое, потому что оно может стать слишком затухающим и медленным, чтобы реагировать вместо этого. Опять же, вам нужно настроить.Также важно отметить, что этот код вычисляет только угловое ускорение. Угол и угловая скорость должны быть обновлены откуда-то еще, используя какой-либо интегратор. Из вопроса я предполагаю, что это было покрыто.
Наконец, есть что сказать об отставании, потому что турель, вероятно, всегда будет отставать при отслеживании быстрой цели. Простой способ справиться с этим - добавить линейный прогноз к позиции цели, то есть всегда стремиться немного вперед в направлении цели.
Что касается удержания револьверной головки в радиусе цели в течение некоторого времени, это может быть жестким требованием для непосредственного наложения на такую систему. Вы можете быть уверены, что этот контроллер будет стремиться всегда держать турель направленной на цель (или, скорее, на прогнозируемую позицию). Если результат оказывается не удовлетворительным , вы должны изменить параметры
predictionTime
,C0
иC1
( в пределах стабильных границ).источник
k
), а C1 - коэффициент демпфирования (обычно называемый «B» или «c»). Так что да, вы можете минимизировать колебания, увеличивая демпфирование, но проблема в том, что он не пытается предвидеть, где будет цель , поэтому обречен на отставание от желаемой цели.То, что у вас здесь есть, является основной проблемой контроля . Турель - это система, ускорение - это контроль, а датчик измеряет положение / скорость. Есть много способов решения этих проблем, так как это очень хорошо изученная проблема в технике.
Ключ заканчивается стабильной системой, то есть системой, которая не генерирует колебания. Обычно это делается путем добавления демпфирования. Страница википедии должна помочь вам начать.
источник
Прежде всего, рассчитайте вектор от башни до цели. Затем сравните это с текущим вектором башни. Затем используйте разницу между этими двумя значениями, чтобы определить угловое ускорение и угловую скорость, необходимые для поворота револьверной головки в нужном направлении в течение заданного времени.
ОК, это казалось простым. Тем не менее, вы должны действительно попытаться предвидеть положение цели, так как цель будет двигаться к тому времени, как вы повернули турель. Сделать это:-
где P - это положение, а V - это скорость, а нижний индекс равен d для пункта назначения (цель) и s для источника (турель), что дает вектор направления:
где D - вектор направления, а Dsd '- требуемое направление в момент времени t. Теперь определите направление револьверной головки на основе текущего положения и максимальной скорости и ускорения для заданного времени t:
Ds и Ds '- направления источника, а Rs - скорость вращения. При всем этом вы хотите найти t для требуемой скорости вращения, когда Dsd '== Ds' и, следовательно, Rs. Не забывайте, что все P, D и V имеют компоненты x и y.
Здесь я не учел ускорение - это значительно увеличивает сложность. Получив Rs и t, вы, вероятно, можете приблизить параболическое Rs (то есть ускорить и замедлить), чтобы получить тот же результат.
источник
То, что вы, вероятно, ищете здесь, - это PID-контроллер , аналогичный ответу, принятому на этот вопрос SO
Первоначально я ответил на этот вопрос, «катясь самостоятельно», но этот ответ значительно более полный и элегантный.
источник
Первое, что нужно сделать, - это рассчитать угол между потоком и отслеживаемым объектом.
Далее нужно проверить, будет ли использование текущей скорости торрента и максимальное ускорение назад (остановка торрента) останавливать торрент до или после отслеживаемого объекта.
Если ответ таков: торрент остановится перед отслеживаемым объектом, примените максимальное ускорение вперед (увеличение скорости).
Если ответ таков: торрент остановится после отслеживаемого объекта, примените максимальное ускорение в обратном направлении (остановите торрент).
Таким образом, торрент всегда прибудет быстрее всех и остановится в нужной точке (или немного позже).
источник