Comment empêcher les missiles à tête chercheuse de tourner autour de leurs cibles?


78

Je développe un jeu spatial en 2D sans frictions et je trouve très facile de placer un missile à tête chercheuse en orbite autour de sa cible. Je suis curieux des stratégies anti-orbite.

Un exemple simple est un missile à tête chercheuse qui accélère simplement directement vers sa cible. Si cette cible devait se déplacer perpendiculairement à la trajectoire du missile, arrêtez-vous, l'accélération du missile vers la cible ne serait pas suffisante pour dépasser sa propre vitesse et le missile pourrait être entraîné en orbite autour de la cible, comme illustré:

Problème en orbite

  • Dans le cadre 1, le missile se dirige droit vers sa cible, aucun problème.
  • Dans l'image 2, la cible a changé de position, comme indiqué. Le missile continue d'accélérer directement vers la cible (en rouge), tout en continuant de se déplacer là où la cible se trouvait (en noir) en raison de sa vitesse existante.
  • Dans l'image 3, la vitesse du missile continue de transporter le missile sur le côté de la cible (en noir), tandis que le vecteur d'accélération tente désespérément de tirer le missile vers la cible.
  • Dans les images 4 et suivantes, le missile tombe sur une orbite potentiellement stable autour de la cible et n'atteint jamais son objectif. Les flèches noires indiquent un vecteur de vitesse tandis que les lignes rouges indiquent les vecteurs d'accélération au même moment.

Considérant qu’il n’ya pas de frottement dans l’espace, rien ne ralentit la vitesse du missile et n’effondre l’orbite. Une solution possible serait de viser "derrière" la cible, ce qui ferait fermer l'orbite, mais comment cela se fait-il du point de vue de la programmation?

Comment faire en sorte qu'un missile à tête chercheuse atteigne sa cible?


9
C'est en fait un moyen extrêmement cool de créer des objets en orbite.
Derek

Cela me rappelle l'intégration d'Euler. Tout ce que vous avez à faire est de faire votre pas de temps infiniment petit, problème résolu!
Jeff

Je veux implémenter cet effet dans mon jeu! : D
Zolomon


6
@Deza C'est la définition même de l'orbite. L'objet en orbite accélère avec une force centripète, vers le centre d'un autre objet.
Bobobobo

Réponses:


49

Tout d’abord, vous devez effectuer tous les calculs sur l’accélération à appliquer dans le cadre de référence du missile (c’est là que le missile est immobile et que tout le reste se déplace autour de lui, également appelé "coordonnées d’objet" ou "coordonnées locales" dans les moteurs de jeu, bien que dans notre cas nous voulons que la vitesse soit exactement égale à zéro).

L'idée n'est donc pas de viser la cible, mais de viser l'endroit où la cible sera au moment de l'impact estimé. Donc, l'algorithme général ressemble à ceci:

  1. Estimez combien de temps il faudra au missile pour atteindre la cible. Si la cible vole directement dessus (rappelez-vous que le missile est stationnaire ), le calcul peut être aussi simple que calculer la distance / la vitesse . Dans d'autres cas, cela peut être plus compliqué. Si la cible peut essayer de s'évader, vous ne pourrez pas faire une estimation parfaite de toute façon. Vous pouvez donc ne pas être très précis.

  2. En supposant une vitesse constante (estimation au 1er degré) ou une accélération constante (estimation au 2e degré) de la cible, calculez où elle se situera au moment estimé ci-dessus.

  3. Calculez l'accélération qui conduira au missile à se trouver à peu près au même endroit au même moment.

  4. Reprenez l'accélération du cadre de référence du missile au cadre global, utilisez-la.

La partie importante ici est d’obtenir l’estimation de temps dans le stade approximatif, et de ne pas oublier les capacités d’accélération du missile. Par exemple, une meilleure estimation pour "la cible est droit devant nous et voler dans notre direction" serait de résoudre l'équation.

