Fichier de définition d'aéronef

Le fichier texte avec l'extension de fichier `.tmd`définit les caractéristiques physiques, les visuels/animations et la définition sonore d'un avion Aerofly FS 2. Ce fichier se trouve dans le dossier de l'avion avec d'autres fichiers comme le fichier de description de l'avion TMC .

> "LE" fichier tmd d'un avion est le fichier qui porte l'extension de fichier `.tmd`et exactement le même nom de fichier que le dossier dans lequel il se trouve, par exemple « nom de l'avion.tmd »
>
>

Les autres fichiers TMD sont les

* controles.tmd - définition du point de clic
* Aircraft\_presets.tmd - état prédéfini pour le décollage, l'atterrissage et le nettoyage

## But

Le fichier TMD contient la définition principale d'un avion. Il décrit l’avion comme un ensemble d’objets pouvant avoir différents attributs et connexions les uns avec les autres dans une approche orientée objet. Parmi les objets pouvant être définis dans un fichier tmd figurent les moteurs, les hélices, les ailes, les profils aérodynamiques, les roues, les actionneurs, les circuits logiques, les corps rigides, les articulations, les sources sonores, les instruments, le pilote automatique, les récepteurs de navigation et de nombreux objets à usage général comme les intégrales et les fonctions mathématiques. .

## Sections

Le fichier TMD se compose de trois sections :

* Objets dynamiques
* Objets graphiques
* Objets sonores

Voici un exemple de la façon dont les trois sections sont définies dans le fichier texte tmd.

```
<[fichier][][]
     <[gestionnaire de modèles][][]
         <[pointer_list_tmuniverse][DynamicObjects][]

             // les objets sont ajoutés ici

         >
         <[pointer_list_tmgraphics][GraphicObjects][]
         >
         <[pointer_list_tmsound][SoundObjects][]
         >
     >
 >

```

### Objets dynamiques

La section dynamique définit tous les objets qui créent la dynamique et la simulation des systèmes pour un avion. Les valeurs physiques, telles que l'emplacement de l'avion, sa vitesse et son orientation ainsi que la déflexion de ses gouvernes, la vitesse de rotation des moteurs ou des hélices , les charges électriques, la consommation de carburant, les états du système et de nombreuses autres valeurs sont calculées numériquement par Aerofly. Le moteur physique de FS 2.

Le cœur de chaque avion du simulateur de vol Aerofly est une simulation de corps rigide . Chaque corps a sa propre masse, position, vitesse, orientation et vitesse angulaire. Les forces telles que la gravité, les forces aérodynamiques , du moteur ou de l'hélice la poussée et le couple , les collisions avec le sol sont calculées et appliquées au corps. Les articulations relient différents corps et appliquent des forces et des couples aux corps. Dans le code tmd, la définition du système de corps rigides est généralement positionnée au tout début du fichier. Plus bas dans la section dynamique, les propriétés aérodynamiques ( aérodynamique , profils aérodynamiques ) de l'avion sont définies, suivies par les systèmes d'avion les plus avancés comme les systèmes électriques , hydrauliques ou de carburant . simulés Les instruments tels que les indicateurs d'attitude, les indicateurs de vitesse et les altimètres se trouvent vers la fin de la section dynamique du TMD.

Les objets définis dans la section graphique et sonore utilisent la sortie générée par la simulation dynamique pour restituer les objets et les animations 3D. Il est donc nécessaire de transmettre les valeurs requises aux graphiques et au son à l'aide d'un objet de sortie. Cela inclut la position de toutes les gouvernes et des commandes de vol principales ainsi que les valeurs visibles sur n'importe quel écran du cockpit. Un exemple peut être trouvé ci-dessous.

Voici une liste de pages qui décrivent plus en détail les systèmes dans la section dynamique du fichier TMD :

* Système de corps rigide
* Collision
* Aérodynamique
* Actionneurs
* Propulsion
* Instrumentation
* Entrées (boutons, interrupteurs et boutons, commandes de vol, entrées numériques)
* Circuits mathématiques et logiques
* Programmation basée sur des événements
* Systèmes électriques
* Systèmes de carburant
* Systèmes hydrauliques
* Pilote automatique et gestion de vol

### Objets graphiques

La deuxième section du fichier tmd est la section graphique. Cette section définit le rendu de tous les affichages du cockpit et de chaque partie visible du modèle 3D et son animation.

