• Aucun résultat trouvé

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations pixélisées

N/A
N/A
Protected

Academic year: 2021

Partager "Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations pixélisées"

Copied!
35
0
0

Texte intégral

(1)

HAL Id: hal-02793473

https://hal.inrae.fr/hal-02793473

Submitted on 5 Jun 2020

HAL is a multi-disciplinary open access

archive for the deposit and dissemination of sci-entific research documents, whether they are pub-lished or not. The documents may come from teaching and research institutions in France or abroad, or from public or private research centers.

L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des établissements d’enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Mise en place de la conversion automatisée des entrées

au sein d’une plateforme de simulations pixélisées

Colas Pomies, Sylvain Boulenger

To cite this version:

Colas Pomies, Sylvain Boulenger. Mise en place de la conversion automatisée des entrées au sein d’une plateforme de simulations pixélisées. Milieux et Changements globaux. 2015. �hal-02793473�

(2)

Institut Supérieur d’Informatique,

de Modélisation et de leurs Applications Campus des Cézeaux

24 avenue des Landais BP 10125

63173 AUBIERE cedex

UREP - INRA Site de Crouel 5, Chemin de Beaulieu 63039 CLERMONT FERRAND cedex 2

Rapport d’ingénieur

Projet de 2

ème

année

Filière : F2 – Génie Logiciel et Systèmes Informatiques

Mise en place de la conversion automatisée

des entrées au sein d'une plateforme

de simulations pixélisées

Présenté par : Colas POMIES

Sylvain BOULENGER

(3)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Remerciements

Nous tenons à remercier notre tuteur de projet M. Raphaël MARTIN ainsi que M. Ulrich EZA tous deux Ingénieur de Recherche à l’UREP, d’avoir était présent durant toute la durée de ce projet, nous permettant ainsi d’organiser des rendez-vous régulièrement.

Nous remercions aussi de manière plus globale toute l’Unité de Recherche sur l’Écosystème Prairial (UREP) de l’Institut National de la Recherche Agronomique (INRA) pour nous avoir accueillis au sein de leurs locaux de Crouël.

(4)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Résumé

Notre projet de deuxième année était de développer en C++/Qt une bibliothèque de

conversion d’unité automatisée intégrable au sein d’une plateforme d’analyse des risques liés

au changement climatique développée par l’UREP. La bibliothèque doit être capable de fournir un moyen de conversion d’une unité source vers une unité cible pour effectuer ensuite un

traitement par lot, ou de prévenir d’une conversion impossible. Pour ce dernier cas, le

convertisseur doit vérifier l’homogénéité de la conversion avant tout.

Nous avons donc développé une bibliothèque C++ utilisant le framework Qt qui est capable de stocker des unités de manières à effectuer simplement des opérations dessus. Elle est effectivement capable de vérifier si une conversion est réalisable et le cas échéant de l’effectuer. Elle est modulable grâce à une configuration via un fichier un XML définissant les unités références. Les quelques tests effectués lors de notre dernière visite à l’INRA sont concluants même si notre outil semble encore en difficulté sur certaines unités complexes.

Mots-clés : C++/Qt, bibliothèque, conversion d’unité, traitement par lot, XML

Abstract

Our second year project was to develop an automated unit conversion library, using the C++ programming language and the Qt framework. The project was integrated in a platform, developed by the UREP, to assess vulnerabilities to climate changed. The library must be able to provide a way to realise unit conversion in order to perform batch conversion, checking the homogeneity of the formula first so that it warns the user if the operation is impossible. Hence we developed a C++ library using the Qt framework. It can store units so that they can easily be used in operations. It checks the feasibility of a conversion before performing it. The library is modular thanks to an XML configuration file that defines some "reference units". The tests performed during our last visit at UREP were conclusive even though the library seems to struggle with some more complex unit.

(5)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Table des matières

Remerciements ... i

Résumé ... ii

Abstract ... ii

Introduction ... 1

I - Déroulement du projet ... 2

A. Organisation du projet ... 2 B. Les objectifs ... 2

II - Outils et méthodes ... 3

A – Choix des outils ... 3

B – Architecture globale ... 3

III – Gestion des unités ... 5

A – Structure générale ... 5

B – Représentation de la dimension ... 5

i – Représentation des dimensions de base ... 6

ii – Les opérateurs ... 6

iii – Unité en dehors des dimensions de base ... 7

C – Calcul des facteurs de conversion ... 8

i – Les bases de la classe Conversion ... 9

ii – Utilisation de deux facteurs ... 10

iii – Utilisation d’un polynôme ... 10

iv - Utilisation de deux polynôme ... 12

D – Les opérateurs ... 13

IV – Gestion du convertisseur ... 15

A – Les unités et facteurs de base ... 15

B – Extraire une unité ... 16

i – Utilisation des expressions régulières ... 16

ii – Algorithme d’extraction ... 18

C – Charger un fichier XML ... 20

(6)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

ii – Choix du format du fichier ... 20

iii – Algorithme de lecture ... 20

D – Algorithmes principaux ... 21

i – Calculer la conversion ... 21

ii – Utiliser les résultats ... 22

V – Résultats ... 23

VI – Perspectives ... 24

Conclusion ... iv

Table des figures ... v

Lexique ... vi

(7)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Introduction

Ce projet nous a été confié par l’Institut National de la Recherche Agronomique (INRA) et plus précisément par l’Unité de Recherche sur l’Ecosystème Prairial (UREP) située sur le site de Crouël, même si nombre de ses dispositifs expérimentaux sont positionnés sur les domaines de Theix ou de l'Unité Expérimentale des Monts d'Auvergne (UEMA).

L'UREP possède une expertise internationale dans le domaine de l'écologie prairiale et plus particulièrement sur l'impact du changement climatique.

C’est dans ce cadre que l’UREP effectue de nombreuses simulations à partir de données préexistantes dans des unités variées dans le but d’analyser les risques liés au changement climatique. L’outil au sein duquel sera intégré notre projet a pour but de mettre en forme des fichiers d’entrées et d’homogénéiser les données à destination de modèles de simulation, puis d’interpréter les résultats de façon à produire des graphiques.

Notre projet sera utile au logiciel pour réaliser sa première tâche : mettre en forme des fichiers d’entrées et homogénéiser les données. La bibliothèque développée va en effet permettre de convertir des mesures physiques par lot de façon rapide et modulable en permettant de modifier les unités de référence.

Jusqu’à présent, les conversions d’unité étaient faites à la main, via des fonctions spécifiques à chaque conversion. Ici le but était d’automatiser ce traitement afin de l’accélérer et de le fiabiliser en évitant les éventuelles erreurs d’une conversion manuelle.

Pour effectuer ce travail il nous a fallu envisager plusieurs solutions au cours de plusieurs entretiens afin de déterminer la meilleure façon de faire et comment répondre aux contraintes d’intégrations de l’UREP.

Pour présenter ce projet, nous aborderons l’organisation globale et le déroulement du projet avant de présenter les outils et méthodes que nous avons utilisés. Afin de présenter au mieux l’un des points clefs qu’est la gestion des unités, nous verrons la structure utilisée ainsi que les différents concepts impliqués dans la gestion des dimensions et de la conversion. Enfin, nous présenterons la façon dont est géré le convertisseur d’unité, son initialisation et son fonctionnement avant d’achever ce rapport par un bilan du projet.

(8)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

I - Déroulement du projet

A. Organisation du projet

La première étape de ce projet a été de prendre contact avec notre tuteur à l’INRA afin d’organiser une première rencontre et discuter du projet. Nous avons alors pu discuter avec eux de leurs besoins, de leurs contraintes et ainsi déterminer les différents objectifs de ce projet.

