Disons que j'ai une circulaire mobile target
définie comme:
Vector2 position;
Vector2 velocity;
float radius;
Et un rotatif turret
(monté sur un véhicule en mouvement de quelque sorte) défini comme:
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 quelque chose dans ce sens. Notez que la position et la vitesse des deux sont contrôlées ailleurs - supposez que la vitesse est constante et que la position change en fonction de la vitesse.)
J'essaie d'écrire deux fonctions IA liées pour déterminer, sur un cadre donné:
Quelle accélération angulaire (et dans quelle direction) appliquer à l'angle de la tourelle pour maintenir la tourelle dirigée vers la cible?
Si la cible est actuellement en vue, peut-elle (n'importe quelle partie dans son rayon) être gardée en vue pendant
x
quelques secondes, oùx
est une fraction de seconde? (Alternativement: existe-t-il une autre stratégie pour s'assurer que la cible est bien "verrouillée" et ne vole pas simplement à travers les vues?)
Et je pourrais utiliser de l'aide ...
Réponses:
Vous devez d'abord déterminer la différence d'angle entre la direction de la tourelle et la direction de la cible.
Une fois que vous avez ces quantités, vous pouvez configurer une expression du deuxième degré pour l'angle de la tourelle. Vous devez calculer cela à chaque mise à jour pour vous assurer que vous utilisez toujours les dernières données de positions et de vitesses.
Ici, le premier terme (zéro degré) dans l'expression d'accélération fera tourner la tourelle vers la cible. Cependant, il ne s'arrêtera pas dans le temps mais oscillera plutôt d'avant en arrière. Pour l'arrêter, nous avons besoin du deuxième terme d'amortissement (premier degré) qui provoque une vitesse de rotation élevée à opposer à une accélération élevée.
Maintenant, les constantes positives (pas nécessairement les constantes de programme) doivent être déterminées et équilibrées pour que le système se comporte bien.
C0
est le principal contrôle de la vitesse du système. Une valeur élevée pourC0
donnera une vitesse de rotation rapide et une valeur faible donnera une vitesse de rotation faible. La valeur réelle dépend de nombreux facteurs, vous devez donc utiliser essais et erreurs ici.C1
contrôle l'amplitude de l'amortissement. Le discriminant de l'équation quadratique nous dit que siC1*C1 - 4*C0 >= 0
nous avons un système non oscillant.Vous devriez probablement choisir
C1
un peu plus grand que cela pour des raisons numériques, mais pas trop grand car il peut devenir très sur-amorti et lent à répondre à la place. Encore une fois, vous devez modifier.Il est également important de noter que ce code ne calcule que l'accélération angulaire. L'angle et la vitesse angulaire doivent être mis à jour à partir de cela ailleurs, en utilisant et en quelque sorte un intégrateur. D'après la question, je suppose que cela a été couvert.
Enfin, il y a quelque chose à dire sur le retard, car la tourelle sera probablement toujours derrière lors du suivi d'une cible rapide. Un moyen simple de résoudre ce problème consiste à ajouter une prédiction linéaire à la position de la cible, c'est-à-dire à viser toujours légèrement en avant dans la direction avant de la cible.
Quant à maintenir la tourelle dirigée dans le rayon de la cible pendant un certain temps, cela peut être une exigence difficile à imposer directement à ce type de système. Vous pouvez être certain que ce contrôleur s'efforcera de garder la tourelle dirigée vers la cible (ou plutôt la position prédite) à tout moment. Si le résultat s'avère que vous avez de ne pas être satisfaisante pour modifier les paramètres
predictionTime
,C0
etC1
(dans des limites de stabilité).la source
k
) et C1 est le facteur d'amortissement (généralement appelé «B» ou «c»). Alors oui, vous pouvez minimiser l'oscillation en augmentant l'amortissement, mais le problème est que cela n'essaie pas d'anticiper où sera la cible , il est donc condamné à être en retard sur l'objectif souhaité.Ce que vous avez ici est un problème de contrôle de base . La tourelle est le système, l'accélération est le contrôle et le capteur mesure la position / vitesse. Il existe de nombreuses façons d'aborder ces problèmes, car c'est un problème très bien étudié en ingénierie.
Key se retrouve avec un système stable, c'est-à-dire un système qui ne génère pas d'oscillations. Cela se fait généralement en ajoutant de l'amortissement. La page wikipedia devrait vous aider à démarrer.
la source
Tout d'abord, calculez le vecteur de la tourelle à la cible. Comparez ensuite cela avec le vecteur actuel de la tourelle. Utilisez ensuite la différence entre les deux pour déterminer l'accélération angulaire et la vitesse angulaire nécessaires pour que la tourelle tourne pour pointer dans la bonne direction dans un délai donné.
OK, cela semblait simple. Cependant, vous devriez vraiment essayer d'anticiper la position de la cible, car la cible va se déplacer au moment où vous aurez tourné la tourelle. Pour faire ça:-
où P est la position et V est la vitesse et l'indice est d pour la destination (cible) et s pour la source (tourelle), ce qui donne un vecteur de direction: -
où D est un vecteur de direction et Dsd 'est la direction requise au temps t. Maintenant, déterminez la direction de la tourelle en fonction de la position actuelle et de la vitesse et de l'accélération maximales pour un temps donné t: -
Ds et Ds 'sont les directions de la source et Rs est la vitesse de rotation. Avec tout cela, vous voulez trouver t pour quand Dsd '== Ds' et donc Rs, la vitesse de rotation requise. N'oubliez pas que tous les P, D et V ont des composantes x et y.
Je n'ai pas pris en compte l'accélération ici - cela ajoute beaucoup plus à la complexité. Une fois que vous avez Rs et t, vous pouvez probablement approcher un R parabolique (c'est-à-dire accélérer et décélérer) pour obtenir le même résultat.
la source
Ce que vous cherchez probablement ici est un contrôleur PID , similaire à la réponse acceptée sur cette question SO
J'avais initialement répondu à cette question en "roulant la mienne" mais cette réponse est nettement plus complète et élégante.
la source
La première chose à faire est de calculer l'angle entre le courant et l'objet suivi.
La prochaine étape consiste à vérifier si l'utilisation de la vitesse actuelle du torrent et l'application de l'accélération maximale vers l'arrière (arrêt du torrent) arrêteront le torrent avant ou après l'objet suivi.
Si la réponse est que le torrent s'arrêtera avant l'objet suivi, appliquez l'accélération maximale vers l'avant (augmentation de la vitesse).
Si la réponse est que le torrent s'arrêtera après l'objet suivi, appliquez l'accélération maximale vers l'arrière (arrêt du torrent).
De cette façon, le torrent arrivera toujours le plus rapidement et s'arrêtera au bon point (ou une fraction après).
la source