Comment déterminer quels propulseurs allumer pour faire pivoter le navire?

47

La configuration du vaisseau change de manière dynamique. Je dois donc déterminer quel propulseur doit être activé lorsque je veux faire pivoter le vaisseau dans le sens des aiguilles d'une montre ou dans le sens inverse. Les propulseurs sont toujours alignés les uns sur les autres avec le navire (jamais à un angle) et sont allumés ou éteints. Voici l'une des configurations possibles:

http://i.stack.imgur.com/GSBSH.png

Ce que j’ai essayé jusqu’à présent, c’est de visualiser le vecteur de tir et le vecteur de direction au centre de gravité du navire:

http://i.stack.imgur.com/ZzNzi.png

Malheureusement, je ne suis pas allé très loin avec ça.

migimunz
la source
7
Vous vous dirigez dans la bonne direction avec les vecteurs de force. Essayez de rechercher des formules de vitesse ANGULAIRE puisque vous essayez de faire pivoter le navire autour du centre de gravité.
Amplify91
Je ne sais plus exactement de le faire, mais essentiellement ses forces seulement sur chaque point en.wikipedia.org/wiki/Center_of_mass et surtout en.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex
1
J'ai eu exactement la même idée! Un conseil qui pourrait vous faciliter la tâche est que vous ne devez calculer les accélérations angulaire et linéaire qu'une seule fois pour chaque propulseur. Les calculs peuvent donc être aussi complexes que vous le souhaitez.
Markus von Broady
@ Amplify91, votre commentaire m'a vraiment aidé à le comprendre, merci!
migimunz
1
@migimunz Je pensais plutôt au calcul des accélérations par propulseur, pas par touche enfoncée (groupe de propulseurs). De plus, donner au joueur le choix des propulseurs à activer sur la touche pressée pourrait être intéressant (certaines personnes échangeraient plus rapidement en tournant pour une rotation en place)
Markus von Broady

Réponses:

22

Succès! Le voici, et il tourne comme il se doit: entrez la description de l'image ici

Ce que j'ai fait est le suivant: pour chaque propulseur, je calcule la magnitude du couple, par rapport au centre de masse.

private function thrustTorque():Float
{
    // distToCom is the distance vector between the thruster and center of mass
    // fire angle is a unit vector representing the direction of the thruster
    var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
    var fireAngle = Math.atan2(dir.y, dir.x);
    var theta = fireAngle - distAngle;
    var torque = distToCOM.length * Math.sin(theta);
    return torque;
}

