Archive for juillet, 2021

OptiGT : A la recherche du Gravity Turn parfait ! (Partie 1)

jeudi, juillet 22nd, 2021

Hello !

Aujourd’hui, nous vous proposons une petite plongée dans l’optimisation d’un Gravity Turn, ayant pour objectif de chercher les paramètres optimaux d’un lancement. Cette première partie permettra de vous présenter la genèse du projet et la phase de recherche ainsi que la récupération et le traitement des données. La seconde partie présentera le script en lui-même, disponible pour tous, et… C’est du lourd 😉

Ce projet est le fruit de nombreux échanges entre PhilippeDS et Dakitess, deux joueurs chevronnés de KSP, le premier ayant acquis une certaine expertise du mod kOS (son tuto est formidable !) permettant de coder des programmes et d’en profiter dans le jeu ; le second ayant l’expertise de la conception de vaisseau et une bonne connaissance des trajectoires idéales à suivre, notamment lors des Gravity Turn. Et on va pouvoir mettre cela à profit !

Mais d’abord, c’est quoi, un Gravity Turn ? Direction le Suivez l’Guide n°3 pour tout comprendre de cette manœuvre appliquée à KSP au sein d’un tuto très complet ! Mais elle est « si simple » que nous pouvons la résumer ici en quelques lignes : il s’agit de donner un petit décalage d’angle (le fameux PitchOver) à la fusée très peu de temps après le décollage, puis de mettre votre SAS en suivi prograde, et ainsi d’atteindre un profil d’ascension très lisse et propre, réduisant au mieux les pertes par gravité, par frottement, et par désaxe de poussée.

Vous l’aurez compris, puisque la fusée suit à tout instant son prograde, elle n’est globalement pas contrôlée pendant toute son ascension, ce qui signifie que tout (ou presque) est déterminé dans les premières secondes après le décollage par deux paramètres uniquement : l’amplitude du décalage et le moment, que nous nommerons respectivement Amp (pour Amplitude du PitchOver) et VPitch (pour Vitesse au moment du PitchOver). Cela entraîne deux remarques : tout d’abord, ces deux paramètres sont extrêmement sensibles ! La moindre variation se répercutera tout le long de l’ascension et aboutira à des résultats qui peuvent être très différents. Mais c’est pleinement répétable et c’est ce qui compte. Ensuite, puisque nous n’avons que 2 paramètres d’entrée en termes de contrôle, il va être relativement facile de mener une étude partiellement automatisée pour trouver les meilleurs couples (Amp ; Vpitch) en répétant plusieurs lancements.

Manuellement, on peut se figurer la méthodologie ainsi, en première approche :

  • Concevoir une fusée spécifique ;
  • La placer sur le pas de tir et choisir un angle de décalage, par exemple 5° depuis la verticale, en direction de l’Est (l’océan !) ;
  • Réaliser un premier décollage avec un Vpitch de 50 m/s et constater le résultat sur la trajectoire ;
  • Si la fusée parvient en orbite, alors on peut réduire Vpitch à 45m/s et constater si le résultat est plus efficace ou non ;
  • Si la fusée ne parvient pas en orbite, il faut alors augmenter la VPitch.

On décide qu’un Gravity Turn est plus efficace qu’un autre lorsque la quantité de carburant restant à la fin est supérieure : cela signifie que le Gravity Turn consomme moins de carburant pour un même travail. Cela est équivalent à comparer la masse finale du vaisseau : plus la masse est importante après la mise en orbite et plus il reste de carburant et donc plus le Gravity Turn est efficace.

Et ainsi de suite, jusqu’à tomber sur une valeur VpitchOpti qui maximise la quantité de carburant restante une fois en orbite, pour une amplitude de décalage donnée, ici 5°. On pourrait refaire cette approche avec une amplitude de décalage de 10°, ce qui abaissera le seuil des Vpitch, et voir si un nouveau couple de valeurs est encore plus bénéfique. Néanmoins un paramètre important demeure : la fusée. Elles sont toutes différentes, en taille, en structure, en étages, en proportions, en durée de combustion… et, bien sûr, ça compte.

Ce couple ne serait donc valable que pour une seule fusée spécifique, et difficilement adaptable à un autre lanceur ? Pas tout à fait, et heureusement.

