Drone targeting

9

Imagine un "dron" y un punto objetivo en un plano 2D. Hay ocho parámetros:

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

(solo diremos que el objetivo es estacionario)

El trabajo del dron es llegar al objetivo lo más rápido posible, obedeciendo el par máximo y el empuje máximo. Solo hay dos formas de aplicar el par, ya que esto es solo en un plano 2d. El empuje está restringido para ir solo en una dirección en relación con la orientación de la nave, y no puede apuntar sin girar el dron. Descuida cualquier resistencia, solo puedes fingir que está flotando en el 2d espacio exterior. Digamos que el dron verifica una ecuación en el intervalo de tiempo t(tal vez algo así como cada 0,01 segundos), conecta los parámetros y ajusta su par y empuje en consecuencia. ¿Cuáles deberían ser las ecuaciones de empuje y par?

Gus
fuente
3
Si el empuje solo puede ir en una dirección, nunca cambiarás de dirección.
MichaelHouse
1
Debería haber especificado más claramente: no se puede hacer cardán el empuje, es decir, el empuje solo puede ir en una dirección en relación con la orientación de la nave. Todavía puede girar la nave y cambiar la dirección de empuje.
Gus
2
¿Esta pregunta está relacionada con nodewar?
Seth Battin
1
Entonces creo que puedo publicar una buena solución para usted (un poco más tarde esta noche). :)
Seth Battin
1
Esta pregunta necesita un título más descriptivo, pero no puedo pensar en uno bueno. Halp?
Anko

Respuestas:

5

A la luz del contexto de su pregunta, http://nodewar.com/ , hay un par de consideraciones específicas para su solución:

  1. Tiene una velocidad angular máxima (baja) y suficiente par máximo para alcanzarla en muy poco tiempo.
  2. Tu dron y objetivo tienen velocidad y aceleración externa no relacionadas con el empuje (abunda la gravitación).
  3. Su objetivo deseado cambia con tanta frecuencia que tratar de apuntar perfectamente sería un desperdicio. Debes intentar acercarte y corregirlo en cada cuadro.

Estos métodos son los que decidí trabajar para alcanzar la aceleración deseada.

Aceleración, no velocidad

Como ya tiene una velocidad determinada y su objetivo se está moviendo, no necesita empujar hacia un punto. Necesita empuje para cambiar su velocidad a lo que debería ser. Esto significa que su nave necesita apuntar no hacia dónde va, sino en la dirección en la que debe acelerar.

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

Dirección hacia la derecha

Tienes un vector de aceleración, ahora quieres aplicarlo. Determine qué tan lejos necesita rotar. Probablemente usé más pasos de los requeridos aquí, pero las coordenadas de rotación me confunden, y creo que el valor de rotación de la nave sin tapar es un error en la API de todos modos.

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

Una formula simple. No hay daño en girar todo el tiempo, así que no se moleste en aplicar valores par parciales. Si necesita una pequeña corrección en la velocidad angular, puede hacer esta determinación muchas veces por segundo, de todos modos.

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

Una fórmula menos simple. Llegará un punto en el que no querrás seguir girando, porque eventualmente quieres detenerte. Afortunadamente, ese límite de velocidad angular significa que puede reducir rápidamente la velocidad angular máxima a cero. Solo necesita calcular cuándo hacerlo.

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

Después de ajustar el código anterior para satisfacer sus necesidades, su nave debe rotar rápida y precisamente a cualquier ángulo que le haya dado al objetivo.

Velocidad de embestida

Entonces, ¿cuándo empujar? Nuevamente, el rápido cambio del objetivo y otros factores crean una gran dificultad para resolver una solución exacta. No lo intentes

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

Para aquellos casos en los que necesita un empuje parcial, puede confiar nuevamente en el hecho de que puede elegir entre 0 y 1 empuje muchas veces por segundo. Esto le proporciona un empuje parcial efectivo sin variar el valor real.

¡Buena suerte!

Seth Battin
fuente
Genial, gracias, esto ayuda mucho. Tendré que modificarlo un poco, creo. ¿Cómo se llama tu especie?
Gus
No los he empujado a la escalera. No tienen método para atacar. :)
Seth Battin
3

Una pregunta similar, con algunas buenas respuestas, incluido el nombre aparente de todo este tema, "planificación de movimiento":
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

Como programador, me gusta la practicidad de la sugerencia de user470365. Sin embargo, intentaré un enfoque más riguroso. Mi sugerencia aquí calcula un plan completo al comienzo, pero supongo que podría volver a evaluar con la frecuencia que desee si los parámetros están cambiando.

El plan

  1. Gire a cierta dirección, d , y mantenga esa dirección.
  2. Espere hasta cierto tiempo, t , luego haga uno, empuje sostenido hasta alcanzar el objetivo.

Detalles

Sugiero métodos iterativos para encontrar d y t :

  1. Asumiendo que no hay empuje, recorre la trayectoria futura del dron usando un bucle y un pequeño paso de tiempo:

    • Para la posición y velocidad del dron en este momento futuro, encuentre la dirección, d , de modo que un empuje sostenido lleve el dron al objetivo. Para ello, muestrea muchas direcciones entre 0 y 360 grados y encuentra la que acerque el dron al objetivo en el menor tiempo posible.
    • Verifique si tenemos suficiente tiempo entre ahora y este tiempo futuro para pasar a d . (Girar no es trivial. Ver discusión al final).
    • Si tenemos suficiente tiempo, entonces nuestra búsqueda está completa, así que salga de este ciclo.
  2. Ahora hemos encontrado d y t .

  3. Vaya a d lo más rápido posible (nuevamente, vea la discusión a continuación).
  4. Espere hasta t , luego comience el empuje sostenido.
  5. El dron eventualmente debería dar en el blanco.

Torneado

Cuando digo "girar a d ", realmente quiero decir, "hacer una secuencia de pares de tal manera que giremos hacia d lo más rápido posible mientras también llevamos la velocidad angular a cero". Probablemente hay una ecuación para esto que involucra la dirección actual, la velocidad angular actual y la aceleración angular máxima, pero se complica por el comportamiento envolvente de los ángulos.

Eric Undersander
fuente
Enfoque interesante Entonces, ¿qué rige nuestra selección de ese tiempo futuro? Parece que cualquier técnica para determinar que tiene sus problemas, por lo que la iteración allí también podría ser necesaria.
Gus