distance = vitesse x temps + 1/2 x accélération x temps 2

... pour gagner du temps (utilisez une vitesse négative pour les objets volant tout de suite du missile), avec la solution que vous recherchez en utilisant la formule quadratique standard étant ...

temps = (√ ( vitesse 2 + 2 x accélération x distance ) - vitesse ) / accélération

L'ajout de paramètres supplémentaires - par exemple, par glissement - transforme rapidement le problème en équations différentielles sans solution algébrique. C'est pourquoi la science de fusée est si dure.


Je pense que c'est exactement ce dont j'ai besoin. Je ne pensais jamais en coordonnées locales avant maintenant.
John McDonald

5
Très bonne réponse. En passant, de nombreux missiles de suivi sont conçus pour exploser automatiquement dans ces conditions: 1) à une distance d’un point à l’autre de la piste et 2) la distance à la piste augmente maintenant. Cela peut ajouter un petit comportement agréable à peu de frais.
Patrick Hughes le

1
C'est une excellente réponse. J'ai fini par utiliser une accélération constante pour l'arme (je pensais que c'était très réaliste), à ​​estimer le temps qu'il faudrait pour arriver (réorganiser d = v t + 1/2 * a t * t et résoudre t). La recette secrète consistait à faire remonter le temps estimé pour projeter à la cible la vitesse actuelle et le temps estimé d’impact. Fonctionne bien.
bobobobo

1
Je suppose que ceci est un type d’ algorithme de calcul à
rebours

42

@ Martin Sojka vous a déjà dit quoi faire. Au lieu d'améliorer sa réponse, je souhaite vous proposer une autre approche plus simple: DELOCK

Comme je l'ai dit dans Trajectoire projetée d'un véhicule? , les objets dont les capacités de pilotage sont limitées font "projeter" deux cercles d'ombres: deux régions inaccessibles via un pilotage direct (un tore et un hypertore dans des dimensions supérieures).

Lorsque vous voyez que votre cible entre dans l’une de ces ombres de direction, vous pouvez cesser de diriger votre cible et conserver une autre direction pendant un temps limité.

Le déclencheur de verrouillage peut être facilement calculé en aproximant votre tori avec un (double) cône *:

Gâchette Delock

Vous devez simplement calculer le produit scalaire entre votre vecteur de direction (normalisé) et votre vecteur de déplacement cible ( Target - Object / | Target - Object |).

Lorsque le produit scalaire se met à zéro, la direction de votre cible devient perpendiculaire à votre direction et conduit à une trajectoire circulaire **. Lorsque la cible tombe dans la région cyan, vous pouvez inverser votre direction pour la placer en dehors de la zone inaccessible et la relancer.

* Pour être honnête, ce n'est pas un cône ... est un autre type de surface réglée générée par la (semi) révolution de deux lignes non parallèles autour d'un axe passant par l'intersection et perpendiculaire à la bissectrice; La projection sur un plan 2D est identique à celle du cône double, mais l’axe de rotation est perpendiculaire à celui qui génère le cône.

** Il est peu probable que cette trajectoire soit circulaire, ni elliptique, ni même fermée. Il y a de fortes chances que la trajectoire suive un spirographe semblable à un chemin (hypotrochoïde) en 2D ou même à d’autres monstres à partir de 3 dimensions. De toute façon, vous ne pouvez pas atteindre le centre de ces courbes et elles ressemblent à des cercles de trajectoire "circulaire".


+1 Belle idée pour le cas où le vecteur d'accélération du missile est limité à la perpendiculaire à la direction du déplacement. Je ne pense pas que ce soit le cas pour cette question cependant.
Martin Sojka

@ Martin Sojka, le vecteur d'accélération peut même être divisé en deux composantes, l'une radiale et l'autre tangente à la direction. Le premier dit à quel point vous pouvez tourner, le second combien vous pouvez accélérer / ralentir.
FxIII