Nous avons également décidé de nous rencontrer régulièrement pour se tenir informés de l’avancement du projet, mais aussi pour discuter des choix et solutions envisagées et trouver plus facilement les solutions aux problèmes que nous avons pu rencontrer. Leurs avis ainsi que leur vision des choses nous ont beaucoup aidés pour mener à bien ce projet.

B. Les objectifs

Ces échanges réguliers et constructifs ont conduit à la détermination des objectifs suivants :

• L’outil développé prendra la forme d’une bibliothèque afin de pouvoir s’intégrer à un projet existant facilement. C’est une demande qui nous a été formulé dès le début du projet.

• La bibliothèque devra être capable de vérifier l’homogénéité et la validité de la conversion demandée. Si toutefois la conversion demandée était impossible, l’utilisateur devra en être averti. Pour ce dernier point nous sommes tombés d’accord pour mettre en place des exceptions personnalisées pour gérer les problèmes d’unité inconnue et de conversion impossible.

• La bibliothèque sera capable d’assurer des conversions plus ou moins complexes, de façon rapide, générique et fiable, tout en assurant une erreur minimale.

• Elle devra être modulable, dans le sens où il doit être possible d’ajouter ou de retirer des unités de références. Pour cela nous avons proposé l’utilisation d’un fichier de configuration XML contenant la description des unités que connaitra l’application. Cette proposition ayant été retenue, elle est intégrée au rendu final. Quelques objectifs « secondaires » ont également été envisagés :

• La possibilité de spécifier des unités « personnalisées » en utilisant le fichier de configuration XML.

Le développement d’une application pour éditer ces fichiers de configuration XML, listant le contenu de façon claire et lisible et permettant l’ajout d’unité en renseignant les informations nécessaires.

(9)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

II - Outils et méthodes

A – Choix des outils

La plateforme de simulation dans laquelle notre bibliothèque doit s’intégrer étant développée en C++ c’est tout naturellement que nous nous sommes orientés vers ce langage pour réaliser notre projet.

De plus, la plateforme utilisant le framework Qt, nous avons également décidé de nous appuyer sur celui-ci pour que notre projet reste cohérent avec la plateforme de simulation. De plus, ce framework étant multiplateforme, cela facilite le développement et le déploiement du projet.

L’utilisation du framework Qt nous a également poussés vers l’utilisation de l’implémentation Qt des expressions régulières : QRegex. En effet les expressions régulières sont très utiles pour extraire et vérifier les unités.

Trois choix s’offraient à nous : les QRegex de Qt, les boost::regex de boost ou les expressions régulières intégrées au sein de c++11. Celles de boost furent écartées d’emblée car nécessitant l’ajout d’une bibliothèque supplémentaire (boost) au projet. Les expressions régulières de c++11 sont connues pour poser des problèmes à certains compilateurs. Enfin, le framework Qt étant déjà utilisé, aucune nouvelle dépendance n’était nécessaire pour pouvoir utiliser les QRegex, d’où ce choix.

Enfin, pour pouvoir avoir un suivi régulier des modifications apportées aux sources du projet et faciliter le travail en équipe nous avons décidé d’utiliser un gestionnaire de version. Dans notre cas nous avons utilisé Subversion (SVN) et le client Tortoise SVN car nous avons l’habitude de l’utiliser et que nous possédons déjà un dépôt.

B – Architecture globale

A la suite de notre premier rendez-vous à l’UREP, nous souhaitions donc que le fonctionnement de la bibliothèque soit le suivant : le Convertisseur charge le fichier XML et s’initialise alors en conséquence. L’utilisateur va alors pouvoir lui demander des conversions et recevoir un résultat lui fournissant la méthode de conversion ou levant une exception si la conversion est impossible.

Chargement XM L Calcul Conversion

Utilisation du résultat Exception [Conversion OK ] [Echec Conversion]

(10)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Pour assurer ce fonctionnement il nous fallait une architecture s’articulant autour d’une classe ConvertisseurINRA et d’une autre pour représenter les unités.

Le but du ConvertisseurINRA est de fournir à l’utilisateur une méthode pour charger des données références depuis un fichier XML et une méthode calculant la conversion entre deux unités. Pour pouvoir effectuer ces traitements elle a besoin d’un ensemble d’unités qu’elle stocke en attribut.

ConvertisseurINRA + loadXM L

+ getConversion

Unite

*

Figure 2 : Lien Unite / ConvertisseurINRA

Le développement de la classe Unite a été une part très importante de notre projet que nous allons maintenant vous détailler.

(11)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

III – Gestion des unités

L’un des points clef du développement de ce projet fût la gestion et l’intégration des unités au sein de la bibliothèque. En effet, il était nécessaire de réfléchir à une méthode pour les convertir et donc de déterminer quelles données seraient nécessaires.

Pour pouvoir gérer les unités au sein de notre bibliothèque nous avons décidé d’écrire une classe Unite. Cette classe a pour but de représenter une unité, mais nous avons aussi fait en sorte qu’elle puisse gérer les différentes interactions qui existent entre elles. Nous allons donc vous présenter dans un premier temps la structure générale de cette classe. Nous expliquerons ensuite comment nous avons implémenté les éléments de celle-ci qui permettent de représenter la dimension de l’unité et le calcul des facteurs de conversion.

A – Structure générale

Une unité est en premier lieu définie par un nom et une abréviation, par exemple la « seconde » a pour abréviation « s ». L’abréviation d’une unité est, dans le système international, unique et permet de l’identifier au sein d’une équation. C’est donc tout naturellement que c’est aussi l’identificateur que nous avons retenu pour différencier les unités au sein de la bibliothèque. Ces deux éléments sont implémentés avec des QString dans notre classe car c’est la classe du framework Qt qui permet de représenter des chaînes de caractères.

Certaines unités étant le résultat d’opérations entre d’autres unités, par exemple le Joule (J) équivaut à des « kg.m2.s-2 », nous avons eu recourt à la surcharge des opérateurs de la classe Unite. Nous reviendrons plus tard sur ces derniers, car ils affectent la représentation de la dimension de l’unité et ses facteurs de conversion qui sont deux parties importantes de la classe que nous détaillerons dans les parties suivantes.

B – Représentation de la dimension

Pour qu’une conversion soit possible entre deux unités, il faut qu’elles soient toutes les deux dans la même dimension. La dimension d’une unité est la grandeur physique qu’elle représente. Il existe sept dimensions physique de base qui sont la longueur, la masse, le temps (ou la durée), l’intensité électrique, la température thermodynamique, la quantité de matière et l’intensité lumineuse. À partir de ces dernières on peut définir des dimensions dérivées, par exemple la vitesse qui est le rapport d’une longueur sur une durée.

Pour pouvoir représenter une dimension dans notre bibliothèque nous avons créé une classe Dimension puis nous avons ensuite ajouté à notre classe Unite un attribut du type Dimension. Nous allons maintenant vous présenter comment nous avons conçu cette classe.

(12)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

i – Représentation des dimensions de base

Nous avons vu qu’il y avait sept dimensions de base desquelles découlent toutes les dimensions physiques. Chaque dimension est donc définie par un certain nombre de fois chaque dimension de base. Si on reprend l’exemple de la vitesse, elle est composée d’une fois la longueur et de moins une fois la durée. En effet, une division par une dimension implique un facteur négatif à celle-ci. Ainsi, pour donner un exemple plus complet, une force est définie par une fois une masse, une fois une distance et moins deux fois une durée (N = kg.m.s-2).