L’un des paramètres les plus influents sur ce couple (Amp ; Vpitch) est le TWR au décollage de votre lanceur, et c’est une valeur que l’on peut aisément récupérer dans le jeu ou via un programme. Par expérience, deux fusées proches dans leur conception (proportions, rapport des étages, configuration), avec des TWR au décollage identique, mais une masse totalement différente, type 1000t ou 100t, donneront des couples de valeur (Amp ; VpitchOpti) très voisins, de sorte qu’il devient possible de rechercher ce couple de valeurs pour un TWR au décollage donné. Pratique !

Voici donc la formulation complète de la problématique traitée dans ce document :

 

Quelles sont les valeurs estimées du couple [Amp ; VpitchOpti] garantissant l’ascension optimale d’un lanceur quelconque à partir de son TWR au décollage ?

 

Il va nous falloir beaucoup de lancements pour construire de manière empirique des courbes permettant d’avoir ces optimisations ! L’avantage, c’est que l’on ne va pas avoir besoin de maths, ou pas trop. Nous utilisons une autre approche : celle de la quantité d’informations pour en tirer des données et être capable de construire un modèle par interpolation / extrapolation 🙂

Pour procéder, il faut commencer par concevoir un lanceur très standard, dont la configuration sera aussi commune et basique que possible pour correspondre au mieux aux lanceurs des joueurs. Nous sommes partis sur le lanceur disponible dans le Suivez l’Guide n°3 qui parle justement en détails de la manœuvre du Gravity Turn et invite les joueurs à faire varier le TWR pour voir l’impact sur la trajectoire.

Nous le modifions de sorte à simplifier sa Charge Utile et la résumer à un réservoir de carburant dont nous interdisons la consommation : voyez cela comme un bloc de béton inerte dont nous pouvons affiner la masse précisément si nécessaire. Le lanceur est constitué d’un simple étage central propulsé par un LVT-45, et, sur les flancs, nous retrouvons deux boosters à poudre BACC.

Au-dessus de l’étage central, un 2ème et dernier étage qui permettra la fin de l’ascension puis la circularisation, avec le célèbre LV909 pour la partie propulsion. Une coiffe est également présente pour protéger la charge utile et sera larguée à 70km, après avoir franchi la limite de l’atmosphère. Un lanceur somme toute très conventionnel !

Au décollage, le LVT-45 et les boosters à poudre sont activés en même temps, ainsi que les pieds de structure qui maintiennent le lanceur bien à la verticale. Le LVT-45 est configuré sur sa puissance maximale alors que la puissance des boosters à poudre est ajustée dans le BAV pour obtenir le TWR souhaité.

Cette configuration de lanceur permet d’ajuster le TWR au décollage sans ajouter / supprimer / échanger une part, en jouant seulement sur la puissance des Boosters à poudre et éventuellement sur les jauges de quantité carburant de la charge utile inerte. La valeur qui sera observée pour quantifier l’efficacité du lancement, sera la masse totale finale en orbite à 100km circulaire. Cela comprendra la charge utile encore solidaire de son dernier étage, et sans la coiffe.

Afin d’automatiser le tout, chaque craft sera équipé de modules propre à kOS, à savoir trois KAL9000. Le KAL9000 est le processeur de kOS le plus puissant avec une très grande capacité de mémoire. Il a été utilisé pour nos tests simplement parce que c’était le plus petit et le plus léger des processeurs proposés par kOS. Pourquoi en avoir utilisé trois ? Un seul est réellement important : celui qui contient le code nécessaire au lancement. Le deuxième est activé dès le décollage et permet d’enregistrer les relevés télémétriques jusqu’à la fin de la circularisation : Altitude, Pitch, TWR, vitesse verticale, vitesse par rapport au référentiel de surface, vitesse orbitale, pression de l’air, masse du vaisseau et delta-v restant. Le troisième enregistre les mêmes données télémétriques mais uniquement lors de l’activation du dernier étage. Ces deux processeurs télémétriques n’ont pas de réelles importances dans le déroulé du vol mais nous ont permis de décortiquer certains comportements, notamment les cas les plus limites.

La première étape indispensable constitue donc la sauvegarde d’un craft dédié pour chaque TWR testé, à partir de la base commune, en jouant sur la puissance des boosters, comme évoqué. Nous obtenons la liste ci-contre, avec un lanceur par dixième de TWR, de 1.2 à 2.08.