1
Oui, et si vous êtes libre de choisir leurs forces relatives indépendamment les unes des autres (c'est-à-dire si la direction et la force du vecteur d'accélération sont indépendantes du vecteur de mouvement), vos "cercles d'exclusion" disparaissent.
Martin Sojka

@ Martin Sojka N'y a-t-il pas de contrainte sur la force d'accélération?
FxIII

1
+1 C'est plutôt cool. Je n'y avais jamais pensé auparavant. Je vais probablement essayer d'utiliser ceci en conjonction avec la réponse de @ Matin
John McDonald

8

Votre système de guidage repose sur l'hypothèse selon laquelle une accélération directe vers la cible provoquera éventuellement la collision des objets. Puisque cette hypothèse est fausse, l'IA d'orientation basé sur cette hypothèse est également infructueuse.

Alors arrêtez d’accélérer directement vers la cible. Ajoutez un peu de logique pour déterminer si la position de la cible est quelque peu perpendiculaire à la direction du mouvement du missile. Si c'est le cas, le missile doit accélérer vers la cible, mais aussi ralentir son avancée. Ainsi, plutôt que d'aller directement vers la cible, il biaise la direction de son accélération de sorte que la vitesse actuelle dans sa direction de mouvement soit ralentie.

En outre, vous aurez besoin d'un déclencheur pour vous assurer de ne pas aller trop lentement. Donc, ajoutez un seuil de vitesse tel que, si vous êtes sous ce seuil, vous arrêtez de faire la polarisation.

Une dernière chose: aucun système de guidage ne sera parfait. La raison pour laquelle les missiles peuvent intercepter des cibles dans la vie réelle est que les cibles se déplacent beaucoup plus lentement que les missiles eux-mêmes, et que les cibles ne sont pas particulièrement agiles (relativement parlant). Si vos missiles ne vont pas être beaucoup plus rapides que les cibles qu'ils poursuivent, ils rateront beaucoup.


2
"Les cibles ne sont pas particulièrement agiles" ... n'est-ce pas?
bobobobo

5

La méthode de navigation proportionnelle est la méthode la plus simple et la plus avancée à utiliser pour cela dans les jeux (et dans la vie réelle).

Selon la logique CBDR (Constant Bearing Decreasing Range), lorsque deux objets (missile et cible) se déplacent dans la même direction sans modification de la ligne de visée, ils entrent en collision.

La ligne de visée ou ligne de visée est une ligne imaginaire située entre le missile et la cible - le vecteur entre la position du missile et la position de la cible. Le taux de changement angulaire de cette NS est le taux de rotation des NS.

Lorsque le taux de rotation de la ligne de vue devient nul, la ligne de vue ne change plus - les deux objets sont maintenant sur une trajectoire de collision. Pensez à vous-même comme à chasser quelqu'un tout en jouant au football. Si vous le conduisez de telle sorte que son corps semble "figé" dans votre champ de vision (la ligne de vue entre vous et lui ne change plus), vous le heurterez tant que vous maintenez l'accélération de votre course pour que son corps paraisse figé. ta vue.

Sous la navigation proportionnelle (PN), le missile accélère "N" plus rapidement que la vitesse de rotation de la couche LOS. Cela forcera le missile à diriger la cible jusqu'à ce que la vitesse de rotation du LOS soit nulle (le missile et la cible semblent figés, la ligne de vue ne changeant plus), ils sont maintenant sur la trajectoire de collision. La variable "N" est appelée constante de navigation (multiplicateur de constante).

La commande de guidage du missile doit être donnée comme suit:

Accélération = vitesse de fermeture * N * Taux de perte de charge

Le taux de LOS peut être facilement calculé en mesurant le vecteur LOS (position cible - position du missile) et en stockant sa variable. Le vecteur LOS de la nouvelle image (LOS1) est soustrait par le vecteur LOS de l'ancienne image (LOS0) pour générer un delta de LOS. Vous disposez maintenant d'une vitesse de rotation LOS primitive.