Pour représenter les sept dimensions de base dans notre classe Dimension nous avons décidé de créer un vecteur d’entier, chacune des colonnes de ce vecteur représentant le facteur d’une des sept dimensions de base. Il nous suffit donc de remplir ce tableau avec les facteurs adéquats pour représenter une dimension physique. Si on reprend notre exemple sur la force il faut donc mettre un facteur 1 aux colonnes représentant la masse et la longueur, un facteur -2 à la colonne de la durée et un facteur 0 aux autres colonnes. Dans notre cas nous avons décidé d’implémenter ce vecteur avec un QVector<int>.

Pour être sûr de toujours initialiser des vecteurs de bonne taille nous utilisons une constante NB_DIMENSION initialisé à 7. Enfin, pour que chaque entrée du vecteur corresponde à une et une seule dimension nous avons écrit une énumération (« enum ») qui associe à chaque dimension de base à un nombre entre 0 et 6.

Grâce à cette implémentation il nous est donc possible de représenter simplement une dimension physique. Cependant, pour créer de nouvelles dimensions de manière dynamique nous devons faire des opérations sur les dimensions. Nous avons donc dût implémenter les opérateurs sur la classe Dimension.

ii – Les opérateurs

Il est possible de faire deux types d’opérations entre des dimensions, des

multiplications et des divisions. Il est également possible d’appliquer des puissances sur les dimensions, mais cela reviens à effectuer plusieurs divisions ou multiplications. Nous avons donc surchargé les opérateurs de multiplication et de division de la classe Dimension.

• Multiplier deux dimensions entre elles consiste seulement à additionner pour chaque dimension de base leurs facteurs.

• Diviser une dimension A par une dimension B consiste à soustraire à chaque facteur de dimension de base de A la valeur du facteur de dimension de base correspondant dans B.

Avec ces méthodes, on peut donc simplement implémenter les opérateurs de multiplication et de division. Nous avons également surchargé les opérateurs d’affectation par multiplication et d’affectation par division selon la même méthode. Ces opérateurs nous ont permis de définir une méthode qui retourne le résultat de la dimension affectée par une puissance, comme s’il existait un opérateur puissance.

(13)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

En effet, pour calculer ce résultat il faut initialiser une dimension avec des facteurs égaux à zéro pour les dimensions de base puis, si la puissance est positive il faut multiplier cette dimension neutre par la dimension de départ autant de fois qu’indiquer par la puissance. Enfin, si la puissance est négative il faut faire le même raisonnement mais en divisant la dimension neutre par la dimension de départ. Sur ce même principe, nous avons également développé une méthode qui effectue la puissance sur la dimension sur laquelle elle est appelée, comme un opérateur d’affectation par puissance.

Enfin, nous avons surchargé l’opérateur de comparaison d’égalité qui retourne vrai si les deux dimensions représentent la même grandeur physique et faux sinon. Pour cet opérateur nous avons seulement eu besoin de comparer les facteurs des dimensions de base entre eux. Cet opérateur permet donc de vérifier simplement si deux unités sont compatibles pour effectuer une conversion en comparant leur dimension.

Pour résumé, la classe Dimension permet de représenter simplement la dimension d’une unité et d’effectuer des opérations au niveau celle-ci.

iii – Unité en dehors des dimensions de base

Grâce à l’implémentation de la classe Dimension présentée précédemment, il est possible de représenter la dimension de toutes les unités qui ont un rapport avec les dimensions de base de la physique. Cependant, tel que définis dans les objectifs de notre projet, nous devons être capables de gérer des unités qui ont une dimension en dehors des dimensions de base. En effet, l’UREP utilise des unités qui sont propres à leur domaine d’étude : il y a par exemple l’Unité Gros Bétail, ou Unité Gros Bovin, qui permet de représenter les besoins nutritionnels de chaque type d’animal d’élevage. La grandeur physique que cette unité représente ne peut être associée à aucune des sept dimensions de base que nous avons vues précédemment. Nous avons donc dû modifier la classe Dimension pour gérer ce genre type d’unité.

Pour résoudre ce problème, nous avons utilisé un conteneur associatif qui associe un entier à une chaîne de caractère. Les identificateurs de ce conteneur (les chaînes de caractère) représentent chaque unité qui n’a pas de rapport avec les dimensions de base. L’entier qui lui est associé représente son facteur et ce conteneur permet donc de créer de nouvelles dimensions aisément. Pour implémenter ce conteneur nous avons utilisé la classe QMap<QString, int>.

L’ajout de ce conteneur nous a contraint à modifier nos opérateurs. En effet, nous avons dû effectuer les opérations que nous faisions sur les facteurs de dimensions de base sur les facteurs contenus dans le conteneur associatif. Dans le vecteur des dimensions de base, nous effectuions ces mêmes opérations, il faut donc garder ce principe en considérant que si une entrée n’est pas définie dans le conteneur associatif alors il faut la définir avec pour facteur 0. En ajoutant simplement ces modifications dans les opérateurs de multiplication, de division, d’affectation par multiplication et d’affectation par division nous pouvons donc gérer toutes les opérations que nous avions définies en prenant en compte les dimensions qui sont en dehors des dimensions de base.

(14)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Avec l’ajout de cette fonctionnalité nous avons également dû modifier l’opérateur de comparaison d’égalité pour vérifier que deux dimensions soient bien homogènes. Nous avons donc dû rajouter un test qui vérifie qu’il y a les mêmes entrées dans les conteneurs associatifs de chacune des deux dimensions et que ces entrées contiennent les mêmes facteurs. Si ce test retourne vrai et que le test sur les vecteurs des dimensions de base retourne également vrai alors les deux dimensions sont homogènes et la conversion est possible

Grâce à cette méthode nous pouvons donc gérer les unités qui n’ont pas de rapport avec les dimensions de base. Cependant, il est également possible d’ajouter une dimension de base dans l’énumération qui les définit et d’incrémenter la constante de nombre de dimension de base. Faire ceci permet de rajouter une nouvelle dimension et donc de définir des unités en fonction de cette dimension, rendant ainsi la bibliothèque plus permissive. Le problème de cette solution est qu’elle oblige à changer les sources de la bibliothèque et donc à la recompiler à chaque modification que l’on souhaite effectuer.

Grâce à la classe Dimension il nous est possible de représenter la dimension d’une unité et de tester si la conversion entre deux unités est possible. Dans ce cas, il faut être capable de calculer et de fournir à l’utilisateur un moyen pour convertir des valeurs d’une unité vers l’autre. Nous allons donc vous présenter comment nous avons fait pour calculer ces facteurs de conversion.

C – Calcul des facteurs de conversion

Le calcul des facteurs de conversion entre deux unités est une partie essentielle de notre projet. C’est d’ailleurs cette partie qui nous a demandé le plus de travail de réflexion pour trouver une solution fiable. En effet, lors de nos différents rendez-vous avec nos tuteurs, nous avons discuté des différentes méthodes pour résoudre ce problème. Nous avons donc fait évoluer notre solution au fur et à mesure des problèmes que rencontrés et des discutions avec nos tuteurs.

Pour gérer le calcul des facteurs de conversion nous avons décidé de créer une classe Conversion et d’ajouter un membre de type Conversion à la classe Unite. C’est donc essentiellement cette classe qui a évolué au cours du projet. Nous allons vous présenter les bases de cette classe pour ensuite montrer les différentes solutions par lesquelles nous sommes passés avant d’arriver à la solution actuelle. Pour chacune des celles-ci nous vous présenterons comment nous les avons implémentées ainsi que les problèmes que nous avons rencontrés et qui nous a donc poussé à faire évoluer notre solution.

(15)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

i – Les bases de la classe Conversion