Note : les lanceurs de TWR 1.2 à TWR 1.8 ne font varier que la puissance des Boosters. Les lanceurs de TWR 1.9 à 2.08 font en parallèle diminuer la quantité de carburant de la charge utile pour atteindre ces valeurs élevées. Ils ne sont donc plus directement comparables les uns avec les autres mais l’étude se focalise bien sur la recherche de la trajectoire idéale pour un TWR donné.

Un programme kOS a été écrit intégralement par PhilippeDS. Afin d’automatiser au maximum les lancers pour un TWR donné, il était important d’initialiser un premier couple de valeurs (Amp ; Vpitch). La difficulté résidait ensuite en la récupération de ces valeurs et la modification automatique. Nous sommes partis de deux constats :

  • pour un TWR donné, plus Amp (angle par rapport à l’horizontal) est faible, plus Vpitch est élevée.
  • pour une valeur de Amp donnée, plus le TWR est élevé, plus Vpitch est faible.

À partir de là, pour un TWR donné, il suffisait d’initialiser le script avec Amp = 65° et une Vpitch suffisamment élevée (114 m/s pour un TWR = 1.2).

Si la mise en orbite se fait correctement, alors le script doit recharger automatiquement le lancement en diminuant Vpitch de 2 m/s. Cela se poursuit jusqu’à l’échec d’une mise en orbite, liée à une trajectoire trop agressive, qui signe la fin de cette première passe automatisée.

Une fois que le programme a déroulé les Vpitch d’une Amplitude d’angle pour obtenir le VpitchOpti correspondant, on passe à une autre Amplitude pour obtenir le spectre complet des possibles. Puisqu’il n’est pas question de tester pour chaque degré d’angle (car cela n’aurait aucun intérêt pratique, reproductible à la main notamment), les valeurs testées seront les suivantes : 85° ; 80° ; 75° ; 70° ; 65°. Un pitch supérieur à 65° semble peu pertinent dans la mesure où cela constitue déjà une consigne d’angle très violente de 25° d’un coup.

Il a été décidé qu’un lancement était automatiquement un échec lorsque le vecteur prograde passait sous l’horizon. Si, en condition réelle, cela n’est éventuellement pas rédhibitoire dans des conditions limites, c’est tout de même très rare qu’un tel lancement puisse parvenir en orbite et aboutir à un bilan optimal, dans la version Stock de KSP. Les échelles du dessus (RSS) seraient du genre à nuancer cette hypothèse, mais ce n’est pas le sujet.

EXPLICATION DU SCRIPT

Initialisations

Au début de notre code, on initialise toutes les variables : l’apogée cible ne correspond pas forcément à l’apogée de notre orbite après la circularisation. Il s’agit simplement d’une condition d’arrêt pour le gravity turn.

Nous lançons notre vaisseau depuis le KSC à l’équateur et en direction de l’est. Notre azimut est donc 90°.

Dans la dernière ligne, on voit apparaître un fichier CSV. Après chaque lancement, le script est réinitialisé et exécuté de nouveau depuis le début. kOS n’a pas de mémoire sur plusieurs lancements, il ne connaît pas les résultats des précédents scripts. Une façon de contourner cela est d’enregistrer les valeurs qui nous intéressent dans un fichier pour que kOS puisse retrouver ces valeurs.

Récupération des données

L’écriture dans un fichier est une méthode fournie par kOS directement, en revanche, il ne fournit pas la possibilité de lire un fichier. Tony48, le concepteur du mod kOS.Utils (entre autres) nous a beaucoup aidé et a ajouté à son mod la possibilité de lire un fichier avec la commande addons:file:readAllLines. Merci à lui ! Des détails sur son mod ici : https://github.com/tony48/kOS.Utils

Cette commande permet de lire un fichier et de remplacer chaque ligne du fichier en une liste compréhensible par kOS. Ensuite, et c’est le but des lignes 2 à 4 ci-dessous, il faut séparer chaque liste en une liste de valeurs. De cette manière, on peut récupérer n’importe quel vol (une ligne du fichier) et, pour chacun de ces vols, on peut récupérer la caractéristique qui nous intéresse (la masse finale par exemple).

Dans notre cas, on récupère la vPitch du précédent vol (vitesse verticale à partir de laquelle le gravity turn commence) et l’amplitude (nommée thePitch dans le code).

Ces données vont être transmises à deux autres processeurs kOS présents dans le craft. Ces processeurs ont pour simple objectif de réaliser des mesures télémétriques pour nous permettre de vérifier nos données après les lancements.

