Націлювання на безпілотники


9

Уявіть собі "безпілотник" та цільову точку на 2d площині. Є вісім параметрів:

P = my position
Q = target position
V = my velocity
I = my moment of inertia
w = my angular velocity
s = my angular position
T = max thrust
U = max torque

(ми просто скажемо, що ціль нерухома)

Завдання безпілотника - досягти цілі якомога швидше, дотримуючись максимального крутного моменту та максимальної тяги. Існує лише два способи застосування крутного моменту, оскільки це лише у 2d площині. Тяга має обмежуватися лише в одному напрямку відносно орієнтації судна, і не може бути спрямована без обертання безпілотника. Нехтуючи будь-яким опором, ви можете просто зробити вигляд, що він пливе навколо у 2d космічному просторі. Скажімо, дрон перевіряє рівняння на часовому інтервалі t(можливо, щось подібне кожні .01 секунди), підключає параметри і відповідно регулює його крутний момент і тягу. Якими повинні бути рівняння тяги та крутного моменту?


3
Якщо тяга може йти лише в одному напрямку, ви ніколи не збираєтесь змінювати напрямки.
MichaelHouse

1
Я повинен був би визначити більш чітко - ви не можете накидати тягу, тобто тяга може йти лише в одному напрямку відносно орієнтації судна. Ще можна обертати судно і змінювати напрямок тяги.
Гас

2
Чи пов’язане це питання з вузловим?
Сет Беттін

1
Тоді я думаю, що зможу розмістити гарне рішення для вас (трохи пізніше сьогодні ввечері). :)
Сет Беттін

1
Це питання потребує більш описової назви, але я не можу придумати гарного. Половина?
Анко

Відповіді:


5

Зважаючи на контекст вашого питання, http://nodewar.com/ , є кілька конкретних міркувань щодо вашого рішення:

  1. У вас (низька) максимальна кутова швидкість і достатній максимальний крутний момент, щоб досягти її за дуже короткий час.
  2. У кожного безпілотника і мішені швидкість і зовнішнє прискорення не пов'язані з поштовхом (гравітаційне безліч).
  3. Ваша бажана мета змінюється настільки часто, що намагатися досягти цілі було б марним. Вам слід спробувати наблизитися і виправити кожен кадр.

Ці методи - це те, що я вирішив працювати для досягнення бажаного прискорення.

Прискорення, а не швидкість

Оскільки у вас вже є задана швидкість, і ваша ціль рухається, вам не потрібна тяга до точки. Вам потрібна тяга, щоб змінити швидкість до такої, якою вона повинна бути. Це означає, що ваш корабель повинен вказувати не на те, куди він прямує, а в напрямку, в якому він повинен прискорюватися.

// My target velocity is for maintaining a circular orbit.  Yours may differ.
// Earlier, I calculated total gravity and the perpendicular direction.
// You may wish to subtract gravity from your total, rather than match it.
var targetVel = o.lib.vec.times(lateralDir, targetVelMag);

var targetAccel = lv.sum(
  o.lib.vec.diff(targetVel, o.me.vel), 
  o.lib.vec.times(gravity, 1 / o.me.mass)  
);

Спрямовуючи до правого заголовка

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

// convert acceleration to an angle
var polar = o.lib.vec.toPolar(targetAccel);
var traj = polar[1];

// constrain the angle to +/-2PI, because the ship's rotation is not limited 
// by default
var fixed_rot = o.lib.ang.rescale(o.me.rot);

// limit the correction to be +/-1PI
var traj_correction = traj - fixed_rot;
if (traj_correction > (Math.PI)){
  traj_correction = (2 * Math.PI) - traj_correction;
} else if (traj_correction < (-1 * Math.PI)){
  traj_correction = (2 * Math.PI) + traj_correction;
}