Lors de notre premier entretient avec nos tuteurs, nous avons décidé qu’il serait judicieux d’exprimer les deux unités que nous avons besoin de convertir en fonction d’unité de base. Ainsi nous pouvions calculer les facteurs de conversion de l’unité source vers les unités de base puis les facteurs de ces dernières vers l’unité cible. Grâce à ce système il nous suffisait de créer une unité associée à chaque dimension physique de base pour pouvoir représenter toutes les unités étant dans ces dimensions. En effet, en ayant des facteurs de conversion vers ces unités de base pour toutes nos unités, il nous était simple de calculer les facteurs pour faire la conversion d’une unité source à une unité cible.

Pour définir les unités de base permettant de représenter les dimensions physiques de base, nous avons décidé d’utiliser les unités du système international qui sont :

• La seconde (s) pour le temps • Le mètre (m) pour la longueur • Le kelvin (K) pour ma température • L’ampère (A) pour l’intensité électrique • La mole (mol) pour la quantité de matière • La candela (cd) pour l’intensité lumineuse

Pour la masse, nous avons préféré utiliser comme unité de base le gramme (g) plutôt que le kilogramme (kg) car cette unité n’est pas composée d’un préfixe modificateur, ce qui n’est pas le cas du kilogramme qui est composé du préfixe kilo (k).

Grâce à la classe Dimension expliquée dans la partie précédente et en exprimant toutes nos unités en fonction des unités de base, on obtient facilement la dimension de notre unité La classe Conversion a donc pour principal objectif d’exprimer les facteurs de conversion. De plus, comme pour la classe Dimension, il est possible de faire des opérations sur les facteurs. Nous avons donc utilisé la surcharge d’opérateur sur la classe Dimension pour gérer ces opérations. Les opérateurs qui ont été redéfinis sont les suivants, accompagnés de leur opérateur d’affectation respectif :

• Multiplication entre deux objets Conversion,

• Multiplication entre un objet Conversion est un réel • Division entre deux objets Conversion

• Division d’un objet Conversion par un réel • Addition entre un objet Conversion et un réel • Soustraction entre un objet Conversion et un réel

Comme pour la Classe Dimension, nous avons créé une méthode qui renvoi des facteurs affectés par une puissance et une méthode qui modifie les facteurs de l’objet Conversion sur lequel elle est appelée.

Dans les parties qui suivent nous allons donc vous présenter comment nous avons géré la représentation des facteurs au sein de la classe Conversion ainsi que la surcharge des opérateurs de cette dernière.

(16)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

ii – Utilisation de deux facteurs

La première solution qui a été envisagée était d’avoir uniquement un facteur multiplicateur et un facteur additionnel ce qui permet de facilement définir la plupart des unités. Par exemple, le joule (J) qui est défini par 1J = 1000 g.m.s-2 aurait pour facteur multiplicateur 1000 et pour facteur additionnel 0. Le degré Celsius (°C) est quant à lui définit par 1°C = 1K 273.15, il a donc un facteur multiplicateur de 1 et un facteur additionnel de -273.15.

Cette solution est très simple à implémenter et elle permet de surcharger la plupart des opérateurs. Il est effectivement très simple d’implémenter les opérateurs d’addition et de soustraction avec un réel en additionnant ou de soustrayant le réel en paramètre au facteur additionnel.

Pour ce qui est des opérateurs de multiplication et de division avec des réels, il faut multiplier ou diviser les deux facteurs de la classe Conversion par le réel passé en paramètre. Les limites de cette solution se font sentir lorsque l’on veut implémenter les opérateurs de multiplication et de division entre classe Conversion. On se rend compte que si on multiplie deux classes Conversion entre elle, cela revient à multiplier deux polynômes de type ax+b entre eux. Hors le résultat de la multiplication de deux polynômes du premier degré donne un polynôme du second degré qui n’est pas représentable avec un simple facteur multiplicateur et un facteur additionnel.

Ce problème qui est apparu lors de notre développement nous a amené à faire évoluer notre solution en exprimant les facteurs de conversion sous forme de polynôme plutôt qu’avec deux facteurs.

iii – Utilisation d’un polynôme

La deuxième solution que nous avons développée consistait donc à exprimer les facteurs de conversion sous forme de polynôme. Cette solution permettait de reprendre le principe de la solution précédente, car n’avoir qu’un facteur multiplicateur et un facteur additionnel équivaut à avoir un polynôme du premier degré.

Pour modéliser un polynôme dans la classe Conversion nous avons décidé d’utiliser un vecteur. Cette structure de donnée permet d’avoir la liste des facteurs pour chaque puissance du polynôme. Ainsi, pour un polynôme de taille N, on associe un vecteur de taille N+1 avec en entrée 0 comme facteur de rang 0 du polynôme. Pour implémenter ce vecteur dans notre classe, nous avons utilisé un QVector<int>.

Grâce à cette méthode on peut toujours effectuer les opérations d’addition et de soustraction avec des réels, il faut pour cela effectuer le traitement de la méthode précédente, mais cette fois-ci sur l’entrée zéro du vecteur. Pour les opérations de multiplication et de division par un réel il suffit d’effectuer l’opération sur toutes les entrées du vecteur pour que

(17)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Pour faire la multiplication entre deux objets de type Conversion il faut effectuer une multiplication entre les deux polynômes qui sont contenus dans ces objets. Pour cela, il faut construire un nouveau vecteur correspondant au résultat de cette opération. On effectue ensuite toutes les multiplications deux à deux sur les deux vecteurs, représentant les deux polynômes. Pour chacune de ces multiplications, on calcule le degré correspondant au résultat de cette opération et on incrémente l’entrée correspondant à ce degré dans le vecteur final avec le résultat de cette multiplication.

En utilisant des polynômes, il est simple d’effectuer une multiplication entre deux objets de type Conversion, cependant il devient plus difficile d’effectuer une division de l’un par l’autre. Nous avons donc dû réfléchir avec nos tuteurs à la représentation physique d’une division par une unité. Nous en avons conclu que diviser une unité A par une unité B correspond à diviser le polynôme représentatif de l’unité A par une fois l’unité B, c’est-à-dire par le résultat du polynôme représentatif de B calculé avec comme valeur d’entrée 1.

Un exemple peut aider à mieux comprendre ce résultat. Lorsque l’on étudie une vitesse en « m/s » on étudie une longueur parcourue, ici en mètre, lorsqu’une unité de temps s’est passée, ici la seconde. Notre mesure s’effectue uniquement sur une seconde, c’est pour cela qu’on divise le polynôme représentatif de l’unité A, ici le mètre, par le polynôme représentatif de B, ici la seconde, avec comme paramètre d’entrée un.

Grâce à l’implémentation des opérateurs de multiplication et de division, nous avons pu écrire simplement les deux méthodes qui gèrent la notion de puissance sur les facteurs de conversion. Pour cela il suffit d’initialiser des facteurs neutre, soit un polynôme du premier degré avec comme facteur de degré zéro 0 et comme facteur de degré un 1. Si la puissance est égale à zéro alors on retourne ce polynôme. Si la puissance est positive on multiplie par l’objet Conversion sur lequel la méthode est appelée, autant de fois qu’indiqué par la puissance. Si la puissance est négative on effectue le même procédé, mais en divisant.

L’utilisation de polynôme sous forme de vecteur et la surcharge de certains opérateurs nous ont permis d’obtenir les facteurs de conversion nécessaire pour passer d’une unité à sa représentation dans les unités de base. Pour pouvoir passer des unités de base à l’unité en question, il faut calculer l’inverse du polynôme. Ce calcul est rapide si le polynôme a été généré à partir de conversion basique, c’est-à-dire avec uniquement des facteurs multiplicateurs. En effet, si un polynôme est créé de cette manière il ne sera composé que d’un seul facteur non nul, il suffit donc d’inverser ce facteur pour effectuer la conversion inverse. Si jamais le polynôme est plus compliqué, il est impossible de calculer le polynôme inverse.

