Come si può impedire ai missili homing di orbitare attorno ai loro obiettivi?


78

Sto sviluppando un gioco spaziale 2D senza attriti e sto trovando molto facile far orbitare un missile homing sul suo obiettivo. Sono curioso di conoscere le strategie anti-orbitanti.

Un semplice esempio è un missile homing che accelera semplicemente direttamente verso il suo obiettivo. Se quel bersaglio dovesse spostarsi perpendicolarmente alla traiettoria del missile, quindi fermarsi, l'accelerazione del missile verso il bersaglio non sarebbe sufficiente per superare la sua stessa velocità e il missile potrebbe essere guidato in orbita attorno al bersaglio, come illustrato:

Problema orbitante

  • Nel frame 1, il missile sta andando dritto verso il suo obiettivo, senza problemi.
  • Nel frame 2, il bersaglio si è spostato in una nuova posizione, come dimostrato. Il missile continua ad accelerare direttamente verso il bersaglio (in rosso), mentre si sposta ancora verso il bersaglio (in nero) a causa della sua velocità esistente.
  • Nel frame 3, la velocità del missile continua a trasportare il missile attorno al lato del bersaglio (nero) mentre il vettore di accelerazione cerca disperatamente di tirare il missile verso il bersaglio.
  • Nei frame 4 e oltre, il missile cade in un'orbita potenzialmente stabile attorno al bersaglio e non raggiunge mai il suo obiettivo. Le frecce nere indicano un vettore di velocità mentre le linee rosse indicano i vettori di accelerazione nello stesso momento nel tempo.

Considerando che non c'è attrito nello spazio, non c'è nulla che possa rallentare la velocità del missile e far crollare l'orbita. Una possibile soluzione sarebbe quella di mirare "dietro" l'obiettivo, e ciò causerebbe la chiusura dell'orbita, ma come si fa dal punto di vista della programmazione?

Come faccio a fare in modo che un missile homing raggiunga il suo obiettivo?


9
Questo è in realtà un modo estremamente interessante di creare orbite.
Derek,

Questo mi ricorda l'integrazione di Eulero. Tutto quello che devi fare è rendere il tuo passo del tempo infinitamente piccolo, risolto il problema!
Jeff,

Voglio implementare questo effetto nel mio gioco! : D
Zolomon


6
@Deza È la definizione stessa di orbita. L'oggetto in orbita sta accelerando con una forza centripeta, verso il centro di qualche altro oggetto.
bobobobo,

Risposte:


49

Prima di tutto, si dovrebbe fare tutti i calcoli su ciò che l'accelerazione da applicare in del missile quadro di riferimento (che è dove il missile è fermo e tutto il resto si muove intorno ad esso, anche spesso chiamato "coordinate oggetto" o "coordinate locali" in motori di gioco, sebbene nel nostro caso vogliamo che anche la velocità sia esattamente zero).

L'idea non è quindi quella di mirare al bersaglio, ma di mirare al luogo in cui il bersaglio sarà al momento stimato dell'impatto. Quindi l'algoritmo generale è simile al seguente:

  1. Stimare quanto tempo impiegherà il missile a raggiungere l'obiettivo. Se il bersaglio vola direttamente verso di esso (ricorda, il missile è fermo ), può essere semplice come calcolare distanza / velocità , in altri casi può essere più complicato. Se il bersaglio può tentare di evadere, non sarai comunque in grado di fare una stima perfetta, quindi va bene non essere molto preciso.

  2. Supponendo che la velocità costante (stima di 1 ° grado) o l'accelerazione costante (stima di 2 ° grado) dell'obiettivo, calcolare dove si troverà al tempo stimato sopra.

  3. Calcola l'accelerazione che porterà il missile a trovarsi all'incirca nello stesso punto allo stesso tempo.

  4. Riproiettare l'accelerazione dal quadro di riferimento del missile a quello globale, usarlo.