Pour simplifier la vitesse de fermeture, vous pouvez simplement utiliser le vecteur LOS actuel à sa place, ainsi:

Accélération = (target_pos - missile_pos) * LOS_delta * N

N est la constante de navigation - dans le monde réel, il est généralement défini entre 3 et 5, mais le chiffre réalisable dans le jeu dépend un peu du taux d'échantillonnage auquel vous dérivez le taux / delta de la NDS. Essayez un nombre aléatoire (à partir de 3) et augmentez jusqu’à 1500, 2000, etc. jusqu’à ce que vous obteniez l’effet principal souhaité dans le jeu. Notez que plus la constante de navigation est élevée, plus le missile réagira rapidement aux changements de vitesse de la LDV au début du vol. Si votre modèle de simulation de roquette à tête chercheuse est quelque peu réaliste, une constante de navigation excessive pourrait surcharger la capacité aérodynamique de votre missile. Vous devez donc utiliser un nombre équilibré basé sur des essais et des erreurs.


4

Comme le soulignent les autres réponses de Martin et Nicol, vous souhaiterez probablement guider votre missile non pas directement sur la cible, mais de manière à le faire entrer en collision avec la cible ultérieurement. Cependant, la méthode décrite par Martin est compliquée et celle décrite par Nicol est inefficace.

Une façon plus simple - mais toujours très efficace - de guider un missile consiste à ajuster son angle en fonction du changement d’angle entre le missile et la cible. À chaque tick, vous calculez l'angle du missile à la cible et comparez-le avec l'angle du tick précédent. La différence est la différence exacte que vous souhaitez faire sur l'angle du missile. Donc, si l'angle était de 0,77 en un tick et de 0,75 dans le suivant, vous voulez ajuster l'angle du missile de -0,02. Cette méthode est simple et, tant que la cible est "devant" le missile, elle est très efficace en termes de route choisie. Cela s'applique également à n'importe quel nombre de dimensions, pas seulement en 2D.

Gardez à l'esprit, cependant:

  • Cette méthode casse si le missile et la cible ont exactement la même vitesse et voyagent en parallèle. Bien, théoriquement, il trace toujours une trajectoire de collision pour le missile, cela prend juste un temps infini :) en pratique, le missile devrait toujours être plus rapide que la cible, mais s’ils ont une vitesse identique, vous devez ajouter un cas de coin pour déterminer s’ils sont parallèles. .

  • La méthode est interrompue si la cible et le missile volent sur la même ligne mais dans des directions opposées. Cela ne peut pas vraiment arriver dans le monde réel, mais ce n’est pas trop rare dans un jeu discret. Vous devez ajouter une vérification de casse de coin à l'algorithme ci-dessus pour le vérifier.

  • Si votre missile a une capacité de virage limitée, faites-lui tourner le virage au maximum chaque fois qu'il doit tourner plus que cela. Tant que le missile est suffisamment éloigné, il fonctionnera toujours. Si c'est trop proche, voir la dernière puce.

  • N'oubliez pas d'être indulgent lorsque vous vérifiez une collision. Dans le monde réel, de nombreux missiles dépendent de leur tête nucléaire pour créer une "zone de destruction". Ils n'ont donc besoin que de s'approcher de la cible et de ne pas la percuter.

  • Enfin, dans la pratique, le missile peut encore manquer , ce qui nous ramène à votre question initiale. Je pense qu’un bon moyen est de désactiver la prise de référence pour quelques ticks, de la laisser atteindre une certaine distance, puis de la reprendre à nouveau. Je pense que la méthode proposée par fxiii pour identifier les zones mortes est un excellent moyen de détecter le moment où vous devez désactiver la prise de référence.


1