Cette solution se rapproche des objectifs attendus pour le projet, mais ne permet pas de résoudre certaines conversions. Pour pallier ce problème, nous avons décidé de développer une nouvelle solution nous permettant d’effectuer des conversions inverses sans avoir à inverser de polynôme compliqué.

(18)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

iv - Utilisation de deux polynôme

La solution que nous allons vous présenter et la solution actuellement présente dans notre projet. Cette solution n’est pas parfaite, mais permet de répondre à un très grand nombre de besoins.

Cette solution se base aussi sur le système de polynôme comme évoqué dans la partie précédente. En effet, dans cette solution aucune modification n’est faite sur la classe Conversion que nous avons décrite précédemment. Nous avons juste ajouté une méthode « inverse » qui permet d’obtenir l’inverse d’un polynôme du premier degré.

La modification majeure effectuée dans cette solution ne se trouve pas dans la classe Conversion en elle-même mais dans son utilisation. Dans les solutions précédentes, la classe Unite avait un membre de type Conversion qui lui fournissait les facteurs de conversion vers sa représentation en unité de base. Dans cette nouvelle solution, le but est d’avoir deux membres Conversion. Le premier calcule les facteurs pour aller dans les unités de base et le second calcule les facteurs de conversion des unités de base vers l’unité à laquelle il est associé. Grâce à ce système on peut faire une conversion d’une unité A vers une unité B en affectant dans un premier temps les facteurs qui permettent d’aller de A vers les unités de base, puis les facteurs qui permettent d’aller des unités de base vers B.

Pour que cette solution fonctionne il faut bien sûr initialiser le polynôme inverse des unités que l’on utilise. Pour cela, il suffit d’appeler la fonction inverse sur l’objet de type Conversion qui permet de faire la conversion vers les unités de bases. L’inversion de ce polynôme est possible car il s’agit d’un polynôme du premier degré. En effet, les unités de bases qui sont chargées grâce au fichier XML sont en fonctions d’autres unités, mais avec uniquement des facteurs de conversion du premier degré.

De plus, pour générer le moins possible de polynôme complexe lors des opérations effectuées entre objets de type Conversion, nous avons décidé que la multiplication par un polynôme du premier degré avec comme facteur de degré zéro 0 serait considéré comme une multiplication par un réel du facteur de degré un.

Cette nouvelle solution implique également de gérer d’une manière différente les deux objets de type Conversion de la classe Unite en fonction de l’opération que l’on fait sur celle-ci. Ces différences seront expliquées dans la partie suivante qui est dédiée aux opérateurs de la classe Unite.

Enfin, si cette solution permet de gérer des cas plus complexes que la solution précédente, elle n’est pas parfaite pour autant. En effet, il existe encore certain cas pour lesquels le calcul des conversions ne s’effectue pas de la bonne manière. Ces cas sont très spécifiques et apparaissent lorsque l’on multiplie des polynômes différents avec un facteur de degré 0 non nul ou que l’on élève un polynôme de ce type à la puissance 3 ou plus. Ces cas peuvent paraitre très contraignants cependant, après avoir analysé les besoins actuels en

(19)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

D – Les opérateurs

Maintenant que nous avons vu de quoi était constituée la classe Unite, nous pouvons expliquer comment nous avons surchargé les opérateurs de celle-ci. Les opérateurs à surcharger pour la classe Unite sont :

• Multiplication entre deux objets Unite

• Multiplication entre un objet Unite est un réel • Division entre deux objets Unite

• Division d’un objet Unite par un réel • Addition entre un objet Unite et un réel • Soustraction entre un objet Unite et un réel

(20)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Comme pour les classes Dimension et Conversion, nous avons implémenté une méthode permettant de retourner le résultat d’une unité modifiée par une puissance et une méthode effectuant directement les modifications par une puissance sur l’objet sur lequel elle est appelée.

Pour les opérations de multiplication et de division entre deux objets Unite et pour les méthodes associées à la puissance, on appelle simplement ces mêmes opérateurs sur l’objet de type Dimension et les deux objets de type Conversion de la classe Unite.

Pour toutes les autres opérations, c’est-à-dire celles qui font intervenir un objet Unite et un réel, il ne faut pas appeler d’opérateur sur le membre de type Dimension. En effet la classe Dimension définis une grandeur physique, il est donc illogique de lui appliquer des modifications en rapport avec des facteurs. Dans ces opérateurs nous n’appelons donc que les opérateurs associés sur les deux membres de type Conversion. Il y a cependant une subtilité lors de ces appels car ses opérateurs sont là pour modifier la conversion vers les unités de base. Il faut donc appeler les opérateurs associés pour l’objet de type Conversion qui calcul la conversion vers les unités de bases et l’opérateur inverse sur l’objet qui calcul la conversion depuis ces unités. Il faut donc effectuer une soustraction lorsque c’est une addition (et inversement) et une division lorsque c’est une multiplication (et inversement).

Grâce à la surcharge des opérateurs et à l’utilisation des classes Dimension et Conversion nous sommes donc capables de représenter une unité et de faire des opérations sur celle-ci.

(21)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

IV – Gestion du convertisseur

La classe Unite permet de représenter des unités et d’effectuer des calculs entre les unités. Il faut donc une interface au sein de la bibliothèque capable de créer, stocker et manipuler des unités pour pouvoir en extraire des résultats exploitables par l’utilisateur de notre projet.

Pour fournir cet accès nous avons créé la classe ConvertisseurINRA. Cette classe permet de créer les unités de bases, mais aussi de charger un fichier XML contenant la définition des unités que l’utilisateur veut utiliser. Enfin elle permet à l’utilisateur de demander une conversion entre deux unités et d’avoir un retour sur les résultats ou d’être informé si une erreur se produit. La classe ConvertisseurINRA a donc été la partie centrale de notre projet dont nous verrons dans cette partie les différentes fonctionnalités.

A – Les unités et facteurs de base

La classe ConvertisseurINRA a pour but de créer et manipuler les unités pour extraire des résultats. Il faut donc qu’elle soit capable de stocker ces unités pour pouvoir effectuer des traitements sur celles-ci. De plus, comme nous l’avons dit précédemment, nous utilisons l’abréviation des unités pour les identifier. Ces abréviations étant des chaînes de caractères, nous avons décidé d’utiliser un conteneur associatif qui associe à une chaîne de caractères, ici notre abréviation, un objet de type Unite. Grâce à ce conteneur on peut accéder simplement à une unité, si elle est définie, en connaissant uniquement son abréviation. Le choix d’utiliser cette donnée comme identificateur a été renforcé par le fait que nous définissons en général une unité en se basant sur les abréviations d’autres unités.

Par exemple, si nous créons une unité « vitesse » qui a pour abréviation « v » et qui est défini comme étant des « m/s », il est très simple d’extraire depuis la définition de cette unité les unités dont elle découle grâce aux abréviations. Ici on voit très clairement que l’on va avoir besoin des unités « mètre » et « seconde » car on a les abréviations « m » et « s ». Dans notre cas nous avons décidé d’utiliser une QMap<QString, Unite> pour implémenter ce conteneur associatif.

Nous avons vu que pour permettre une conversion simple et rapide nous définissons toutes nos unités en fonctions de sept unités de base qui sont le gramme, la seconde, le mètre, le kelvin, l’ampère, la mol, et la candela. Il faut cependant que ces unités soient créées et stockées quelque part pour que l’on puisse les utiliser. Comme nous pourrons effectuer par la suite des opérations sur ces unités de la même manière que nous allons le faire sur d’autre unité il est logique qu’elles soient stockées dans le conteneur associatif mis en place pour stocker les unités. La différence avec les autres unités est que celles-ci ne sont pas créées dynamiquement grâce à la lecture d’un fichier XML mais qu’elles sont instanciées à la création de la classe ConvertisseurINRA.