La fonction doFlight

La partie présentée dans l’image ci-dessous permet d’initialiser le vol. On commence par enregistrer les noms des fichiers dont on aura besoin et on envoie aux deux processeurs télémétriques la vitesse et le pitch qui seront testés. Deux intérêts à cela :

  • s’assurer que les processeurs sont prêts à relever les mesures avant le décollage ;
  • permettre à ces processeurs de créer eux-mêmes des fichiers qui seront nommés à partir du nom du craft, de la vitesse et du pitch testés.

On obtient alors une liste de fichiers de ce genre :

On aurait été très embêté si on n’avait pas eu de noms clairs pour les distinguer.

Condition d’échec

Certains vols étaient voués à l’échec. On le sait. En cherchant le GT optimal, on s’approche forcément d’une limite en dessous de laquelle le vaisseau ne pourra jamais atteindre l’espace et va retomber sur Kerbin. Inutile alors de perdre du temps en continuant le vol jusqu’au crash. Il nous fallait donc une condition d’arrêt : nous avons choisi d’arrêter le vol lorsque le marqueur prograde passait sous l’horizon. kOS mesure les angles par rapport au “dessus” de la navball et non pas par rapport à l’horizon. Ainsi, si cet angle est supérieur à 90° alors, le prograde est sous l’horizon. Le prograde est exactement à l’horizon lorsque le vaisseau est au niveau de son apogée. Si le prograde passe sous l’horizon, ça veut dire que le vaisseau a passé son apogée et est en train de retomber. Bien sûr, cette condition d’arrêt n’est valable que lorsque le vaisseau est encore dans l’atmosphère.

L’échec est enregistré dans notre fichier avec une ligne de FAILED bien visible.

Gravity turn

Dans la fonction doFlight, on voit ensuite apparaître ces lignes. Elles disent simplement d’attendre que la vitesse soit supérieure ou égale à la vitesse qu’on teste actuellement. Une fois cette vitesse atteinte, on démarre le Gravity Turn.

J’ai utilisé la fonction gravityTurn que j’ai présenté dans l’épisode 6 de mon tutoriel.

Fin de la fonction doFlight

Tout d’abord, le processeur principal envoie un message aux autres processeurs pour leur indiquer que la circularisation est terminée. Ces derniers peuvent donc interrompre leur script. Ensuite, on enregistre tout dans notre fichier csv et, en fonction de la situation, on arrête définitivement la simulation ou bien on démarre un nouveau lancement avec une nouvelle vitesse.

Au final, pour chaque vaisseau testé, on obtient un tableau récapitulatif qui nous permet de déterminer, à la main cette fois, la meilleure valeur à conserver. On a constaté que, pour une amplitude donnée, la meilleure vitesse était toujours la plus faible. Et puisque nous parcourons les vitesses de haut en bas, il s’avère que le profil le plus optimal est toujours l’avant dernier, celui avant l’échec.

Sans plus attendre, voici les résultats synthétiques de ces quelques centaines (!) de lancements ! Nous avons concaténé pour chaque TWR les couples (Amp ; Vpitch) optimaux, afin de disposer de l’abaque suivant :

Abaque Opti GT

Chaque couleur correspond à une amplitude d’angle donnée, calculée depuis l’horizon. Les abscisses font figurer les TWR, et les ordonnées correspondent aux valeurs de VpitchOpti. En d’autre terme, la lecture de ce graphique vous permet, pour un lanceur quelconque, et à partir de son TWR au décollage, d’en déduire une bonne estimation du VpitchOpti conduisant à un GT optimal. Pour chaque TWR en abscisse, on a donc plusieurs couples de (Amp ; VpitchOpti). Le couple de valeur dont le Vpitch est le plus faible sera très généralement le meilleur, mais les résultats restent sensiblement identiques. Il restera plus simple pour une utilisation “à la main” de déclencher un GT à 16m/s plutôt qu’à 8m/s par exemple, en termes de temps de réaction et de rapidité d’exécution.

Prenons un exemple ! Le TWR 1.4 nous offre 5 courbes, donc 5 couples de valeurs possibles, les voici :

  • 85° ; 22 m/s
  • 80° ; 36 m/s
  • 75° ; 50 m/s
  • 70° ; 62 m/s
  • 65° ; 78 m/s