Il existe un certain nombre de méthodes d'animation différentes. Pour n'en nommer que quelques-uns, il existe des animations statiques qui déplacent simplement toutes les pièces dans le monde simulé en fonction de la position du fuselage ( rigidbodygraphics ), il y a des objets qui tournent autour d'un certain axe ( hingedbodygraphics ou rotation ) comme la gouverne de profondeur, l'aileron et le gouvernail et là sont des objets qui peuvent être déplacés le long d'un axe comme la manette des gaz du C172 ( images mobiles ou traductions ).

Chaque objet du modèle 3D (géométrie) qui doit être rendu à l'écran doit être placé dans une et une seule 'GeometryList'. Pour commencer, toutes les géométries peuvent être ajoutées à la rigidbodygraphics « GeometryList » d'un seul objet , comme indiqué dans l'exemple de code ci-dessous. Chaque objet du modèle 3D qui constitue cette liste sera déplacé avec le corps rigide « Fuselage » et sera ensuite rendu par la carte graphique s'il est dans le champ de vision de la caméra.

```
<[rigidbodygraphics][Fuselage][]
                 <[uint32][PositionID][Fuselage.R]>
                 <[uint32][OrientationID][Fuselage.Q]>
                 <[string8][GeometryList][Antenne du panneau principal du fuselage]>
             >

```

Plus tard dans le développement, les pièces individuelles seront déplacées de cette « GeometryList » vers la « GeometryList » d'un nouvel HingedbodyGraphics , MovingGraphics animé ou RigidbodyGraphics objet .

Le moteur de rendu lui-même ne peut pas accéder directement aux entrées de contrôle de l'utilisateur ni simuler la position des actionneurs lents ; c'est ce que fait le moteur physique. Chaque animation doit donc recevoir ses entrées de la section dynamique où tous les mouvements physiques ou retards peuvent être simulés. Pour envoyer une valeur de la section dynamique à la section graphique, la section dynamique doit définir un objet « sortie » comme décrit ci-dessus et la section graphique doit avoir un objet graphiques\_input dont l'InputID correspond à la propriété « Nom » de la sortie suivi du texte '.Sortie'.

Collection des pages pertinentes pour la section GraphicObjects :

* Animation des boutons, interrupteurs et boutons
* Graphiques de corps rigides, transformations et graphiques de corps en flexion
* Éclairage intérieur et éclairage extérieur
* Écrans numériques, écrans LCD, écrans de vol, HUD
* Caractère humain

### Objets sonores

La troisième et dernière partie est la section sonore. La section sonore lit également les valeurs de la simulation numérique dans la section dynamique, puis utilise un mélange d'interpolations pour déterminer la hauteur et le volume d'un fichier sonore particulier.

Semblable à la section graphique, un objet soundinput lira la valeur d'un objet de sortie dynamique et fournira sa valeur pour toute la section sonore.

Pages les plus pertinentes

* Sons des boutons, interrupteurs et boutons déclenchés dans DynamicObjects
* Entrée sonore, mixage, mapping, fondu, etc.

## Noms uniques des objets

Chaque objet d'une section doit avoir un nom unique par lequel il peut être référencé. L'utilisation d'un nom pour plusieurs objets dans une section peut avoir des effets indésirables.

## Conventions de dénomination des objets

Nous utilisons des règles de dénomination et donnons aux objets similaires les mêmes noms sur différents avions :