Quelques options simples qui ont été jugées «assez bonnes» pour les jeux sur lesquels j'ai travaillé dans le passé:

1) Si la résolution de la scène que vous regardez le permet, alors l’objet peut exploser s’il est proche de la cible (c’est ainsi que, selon moi, la plupart des missiles à tête chercheuse courants fonctionnent de toute façon). Si votre portée en orbite est environ deux fois plus grande que l’objet éloigné, cela ne fonctionnera probablement pas pour vous, car cela donnerait un mauvais aspect.

Si votre objectif final dans votre solution est simplement de vous assurer que votre missile touche la cible, je suis tout à fait partisan de le faire toucher la cible. Encore une fois, cela dépendra simplement de l’apparence de la solution.

2) Si vous trouvez que votre missile est à angle droit par rapport à votre cible, il est possible que le verrou "casse" et que le missile se déplace droit, à moins que la cible ne se retrouve "devant" à nouveau.

Je préfère toujours les solutions simples autant que possible. Si vous créez un jeu dans lequel le missile à tête chercheuse est l'une des armes utilisées, vous pouvez probablement vous en tirer, car les joueurs risquent de lancer une salve puis de revenir à leurs armes à engagement constant dès que possible. Cependant, si vous faites une simulation de missile, l’une des autres réponses est clairement le meilleur choix.

J'espère que cela t'aides.


0

Comme il a été dit, vous devriez viser le missile pour savoir où la cible devrait être lorsque vous y arriverez plutôt que pour la cible actuelle. Cela empêchera la plupart des missiles d'entrer en orbite, mais une orbite est toujours possible si la cible se dérobe comme il convient. Il s’agit là d’une tactique légitime utilisée par les pilotes d’avions pour éviter les missiles: dans la mesure où le missile va beaucoup plus vite que vous, il aura un plus grand rayon de braquage et une secousse brusque au bon moment le fera passer. (Bien que vous puissiez toujours être exposé à une détonation à proximité.)

Puisque nous avons affaire à un missile qui peut toujours suivre et a encore une poussée, vous obtenez une situation d’orbite si la cible s’évade dans une des zones dont parle la publication de FxIII.

Cependant, je ne suis pas d'accord avec sa solution au problème. Au lieu de cela, je programmerais les missiles comme suit:

Si le missile a été poussé à 90 degrés de sa ligne de mouvement pour 360 degrés de mouvement, vous êtes en orbite. Ajustez la poussée à 120 degrés de la ligne de mouvement. L'orbite du missile s'élargira car il ne tournera pas aussi fort mais le missile ralentira également, lui permettant ainsi de mieux manœuvrer. Lorsque la plage à cibler ouvre à 1,25 fois le diamètre de la zone morte (notez que ce diamètre est basé simplement et uniquement sur la vitesse du missile, aucun calcul complexe n'est requis au moment de l'exécution), le missile reprend son comportement de suivi normal.

Vous pouvez également utiliser des têtes de recherche plus sombres - lorsque la portée à cibler cesse de décompter, vous détonez.


0

Je sais que la question est ancienne, mais je pense que quelque chose a été oublié dans les réponses données jusqu'à présent. Dans la question initiale, le missile (ou autre chose) devait accélérer pour atteindre la position de la cible. Plusieurs réponses ont indiqué que cela était faux et que vous devriez accélérer vers l'endroit où vous pensez que la cible se situera à un moment ultérieur. C'est mieux mais toujours faux.

