• Aucun résultat trouvé

Plutôt que d’utiliser une instance de A dans la définition de UneClasse, l’instance est stockée dans un pointeur sans type de manière privée.

class UneClasse { public: void FaitQuelquechose(); private: void* m_A; };

Dans cette définition, l’information m_A est accessible uniquement par la classe UneClasse. Les ma-nipulations relatives à cette information sont donc restreintes à l’étendue de cette classe. Celle-ci n’est représentée que par un pointeur d’adresse sans type, il n’est donc pas nécessaire de définir le type de m_A dans la définition de l’objet.

Pour la gestion de la mémoire associée à cet attribut, celle-ci est allouée à la construction de l’objet et détruite à sa destruction. #include "A. h " // ... UneClasse::UneClasse() : m_A(0) { m_A = new A; ... }; UneClasse::~UneClasse() { delete m_A; ... };

Pour faciliter l’accès à l’information lors d’un appel à A, il suffit de réaliser un transtypage

#include "A. h " // ... void UneClasse::FaitQuelquechose() { A* pA = ((A*) &m_A); pA->getValue(); ... };

La mise en oeuvre de cette méthode permet de s’affranchir des conflits de définition rencontrés lors de l’intégration conjointe des définitions du modèle et de la plateforme pour la mise en oeuvre des plug-ins associés aux modèles.

L’encapsulation de dépendances

Un autre problème rencontré lors de l’intégration d’un développement au sein d’une plateforme est la collision entre des versions de dépendances différentes. Il n’est pas toujours souhaitable ou il s’avère parfois compliqué de déployer des solutions logicielles dans des environnements hétérogènes. Toutes ces dépendances ne sont pas toujours reconstructibles et leurs propres dépendances s’ajoutent par-fois aux dépendances existantes, ou bien le temps d’adaptation est tel qu’il est rédhibitoire et interdit l’adaptation des dépendances, surtout si leurs implémentations n’a pas été réalisé avec le même com-pilateur. Il peut également ne pas être souhaitable de lier le projet à un projet externe, problème de license, nécessité de définir tout un tas de règles pour une utilisation très sommaire du composant. Des conflits entre la version utilisée et la version déployée peuvent également apparaître, avec une impos-sibilité de combiner les deux dans le cadre d’une liaison statique (cas de la librairieOpen Computer Vision (OpenCV)qui pour deux versions différentes d’un même fichier emploie le même nom). Le masquage de type a permis de faire disparaître les définitions externes non désirées des définitions du modèle, il reste maintenant à s’occuper des liaisons entre les dépendances et les projets relatifs aux modèles.

La première solution, visible sur la figureIII, consiste en la définition d’une librairie dynamique inter-médiaire qui réalisent les liens vers les dépendances. Les développements au Niveau 1 sur la figure n’auront de liaison qu’avec la librairie dynamique et les dépendances utilisées hors du cadre de celle-ci.

Cependant, cette méthode implique que soit installée sur le système la librairie dynamique utilisée. Pour les librairies systèmes, qui sont par définition disponibles, cela ne posent pas de problème. C’est différent lorsqu’il s’agit d’une dépendance externe répondant à un besoin précis, c’est à dire que l’uti-lisation faite est limitée. Celles-ci ne sont pas toujours disponibles par défaut et il faut donc penser à les installer et les distribuer.

Aujourd’hui les ressources de stockage et de mémoire ne sont plus limitées, les capacités de stockage sont de l’ordre du téraoctet et les capacité en mémoire vives de l’ordre de plusieurs gigaoctets. Il peut donc parfois être pertinent finalement d’utiliser quelques megaoctets de mémoire vive supplémentaires en vue d’utiliser les dépendances d’une autre façon, le delta mémoire associé à cette pratique étant négligeable au vue des capacités nécessaires aux modèles plutôt de l’ordre de la centaine de megaoctet sur une quantité disponible de l ordre du gigaoctet.

C’est la méthode mise en oeuvre ici, le langageC++et lesAPIssystèmes permettent de charger dyna-miquement des fonctions pendant l’exécution d’un programme. De plus, il est possible d’encapsuler du contenu binaire dans un projet. Ce sont les deux fonctions utilisées ici pour réaliser l’encapsulation des dépendances dans les projets comme ressources.

Deux tâches sont nécessaires pour cette méthode.

La première concerne l’accès aux fonctions de la librairie dynamique utilisée. Cela nécessite de vérifier sa présence ou non sur le système, de l’extraire le cas échéant et de fournir un accès à son contenu. La seconde tâche consiste à charger les symboles utilisés et à fournir un accès à ceux-ci.

Si la première tache est commune à l’ensemble des dépendances ainsi traitées, la seconde est propre à chacune d’elle. Cette constatation mène à la définition des objets suivants (figureIII.2)

DependancyWrapper # f ile : file # handle : pointer # copied : boolean check_file() copy_file() delete_file() load_file() unload_file() FFTWWrapper plan1d(. . . ) fftw(. . . ) YWrapper do_something(. . . ) do_other(. . . )

Figure III.2 – Représentation des traitements associés à un modèle de composant électronique

La classe abstraite DependancyWrapper mutualise l’ensemble des méthodes et attributs nécessaire à la gestion de la ressource quant aux classes dérivées, elle définissent la surcouche permettant l’accès aux fonctions de la dépendance.

Pour l’intégration d’une fonction quelconque

<type_returned> do_something_with(<type_arg1>, ..., <type_argn>);

Il faut déclarer sa signature

typedef <type_returned> (*DO_SOMETHING_WITH_SIGNATURE)(<type_arg1>, ..., <type_argn>);

