полет в заданную точку, чтобы в точке была заданная скорость.
Исходные данные: Летит корабль, известны его координаты, угол поворота, скорость, ускорение. Нужно чтобы он прилетел в заданную точку назначения(цель), оказался в ней с заданной скоростью и повернутый в заданном направлении. Цель может двигаться.
Тупой вариант решения, когда конечная скорость=0 (как сделал я :) ): Поворачиваем в сторону цели. Набираем скорость если расстояние до цели большое. Снижаем скорость если расстояние до цели маленькое (снижение идет пропорционально расстоянию). После остановки разворачиваемся в заданном направлении.
В итоге корабль нарезает круги вокруг цели. А хотелось бы, чтобы он по дуге зашел и сразу был повернут в нужном направлении :)
Может кто сталкивался? Есть какие-нибудь статьи на эту тему?
Думаю надо описать движение корабля системой уравнений, и её решить.
Что нибудь вроде: x = x0 + f1(t) < y = y0 + f2(t) x' = f3(t) y' = f4(t)
Вот как-то так. Функции f1, f2 будут описывать механику полёта с двигателем (равноускоренный полёт к примеру). Функции f3, f4 будут описывать изменение скорости (линейное изменение к примеру).
С другой стороны, если ты хочешь чтобы твой самодельный алгоритм навигации приводил в нужную точку без решения системы уравнений, следует оценивать время до прибытия, и использовать для рулёжки и мощности двигателей. Немного считерить и пустить корабль не по правилам игры, чтобы поворачивал и ускорялся резче, чем реально могут такие корабли, причём чем ближе к точке назначения, тем больше коэффициент чита.
А какие "ручки управления" доступны для корабля?
эхх. плохо я физику в школе учил :) пошел читать по равноускоренное движение по окружности.
c4tnt газ, тормоз и поворот. газ и тормоз меняют ускорение.
могу предложить тупой вариант решение задачи. делай нейросеть на входе текущее состояние + то которое надо получить на входе что надо делать. и обучи ее. хотя метод и тупой но зато самый лучший если не нужна 100% точность а если на вход подать радар а на выход типа поли уже есть ИИ.
Другой вариант если не так важна скорость то можно по другому, обратный отсчет.. если из А нужно попасть в Б. то возьмем точку Б` так чтобы из нее можно было попасть в Б за одну итерацию. и так чтобы Б` была ближе к А < по координатам углу и скорости> теперь зада свелась к нахождению пути из А к Б`.
>эхх. плохо я физику в школе учил :)
Это задача не по физике, а по теории управления. Тривиального решения у нее нет. Однако подход ты выбрал верный - управление по состоянию. То есть задаешь ускорение на основании положения, скорости и поворота корабля относительно цели. Только надо правильно коэффициенты подобрать. Будет разумно поддерживать скорость такой, что при максимальном торможении корабль окончит движение на цели - это будет оптимальное по времени управление. Таким образом получим, что требуемая скорость равна: V=sqrt(2*maxa*s) Где s- расстояние до цели, а maxa - максимальное ускорение. Если текущая скорость меньше требуемой - то ее надо увеличить, если больше - уменьшить. Так же следует принять во внимание, что я здесь рассматриваю прямолинейный случай, или на, худой конец, случай, когда ты можешь мгновенно применить ускорение в направлении цели. В твоем же случае нужно сначала повернуть корабль, поэтому приведенную схему можно применять, когда корабль уже повернут к цели с некоторой точностью (точность нужно будет выбрать экспериментально).
Я думаю что достаточно рассчитать желаемое ускорение и скорость поворота и максимально быстро выйти на эти значения, тогда корабль спокойно прилетит с минимальной погрешностью в заданную точку. Для уточнения результата просто ещё несколько раз по ходу полёта перерассчитать эти значения и подкорректировать. И получается практически то, о чём говорил GeniusIsme.
Кстати, полёт по окружности хоть и даёт решение практически в 100% случаев, не является оптимальным. Например, когда в точке назначения скорость направлена против нашей начальной скорости, решением являлась бы длинная дуга. Было бы сильно дешевле пролететь недалеко от точки назначения и сделать максимально крутой поворот, вместо длинного и долгого полёта по почти полной дуге.
Spawner > известны его координаты, угол поворота, скорость, ускорение. 1) в каких координатах летит корабль? Хотя давай так. в 2Д или 3Д 2) что в твоем понимании есть "угол поворота"? Хотя если в 2Д - то понятно
Какая точность физической модели нужна?
А вообще задача довольно сложная. Я, например, занимаюсь этим уже полтора года, но до сих пор все до конца не сделано.
Мы сделали вполне успешно.
Есть точка А и точка B. У обоих есть вектор скорости. A обладает некой конечной тягой (с учетом массы уже) и может применять ее в любое время в любом направлении. Кроме того точка А всегда знает позицию и скорость B.
1. совместить оба вектора скорости в пространстве. 2. сделать их равными по направлению и скаляру.
Задачи решаются отдельно.
1. Вычисляется вектор тяги направления от А к B. Это R1 Вычисляется вектор торможения обратный R1 и записывается в R2. Скаляр расчитывается исходя из массы объекта и его тяги и расстояния до B. Далее далее вектора складываются.
2. Для решения второй точка А в силу своих способностей выполняет постоянно векторное вычитание из своей скорости скорость B. r3
Итого мы имеем вектор движения для перемещения к текущей точке R12 (учитывающий торможение) и вектор для уравнивания скорости. Складываем их. Если скаляр результата больше максимальной тяги, то нормируем и умножаем на тягу. Если нет - то тяга и есть этот результат.
И еще. Если дело происходит в гравполе, то в сумму надо добавлять R4=обратному вектору действия гравитации. Ну и прочие силы. Что бы А движком их подгребала.
Собственно все. Итерационно работает. Топливо жжется правда много, зато справедливо при любых раскладах. 3D-2D не важно. И ради всего хорошего, никаких систем уравнений не решай.
Спасибо всем за ответы!
Читал http://www.red3d.com/cwr/steer/gdc99/ много думал :) В принципе как раз статья на нужную тему.
Переделал все на векторы (с косинусов-синусов), буду сейчас пробовать реализовать решение shosh
Еще вопрос, у меня сейчас ориентация корабля хранится в векторе. Игра 2д, вид сверху, вектор двухкомпонентный. Как из этого вектора получить угол поворота?(Нужно для рисовки спрайтов, на каждые 10 градусов отдельный спрайт)
Я считаю по теореме пифагора через арксинус/арккосинус, плюс еще анализ в какой координатной четверти находится вектор ^_^ (т.к. угол изменяется от 0 до 360) Может есть какой-нибудь простой путь?
Да в общем нормальный путь. Можно обойтись только синусами и косинусами - что-то вроде: if(cos_val < 0.1)else if(cos_val < 0.2)else. Может быстрее будет.