La parte importante qui è quella di ottenere la stima del tempo nel ruvido campo da baseball e di non dimenticare le capacità di accelerazione del missile mentre lo fa. Ad esempio, una migliore stima per "l'obiettivo è dritto davanti a noi e vola nella nostra direzione" sarebbe quella di risolvere l'equazione.

distanza = velocità x tempo + 1/2 x accelerazione x tempo 2

... per tempo (utilizzare velocità negativa per oggetti volanti dritto di distanza dal missile), con la soluzione che stai cercando utilizzando lo standard formula quadratica essendo ...

tempo = (√ ( velocità 2 + 2 x accelerazione x distanza ) - velocità ) / accelerazione

L'aggiunta di parametri aggiuntivi, ad esempio il trascinamento, trasforma rapidamente questo in equazioni differenziali senza soluzioni algebriche. Ecco perché la scienza missilistica è così difficile.


Penso che sia esattamente ciò di cui ho bisogno. Prima d'ora non avevo mai pensato alle coordinate locali.
John McDonald,

5
Bella risposta. Come nota a margine, molti missili di tracciamento sono progettati per esplodere automaticamente su queste condizioni: 1) raggiunti entro una certa distanza dalla traccia e 2) la distanza dalla traccia è ora in aumento. Ciò può aggiungere un comportamento piacevole a un costo contenuto.
Patrick Hughes,

1
Questa è un'ottima risposta Ho finito per usare un'accelerazione costante per l'arma (pensavo fosse il più realistico), ho stimato il tempo necessario per arrivare (riorganizzare d = v t + 1/2 * a t * t e risolvere per t). La salsa segreta consisteva nel fornire la stima del tempo per proiettare dove il bersaglio avrebbe avuto la sua velocità attuale e il tempo stimato per l'impatto. Funziona bene.
Bobobobo,

1
Immagino che questo sia un tipo di algoritmo di calcolo dei morti
bobobobo,

42

@Martin Sojka ti ha già detto cosa fare. Invece di migliorare la sua risposta, voglio proporti un altro approccio più semplice: DELOCK

Come ho detto in Traiettoria proiettata di un veicolo? , gli oggetti con capacità di sterzata limitata "proiettano" un paio di cerchi nell'ombra: due regioni che non possono essere raggiunte tramite la sterzata diretta (un toro e un ipertorus di dimensioni superiori).

Quando vedi che il tuo bersaglio sta entrando in una di queste ombre di governo, puoi smettere di cercare il bersaglio e mantenere un'altra direzione per un periodo di tempo limitato.

Il trigger di delocking può essere calcolato facilmente aprendo il tuo tori con un (doppio) cono *:

Trigger del Delock

Devi semplicemente calcolare il prodotto scalare tra il tuo vettore di direzione (normalizzato) e il vettore di spostamento del bersaglio ( Target - Oggetto / | Target - Oggetto |).

Man mano che il prodotto scalare va a zero, la direzione del bersaglio diventa perpendicolare alla direzione dell'utente, portando a una traiettoria circolare **. Quando il bersaglio cade nella regione del ciano, puoi invertire la direzione di sterzo in modo da poterlo mettere fuori dall'area irraggiungibile e rientrare indietro.

* A dire il vero questo non è un cono ... è un altro tipo di superficie rigata generata da (semi) rivoluzione di due linee non parallele attorno ad un asse che passa attraverso l'intersezione e perpendicolare alla linea bisettrice; La proiezione su un piano 2D è la stessa del doppio cono, ma l'asse di rotazione è perpendicolare a quello che genera il cono.

** È improbabile che quella traiettoria sia circolare, ellittica o addirittura chiusa. Le probabilità sono che la traiettoria segua un percorso simile a uno spirografo (un ipotrochoid) in 2D o anche altri mostri in 3 e successive dimensioni. Non puoi comunque raggiungere il centro di tali curve e sembrano cerchi così traiettoria "circolare".


+1 Bella idea per il caso in cui il vettore di accelerazione del missile è limitato per essere perpendicolare alla direzione di viaggio. Non penso che questo sia il caso di questa domanda.
Martin Sojka,