définir un pointeur de fonction pour stocker sa référence et définir une méthode pour l’utiliser.

class DLLWrapper {

public:

<type_returned> do_something_with(<type_arg1>, ..., <type_argn>);

private :

DO_SOMETHING__WITH_SIGNATURE ptrDoSomethingWith; };

Cette méthode est surtout applicable lors d’un usage très ponctuel (peu de symboles utilisés) d’une librairie externe mais elle s’avère très performante.

* * *

Les objets permettant de manipuler les concepts informatiques élémentaires étant disponibles, il est maintenant temps de s’intéresser à la réalisation des modèles.

1 Architecture logicielle des modèles: le

capteur

Les modèles sont définis, l’accès aux capacités avancées du matériel est accessible simplement par l’intermédiaire d’objets, il est temps de s’intéresser à la mise en oeuvre du modèle.

Le modèle théorique complet traitant de deux problématiques distinctes, l’implémentation de celui-ci ne fait pas défaut à cette règle.

Deux architectures distinctes sont nécessaires pour la mise en oeuvre du modèle. L’une pour le modèle du capteur matériel, l’autre pour le modèle de propagation.

Pour la partie matérielle, les traitements s’opèrent sur un signal électrique (vecteur de composantes), ils s’apparentent aux problématiques rencontrées dans les problèmes matriciels et vectoriels. Leur for-malisme mathématique est simple à mettre en oeuvre, et les dimensions du problèmes sont figées par les paramètres du modèles. Il s’agit de la résolution d’opérateur mathématique simple et bornée en terme de complexité.

Pour les modèles de propagations, les traitements sont d’une toute autre nature. La caractérisation de la scène et des phénomènes modélisées, n’autorise plus le parallélisme avec les traitements matriciels de dimensions fixes. L’information, caractérisé par des ondes électromagnétiques, est véhiculé au travers de la scène par un ensemble d’agent (rayons, faisceaux, . . . ) dont le parcours dans l’environnement est indépendant de celui de ses voisins. La compléxité du problème n’est plus lié à sa définition mais à la situation rencontrée et chaque agent a une complexité qui lui est propre du fait de son voyage particulier au travers de l’environnement. La parallélisation du traitement et les performances associées seront donc également d’une autre nature pour cet aspect du problème.

Cette section développe la réalisation d’un modèle de traitement du signal, la section suivante aborde la propagation.

Un modèle, appelé composant électronique fonctionnel dans la section 1.1 (p. 26), a permis de mo-déliser le comportement de tous les composants analogiques d’un capteur électromagnétique grâce à plusieurs propriétés, représentant le bruit généré et les gains et pertes relatifs à ce composant, et une fonction mathématique f , représentant son action. Cette définition permet assez facilement de mettre en oeuvre d’un point de vue informatique de tels composants.

1.1 Le composant électronique fonctionnel

lo-giciel

L’équivalent informatique du composant électronique fonctionnel pour ce modèle s’appelle Hardware-Component.

C’est une classe abstraite contenant les propriétés du quadripôle relatif au composant électronique fonctionnel qu’il représente et définissant un ensemble de méthodes permettant de définir de nouveaux composants aux propriétés équivalentes à ceux dont il se substitue, notamment pour les montages séries, grâce aux lois établies en électronique et présentées dans la section1.2(p.30).

HardwareComponent #Rin: double[] #Rout: double[] #G : double[] #NF : double[] setter/getter() set_from_others(hc0 : HardwareComponent, . . . ) VoltageControlOscillator #Mod : EMTechnology generate(duration : double, . . . ) : Signal Amplifier amplify(signal : Signal) : Signal Mixer dechirp(recv : Signal, trans : Signal) : Signal

AntennaTX transmit(signal : Signal) : void AntennaRX receive(waves : Path) : Signal Computer #Mod : EMTechnology process(signal : Signal) : void Tracker process(input : Target) : Track

Figure III.3 – Diagramme UML du modèle matériel: partie composant électrique

Ensuite, chacune des entités identifiées dans le modèle matériel est définie sous la forme d’une classe dérivée (figureIII.3). Il n’est pas possible ici de mettre un mécanisme d’implémentation forcée, fondé sur l’utilisation d’une définition de méthode virtuelle dans la classe HardwareComponent pour la défi-nition des actions. Les défidéfi-nitions mathématiques (les fonctions fcomposant) des actions des composants sont multiples tout comme leur signification et une formalisation arbitraire ne permet pas d’inclure dans sa définition l’ensemble des possibilités. La définition de la fonction f d’un point de vue infor-matique est entièrement à la charge de l’utilisateur tant pour sa définition que son implémentation. Il sera cependant possible d’initier un héritage comportemental à travers les objets concrets déjà définis pour le modèle générique et définissant le modèle générique (p.29).

Dans le diagramme ci-dessus, les composants associés aux traitements dits "numériques", extraction des informations et pour le radar suivi de cible, à savoir les composants Computer et Tracker, n’héritent pas des caractéristiques de HardwareComponent puisqu’il est considéré qu’elles n’influent pas sur les résultats numériques.

Le traitement relatif à l’aspect traitement numérique du signal par les composants Computer et Tracker est abordé page32et58et page130.

Deux objets se distinguent également par leurs attributs, c’est le cas du VoltageControlOscillator et du Computer. Il comporte chacun un attribut nommé EMTechnology. Celui-ci sert à spécialiser le fonction-nement du capteur. En effet, jusqu’à maintenant, le modèle définit est générique et n’a pas de fonction particulière, si ce n’est générer et recevoir des signaux.