Celowanie dronów

9

Wyobraź sobie „drona” i punkt docelowy na płaszczyźnie 2D. Istnieje osiem parametrów:

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

(powiemy tylko, że cel jest nieruchomy)

Zadaniem drona jest jak najszybsze dotarcie do celu, przestrzegając maksymalnego momentu obrotowego i maksymalnego ciągu. Istnieją tylko dwa sposoby zastosowania momentu obrotowego, ponieważ odbywa się to tylko w płaszczyźnie 2d. Ciąg jest ograniczony do poruszania się tylko w jednym kierunku względem orientacji jednostki i nie może być wycelowany bez obracania drona. Zlekceważąc opór, możesz po prostu udawać, że unosi się w przestrzeni kosmicznej 2d. Powiedzmy, że dron sprawdza równanie w przedziale czasowym t(może mniej więcej co 0,01 sekundy), podłącza parametry i odpowiednio dostosowuje swój moment obrotowy i ciąg. Jakie powinny być równania dla ciągu i momentu obrotowego?

Gus
źródło
3
Jeśli ciąg może iść tylko w jednym kierunku, nigdy nie zmienisz kierunku.
MichaelHouse
1
Powinienem był sprecyzować - nie można przegubić pchnięcia, tzn. Pchnięcie może iść tylko w jednym kierunku w stosunku do orientacji jednostki. Nadal możesz obracać pojazd i zmieniać kierunek ciągu.
Gus
2
Czy to pytanie dotyczy nodewaru?
Seth Battin,
1
Więc myślę, że mogę opublikować dobre rozwiązanie dla ciebie (nieco później wieczorem). :)
Seth Battin
1
To pytanie wymaga bardziej opisowego tytułu, ale nie mogę wymyślić dobrego. Halp?
Anko

Odpowiedzi:

5

W świetle kontekstu pytania, http://nodewar.com/ , istnieje kilka szczegółowych uwag dotyczących twojego rozwiązania:

  1. Masz (niską) maksymalną prędkość kątową i wystarczający maksymalny moment obrotowy, aby ją osiągnąć w bardzo krótkim czasie.
  2. Zarówno twój dron, jak i cel mają prędkość i przyspieszenie zewnętrzne niezwiązane z pchnięciem (obfituje grawitacja).
  3. Wybrany cel zmienia się tak często, że próba doskonałego celu byłaby stratą. Powinieneś spróbować zbliżyć się i poprawić go co klatkę.

Metody te postanowiłem wykorzystać do osiągnięcia pożądanego przyspieszenia.

Przyspieszenie, a nie prędkość

Ponieważ masz już określoną prędkość, a twój cel się porusza, nie potrzebujesz pchnięcia w kierunku punktu. Potrzebujesz ciągu, aby zmienić prędkość na taką, jaka powinna być. Oznacza to, że twój statek musi wskazywać nie w kierunku, w którym zmierza, ale w kierunku, w którym powinien przyspieszyć.

// 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)  
);

Kierowanie w prawo

Masz wektor przyspieszenia, teraz chcesz go zastosować. Określ, jak daleko trzeba obrócić. Prawdopodobnie użyłem więcej kroków, niż jest to wymagane, ale wprawiają mnie w zakłopotanie współrzędne i myślę, że nielimitowana wartość obrotu statku i tak jest błędem w 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;
}

Prosta formuła. Cały czas obracanie jest bezpieczne, więc nie zawracaj sobie głowy zastosowaniem częściowych wartości momentu obrotowego. Jeśli potrzebujesz niewielkiej korekty prędkości kątowej, i tak możesz to ustalić wiele razy na sekundę.

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

Mniej prosta formuła. Nadejdzie moment, w którym nie będziesz chciał kontynuować skręcania, ponieważ w końcu chcesz przestać. Na szczęście to ograniczenie prędkości kątowej oznacza, że ​​możesz szybko zwolnić od maksymalnej prędkości kątowej do zera. Musisz tylko obliczyć, kiedy to zrobić.

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;
}

Po poprawieniu powyższego kodu, aby dopasować go do twoich potrzeb, twój statek powinien szybko i precyzyjnie obrócić się pod dowolnym kątem, który podałeś do celu.

Szybkość taranowania

Kiedy więc pchnąć? Ponownie szybka zmiana celu i inne czynniki powodują ogromne trudności w rozwiązaniu dokładnego rozwiązania. Nie próbuj.

// 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;
  } 
}

W przypadkach, w których potrzebujesz częściowego ciągu, możesz ponownie polegać na tym, że możesz wybierać między 0 a 1 ciągiem wiele razy na sekundę. Zapewnia to efektywny ciąg cząstkowy bez zmiany rzeczywistej wartości.

Powodzenia!

Seth Battin
źródło
Świetnie, dzięki, to bardzo pomaga. Myślę, że będę musiał to trochę zmodyfikować. Jak nazywa się twój gatunek?
Gus
Nie zepchnąłem ich na drabinę. Nie mają metody ataku. :)
Seth Battin
3

Podobne pytanie, z kilkoma dobrymi odpowiedziami, w tym pozorną nazwą tego całego tematu, „planowanie ruchu”:
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

Jako programista podoba mi się praktyczność sugestii użytkownika user470365. Jednak poddam się bardziej rygorystycznemu podejściu. Moja propozycja tutaj oblicza pełny plan na początku, ale przypuszczam, że możesz zmienić ocenę tak często, jak to pożądane, jeśli parametry się zmieniają.

Plan

  1. Skręć w określonym kierunku, d i przytrzymaj ten kierunek.
  2. Czekać do pewnego czasu t , po czym do jednego przedłużonym nacisk aż zostanie osiągnięta.

Detale

Sugeruję iteracyjne metody znajdowania d i t :

  1. Zakładając brak ciągu, przemierzaj przyszłą trajektorię drona za pomocą pętli i małego pomiaru czasu:

    • Dla pozycji i prędkości drona w tym przyszłym czasie znajdź kierunek d , taki, aby ciągły ciąg doprowadził drona do celu. Zrób to, próbkując wiele kierunków w zakresie od 0 do 360 stopni i znajdując taki, który w najbliższym czasie zbliży drona do celu.
    • Sprawdź, czy mamy wystarczająco dużo czasu między teraz a przyszłym czasem, aby przejść do d . (Toczenie nie jest trywialne. Zobacz dyskusję na końcu.)
    • Jeśli mamy wystarczająco dużo czasu, nasze wyszukiwanie jest zakończone, więc wyrwij się z tej pętli.
  2. Znaleźliśmy teraz d i t .

  3. Skręć w d tak szybko, jak to możliwe (ponownie, patrz dyskusja poniżej).
  4. Poczekaj, aż t , a następnie rozpocznij ciągły ciąg.
  5. Dron powinien ostatecznie trafić w cel.

Obrócenie

Kiedy mówię „obróć na d ”, mam na myśli „zrób sekwencję momentów obrotowych, aby obrócić do d tak szybko, jak to możliwe, jednocześnie zmniejszając prędkość kątową do zera”. Prawdopodobnie istnieje równanie dla tego obejmujące kierunek prądu, bieżącą prędkość kątową i maksymalne przyspieszenie kątowe, ale komplikuje to zachowanie zawijania kątów.

Eric Undersander
źródło
Ciekawe podejście Co zatem rządzi naszym wyborem tego przyszłego czasu? Wygląda na to, że każda technika ma swoje problemy, więc iteracja też może być konieczna.
Gus,