Проста формула. Немає ніякої шкоди в тому, щоб весь час повертати, тому не турбуйтеся застосовувати часткові значення крутного моменту. Якщо вам потрібна невелика корекція кутової швидкості, ви все одно зробите це визначення багато разів на секунду.

if (traj_correction > 0){
  torque = 1;
} else if (traj_correction < 0){
  torque = -1;
}

Менш проста формула. Настане момент, коли ви не хочете продовжувати повороти, тому що з часом хочете зупинитися. На щастя, така кутова швидкість швидкості означає, що ви можете швидко сповільнити з максимальної кутової швидкості до нуля. Вам потрібно лише розрахувати, коли це зробити.

var max_a_accel = c.MAX_TORQUE / o.me.m_i;
var a_deccel_time = Math.abs(o.me.a_vel) / max_a_accel;
// the same math as linear acceleration, now in angles.
var stopping_angle = 0.5 * max_a_accel * a_deccel_time * a_deccel_time;


if (stopping_angle >= Math.abs(traj_correction)){
  // slowdown required.  Reverse torque
  torque *= -1;
}

Після виправлення коду вище, щоб відповідати вашим потребам, ваш корабель повинен швидко і точно обертатися під будь-яким кутом, на який ви його націлили.

Швидкість таран

Отже, коли підштовхнути? Знову-таки, швидка зміна цілі та інші фактори створюють великі труднощі у вирішенні точного рішення. Не намагайся.

// if the heading is close to the final value, thrust.
if (Math.abs(traj_correction ) < 0.02) {  // about 1 degree
  if (true 
      // some logical test, in case you don't want to accelerate past
      // a maximum speed, or some such.  Not required for your stated purpose.
     ){
    thrust = 1;
  } 
}

У тих випадках, коли вам потрібна часткова тяга, ви можете знову покластися на те, що ви можете вибирати між 0 і 1 поштовхом багато разів на секунду. Це дає ефективну часткову тягу без зміни фактичного значення.

Удачі!


Чудово, дякую, це дуже допомагає. Мені доведеться трохи його змінити. Як називається ваш вид?
Гас

Я не штовхнув їх до драбини. У них немає способу нападу. :)
Сет Беттін

3

Подібне запитання, де є кілька хороших відповідей, включаючи очевидну назву всього цього предмета, "планування руху":
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

Як програмісту мені подобається практичність пропозицій user470365. Однак я прийму удар при більш жорсткому підході. Моя пропозиція тут обчислює повний план на початку, але, мабуть, ви могли б переоцінити так часто, як потрібно, якщо параметри змінюються.

План

  1. Поверніть у певному напрямку, d , і утримуйте цей напрямок.
  2. Дочекайтеся певного часу, t , тоді зробіть одну, стійку тягу до досягнення мети.

Деталі

Я пропоную ітеративні методи пошуку d і t :

  1. Якщо немає тяги, пройдіться по майбутній траєкторії безпілотника, використовуючи петлю та невеликий часовий крок:

    • Для положення та швидкості безпілотника в цей майбутній час знайдіть напрямок, d , такий, що стійкий поштовх приведе дрона до цілі. Зробіть це, відібравши вибірку напрямків від 0 до 360 градусів і знайдіть той, який в найкоротший час наблизить гул до цілі.
    • Перевірте, чи є у нас достатньо часу між тепер і цим майбутнім часом, щоб перейти до d . (Поворот нетривіальний. Дивіться обговорення наприкінці.)
    • Якщо у нас достатньо часу, то наш пошук завершений, тому вийдіть з цього циклу.
  2. Зараз ми знайшли d і t .

  3. Поверніться до d якомога швидше (знову дивіться обговорення нижче).
  4. Зачекайте, поки t , тоді запустіть стійку тягу.
  5. Дрон повинен врешті-решт потрапити в ціль.

Поворот

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


Цікавий підхід. Отже, що регулює наш вибір того майбутнього часу? Здається, що будь-яка методика визначення її має свої проблеми, тому ітерація може бути необхідною.
Гас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.