La mise en réseau du Simulateur

Un problème complexe

L'interface réseau du simulateur s'est vite révélée plus complexe à mettre en œuvre que nous ne le pensions au départ. En effet, nous devions être capables d'envoyer à la fois des informations à l'IHM déportée à un rythme relativement soutenu, mais également de pouvoir recevoir des ordres de l’application Android, et ce sans diminuer les performances de la simulation par le moteur Raydium.

Le formatage et l'envoi de message

Nous avons décidé dans un premier temps de mettre en place une interface de parsage et d'envoi de trames externe à l'implémentation des fonctions existantes dans le simulateur notamment les fonctions de rappel utile à la physique et au rendu graphique. Pour cela, nous n'utilisons qu'une seule fonction à nombre de paramètres variable pour créer la trame que va envoyer le simulateur afin de simplifier l'utilisation directement à partir des fonctions citées ci-dessus et une autre fonction qui permet de l'envoyer sur le socket.

Ce diagramme nous permet de voir le flot d'exécution du simulateur lorsque nous avons décidé d'intégrer le formatage des messages et l'envoi à l'IHM des informations du drone simulé. On peut voir qu'entre chaque boucle d'affichage, la création et l'envoi de ces trames prennent du temps, et si les traitements sont trop longs, on perd en performances.

La fonction de formatage se base sur l'utilisation d'une énumération déterminant le type de trame que l'on souhaite envoyer, en lui donnant par la suite les différentes variables afin de créer la trame. Cette fonction est très puissante puisque toute la création de la trame est centralisée au même endroit, cependant elle reste gourmande en raison de l'utilisation de fonctions sur les chaînes de caractères qui prennent du temps processeur tels que sprintf.

Cette méthode nous permettait alors de formater jusqu'à une dizaine de trames par secondes et de l'envoyer sur le socket sans avoir de baisse de performances significative sur l'affichage ni les calculs de la physique. Cependant, l'implémentation ne permettait pas encore la flexibilité escomptée ni une implémentation de la réception d'informations par le simulateur.

La Mise en place des threads

La solution qui nous a paru la plus appropriée pour améliorer le réseau de l'application a été de mettre en place toute la partie réseau autant en écriture qu'en lecture dans différents thread spécialisés pour ces tâches.

On peut voir sur ce diagramme que chaque opération pouvant prendre un certain temps (déterminé ou non) possède leur propre flot d'exécution. Chaque thread peut être arrêté indépendamment des autres sans bloquer l’exécution du simulateur.

Cette méthode nous permet désormais d'envoyer et de recevoir des informations en parallèle des fonctions de rappels de Raydium/ODE de manière beaucoup plus performante sans bloquer le flot d’exécution principal du programme.

Cependant, même si avec la première version de l'application, l'envoi de trames était directement synchronisé avec la boucle de rendu du programme (plus ou moins de 60 images par secondes) nous n'avions plus cette synchronisation avec notre implémentation multithread. Pour cela il nous a suffi d'utiliser des variables de conditions entre les threads dont nous souhaitions la synchronisation, cela a été fait entre le thread d’envoi d'informations du drone et la fonction de rappel de display de Raydium, afin d'avoir exactement un nombre de trames égales au nombre d'images par secondes de l'application et donc de permettre une mise à jour en temps réel de l'IHM la plus précise possible.

Cette implémentation nous permet d'envoyer un nombre de trames beaucoup plus important par secondes sur le réseau et permet en outre une réception d'information simplifiée. Elle permet également de s'affranchir de tout code en rapport avec le réseau dans le reste de l'application et donc une relecture et une compréhension du code facilitée. De plus, la création des threads est déportée dans une fonction à part et l'intégration de nouveaux threads pourra se faire de façon très simple.

Compatibilité Windows / Linux

La compatibilité Windows et Linux, fil rouge de notre projet, est assurée par l'utilisation de la bibliothèque pthread pour la mise en place des threads et par une compilation différente au niveau réseau pour les sockets de par l'utilisation de directives de préprocesseur spécifiques à ces deux systèmes.

Diagramme_d_activité_du_simulateur.png (30.6 KB) Charles Neau, 03/28/2013 01:22 AM

Diagramme_d_activité_du_simulateur_multi-thread.png (68.9 KB) Charles Neau, 03/28/2013 01:22 AM