Implementando navegação proporcional simples para um míssil

8

Estou tentando implementar a forma mais simples possível de navegação proporcional , ou seja, o míssil gira na direção em que seu rumo ao alvo está mudando e, uma vez que o rumo ao alvo é imutável, ele está em um curso de interceptação.

Então, eu tenho um míssil 2D movendo-se a uma velocidade constante na direção em que está voltado, o que pode girar a uma taxa constante, e a cada intervalo eu atualizo o míssil com 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

O problema é que o míssil sempre oscila em sua direção de lançamento, porque assim que o míssil gira pela primeira vez, isso reverte o sinal de TargetBearingDelta, fazendo com que ele gire na direção oposta e assim por diante ...

Qual é a maneira mais simples de resolver esse problema? Tenho certeza de que estou perdendo algo simples.

Pergunta relacionada ao StackOverflow: Como criar um "míssil de interceptação" para um jogo?

Para reiterar, estou interessado especificamente na implementação do algoritmo de navegação proporcional , não nos algoritmos de retorno em geral.


Atualização: Eu acho que a resposta óbvia é não verificar o rumo e ajustar o rumo a cada turno, mas alternar entre os dois. Eu vou tentar isso.

e100
fonte

Respostas:

1

Etapa 1) Calcule o tempo para segmentar se estiver em linha reta

Etapa 2) Calcule onde o alvo estará com o rumo atual naquele momento.

Etapa 3) Defina o cabeçalho do míssil para ser esse ponto.

Etapa 4) Atualize conforme necessário

No início, isso não será muito preciso, mas à medida que a distância se aproxima, ela se torna mais precisa; À medida que o tempo de viagem chega a zero, o local alvo do míssil se aproxima do alvo.

Dê um giro nisso. É simples de implementar. Deixe-me saber como funciona, porque quero colocar mísseis no meu jogo e esse foi o meu primeiro pensamento.

E para esta parte:

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

Em vez disso, eu teria duas variáveis ​​missileDirection. Um pelo que realmente é e outro pelo que deveria ser no futuro. Então, o movimento do míssil está indo na direção desejada pela sua taxa de turno. Se o título desejado for maior que o título atual, adicione a taxa de conversão. Se for menor, subtraia. Se você passar, defina-o igual.

Azaral
fonte
Isso não parece estar usando o método de navegação proporcional?
e100
Não, mas deve ter o mesmo efeito. Isso traçará um curso de interceptação entre o míssil e o alvo. O objetivo da navegação é o míssil interceptar o alvo. O processo acima deve fazer isso. Você queria simples.
Azaral
Ponto justo, +1 para você
e100
Se você tentar, deixe-me saber como vai. Este era o meu plano para o lançamento de mísseis no meu jogo; Ainda não consegui programar o míssil ainda.
Azaral
Eu implementei esse método por enquanto e funciona bem. Acho que não posso aceitar essa resposta, pois ela não é suficientemente próxima do que quero terminar, mas muito obrigado.
e100
4

Como diz Nailer, você pode limitar a mudança de movimento de alguma maneira.

Confira o PID , uma ótima maneira de fazer as coisas mudarem rapidamente para um certo "valor", mas sem superá-lo, isso pode lhe dar algumas idéias.

Você também pode verificar esta pergunta , um pouco abaixo é uma explicação da "curva do cão", um algoritmo de retorno muito preciso usado pelos cães.

Valmond
fonte
Percebo que preciso de alguma forma de loop de controle de feedback amortecido quando o míssil estiver rastreando o alvo, mas acho que tenho um problema inicial mais simples, pois o míssil oscila apenas na direção inicial de lançamento. Só para enfatizar, eu definitivamente quero usar o algoritmo de navegação proporcional.
e100
Embora o PID seja um bom instrumento, é difícil ajustar .. mas uma vez que os três parâmetros (se um exigir três) são encontrados, você tem uma solução para esse mecanismo específico. +1 do meu lado.
Teodron # 25/12
obrigado teodron ;-) @ e100: se você quiser fazer o míssil "seguir em frente" quando os cálculos forem feitos e o alvo estiver em movimento constante, verifique o exemplo da 'curva do cão', como faz exatamente isso. Caso contrário, seu 'TurnRate' é igual ao 'P' (IIRC) no PID, você pode calculá-lo em tempo real, digamos 10% da diferença e não um valor fixo. Se você estiver a 2 ° de distância do curso, não precisará da mesma alteração como se estivesse a 20 ° de distância.
Valmond
1

Na minha opinião, haveria outro método envolvendo dois vetores, um para a direção de um míssil, e outro para ele mesmo ler (ou dizer, mudar sua direção para corresponder ao primeiro vetor).

Dessa forma, podemos produzir um tempo de latência, permitindo que um míssil mude sua direção suavemente de acordo com uma mudança no primeiro vetor. Eu acredito que ele removerá o problema no "sinal" da operação matemática.

PS. O ponto principal é que transferimos o vetor de um míssil para um vetor direcional (a ser atingido) em relação a algum pequeno atraso no tempo.

haxpor
fonte
Observe que, embora essa abordagem possa produzir resultados, isso daria ao míssil um tempo de giro constante (em vez de uma velocidade de giro constante ) - a menos que você recalcule a taxa de interpolação de cada quadro com base na distância de giro ainda a percorrer para produzir um velocidade de rotação constante.
Doppelgreener
Eu preciso pesquisar em "lerping"!
e100
1

A navegação proporcional é simples de implementar nos jogos.

Um exemplo de implementação no jogo é:

Aceleração necessária = LOS * LOS_Rate * NC + APN_bias

LOS = Vetor3 (TargetPosition) - Vetor3 (MissilePosition)

NC = Multiplicador constante de navegação (dependendo da taxa de quadros em execução)

APN_bias = LOS_Rate / delta_T * (NC / 2)

LOS_Rate = LOS Rotation Rate é a taxa angular de mudança na linha de visão entre o míssil e o alvo. Isso é medido registrando o míssil e o vetor alvo, posicionando todos os quadros em delta_T e subtraindo cada um para obter a diferença. Delta_T é a referência de tempo (ou seja, taxa de quadros) na qual seu míssil está em execução no jogo.

Para obter o LOS_Rate, basta fazer com que seu loop de orientação de mísseis faça o seguinte em cada quadro (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 )

Você pode encontrar mais informações sobre como implementamos o PN para o jogo World in Conflict nos seguintes URLs abaixo. Espero que você ache isso útil.

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
fonte
0

Você não pode limitar a taxa de turno para que ela nunca ultrapasse o TargetBearing em um quadro?

Se um turno fizer o míssil girar além do alvo, basta definir o novo rumo igual ao rumo do alvo.

Isso faz sentido?

Nailer
fonte
Não, eu não penso assim. A ideia não é transformar o míssil em direção ao TargetBearing, mas sim na direção em que o TargetBearing está mudando.
e100
Está bem. Acho que não entendi.
quer