Implementación de navegación proporcional simple para un misil de referencia

8

Estoy tratando de implementar la forma más simple posible de navegación proporcional , es decir, el misil gira en la dirección en que cambia su rumbo hacia el objetivo, y una vez que su rumbo hacia el objetivo no cambia, está en curso de intercepción.

Entonces, tengo un misil 2d moviéndose a una velocidad constante en la dirección que está mirando, que puede girar a una velocidad constante, y cada intervalo actualizo el misil con algo como:

Position += VectorProduct (Direction * Speed * TimePassed)

PreviousTargetBearing = TargetBearing
TargetBearing = AngleBetween(TargetPosition, Position)
TargetBearingDelta = TargetBearing - PreviousTargetBearing

If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed

El problema es que el misil siempre oscila alrededor de su dirección de lanzamiento, porque tan pronto como el misil gira por primera vez, esto invierte el signo de TargetBearingDelta, haciéndolo girar en la dirección opuesta, y así sucesivamente ...

¿Cuál es la forma más simple de resolver este problema? Estoy seguro de que me falta algo simple.

Pregunta relacionada de StackOverflow: ¿Cómo crear un "misil de intercepción" para un juego?

Para reiterar, estoy interesado específicamente en implementar el algoritmo de navegación proporcional , no en los algoritmos de referencia en general.


Actualización: supongo que la respuesta obvia es no verificar el rumbo y ajustar el rumbo cada turno, sino alternar entre los dos. Lo intentaré

e100
fuente

Respuestas:

1

Paso 1) Calcule el tiempo hasta el objetivo si va en línea recta

Paso 2) Calcule dónde estará el objetivo con su rumbo actual en ese momento.

Paso 3) Establecer el rumbo del misil para que sea ese lugar.

Paso 4) Actualice según sea necesario

Al principio, esto no será muy preciso, pero a medida que la distancia se cierre será más precisa; A medida que el tiempo de viaje llega a cero, el punto objetivo para el misil se acerca al objetivo.

Dale un giro. Es lo suficientemente simple de implementar. Déjame saber cómo funciona porque quiero poner misiles guiados en mi juego y este fue mi primer pensamiento.

Y para esta parte:

If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed

En cambio, tendría dos variables missileDirection. Uno para lo que realmente es, y otro para lo que debería ser en el futuro. Entonces, el movimiento del misil se dirige hacia el rumbo deseado por su velocidad de giro. Si el rumbo deseado es más grande que el rumbo actual, agregue la velocidad de giro. Si es más pequeño, resta. Si pasa, póngalo igual.

Azaral
fuente
¿Esto no parece estar usando el método de navegación proporcional?
e100
No, pero debería tener el mismo efecto. Esto trazará un curso de intercepción entre el misil y el objetivo. El propósito de la navegación es que el misil intercepte el objetivo. El proceso anterior debería hacer eso. Querías simple.
Azaral
Punto justo, +1 para usted
e100
Si lo intentas, házmelo saber cómo va. Este era mi plan para dirigir misiles en mi juego; Simplemente no he llegado a programar el misil todavía.
Azaral
He implementado este método por ahora y funciona bien. No creo que pueda aceptar esta respuesta, ya que no está lo suficientemente cerca de lo que quiero terminar, pero muchas gracias.
e100
4

Como dice Nailer, puedes limitar el cambio de movimiento de alguna manera.

Echa un vistazo a PID , una buena manera de hacer que las cosas se muevan rápidamente a un cierto "valor", pero sin excederlo, podría darte algunas ideas.

También puede consultar esta pregunta , un poco abajo es una explicación de la "curva del perro", un algoritmo de referencia muy preciso utilizado por los perros.

