Digamos que eu tenha uma circular móvel target
definida como:
Vector2 position;
Vector2 velocity;
float radius;
E uma rotação turret
(montada em algum veículo em movimento) definida como:
Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second
(Ou algo nesse sentido. Observe que a posição e a velocidade de ambos são controladas em outros lugares - suponha que a velocidade seja constante e a posição mude com base na velocidade.)
Estou tentando escrever duas funções relacionadas à AI para determinar, em um determinado quadro:
Qual aceleração angular (e em qual direção) aplicar ao ângulo da torre para manter a torre apontando para o alvo?
Se o alvo estiver à vista no momento, ele (qualquer parte dentro do raio) pode ser mantido à vista por
x
segundos, ondex
fica uma fração de segundo? (Como alternativa: existe outra estratégia para garantir que o alvo esteja realmente "travado" e não simplesmente voando pelos locais?)
E eu poderia usar alguma ajuda ...
Respostas:
Primeiro, você precisa determinar a diferença de ângulo entre a direção da torre e a direção do alvo.
Depois de ter essas quantidades, você pode configurar uma expressão de segundo grau para o ângulo da torre. Você precisa calcular isso em cada atualização para garantir sempre o uso dos dados mais recentes de posições e velocidades.
Aqui, o primeiro termo (grau zero) na expressão de aceleração fará com que a torre comece a girar em direção ao alvo. No entanto, ele não para no tempo, mas oscila de um lado para o outro. Para fazê-lo parar, precisamos do amortecimento do segundo termo (primeiro grau), que faz com que uma alta velocidade de rotação seja oposta a uma alta aceleração.
Agora, as constantes positivas (não necessariamente constantes do programa) precisam ser determinadas e equilibradas para que o sistema se comporte bem.
C0
é o principal controle da velocidade do sistema. Um valor alto paraC0
dará uma velocidade de rotação rápida e um valor baixo dará uma velocidade de rotação baixa. O valor real depende de muitos fatores; portanto, você deve usar tentativa e erro aqui.C1
controla a magnitude do amortecimento. O discriminante da equação quadrática nos diz que seC1*C1 - 4*C0 >= 0
temos um sistema não-oscilante.Você provavelmente deve escolher
C1
um pouco maior que isso por razões numéricas, mas não muito grande, pois pode ficar muito úmido e lento para responder. Novamente, você precisa ajustar.Também é importante observar que esse código calcula apenas a aceleração angular. O ângulo e a velocidade angular precisam ser atualizados a partir disso em outro lugar, usando algum tipo de integrador. Da pergunta, presumo que isso tenha sido coberto.
Finalmente, há algo a dizer sobre o atraso, porque a torre provavelmente sempre estará para trás ao rastrear um alvo rápido. Uma maneira simples de resolver isso é adicionar uma previsão linear à posição do alvo, ou seja, sempre apontar um pouco à frente na direção para frente do alvo.
Quanto a manter a torre apontada dentro do raio do alvo por algum tempo, pode ser um requisito difícil de impor diretamente a esse tipo de sistema. Você pode ter certeza de que este controlador se esforçará para manter a torre apontada para o alvo (ou melhor, para a posição prevista) o tempo todo. Se o resultado acaba por não ser satisfatório você tem que modificar os parâmetros
predictionTime
,C0
eC1
(dentro de limites estáveis).fonte
k
) e C1 é o fator de amortecimento (geralmente chamado de 'B' ou 'c'). Portanto, sim, você pode minimizar a oscilação acionando o amortecimento, mas o problema é que isso não tenta antecipar onde o alvo estará , portanto está fadado a atrasar o objetivo desejado.O que você tem aqui é um problema de controle básico . A torre é o sistema, a aceleração é o controle e o sensor mede a posição / velocidade. Existem muitas maneiras de resolver esses problemas, pois é um problema muito bem estudado em engenharia.
A chave está finalizando com um sistema estável, ou seja, um sistema que não gera oscilações. Isso geralmente é feito adicionando amortecimento. A página da Wikipedia deve começar.
fonte
Primeiro, calcule o vetor da torre para o alvo. Em seguida, compare isso com o vetor atual da torre. Em seguida, use a diferença entre os dois para calcular a aceleração angular e a velocidade angular necessárias para fazer com que a torre gire para apontar na direção certa dentro de um determinado período de tempo.
OK, isso parecia simples. No entanto, você deve realmente tentar antecipar a posição do alvo, já que o alvo se moverá quando você girar a torre. Para fazer isso:-
onde P é a posição e V é a velocidade e o índice é d para o destino (alvo) es para a fonte (torre), que fornece um vetor de direção: -
onde D é um vetor de direção e Dsd 'é a direção necessária no tempo t. Agora, calcule a direção da torre com base na posição atual e velocidade e aceleração máximas por um determinado tempo t: -
Ds e Ds 'são as direções da fonte e Rs é a velocidade de rotação. Com tudo isso, você deseja encontrar t para quando Dsd '== Ds' e, portanto, Rs, a velocidade de rotação necessária. Não esqueça que todos os P's, D's e V's possuem componentes x e y.
Não levei em consideração a aceleração aqui - isso adiciona muito mais à complexidade. Depois de obter Rs e t, você provavelmente poderá aproximar um Rs parabólico (ou seja, acelerar e desacelerar) para obter o mesmo resultado.
fonte
O que você provavelmente está procurando aqui é um controlador PID , semelhante à resposta aceita nesta pergunta do SO
Inicialmente, eu respondi a essa pergunta "fazendo o meu próprio", mas essa resposta é significativamente mais completa e elegante.
fonte
A primeira coisa a fazer é calcular o ângulo entre o turrent e o objeto rastreado.
O próximo passo é verificar se, usando a velocidade atual do torrent e aplicando a aceleração máxima para trás (interrompendo o torrent), o torrent será interrompido antes ou depois do objeto rastreado.
Se a resposta for que o torrent irá parar antes do objeto rastreado, aplique a aceleração máxima para frente (velocidade crescente).
Se a resposta for que o torrent irá parar após o objeto rastreado, aplique a aceleração máxima para trás (interrompendo o torrent).
Dessa forma, o torrent sempre chegará mais rápido e parará no ponto certo (ou uma fração depois).
fonte