(22)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Ainsi, lors de la construction de cette classe nous créons chacune des unités de base en lui affectant son nom, son abréviation, le facteur 1 dans la dimension qu’elle représente et un polynôme du premier degré avec le facteur de degré zéro à 0 et le facteur de degré un à 1. Grâce à ceci on a déjà une base assez solide pour définir par la suite des unités dans n’importe quelle dimension physique de manière très simple.

Pour pouvoir définir de manière plus complète nos unités il faut également ajouter à notre bibliothèque la notion de préfixe modificateur. Les préfixes modificateurs sont des facteurs multiplicateurs que nous utilisons tout le temps pour simplifier les notations. Par exemple, pour éviter de dire « 1000 g » ou même « 10-3 g » on va utiliser le préfixe kilo (k) et dire « 1 kg ». Les préfixes sont très utiles, c’est pour cela que nous avons décidé d’inclure dans notre projet les préfixes les plus courants. En voici une liste avec leur nom, leur symbole et facteur : • le yocto (y, 10-24) • le zepto (z, 10-21) • le atto (a, 10-18) • le femto (f, 10-15) • le pico (p, 10-12) • le nano (n, 10-9) • le micro (µ, 10-6) • le milli (m, 10-3) • le centi (c, 10-2) • le déci (d, 10-1) • le déca (da, 101), • l’hecto (h, 102) • le kilo (k, 103) • le méga (M, 106) • le giga (G, 109) • le tera (T, 1012) • le péta (P, 1015) • le exa (E, 1018) • le zetta (Z, 1021) • le yotta (Y, 1024).

Comme ces préfixes n’ont pas lieu de changer nous les avons décidés de les stocker dans un conteneur associatif liant chaque symbole à sa puissance de dix associée. Ce conteneur est rempli lors de la création de la classe ConvertisseurINRA et ne peux pas être modifié par la suite. Pour implémenter ce conteneur, nous avons utilisé une QMap<QString, int>.

Avec ces deux premiers éléments, la classe ConvertisseurINRA est capable de créer tous types d’unité définis en utilisant les unités de bases et les préfixes modificateurs. Nous allons maintenant voir comment nous arrivons à extraire une unité depuis une chaîne de caractères.

Initialisation du

Convertisseur Chargement du fichier XML Mise à jour de l'expression régulière des unités

(23)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

B – Extraire une unité

Lorsque l’utilisateur demande une conversion entre deux unités il donne deux chaînes de caractères correspondant aux deux unités. De plus, dans le fichier XML, chaque unité contient une chaîne de caractères correspondant à sa représentation par rapport à d’autres unités. Dans ces deux cas il faut qu’on arrive à extraire une unité depuis une chaîne de caractères. Pour pouvoir extraire des données depuis une chaîne de caractères, nous utilisons des expressions régulières.

Nous allons définir dans un premier temps ce qu’est une expression régulière et comment nous les avons utilisées. Nous expliquerons ensuite notre algorithme pour générer des unités depuis des chaînes de caractères.

i – Utilisation des expressions régulières

Une expression régulière est une chaîne de caractères qui définit un ensemble de chaînes de caractères selon une syntaxe. Grâce à cet outil, on peut vérifier si les chaînes de caractères que l’on veut transformer en unité sont correctes ou non. En plus d’être un outil de vérification, il est possible d’extraire des informations grâce aux expressions régulières.

Dans notre cas nous avons défini plusieurs expressions régulières que nous assemblons ensuite pour créer des expressions régulières capables de vérifier si la chaîne de caractères passée en paramètre correspond bien à un ensemble d’opération valide sur des unités.

Dans un premier temps nous avons écrit une expression régulière qui définit une chaîne de caractères composée uniquement d’un des préfixes. Cette expression régulière se présente sous la forme « (E|G|M|P|T|Y|Z|a|c|d|da|f|h|k|m|n|p|y|z|µ) ». Le signe « | » définit un ou logique.

Par exemple si on a l’expression régulière « a|b » cela signifie qu’il faut le caractère a ou le caractère b pour que la chaîne de caractère vérifie la syntaxe de l’expression régulière. Dans notre cas il faut donc un des caractères (et un seul) qui représente un des préfixes définis lors de la construction de la classe ConvertisseurINRA. De plus cette expression régulière est entourée de parenthèse, cela signifie que l’on veut enregistrer ce qui est lu par celle-ci. On peut donc vérifier qu’on a un préfixe valide et, si jamais c’est le cas, récupérer son symbole. Cette expression régulière est construite en même temps que la construction de la classe ConvertisseurINRA. Elle est créée à partir du conteneur qui contient les préfixes ce qui permet qu’elle soit cohérente avec les données contenues dans ce dernier. De plus, si l’on décide d’ajouter un nouveau préfixe, l’expression régulière se mettre automatiquement à jour lors de la construction de la classe ConvertisseurINRA.

(24)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Nous avons ensuite besoin d’une expression régulière capable de vérifier et d’extraire l’abréviation d’une unité. Pour cela nous générons une expression régulière de la même manière que pour les préfixes. On parcourt donc notre conteneur associatif et on met dans notre expression régulière toutes les abréviations qui sont contenues dedans et on les sépare par le caractère « | ». On rajoute aussi « [a-zA-Z]* » séparé par un « | » dans l’expression. Ce rajout permet de récupérer la chaîne de caractère si jamais celle-ci ne correspond pas à une abréviation et si elle correspond à une suite de lettre non vide. En ayant uniquement les unités de bases on obtient donc cette expression régulière « (A|K|cd|g|m|mol|s|[a-zA-Z]+) ». Comme pour les préfixes on entoure l’expression régulière de parenthèse pour enregistrer ce qu’elle analyse.

Nous avons également besoin de définir une expression régulière capable de vérifier et récupérer la puissance que l’on applique à une unité. Cette expression régulière est une constante de la classe ConvertisseurINRA car elle ne change jamais. En effet même en changeant les préfixes ou en ajoutant des unités, la manière d’écrire la puissance d’une unité ne change pas.

Cette expression régulière se présente sous cette forme « (\^?(\+|-)?(\d+)) ». Cette expression régulière est plus compliquée à comprendre. On va donc analyser cette expression régulière morceau par morceau. La chaîne « \^ » veux dire que l’on attend un caractère « ^ », elle est suivie du caractère « ? » qui signifie que ce qu’il y a avant n’est pas obligatoire. La chaîne « \^? » signifie donc qu’on attend le caractère « ^ » ou rien. De la même manière la chaîne « (\+|-)? » signifie que l’on attend le caractère « + » ou le caractère « - » ou rien.

De plus avec les parenthèses, on indique qu’on enregistre le ce qui est lu. Cette expression régulière se fini par « (\d+) » qui signifie qu’il doit y avoir une suite de chiffre de taille minimum d’un chiffre. On enregistre également cette suite de chiffre grâce à des parenthèses. Enfin, l’expression régulière est entourée de parenthèse pour enregistrer toutes les données lues par celle-ci. Grâce à cette expression régulière il nous est possible de définir la puissance d’une unité de plusieurs manières différentes. Si on prend une unité « X » on peut alors définir une puissance positive « X2 », « X+2 », « X^2 » ou encore « X^+2 ». Et on peut définir une puissance négative avec « X-2 » ou « X^-2 ».