Valmond
fuente
Puedo ver que necesito algún tipo de circuito de control de retroalimentación amortiguado una vez que el misil está siguiendo el objetivo, pero creo que tengo un problema inicial más simple ya que el misil simplemente oscila en la dirección de lanzamiento inicial. Solo para enfatizar, definitivamente quiero usar el algoritmo de navegación proporcional.
e100
Aunque PID es un buen instrumento, es difícil de ajustar ... pero una vez que se encuentran los tres parámetros (si uno requiere tres), tiene una solución para ese mecanismo específico. +1 de mi lado.
teodron el
gracias teodron ;-) @ e100: si quieres hacer que el misil vaya "hacia adelante" cuando se hacen los cálculos y el objetivo está en un movimiento constante, mira el ejemplo de la "curva del perro", ya que hace exactamente eso. De lo contrario, su 'TurnRate' es igual a la 'P' (IIRC) en PID, puede calcularlo sobre la marcha, digamos el 10% de la diferencia y no un valor fijo. Si está 2 ° fuera del curso, no necesita el mismo cambio que si está 20 ° fuera.
Valmond
1

En mi opinión, habría otro método que involucrara dos vectores, uno para la dirección para que un misil golpee, y otro para él mismo (o digamos que la transición de su dirección coincida con el primer vector).

De esta manera, podemos producir un tiempo de retraso que permita que un misil cambie suavemente su dirección de acuerdo con un cambio en un primer vector. Creo que eliminará el problema en el "signo" de la operación matemática.

PD. El punto principal es que derivamos el propio vector de un misil a un vector direccional (para golpear) con respecto a un pequeño retraso en el tiempo.

haxpor
fuente
Tenga en cuenta que, aunque este enfoque puede producir resultados, esto le daría al misil un tiempo de giro constante (en lugar de una velocidad de giro constante ), a menos que recalcule la velocidad de interpolación de cada cuadro en función de la distancia de giro que aún tiene que recorrer para producir un Velocidad de giro constante.
doppelgreener
¡Necesito buscar en "lerping"!
e100
1

La navegación proporcional es fácil de implementar en los juegos.

Un ejemplo de implementación en el juego es:

Aceleración requerida = LOS * LOS_Rate * NC + APN_bias

LOS = Vector3 (TargetPosition) - Vector3 (MissilePosition)

NC = multiplicador constante de navegación (dependiendo de la velocidad de fotogramas)

APN_bias = LOS_Rate / delta_T * (NC / 2)

LOS_Rate = LOS Rotation Rate es la tasa angular de cambio en la línea de visión entre el misil y el objetivo. Esto se mide registrando el misil y el vector objetivo posiciona cada cuadro en delta_T, y restando cada uno para obtener la diferencia. Delta_T es la referencia de tiempo (es decir, la velocidad de fotogramas) a la que se ejecuta su misil de referencia en el juego.

Para obtener LOS_Rate, simplemente haga que su bucle de guía de misiles haga lo siguiente en cada cuadro (delta_T):

// New LOS rate

LOS_Delta = Vector3( LOS ) - Vector3( LOS_previous_frame ) 

LOS_Rate = LOS_Delta.Vector3Length()

// Update LOS before we finish

LOS_previous_frame = Vector3( LOS )

Puede encontrar más información sobre cómo implementamos PN para el juego World in Conflict en las siguientes URL a continuación. Espero que encuentres estos útiles.

http://www.moddb.com/mods/wicmw/features/flint-lead-pursuit-guidance-principles

http://download.wicmwmod.com/Fun_Mod/presentations/FLINT%20Jul%202012.pdf

-blahdy

James
fuente
0

¿No puedes limitar la velocidad de giro para que nunca pueda pasar TargetBearing en un cuadro?

Si un giro hace que el misil gire más allá de su rumbo objetivo, simplemente establece el nuevo rumbo igual al rumbo objetivo.

¿Tiene sentido?

Fabricante de clavos
fuente
No, no lo creo. La idea no es girar el misil hacia TargetBearing, sino girar en la dirección en que TargetBearing está cambiando.
e100
Okay. Supongo que no entendí bien.
Nailer