@Martin Sojka il vettore di accelerazione può anche essere suddiviso in due componenti uno radiale e l'altro tangenziale alla direzione. Il primo dice quanto puoi girare, il secondo quanto puoi accelerare / decellerare.
FxIII,

1
Sì, e se sei libero di scegliere i loro punti di forza relativi indipendentemente l'uno dall'altro (ovvero, se la direzione e la forza del vettore di accelerazione è indipendente dal vettore di movimento), i tuoi "cerchi di esclusione" svaniscono.
Martin Sojka,

@Martin Sojka Non ci sono vincoli alla forza di accelerazione?
FxIII,

1
+1 Questo è piuttosto interessante. Non ci avevo mai pensato prima. Probabilmente proverò a usarlo insieme alla risposta di @ Matin
John McDonald,

8

Il tuo sistema di guida si basa sul presupposto che l'accelerazione diretta verso il bersaglio alla fine causerà la collisione degli oggetti. Poiché tale presupposto è falso, anche l'IA guida basata su tale presupposto non ha esito positivo.

Quindi smetti di accelerare direttamente verso l'obiettivo. Aggiungi un po 'di logica per rilevare se la posizione del bersaglio è in qualche modo perpendicolare alla direzione del movimento del missile. In tal caso, il missile deve accelerare verso il bersaglio, ma anche rallentare il suo movimento in avanti. Quindi, piuttosto che andare direttamente verso il bersaglio, inclina la direzione della sua accelerazione in modo che la velocità corrente nella sua direzione di movimento venga rallentata.

Inoltre, avrai bisogno di un grilletto per assicurarti di non andare troppo piano. Quindi aggiungi un po 'di velocità di soglia in modo tale che, se sei al di sotto di tale soglia, smetti di fare il bias.

Un'ultima cosa: nessun sistema di guida sarà perfetto. La ragione per cui i missili possono intercettare i bersagli nella vita reale è che i bersagli si muovono molto più lentamente dei missili stessi e che i bersagli non sono particolarmente agili (relativamente parlando). Se i tuoi missili non saranno molte volte più veloci degli obiettivi che inseguono, allora mancheranno molto.


2
"Gli obiettivi non sono particolarmente agili" .. vero?
Bobobobo,

5

Il metodo più semplice e avanzato da utilizzare per questo nei giochi (e nella vita reale) è la navigazione proporzionale.

Sotto il cuscinetto Constant decrescente Gamma logica (CBDR), quando due oggetti (missili e target) viaggiano nella stessa direzione, senza variazione sightline tra loro, che si scontrano.

Sightline o Line of Sight (LOS) è una linea immaginaria tra missile e bersaglio - il vettore tra posizione missile e posizione bersaglio. Il tasso di variazione angolare di questo LOS è il LOS Rotation Rate.

Quando la velocità di rotazione di LOS diventa zero, la linea di mira non cambia più: i due oggetti sono ora in rotta di collisione. Pensa a te stesso come a inseguire qualcuno mentre giochi a calcio / calcetto. Se lo conduci in un modo in cui il suo corpo appare "congelato" nel tuo campo visivo (la linea di vista tra te e lui non cambia più), ti scontrerai con lui finché manterrai la tua accelerazione di corsa per mantenere il suo corpo congelato dentro il tuo punto di vista.

Sotto Navigazione proporzionale (PN), il missile accelera "N" volte più velocemente della velocità di rotazione LOS. Ciò costringerà il missile a guidare il bersaglio fino a quando la velocità di rotazione di LOS non diventa zero - cioè, il missile e il bersaglio appaiono congelati nello stato quando la linea di mira non cambia più - ora sono in rotta di collisione. La variabile "N" è nota come costante di navigazione (un moltiplicatore costante).

Il comando di guida del missile dovrebbe essere dato come segue:

Accelerazione = Velocità di chiusura * N * Velocità LOS

