Segmentação por drone

9

Imagine um "drone" e um ponto de destino em um avião 2D. Existem oito 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

(diremos apenas que o alvo está parado)

O trabalho do drone é chegar ao alvo o mais rápido possível, obedecendo ao torque máximo e ao empuxo máximo. Existem apenas duas maneiras de aplicar o torque, uma vez que este é apenas em um plano 2D. O impulso é restrito a seguir apenas uma direção em relação à orientação da nave e não pode ser apontado sem a rotação do drone. Negligencie qualquer resistência, você pode apenas fingir que está flutuando no espaço 2d. Digamos que o drone verifique uma equação no intervalo de tempo t(talvez algo como 0,01 segundos), conecte os parâmetros e ajuste seu torque e pressão de acordo. Quais devem ser as equações de empuxo e torque?

Gus
fonte
3
Se o impulso puder ir em uma direção, você nunca mudará de direção.
MichaelHouse
11
Eu deveria ter especificado com mais clareza - você não pode cardar o impulso, ou seja, o impulso só pode ir em uma direção em relação à orientação da nave. Você ainda pode girar a nave e mudar a direção do impulso.
quer
2
Esta pergunta está relacionada à guerra de nós?
Seth Battin
11
Então acho que posso postar uma boa solução para você (um pouco mais tarde esta noite). :)
Seth Battin
11
Esta pergunta precisa de um título mais descritivo, mas não consigo pensar em um bom. Halp?
Anko

Respostas:

5

À luz do contexto da sua pergunta, http://nodewar.com/ , existem algumas considerações específicas para sua solução:

  1. Você tem uma velocidade angular máxima (baixa) e torque máximo suficiente para alcançá-la em um tempo muito curto.
  2. Seu drone e seu alvo têm velocidade e aceleração externa não relacionadas ao empuxo (a gravitação é abundante).
  3. Seu alvo desejado muda com tanta frequência que tentar mirar perfeitamente seria um desperdício. Você deve tentar se aproximar e corrigi-lo em todos os quadros.

Esses métodos são os que eu decidi trabalhar para alcançar a aceleração desejada.

Aceleração, não velocidade

Como você já tem uma velocidade determinada e seu alvo está se movendo, não precisa ser empurrado em direção a um ponto. Você precisa se esforçar para mudar sua velocidade para o que deveria ser. Isso significa que sua nave precisa apontar não para onde está indo, mas na direção em que deve 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)  
);

Dirigindo na direção certa

Você tem um vetor de aceleração, agora deseja aplicá-lo. Determine a distância que você precisa girar. Provavelmente usei mais etapas do que o necessário aqui, mas as coordenadas de rotação me confundem e, de qualquer maneira, acho que o valor de rotação de navio sem limite é um bug na 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;
}

Uma fórmula simples. Não há mal em girar o tempo todo, portanto, não se preocupe em aplicar valores de torque parciais. Se você precisar de uma pequena correção na velocidade angular, faça essa determinação muitas vezes por segundo, de qualquer maneira.

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

Uma fórmula menos simples. Chegará um ponto em que você não deseja continuar girando, porque eventualmente quer parar. Felizmente, esse limite de velocidade angular significa que você pode diminuir rapidamente a velocidade angular máxima para zero. Você só precisa calcular quando fazer isso.

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

Depois de ajustar o código acima para atender às suas necessidades, seu navio deve girar rápida e precisamente para qualquer ângulo que você der ao alvo.

Velocidade de percussão

Então, quando empurrar? Novamente, a mudança rápida do alvo e outros fatores criam grande dificuldade na resolução de uma solução exata. Não tente.

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

Nos casos em que você precisa de impulso parcial, pode confiar novamente no fato de poder escolher entre 0 e 1 impulso várias vezes por segundo. Isso fornece um impulso parcial efetivo sem variar o valor real.

Boa sorte!

Seth Battin
fonte
Ótimo, obrigado, isso ajuda muito. Vou ter que modificá-lo um pouco, eu acho. Qual o nome da sua espécie?
Gus
Eu não os empurrei para a escada. Eles não têm método para atacar. :)
Seth Battin
3

Uma pergunta semelhante, com algumas boas respostas, incluindo o nome aparente de todo esse assunto, "planejamento de movimento":
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

Como programador, gosto da praticidade da sugestão de user470365. No entanto, vou tentar uma abordagem mais rigorosa. Minha sugestão aqui calcula um plano completo no início, mas suponho que você possa reavaliar quantas vezes desejar, se os parâmetros estiverem mudando.

O plano

  1. Gire para uma certa direção, d , e mantenha-a nessa direção.
  2. Espere até um certo tempo, t , depois faça um impulso sustentado até que o alvo seja alcançado.

Detalhes

Sugiro métodos iterativos para encontrar d e t :

  1. Sem pressões, percorra a trajetória futura do drone usando um loop e um pequeno passo no tempo:

    • Para a posição e velocidade do drone neste momento futuro, encontre a direção, d , de modo que um impulso sustentado leve o drone ao alvo. Faça isso amostrando muitas direções entre 0 e 360 ​​graus e encontrando a que aproxima o drone do alvo no menor tempo possível.
    • Verifique se temos tempo suficiente entre agora e o futuro para voltar para d . (Virar não é trivial. Veja a discussão no final.)
    • Se tivermos tempo suficiente, nossa pesquisa será concluída, portanto, saia deste ciclo.
  2. Agora encontramos d e t .

  3. Vá para d o mais rápido possível (novamente, consulte a discussão abaixo).
  4. Aguarde t , depois inicie o impulso sustentado.
  5. O drone deve eventualmente atingir o alvo.

Girando

Quando digo "vire para d ", quero dizer realmente, "faça uma sequência de torques de tal forma que giremos para d o mais rápido possível, além de levar a velocidade angular a zero". Provavelmente existe uma equação para isso envolvendo a direção atual, a velocidade angular da corrente e a aceleração angular máxima, mas é complicado pelo comportamento de quebra dos ângulos.

Eric Undersander
fonte
Abordagem interessante. Então, o que governa nossa seleção daquele tempo futuro? Parece que qualquer técnica para determinar se tem seus problemas; portanto, a iteração pode ser necessária também.
Gus