Enfin, il nous faut une expression régulière pour vérifier et récupérer les opérateurs entre les unités. Elle se présente sous la forme « (\*|/|\.) ». Cette expression régulière attend le caractère « * » ou « / » ou « . ». Comme pour les précédentes on récupère ce qui a été lu grâce aux parenthèses présentent autour de l’expression régulière.

Nous allons maintenant vous présenter comment nous avons utilisé ces expressions régulières pour extraire les données et créer des unités depuis des chaînes de caractères.

(25)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

ii – Algorithme d’extraction

Pour extraire une unité d’une chaîne de caractère nous allons donc utiliser les expressions régulières que nous avons définies plus haut. Nous allons ensuite suivre l’algorithme décris dans les diagrammes ci-dessous.

Supression des espaces L ecture de la première unité L ecture du reste de la chaine [Chaine vide] L ire unité Exception ChaineInvalide [Chaine !vide] L ecture Opérateur *= / = [multiplication] [division] [L ecture OK ] [Erreur L ecture] [L ecture OK ] [Erreur L ecture]

(26)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

L ecture abréviation L ecture préfixe

L ecture puissance

Figure 6 : Processus de lecture d'une unité

Après avoir supprimé les espaces de la chaîne de caractère on tente de lire un préfixe, suivi d’une abréviation suivie d’une puissance avec les expressions régulières définies dans la partie précédente. Pour que la chaîne de caractère vérifie cette expression régulière il faut qu’il y ait au moins une abréviation. Une fois qu’on a extrait ces informations, on instancie un objet de type Unite avec celles-ci. On va maintenant effectuer les traitements qui suivent tant qu’il nous reste des éléments à analyser dans la chaîne de caractère. On utilise les expressions régulières pour extraire un opérateur, un préfixe, une abréviation et une puissance.

Avec ces informations, à l’exception de l’opérateur, on instancie une nouvelle unité et nous effectuons l’opérateur d’affectation associé à l’opérateur lu. On va donc mettre à jour les informations de la première unité créée avec celle que l’on vient d’instancier. On analyse maintenant la partie non-analysée de la chaîne de caractère.

SI jamais on doit analyser une chaîne vide, c’est que nous sommes arrivés à la fin de la chaîne de caractère et donc on retourne l’unité que nous avons créée. Si une des expressions régulières ne peut pas être vérifiée avec la chaîne de caractère analysée alors nous levons une exception de type ChaineInvalideException.

Grâce à cet algorithme nous sommes maintenant capables d’extraire une unité à partir d’une chaîne de caractère.

(27)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

C – Charger un fichier XML

i – Choix du type lecture

Concernant le parcours et la lecture d’un fichier XML il existe deux approches :

• SAX (Simple API for XML) : Il s’agit d’un parcours progressif c’est à dire qu’on se déplace au sein du fichier et que l’on peut déclencher des évènements en cours d’analyse.

• DOM (Document Object Model) : On analyse le fichier pour construire un arbre en mémoire afin de stocker l’intégralité des éléments. Cela peut-être lourd et plus lent si les fichiers XML sont de grande taille.

Ici le fichier de configuration restant de taille très modeste, il est plus pratique et performant d’utiliser un analyseur DOM via le module Qt XML et les classes QDomDocument et QDomElement.

ii – Choix du format du fichier

Comme tout fichier XML il comporte une balise racine contenant toutes les données. Nous avons fait le choix d’utiliser une balise unite et de stocker les données de l’unité en attributs de cette balise. De cette façon, il est plus simple pour nous de vérifier que toutes les données nécessaires sont présentes mais aussi de les récupérer.

<unite id="°C" nomComplet="Celsius" facteurMultiplicateur="1" facteurAditionnel="273.15" formule="K" />

On peut en effet récupérer chaque attribut à partir de son nom et donc s’assurer que l’on récupère bien la donnée voulue.

iii – Algorithme de lecture

Nous allons maintenant voir comment le programme analyse le fichier XML. Lors de l’appel à la fonction loadXML du ConvertisseurINRA, le convertisseur va boucler en lecture sur le fichier tant qu’il parvient à en extraire des unités. A chaque unité rencontrée, l’appel à la fonction extraire tente de créer une Unite à partir des données du fichier XML, si elle n’y parvient pas une exception est levée.

Si l’extraction se déroule sans accroc, on vérifie que l’abréviation de l’unité n’existe pas déjà dans le conteneur associatif des unités et si l’unité est définie uniquement par les dimensions de bases. Le cas échéant, on ajoute cette Unité au conteneur associatif des unités et l’on positionne un flag de mise à jour à vrai.

(28)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

D – Algorithmes principaux

Pour faciliter l’utilisation de notre bibliothèque par l’utilisateur nous avons décidé de renvoyer les résultats de la conversion dans une classe Resultat qui a pour but de cacher l’implémentation de la conversion. Cette classe propose une méthode qui permet de transformer une valeur en utilisant la conversion qu’elle représente. Cette classe est simplement constitué de deux objets de type Conversion qui permette de faire la conversion vers les unités de bases puis de faire la conversion vers l’unité cible.

Nous allons maintenant vous présenter comment nous avons implémenté l’algorithme qui permet de fournir à l’utilisateur ce résultat. Nous expliquerons ensuite comment nous évaluons une valeur avec la classe Resultat.

i – Calculer la conversion

À partir du moment où notre classe ConvertisseurINRA était capable de créer et d’avoir accès au conteneur associatif d’unité et qu’elle était capable d’extraire une unité depuis une chaîne de caractère, nous avons pu commencer à rédiger l’algorithme de conversion.

L’algorithme consiste à extraire les deux unités associées aux deux chaînes de caractères passé en paramètres. S’il y a une erreur dans une des deux chaînes de caractère alors une exception de type ChaineInvalideException est levé. Si l’extraction des unités c’est passée sans problème on alors on vérifie que la conversion est homogène en comparant les dimensions des deux unités entre elles. S’il ce test retourne faux alors on essaye de comprendre pourquoi. Si on remarque qu’il y a une erreur dans l’homogénéité des dimensions de base alors on lève une exception de type HomogeneiteException. Si le test renvoie faux car il y a une erreur d’homogénéité dans les dimensions qui ne sont pas des dimensions de bases, alors on lève une exception de type InvalidDimensionException. Enfin, si les deux unités sont homogènes, alors on génère un objet de type Resultat avec la conversion de l’unité source vers les unités de bases et avec la conversion des unités de bases vers l’unité cible. On renvoi ensuite ce résultat.

L’utilisateur peut donc facilement avoir un retour sur le résultat de la conversion qu’il a demandé. En effet, si une exception est générée il peut traiter les différents cas vu qu’il existe différents types d’exception. Si un résultat est généré il ne lui reste plus qu’à utiliser la méthode « evaluer » sur celui-ci avec les valeurs qu’il veut convertir. La partie qui suit détail le fonctionnement de cette méthode.

(29)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Extraction des Unite

source et cible Conversion source vers SI

Conversion SI vers

cible Création du Resultat Vérification de faisabilité

de la conversion

Figure 7 : Diagramme récapitulatif de la conversion

ii – Utiliser les résultats

Grâce à la classe Resultat l’utilisateur peux simplement convertir un grand nombre de valeur en appelant simplement la méthode « évaluer » de celle-ci avec en paramètre la valeur qu’il veut convertir. Si l’utilisation de cette méthode est très simple en apparence, il y a quand même un traitement particulier qui est fait derrière.

Évaluer une valeur depuis la classe Resultat consiste à effectuer la conversion vers les unités de bases puis vers l’unité cible. On effectue donc deux fois le même traitement qui consiste à convertir une valeur avec l’aide d’un objet de type Conversion.