La LOS Rate può essere facilmente derivata misurando il vettore LOS (posizione di destinazione - posizione del missile) e memorizzandone la variabile. Il vettore LOS dal nuovo frame (LOS1) viene sottratto dal vettore LOS dal vecchio frame (LOS0) per generare un delta di LOS - ora hai una velocità di rotazione LOS primitiva.

Per semplificare Closing Velocity, puoi semplicemente usare il vettore LOS corrente al suo posto, quindi:

Accelerazione = (target_pos - missile_pos) * LOS_delta * N

N è la costante di navigazione: nel mondo reale, è in genere impostata tra 3 e 5, ma la cifra effettiva praticabile nel gioco dipende in qualche modo dalla frequenza di campionamento a cui stai ricavando la velocità / delta LOS. Prova un numero casuale (inizia da 3) e aumenta fino a 1500, 2000, ecc finché non vedi l'effetto desiderato desiderato nel gioco. Si noti che maggiore è la costante di navigazione, più veloce il missile reagirà alle variazioni della velocità di LOS nelle prime fasi del volo. Se il tuo modello di simulazione del razzo di ricerca è in qualche modo realistico, un'eccessiva costante di navigazione potrebbe sovraccaricare la capacità aerodinamica del tuo missile, quindi dovresti usare un numero bilanciato basato su tentativi ed errori.


4

Come sottolineato dalle altre risposte di Martin e Nicol, probabilmente vorrai guidare il tuo missile non direttamente sul bersaglio, ma in un modo che lo farà scontrare con il bersaglio in seguito. Tuttavia, il metodo descritto da Martin è complicato e quello descritto da Nicol è inefficiente.

Un modo più semplice - ma comunque abbastanza efficace - per guidare un missile è regolando il suo angolo in base al cambiamento di angolo tra il missile e il bersaglio. Ad ogni tick si calcola l'angolo dal missile al bersaglio e lo si confronta con l'angolo dal tick precedente. La differenza è la differenza esatta che vuoi fare sull'angolazione del missile. Quindi, se l'angolo era 0,77 in un segno di spunta e 0,75 nel successivo, si desidera regolare l'angolo del missile di -0,02. Questo metodo è semplice e fintanto che l'obiettivo è "davanti" al missile, è molto efficiente in termini di rotta scelta. Si applica anche a qualsiasi numero di dimensioni, non solo in 2d.

Tieni presente, tuttavia:

  • Questo metodo si interrompe se il missile e il bersaglio hanno la stessa identica velocità e viaggiano in parallelo. Beh, in teoria traccia ancora una rotta di collisione per il missile, ci vuole solo un tempo infinito :) in pratica il missile dovrebbe essere sempre più veloce del bersaglio, ma se hanno la stessa velocità è necessario aggiungere un caso d'angolo per identificare se sono paralleli .

  • Il metodo si interrompe se il bersaglio e il missile volano sulla stessa identica linea ma in direzioni opposte. Questo non può davvero accadere nel mondo reale, ma non è troppo raro in un gioco discreto. È necessario aggiungere un controllo caso d'angolo all'algoritmo sopra per verificare ciò.

  • Se il tuo missile ha una capacità di virata limitata, fai semplicemente la virata massima ogni volta che deve girare di più. Finché il missile è abbastanza lontano funzionerà comunque. Se è troppo vicino, vedi l'ultimo punto.

  • Ricorda di essere indulgente quando controlli la collisione. Nel mondo reale molti missili fanno affidamento sulla loro testata per produrre una "zona di uccisione", quindi devono solo avvicinarsi al bersaglio, non effettivamente scontrarsi con esso.

  • Infine, in pratica il missile potrebbe ancora mancare , il che ci riporta alla tua domanda originale. Penso che un buon modo sia davvero disabilitare l'homing per alcune zecche, lasciandolo raggiungere una certa distanza, e poi farlo tornare di nuovo alla ricerca. Penso che il metodo proposto da Fxiii per identificare le zone morte sia un ottimo modo per rilevare quando è necessario disattivare la ricerca del punto di riferimento.


