Объединение управляющих сил

avatar
user3105897
8 апреля 2018 в 00:58
229
1
1

Я пытаюсь понять, как реализовать и объединить векторы управления для автономных агентов, как описано Крейгом Рейнольдсом.

Насколько я понимаю, каждое усилие на рулевое управление должно рассчитываться отдельно, а затем все усилия на рулевое управление должны складываться вместе, а затем применяться.

Я понимаю, что каждое управляющее усилие равно желаемой скорости для определенного поведения минус текущая скорость агента.

Я пытаюсь объединить два основных поведения: искать и бежать. Ниже приведены две диаграммы, иллюстрирующие мою проблему.

Cumulative steering force at rest

У меня есть агент, который ищет цель прямо перед собой и убегает от цели под ней. Когда агент находится в состоянии покоя (текущая скорость = 0), управляющие силы для каждого поведения равны их соответствующим желаемым скоростям:

vSteer = vDesired - currentVelocity = vDesired - 0 = vDesired

И комбинированное рулевое усилие направлено вверх и вправо, выделено синим цветом. Примерно этого я и ожидал.

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

enter image description here

Когда текущая скорость агента равна желаемой скорости поиска, то усилие управления поиском равно 0 (vSteer = текущее - желаемое = желаемое - желаемое = 0). Сила управления уклонением тогда равна желаемой скорости уклонения минус текущая скорость, что дает вектор, указывающий НАЗАД! А поскольку усилие руления при поиске равно нулю, общее усилие руления равно усилию руления при беге.

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

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

Источник
user3386109
8 апреля 2018 в 03:01
0

Я не думаю, что вы должны вычитать текущую скорость из каждого отдельного компонента.

user3105897
8 апреля 2018 в 03:22
0

Это была и моя первоначальная мысль, но все, что я читал по этому вопросу, прямо говорит, что вы. См. здесь: gamedevelopment.tutsplus.com/tutorials/… В частности, реализация doSeek, расположенная примерно на четверть ниже по странице, возвращает требуемое.вычитание(host.getVelocity())

user3386109
8 апреля 2018 в 08:41
0

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

Ответы (1)

avatar
EvilTak
19 апреля 2018 в 13:06
1

Вы ничего не понимаете неправильно; в соответствии с определением управляющей силы, приведенным в статье Tuts+, такое поведение ожидается. Определение вводит нежелательный компонент скорости рулевого управления в сочетании с другими видами поведения, что, несомненно, является проблемой, с которой вы столкнулись. Чтобы обойти это, необходимо изменить само поведение беглеца.

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

Математически наше ограничение принимает следующий вид:

dot(radius, velocity) <= 0

Где radius = targetPos - agentPos.

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

Наш алгоритм ограничения поведения бегства будет выглядеть следующим образом:

radius = targetPos - agentPos
radiusVel = dot(radius, velocity)

if radiusVel <= 0 {
    return
}

BIAS = 0.02      // Can be any small value determined after testing
steering = -(radiusVel + BIAS) * radius

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