Pour effectuer cette conversion, on récupère les facteurs contenus dans la classe Conversion et on évalue le polynôme qu’ils représentent en utilisant notre valeur à convertir comme inconnue. On effectue donc ainsi les deux conversions d’affiler pour obtenir une valeur que l’on retourne à l’utilisateur.

(30)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

V – Résultats

Au terme de ce projet, nous avons une bibliothèque développée en C++/Qt permettant de convertir des unités plus ou moins complexes et que l’on peut configurer à l’aide d’un fichier XML. Elle a été testée de façon concluante au sein de la plateforme à laquelle elle est destinée et n’a pas posé de problèmes d’intégration particuliers.

A l’heure où ce rapport est écrit, quelques ajustements restent à faire pour prendre en compte certains cas complexes, mais cela sera fait avant la soutenance. Certaines conversions peu ordinaires restent problématiques et ne seront pas gérées par la bibliothèque cependant, ces conversions ne seront, en théorie, jamais nécessaires.

(31)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

VI – Perspectives

Bien qu’une grande partie du projet soit fonctionnelle, certains points resteraient selon nous à parfaire ou à continuer :

• La gestion d’unités personnalisées au sein du XML n’est pour l’instant pas implémenter mais dans nos choix structurels et algorithmiques nous avons pris en compte cette possibilité. Cela ne remet donc pas en doute la structure du projet. • Tenter de trouver une solution au problème des conversions peu ordinaires qui ne

sont pas fonctionnelles.

• Développer un logiciel afin de gérer les fichiers de configuration XML pour faciliter l’édition, la vérification et la création de ces fichiers.

(32)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Conclusion

Le but de notre projet était de réaliser une bibliothèque de conversion d’unité automatisée intégrable au sein d’une plateforme d’analyse développée par l’UREP. Cette bibliothèque devait être capable de charger des unités définies dans un fichier XML et de vérifier l’homogénéité des conversions demandées.

À ce jour nous avons fourni une solution capable de faire la conversion entre des unités tant que celles-ci ne sont pas trop complexes. La solution produite correspond cependant aux besoins formulés lors des entretiens car elle permet la conversion des unités utilisées par la plateforme de simulation. De plus elle permet de charger des fichiers au format XML contenant les définitions des unités que nous utilisons.

Il faut encore régler le problème des unités trop complexes. De plus il nous reste à ajouter la possibilité de définir des unités dans le fichier XML qui n’ont pas de rapport avec les dimensions de bases.

Nous sommes très heureux d’avoir pu participer à ce projet car il nous a permis de travailler avec une entreprise et d’apporter notre contribution à un projet de plus grosse envergure. Nous espérons que le travail que nous avons réalisé pourra réellement aider les gens qui travaillent sur cette plateforme de simulation en leur faisant gagner du temps pour la conversion de leurs données.

(33)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Table des figures

Figure 1 : Diagramme du fonctionnement de base du projet ... 3

Figure 2 : Lien Unite / ConvertisseurINRA ... 4

Figure 3 : La classe Unite et ses nombreux opérateurs ... 13

Figure 4 : Diagramme résummant l'initialisation du Convertisseur ... 16

Figure 5: Diagramme d'activité de l'extraction d'une unité... 18

Figure 6 : Processus de lecture d'une unité ... 19

(34)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Lexique

Bibliothèque (logicielle) : En informatique, une bibliothèque logicielle est une collection de

fonctions, qui peut être déjà compilée et prête à être utilisée par des programmes

Classe : En programmation orientée objet, une classe déclare des propriétés communes à un

ensemble d'objets. La classe déclare des attributs représentant l'état des objets et des méthodes représentant leur comportement. Une classe représente donc une catégorie d'objets. Elle apparaît aussi comme un moule ou une usine à partir de laquelle il est possible de créer des objets.

Conteneur associatif : les conteneurs associatifs sont capables d'identifier leurs éléments à l'aide de

la valeur de leur clef. Grâce à ces clefs, les conteneurs associatifs sont capables d'effectuer des recherches d'éléments de manière extrêmement performante.

Dimension : La dimension d'une grandeur physique est sa dimension exprimée par rapport aux

dimensions des sept unités de base du Système International. On exprime la valeur d'une grandeur avec une unité. Par exemple, la vitesse a la dimension d'une longueur divisée par un temps.

Framework : En programmation informatique, un framework ou structure logicielle est un ensemble

cohérent de composants logiciels structurels, qui sert à créer les fondations ainsi que les grandes lignes de tout ou d’une partie d'un logiciel

Gestion de Version : La gestion des versions consiste à maintenir l'ensemble des versions d'un ou

plusieurs fichiers (généralement en texte). Essentiellement utilisée dans le domaine de la création de logiciels, elle concerne surtout la gestion des codes source.

Méthode : En programmation orientée objet (POO), une méthode est une fonction membre d'une

classe. Une méthode peut être:

- une méthode d'instance, n'agissant que sur un seul objet (instance de la classe) à la fois; - une méthode statique (ou méthode de classe), indépendant de toute instance de la classe

(objet).

Qt : une API orientée objet et développée en C++. Elle offre des composants d'interface graphique

(widgets), d'accès aux données, de connexions réseaux, de gestion des fils d'exécution, d'analyse XML, etc. Qt permet la portabilité des applications qui n'utilisent que ses composants par simple recompilation du code source.

Surcharge d'opérateur : le fait de pouvoir redéfinir le comportement des opérateurs du langage. XML : L'Extensible Markup Languag est un langage informatique de balisage générique. Cette syntaxe

est dite « extensible » car elle permet de définir différents espaces de noms, c'est-à-dire des langages avec chacun leur vocabulaire et leur grammaire, comme XHTML, XSLT, RSS, SVG… Elle est

reconnaissable par son usage des chevrons (< >) encadrant les balises. L'objectif initial est de faciliter l'échange automatisé de contenus complexes (arbres, texte riche…) entre systèmes d'informations hétérogènes.

(35)

Mise en place de la conversion automatisée des entrées au sein d'une plateforme de simulations

Bibliographie

Wikpédia l’encyclopédie libre

[en ligne] : http://fr.wikipedia.org/

Documentation Qt Framework [en ligne] : http://doc.qt.io/

Unité de Recherche sur l’Ecosystème Prairial

[en ligne] : https://www1.clermont.inra.fr/urep/

Standard C++ Library reference

Figure

Figure 1 : Diagramme du fonctionnement de base du projet
Figure 2 : Lien Unite / ConvertisseurINRA
Figure 3 : La classe Unite et ses nombreux opérateurs
Figure 5: Diagramme d'activité de l'extraction d'une unité
+3

Références

Documents relatifs

Aussi la somme des chiffres de la somme de tous les entiers palindromes de n chiffres est une constante égale à 4+9+5 soit 18..

Quelle est la plus petite variation d’énergie pour une particule passant d’un niveau à un

Bientôt nous rencontrons à Troyes le créa- teur : notre sympathique collègue Guérin, ainsi que le constructeur, M.. Paris, ·artisan radio, technicien de

C ’est ce que nous avons constaté d’une manière flagrante, chez des élèves réintégrés, après une année dans la classe de l’enseignement adapté, dans la classe normale de

Dans les conversations entre camarades, à l’intérieur de la salle de classe, les élèves emploient des termes comme « tu », appellent un camarade par son prénom

UJle certaine diffraction. Cette onde teuse. signal atteignait 10 microvolts. Après remise en ce est pratiquement parfait. elle produisait des déphasages im-

La protecNor1 britaooiques vient d'at- troen (pour laquelle un mon,.. race, il fallut un cœur de triple airain à ceux qui n'hé- sitèrent pas à porter la

tion par lねmate'ur d laPPar融ls de mesure et de contr61e, etC. ‥ 漢65 DEUX RECEPTEIJ RS DE TEI」EVISION