1

Un paio di semplici opzioni che sono state ritenute "abbastanza buone" per i giochi a cui ho lavorato in passato:

1) Se la risoluzione della scena che stai guardando lo consente, l'oggetto può esplodere quando si trova vicino al bersaglio (che è come credo che i missili di ricerca del giorno più comuni funzionino effettivamente in ogni caso). Se il tuo raggio di orbita è circa il doppio delle dimensioni dell'oggetto, probabilmente questo non funzionerà per te in quanto finirebbe per sembrare brutto.

Se il tuo obiettivo finale nella tua soluzione è semplicemente quello di assicurarti che il tuo missile colpisca il bersaglio, allora sono tutto solo per farlo colpire il bersaglio. Ancora una volta, questo dipenderà solo dall'aspetto della soluzione.

2) Se scopri che il tuo missile è ad angolo retto rispetto al tuo bersaglio, questo potrebbe essere il punto in cui il lucchetto "si rompe", e il missile si sposta semplicemente diritto a meno che il bersaglio non si "metta di nuovo" davanti al missile.

Preferisco sempre soluzioni semplici quando possibile. Se stai realizzando un gioco in cui il missile homing è solo una delle armi utilizzate, puoi probabilmente scappare con queste poiché i giocatori probabilmente sparano una salva e poi tornano alle loro armi di ingaggio il più presto possibile. Se stai comunque effettuando una simulazione missilistica, allora chiaramente una delle altre risposte è la scelta migliore.

Spero che sia di aiuto.


0

Come è stato detto, dovresti puntare il missile su dove dovrebbe essere l'obiettivo quando ci arrivi piuttosto che su dove si trova l'obiettivo in questo momento. Ciò impedirà alla maggior parte dei missili di entrare in orbita ma un'orbita è ancora possibile se il bersaglio sfugge al punto giusto. Questa è una tattica legittima usata dai piloti di aerei per schivare i missili in arrivo - poiché il missile sta andando molto più veloce di te avrà un raggio di sterzata più ampio e un forte movimento all'istante giusto lo farà proseguire. (Anche se potresti essere ancora a rischio a causa di una detonazione di prossimità.)

Dato che abbiamo a che fare con un missile che può ancora rintracciare e ha ancora una spinta, si ottiene una situazione di orbita se il bersaglio fuoriesce in una delle zone di cui parla il post di FxIII.

Tuttavia, non sono d'accordo con la sua soluzione al problema. Invece, programmerei i missili in questo modo:

se il missile ha spinto a 90 gradi rispetto alla sua linea di movimento per 360 gradi di movimento, sei in orbita. Regola la spinta a 120 gradi dalla linea di movimento. L'orbita del missile si allargherà in quanto non si trasforma in modo duro ma anche il missile rallenterà, permettendogli così di manovrare meglio. Quando l'intervallo da colpire si apre a 1,25 volte il diametro della zona morta (si noti che questo diametro si basa semplicemente e solo sulla velocità del missile, non è richiesto alcun calcolo complesso in fase di esecuzione) il missile ritorna al suo normale comportamento di tracciamento.

In alternativa, usa le teste più stupide del cercatore - quando l'intervallo da colpire cessa di fare il conto alla rovescia, fai esplodere.


0

So che questa è una domanda antica, ma penso che ci sia qualcosa che è mancato nelle risposte finora fornite. Nella domanda originale, al missile (o qualunque cosa) fu detto di accelerare verso la posizione del bersaglio. Diverse risposte hanno sottolineato che ciò era sbagliato e dovresti accelerare verso dove pensi che l'obiettivo sarà in un secondo momento. Questo è meglio ma è ancora sbagliato.

Quello che vuoi veramente fare non è accelerare verso l'obiettivo ma spostarti verso l'obiettivo. Il modo di pensare a questo è impostare la velocità desiderata puntata sul bersaglio (o una proiezione della posizione del bersaglio) e quindi capire quale accelerazione potresti applicare meglio (date le restrizioni che hai, cioè un missile probabilmente non può accelerare direttamente al contrario) per ottenere la velocità desiderata (ricordando che la velocità è un vettore).