* Le nom d'un objet utilise uniquement les caractères AZ, az, 0-9 et le premier caractère du nom est toujours en majuscule.
* Les noms d'objet ne doivent contenir aucun espace. Séparez les mots en mettant la première lettre de chaque mot en majuscule (style UpperCamelCase).
* Utilisez des traits de soulignement uniquement si nécessaire.
* Les tirets, les deux-points et les virgules en dehors des commentaires (//) ne doivent pas être utilisés.
* Pour assurer la compatibilité multiplateforme, l’utilisation de l’indentation des tabulations est déconseillée. Utilisez plutôt des espaces pour l’indentation. Il est recommandé de définir les paramètres des éditeurs de texte pour remplacer automatiquement les tabulations par des espaces.
* Les abréviations sont évitées, le nom complet est toujours préféré.

## Structure de l'objet

L'exemple de code ci-dessous crée un objet de la classe « control\_input » avec le nom « ThrottleLever » dans la section dynamique lorsque le simulateur charge l'avion. Pendant l'exécution, cet objet filtrera les messages portant le nom « Controls.Throttle1 » qui sont généralement envoyés par le dispositif de contrôle affecté à l'entrée de l'accélérateur gauche dans l'interface utilisateur « Paramètres de contrôle ». L'objet control\_input stockera la valeur du dernier message en mémoire pour une utilisation ultérieure par d'autres objets.

Un message avec un nom de message personnalisé peut également être généré en ajoutant un point de clic au fichier « controls.tmd » .

```
<[fichier][][]
     <[gestionnaire de modèles][][]
         <[pointer_list_tmuniverse][DynamicObjects][]

             // Manette de Gaz
             <[input_lever][ThrottleInput][]
                 <[string8][Message][Controls.Throttle1]>
             >

         >
     >
 >

```

## Communication au sein d'une section

La plupart des objets du fichier tmd doivent communiquer sous une forme ou une autre. Par exemple, un objet jet\_engine doit connaître la position du levier des gaz afin de pouvoir calculer l'augmentation ou la diminution de la poussée au fil du temps et appliquer une force variable au « fuselage » pour l'accélérer. Dans le code tmd extrait ci-dessous, le développeur a défini que le moteur doit utiliser la sortie de l'objet ThrottleLever comme entrée ThrottleControl. Il serait également possible d'utiliser la sortie de l'automanette comme exemple ou toute autre sortie imaginable provenant d'une lecture d'instrument ou d'une sortie d'un circuit logique si cela est souhaité.

```
// exemple de JetEngine récupérant la sortie de l'objet ThrottleLever
             // Manette de Gaz
             <[input_lever][ThrottleInput][]
                 <[string8][Message][Controls.Throttle1]>
             >
             <[jet_engine][JetEngine][]
                 <[string8][Corps][Fuselage]>
                 <[string8][ThrottleControl][ThrottleInput.Output]>
                 <[float64][MaximumThrust][10000.0]>
             >

```

Ces connexions programmées manuellement permettent une énorme flexibilité, un débogage facile et un code objet incroyablement simple et rapide. Chaque objet peut être aussi « stupide » que possible, il utilise simplement ses entrées, en fait quelque chose et définit sa valeur de sortie ou son état interne s'il en a un. Ensuite, si un autre objet passe et veut connaître la valeur de sortie, il la saisit simplement et calcule ses sorties avec cela. De cette façon, de très longues chaînes, des arbres logiques ou même des itérations et des boucles de contrôle peuvent être créés qui exécutent réellement une logique différente en fonction de l'état de l'avion ou des entrées de l'utilisateur. Il est important de noter que l'ordre dans lequel les objets apparaissent dans le code tmd n'a aucun effet sur la simulation.

## Communication entre les sections

Les objets définis dans différentes sections du tmd ne peuvent pas communiquer directement. Les seules connexions possibles sont de la section dynamique vers la section graphique et de la section dynamique vers la section son.

Presque toutes les valeurs utilisées en dehors de la section dynamique devront passer par un objet « sortie » et devront être lues par toute section ayant besoin de cette valeur. La raison en est la conception de base de l'Aerofly FS 2 qui sépare strictement la simulation physique de la représentation graphique et de la génération sonore. La conception des sections graphiques et sonores en tant que fonctions « en lecture seule » des valeurs physiques présente un avantage considérable en termes de performances et permet une conception logicielle plus flexible. Les différents processus de calcul de la physique et de calcul de la représentation du modèle graphique peuvent être effectués sur différents cœurs CPU ou même en partie sur la carte graphique pour éviter des goulots d'étranglement majeurs.

Une façon d'imaginer la communication entre les sections est que chaque valeur de la section dynamique est envoyée via un fil vers l'unité de traitement graphique ou vers les dispositifs de traitement du son.

### Exemple de section Dynamique vers Graphiques

Dans l'exemple ci-dessous, la position de l'entrée du levier des gaz est émise par la section dynamique, puis dans la section graphique, la valeur est lue. Nous donnons généralement à l'objet 'graphics\_input' le même nom que la 'sortie' de la section dynamique. pour éviter toute confusion.

```
<[fichier][][]
     <[gestionnaire de modèles][][]
         <[pointer_list_tmuniverse][DynamicObjects][]

             // cet objet permet d'appeler 'ThrottleInputPosition.Output'
             // dans un objetgraphics_input (ou soundinput) comme indiqué ci-dessous
             <[sortie][ThrottleInputPosition][]
                 <[string8][Input][ThrottleInput.Output]>
             >

         >
         <[pointer_list_tmgraphics][GraphicObjects][]

             // cet objet lit la sortie de la section dynamique dans
             // et fournit cette valeur pour d'autres objets dans la section graphique
             <[graphics_input][ThrottleInputPosition][]
                 <[string8][InputID][ThrottleInputPosition.Output]>
             >

         >
     >
 >

```

Désormais, pour animer le modèle 3D du levier d'accélérateur, un objet 'hingedbodygraphics' est ajouté avec sa GeometryList contenant le nom de la géométrie dans le modèle 3D. Il utilise ThrottleLeverPosition pour la saisie de son angle de rotation. Les paramètres « Axe » et « Pivot » peuvent être mesurés dans le logiciel 3D ou se trouvent dans le fichier journal de l'exportateur « tm.log » dans le dossier intermédiaire.

```
<[graphics_input][ThrottleLeverPosition][]
                 <[string8][InputID][ThrottleLeverPosition.Output]>
             >
             <[hingedbodygraphics][ThrottleLeverGraphics][]
                 <[uint32][PositionID][Fuselage.R]>
                 <[uint32][OrientationID][Fuselage.Q]>
                 <[string8][GeometryList][ ThrottleLever ]>
                 <[string8][Input][ThrottleLeverPosition.Output]>
                 <[float64][Mise à l'échelle][0.5]>
                 <[tmvector3d][Axis][ 0.0 1.0 0.0 ]>
                 <[tmvector3d][Pivot][ 5.123 0.0 -0.321 ]>
             >

```

### Résumé

1. L'objet 'control\_input' dans la section dynamique lit la position du périphérique d'entrée de contrôle de l'utilisateur et rend cette valeur disponible dans toute la section dynamique sous le nom de 'ThrottleLever.Output'.
2. Un objet 'output' portant le nom 'ThrottleLeverPosition' est déclaré dans la section dynamique, ce qui rend sa valeur d'entrée également disponible pour les objets 'graphics\_input' et 'soundinput' dans les sections graphiques et sonores respectivement.
3. Dans la section graphique, un 'graphics\_input' reçoit les valeurs envoyées par la dynamique. Désormais, la valeur de l'angle du levier des gaz est disponible sous la forme « ThrottleLeverPosition.Output » pour tous les objets de la section graphique.
4. L'objet 'hingedbodygraphics' fait pivoter toutes les géométries de sa GeometryList en fonction de la valeur 'ThrottleLeverPosition.Output'.

## Débogage

La ressource la plus importante pour le dépannage est le fichier journal du simulateur **tm.log** dans le dossier « Documents/Aerofly FS 2 ». Ce fichier enregistre tous les événements lors de l'exécution d'Aerofly FS 2 Flight Simulator. Il contient des avertissements et des erreurs pouvant être générés lors du chargement du nouvel avion.

Les problèmes courants lors du développement d’avions sont :

* **La syntaxe** a été accidentellement modifiée… faites particulièrement attention aux accolades et aux crochets, pour chaque crochet/accolade ouvrant, il doit également y en avoir un de fermeture. Certains éditeurs de texte proposent une fonction de comptage, qui peut vous aider à retrouver la position du caractère manquant.
* **Fautes d'orthographe** , Aerofly est sensible à la casse et n'autorise pas les espaces.
* **Même nom d'identification** utilisé plus d'une fois par section
* **Boucles infinies** créées en utilisant la sortie du même objet ou en enchaînant un objet à une boucle sans aucun objet dans la chaîne pouvant fournir un retard (comme un servoclassique ou un servolinéaire).
* **L'objet référencé** n'existe pas (par exemple, essayer d'appeler .Output sur un objet qui n'est pas défini dans la portée de la même section)
* **Pièce d'objet 3D utilisée plusieurs fois** dans une section
* **Force d'articulation** (de connexion) et constantes d'amortissement trop élevées (affichera un écran noir ou l'avion explosera)
* **Sortie/Entrée** non définie ou noms ne correspondant pas (lien entre les sections rompu)
* **Les noms des messages de contrôle** ne correspondent pas (lien des contrôles vers la dynamique rompu)
* **Le qualificateur de message de contrôle** « bascule » n'est pas défini pour un interrupteur à bascule

Pour déboguer une chaîne plus longue d'objets connectés, il suffit d'écraser la propriété d'entrée d'un objet en remplaçant le texte xyz.Output habituel par « 1.0 », « 0.0 » ou toute autre valeur constante. Notez que les entrées avec un « ID » dans leur nom ne lisent pas directement la valeur mais utilisent plutôt un objet pointeur. Il est possible d'écrire une valeur constante dans le paramètre InputID d'un objet.

Pour le débogage, il est très utile d'attribuer une clé au 'Reload plane' dans les paramètres de contrôle du simulateur (disponible uniquement si l'option 'developer' est définie sur true dans le 'main.mcf'). En utilisant cette fonction, seul l'avion mais aucune scène n'est rechargé.