Ce que vous voulez vraiment faire, ce n’est pas d’ accélérer vers la cible, mais de vous rapprocher de la cible. Pour ce faire, définissez la vitesse désirée en fonction de la cible (ou une projection de l'emplacement de la cible), puis déterminez quelle accélération vous pouvez le mieux appliquer (quelles que soient vos restrictions, par exemple, un missile ne peut probablement pas accélérer.) directement en sens inverse) pour obtenir la vélocité souhaitée (en se rappelant que la vélocité est un vecteur).

Voici un exemple concret que j'ai implémenté ce matin, dans mon cas pour un joueur IA dans un jeu de simulation de sport, où le joueur essaie de chasser son adversaire. Le mouvement est régi par un modèle standard de "dérive de kick", dans lequel les accélérations sont appliquées au début d'un pas de temps pour mettre à jour les vitesses, puis les objets dérivent à cette vitesse pendant la durée du pas de temps.

Je voudrais poster la dérivation de cela, mais j'ai trouvé qu'il n'y a pas de balisage mathématique pris en charge sur ce site. Huer! Vous devrez simplement avoir confiance que c'est la solution optimale, sachant que je n'ai aucune restriction quant à la direction de l'accélération, ce qui n'est pas le cas pour un objet de type missile, de sorte que des contraintes supplémentaires seraient nécessaires.

Le code est en python, mais doit être lisible avec tous les antécédents linguistiques. Par souci de simplicité, je suppose que chaque pas de temps a une longueur de 1 et exprime la vitesse et l’accélération en unités appropriées pour refléter cela.

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)

Notez que la fonction atan2 (a, b) calcule le tan inverse de a / b, mais assure que les angles se situent dans le quadrant correct d'un cercle, ce qui nécessite de connaître le signe de a et de b.

Dans mon cas, une fois que j'ai l'accélération, je l'applique pour mettre à jour la vitesse en

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)

Je vérifie également la nouvelle vitesse par rapport à une vitesse maximale dépendant du joueur et la limite à cela. Dans le cas d'un missile, d'une voiture ou de quelque chose avec une vitesse de rotation maximale (en degrés par tick), vous pouvez simplement regarder l'angle de mouvement actuel par rapport à l'idéal calculé et si ce changement est supérieur à celui autorisé, il suffit de changer l'angle de vue. autant que possible vers l'idéal.

Pour ceux qui sont intéressés par cette dérivation, j’ai noté la distance entre le joueur et la cible après le pas de temps, en termes de position initiale, de vitesse, de taux d’accélération et d’angle d’accélération, puis j’ai pris la dérivée par rapport à l’angle d’accélération. Définissez-le sur zéro pour trouver les minima de la distance joueur-cible après le pas de temps en fonction de l'angle d'accélération, ce qui correspond exactement à ce que nous voulons savoir. Fait intéressant, même si le taux d’accélération se trouvait à l’origine dans les équations, la direction optimale n’est pas prise en compte, indépendamment de la capacité réelle d’accélération.


Dans certains cas, je conseillerais presque de régler directement la vitesse, bien que cela puisse être difficile à intégrer à un système physique dépendant principalement de la force. S'il s'agit d'un jeu dans lequel des missiles sont tirés régulièrement, "esquiver" n'étant pas un mécanisme de jeu remarquable, vous voudrez peut-être éviter le petit risque que la physique ne vous gêne et assurez-vous simplement que ce mécanisme fonctionne comme le joueur s'y attend à chaque fois. Cela peut sembler plus logique, par exemple, dans un RTS que dans un jeu d'action spatiale.
Katana314

0

Vous utilisez un taux de rotation constant. C'est exactement ce qui cause la belle orbite parfaitement circulaire.

Une approche plus réaliste pour un système de guidage consisterait à faire varier le taux de virage avec la distance cible inversement (moins de distance -> plus de taux de virage). Cela donnerait une spirale plutôt que sur une orbite et garantirait une collision avec une cible plus lente.

Cela donne aussi une trajectoire de vol beaucoup plus réaliste. Le taux de rotation constant est anormalement parfait. Vous pouvez également ajouter des variations aléatoires au taux de virage pour simuler la turbulence. Encore une fois, beaucoup plus réaliste et peut réellement éviter des scénarios en orbite à l'état stable.

Pas besoin d'équations partielles.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.