L'équation de la mangitude du couple, selon wikipedia, est la suivante T = rF sin(theta):

  • r est la distance entre le propulseur et COM
  • F est la magnitude de la force appliquée (je laisse cela de côté, prétendant que c'est juste une, parce que je me soucie seulement du signe).
  • thêta est l'angle entre les deux vecteurs

Lorsque le joueur appuie à gauche, je vérifie le signe de couple pour ce propulseur. S'il est inférieur à zéro, je déclenche le propulseur. C'est tout le contraire pour tourner dans le sens des aiguilles d'une montre.

Cela pourrait probablement être amélioré en utilisant le produit scalaire pour calculer le cosinus de l'angle entre les vecteurs, mais cela devra attendre jusqu'à demain.

Enfin, voici une démo en direct .

migimunz
la source
Presque là je pense. Il semble ne pas être exactement au centre de la masse. En utilisant uniquement les flèches gauche / droite, le navire peut facilement quitter l'écran. Très proche cependant. Peut-être que le point que vous mesurez est légèrement en retrait. Ou cela pourrait être un problème de timing car il semble se stabiliser dans un bon tour après un certain temps. Beau travail cependant.
MichaelHouse
Je ne pense pas que cela a à voir avec cette logique. Rien ne garantit ici que le véhicule ne reçoit pas une force de translation nette du fait de tirer l'ensemble de thursters sélectionnés par ce mécanisme. S'il est impératif de ne pas maintenir la force de translation nette, il faudra pouvoir moduler la force de chaque propulseur (et cela deviendra probablement un problème beaucoup plus difficile à résoudre)
Trevor Powell
@TrevorPowell, exactement. Par souci de simplicité (et aussi d'amusement, car les performances de votre vaisseau dépendront de la qualité de votre conception), j'ai décidé que les propulseurs sont activés ou désactivés. Je vais probablement inclure un seuil afin que ceux qui causent trop peu de couple (et donc trop de mouvements latéraux) ne soient pas allumés, mais le nombre exact de "trop ​​/ peu" sera probablement déterminé par essais et erreurs.
migimunz
3
Ce que vous voulez faire pour éviter les calculs d'angle est d'utiliser le produit du point perpendiculaire (dérivé de la définition du couple entre produits T = r croix F si vous utilisez des vecteurs 3D avec z = 0). Vous prenez le vecteur (-ry, rx), qui est perpendiculaire à r avec la même amplitude, et vous calculez le produit scalaire de ce vecteur avec F. Le résultat est T = rx * Fy - Fy * Fx. Alors abs (T) est la valeur du couple et son signe indique la direction: T> 0 dans le sens anti-horaire, T <0 dans le sens des aiguilles d'une montre.
Joren
1
La raison pour laquelle cela fonctionne est facile à voir de manière intuitive: r point F = r F cos θ. Si vous faites pivoter r de 90 degrés dans le sens anti-horaire et prenez le produit scalaire, vous obtenez r F sin θ car cos (θ - 90˚) = sin (θ).
Joren
14

L'expression générale 3D pour le couple est le produit vectoriel de déplacement et la force: T = rF . En deux dimensions, une valeur scalaire pour le couple suffira et, étant donné que quatre orientations orthogonales pour les propulseurs, nous pouvons écrire sous forme de morceaux:

  • Force dans la direction + x: T = F * (-ry)
  • Force dans la direction -x: T = F * (ry)
  • Force dans la direction + y: T = F * (rx)
  • Force dans la direction -y: T = F * (-rx)

Ici, F est l’ampleur de la force générée par les propulseurs, rx et ry sont les composantes x et y du vecteur allant du point de pivotement au propulseur. Les couples positifs ont tendance à faire pivoter le navire dans le sens anti-horaire. En utilisant les quatre formules ci-dessus, il est trivial de déduire le signe du couple que chaque propulseur produit.

Pour une représentation modeste de la physique, vous devez connaître non seulement le signe de la poussée, mais également sa magnitude totale et son inertie de rotation. De plus, vous ne voudrez peut-être pas simplement activer tous les propulseurs correctement alignés pour effectuer une rotation.

Vaisseau spatial

Comme indiqué, la pleine puissance des propulseurs B, D et E maximisera la rotation, mais accélérera également le navire vers la droite. Fermer D empêchera cela. Si au contraire, l’accélération vers la droite est souhaitée, mais pas dans le sens des aiguilles d’une montre, le moyen le plus efficace consiste à permettre à C et à F à deux tiers de la pleine puissance avec D.

Si cela ne dépasse pas le cadre de ce que vous essayez de faire, vous devrez écrire une sorte de solutionneur d'équations du mouvement, ce qui n'est clairement pas une tâche simple.

Marcks Thomas
la source
7

Quelques choses différentes. Premièrement, nous devons reconnaître qu’il s’agit d’un problème sous-contraint. C'est-à-dire qu'il existe de nombreuses combinaisons de propulseurs pouvant donner lieu à une rotation dans le même sens. Je suppose que dans votre situation, il n'y a que deux états pour les propulseurs, "on" et "off", et tous les propulseurs produisent une force égale.

Deuxièmement, en regardant votre modèle, il semble que votre "centre de masse" ne soit pas réellement votre centre de masse. Heureusement, cela n'affectera pas vos calculs pour le couple. Cependant, cela affectera vos calculs pour le déplacement du centre de masse. Je ne sais pas si vous vous souciez de la précision à ce niveau, car votre "centre de masse" est au moins le carré le plus proche du véritable centre de masse.

Troisièmement, si vous voulez calculer l’impact d’un certain propulseur sur la rotation, vous avez raison, bien que vous utilisiez une formule inefficace. Le couple peut être calculé comme r x F, ce qui a une magnitude r*F*sin(theta). Cependant, calculer les angles dans ce cas est une méthode inefficace. Au lieu de cela, vous devez utiliser directement la définition de couple entre produits, car cela sera beaucoup plus simple en utilisant les représentations que vous avez. Comme tous vos vecteurs n’ont pas de composante z, la formule du produit croisé se simplifie grandement.

Sans changer les résultats de vos calculs, nous pouvons simplement mettre à jour votre code

private function thrustTorque():Float
{
    var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
    return torque;
}

C'est beaucoup mieux (et plus rapide).

Vous suggérez dans votre propre réponse que votre solution consiste à allumer tous les propulseurs avec un couple dans la bonne direction. Maintenant, cela résout à peu près la question que vous avez posée. Cependant, je m'attends à ce que vous constatiez que votre stratégie n’est pas aussi satisfaisante, si un utilisateur appuie sur le bouton "Rotation" et que tous les propulseurs avec un couple positif tournent, les déplaçant potentiellement vers le haut. de les faire pivoter (je ne suis pas sûr du niveau de détail de votre simulation, si vous calculez réellement les forces des propulseurs, ou si vous les montrez visuellement en train de tirer, puis faites pivoter votre modèle avec une accélération constante, ou quelque chose du genre. vous voulez que les propulseurs tirent au moins approximativement avec précision).

Vous ne tenez pas compte de la force nette sur le navire. Si vous aviez des montants de propulseur arbitraires, cela pourrait alors devenir un problème assez compliqué. Cependant, comme nos propulseurs n'ont que deux états, il est assez simple à analyser. Je ne sais pas exactement quel est notre objectif, alors je pourrais en imaginer deux différents: premièrement, nous voulons minimiser la force totale tout en maintenant le couple dans la direction souhaitée. Deuxièmement, nous voulons maximiser le rapport couple / force totale.

En passant, si vous pouviez imaginer un contrôle supplémentaire du "volume du propulseur" qui affecte la puissance de tous les propulseurs simultanément, vous pouvez régler ce contrôle de sorte que vos deux solutions aient un couple égal, et vous voyez que la deuxième solution ne peut avoir qu'un déplacement plus petit que le premier. Cependant, nous devons nous rappeler que s'il est possible de déclencher les propulseurs de manière à ne faire que pivoter et à ne pas bouger du tout, les deux solutions seront identiques.

Nous allons donc passer à la deuxième solution, basée sur les arguments du paragraphe précédent. Maintenant, en analysant la force totale, nous pouvons simplement noter que les moteurs ne peuvent pointer que dans quatre directions. Ainsi, la force totale dans la direction x est simplement le nombre de propulseurs pointant à gauche moins le nombre pointant à droite, et de même pour la direction y.

Après avoir écrit jusque-là, je dois réfléchir un peu plus à l’algorithme pour l’optimiser. Je pense que le reste de mon message est utile en l’état, je le poste donc, mais je le mettrai à jour lorsque je trouverai le meilleur moyen d’optimiser cette configuration (j’ai pensé à plusieurs façons d’obtenir des réponses approximatives, mais aucun d’eux n’est exact).

Jeremy Salwen
la source
Merci pour la réponse (et la solution plus rapide et plus propre pour calculer le couple). Le cercle rouge n'est pas le COM du vaisseau, c'est le noyau de puissance. J'utilise un moteur physique et je ne fais qu'appliquer une impulsion locale au navire. Je suis d'accord avec la solution qui n'est pas parfaite, car cela rend le jeu très amusant avec différentes configurations, mais j'aimerais savoir ce que vous proposez.
migimunz
1
Vous pouvez calculer le couple à partir d'un point de référence arbitraire. Le nombre résultant changera, mais le comportement physique ne changera pas tant que le navire tournera autour de ce point, qui ne doit pas nécessairement être le centre de gravité. En fait, sans information sur la distribution de masse, le centre de masse est lui-même arbitraire et ne peut être calculé en tant que tel.
Marcks Thomas