Globalement, toutes ces combinaisons devraient vous amener à un GT très agressif et optimal. La combinaison dont la valeur de l’amplitude du PitchOver est la plus faible, ici 85° (5° d’amplitude depuis la verticale), permet la trajectoire la plus naturelle et la plus efficace. Le lanceur réalise un petit décalage de 5°, très tôt après le lancement, dès 22m/s, puis reste en prograde jusqu’à atteindre l’Apoapsis de 100km, et enfin circulariser.

Néanmoins, attention : il s’agit d’une valeur cible idéale pour notre craft précis. C’est donc une très bonne estimation de départ, mais qui pourrait s’avérer légèrement hors limite pour un autre craft quelconque du même TWR. Par précaution et si vous n’êtes pas du genre à relancer plusieurs fois un craft pour trouver son couple (Amp ; VpitchOpti) parfait, n’hésitez pas à simplement prendre un peu de marge, en ajoutant 5m/s par exemple !

Ces courbes peuvent donc servir pour l’utilisateur ne disposant pas de kOS et réalisant simplement ses lancements à la main. Il faut néanmoins apporter une considération importante : la réactivité d’un programme est certes bien plus importante que celle d’un humain, la consigne de décalage d’angle se fera pourtant plus lentement pour kOS que pour vous, car le programme reste dépendant de l’asservissement de KSP qui n’envoie pas une consigne binaire “tourner” au clavier.

De fait, pour Dakitess par exemple, il ajoute quelques m/s au feeling, pour obtenir la même ascension. Simplement parce qu’il atteint, au clavier, le décalage un peu plus vite que ne le fait kOS. Un autre joueur qui appuierait par petites touches, progressivement, pour rejoindre la consigne d’angle, sera peut-être exactement dans le même genre de valeur que notre graphique précédent.

Car notre ambition première avec cette petite méthodologie, c’est bien sur le fait de pouvoir vous proposer un programme kOS qui détecte le TWR de votre lanceur au décollage et lui associer, grâce à ces quelques courbes, le couple de valeurs optimal (Amp ; VpitchOpti). Pour cela, et puisqu’un programme ne sait pas forcément “lire” les données comme nous venons de le faire sur le graphique, il faut transformer ces courbes en fonctions, en les approchant à l’ordre 2 pour un maximum de précision et un temps de calcul raisonnable.

Cela donne les équations suivantes, de la forme VpitchOpti = f(TWR) pour chaque Amp :

On remarque que le R² est très proche de 1, ce qui signifie que nos courbes de tendances passent presque parfaitement par les valeurs que nous avons obtenues lors de nos essais concrets. Cela signifie surtout que nous allons pouvoir attribuer un VpitchOpti précis à une valeur de TWR intermédiaire du type 1.43 ou 1.77, et ne pas nous contenter des valeurs discrètes et entières définies lors de la méthodologie.

Par exemple, si un joueur charge une fusée dont le TWR au décollage est de 1.55, et qu’il utilise kOS, alors notre petit programme sélectionnera le couple dont l’Amplitude d’angle est la plus faible, ici 5° (85° depuis l’horizon), et utilisera la fonction pour lui retourner la valeur de VpitchOpti, ce qui donne ici : VpitchOpti (1.55 ; 85°) = 9.13m/s.

Y’a plus qu’à décoller ! Et voir ce que ça donne. On ne saurait trop insister : cette estimation correspond à l’idéal de la fusée de notre expérience, il est possible que cette combinaison entraîne une trajectoire trop agressive qui mène votre lanceur à sa perte, ou à une ascension légèrement sous-optimale. Mais, normalement, l’idéal est au voisinage et nous avons donc un très bon point de départ pour la suite.

En parlant de suite… Nous l’avons justement réalisé, ce script kOS à destination des utilisateurs, et capable de bien des merveilles ! Il permet notamment d’avoir une estimation des paramètres de décollage basé sur le modèle présenté dans cet article, bien sûr, mais introduit également des facteurs de corrections, des profils de vols basés sur votre propension au risque, et… Cerise sur le gâteau, un mode complètement automatisé permettant d’obtenir pour VOTRE lanceur, le GT parfait ! Mais ce sera l’objet d’un prochain article :p

En espérant que cet article vous aura plu, vous pouvez dès à présent profiter des données issues de l’abaque pour vos lancements à la main, et nous vous invitons à poser toutes vos questions directement en commentaire sur le topic dédié ^^ A très bientôt pour la suite !