Ecco un esempio funzionante che ho implementato stamattina, nel mio caso per un giocatore AI in un gioco di simulazione sportiva, in cui il giocatore sta cercando di inseguire il proprio avversario. Il movimento è governato da un modello standard di "kick-drift" in cui le accelerazioni vengono applicate all'inizio di un timestep per aggiornare le velocità e quindi gli oggetti si spostano a quella velocità per la durata del timestep.

Vorrei pubblicare la derivazione di questo, ma ho scoperto che non esiste alcun markup matematico supportato su questo sito. Boo! Dovrai solo fidarti che questa è la soluzione ottimale, tenendo conto del fatto che non ho restrizioni sulla direzione di accelerazione, il che non è il caso di un oggetto di tipo missilistico, quindi ciò richiederebbe alcuni vincoli extra.

Il codice è in Python, ma dovrebbe essere leggibile con qualsiasi background linguistico. Per semplicità, suppongo che ogni passaggio abbia una lunghezza di 1 ed esprimo la velocità e l'accelerazione in unità appropriate per riflettere ciò.

self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)

Si noti che la funzione atan2 (a, b) calcola l'abbronzatura inversa di a / b, ma assicura che gli angoli si trovino nel quadrante corretto di un cerchio, il che richiede la conoscenza del segno sia di a che di b.

Nel mio caso, una volta ottenuta l'accelerazione, la applico per aggiornare la velocità di

vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)

Controllo anche la nuova velocità rispetto alla velocità massima dipendente dal giocatore e la capisco. Nel caso di un missile, un'auto o qualcosa con una velocità di rotazione massima (in gradi per tick) potresti semplicemente guardare l'angolo di movimento attuale rispetto all'ideale calcolato e se questo cambiamento è maggiore di quanto consentito, basta cambiare l'angolo di come il più possibile verso l'ideale.

Per chiunque sia interessato alla derivazione di questo, ho scritto la distanza tra il giocatore e il bersaglio dopo il timstep, in termini di posizione iniziale, velocità, velocità di accelerazione e angolo di accelerazione, quindi ho preso la derivata rispetto all'angolo di accelerazione. Impostando questo su zero si trovano i minimi della distanza target-giocatore dopo il timestep in funzione dell'angolo di accelerazione, che è esattamente ciò che vogliamo sapere. È interessante notare che, sebbene il tasso di accelerazione fosse originariamente nelle equazioni, si annulla rendendo la direzione ottimale indipendente da quanto si è effettivamente in grado di accelerare.


In alcuni scenari consiglierei quasi di impostare direttamente la velocità, anche se potrebbe essere difficile integrarlo con un sistema fisico che dipende principalmente dalla forza. Se questo è un gioco in cui i missili vengono lanciati regolarmente, con "schivare" non essendo una meccanica di gioco notevole, allora potresti voler evitare il piccolo rischio che la fisica si frapponga e assicurarti che questa meccanica funzioni come previsto dal giocatore ogni volta. Questo potrebbe avere più senso, per esempio, in un RTS che in un gioco d'azione spaziale.
Katana314,

0

Stai utilizzando una frequenza di virata costante. Questo è esattamente ciò che sta causando la bella orbita perfettamente circolare.

Un approccio più realistico per un sistema di guida sarebbe quello di variare la velocità di virata con inversamente la distanza target (meno distanza -> più velocità di virata). Ciò darebbe una spirale anziché un'orbita e garantirebbe una collisione con un obiettivo più lento.

Dà anche un percorso di volo molto più realistico. La velocità di virata costante è innaturalmente perfetta. È inoltre possibile aggiungere variazioni casuali alla velocità di virata per simulare la turbolenza. Ancora una volta, molto più realistico e può effettivamente evitare scenari in orbita di stato stazionario.

Non sono necessarie equazioni parziali.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.