OpenMASK 4 Nouvelle version
Plan Introduction Principes Simulation, ordonnancement, distribution Echanges de données entre objets Nouvelle version Les types Les attributs Les extensions Visualisation Principes Visualisation Ogre Créer une simulation Exemples
Historique L’ancêtre d’OpenMASK était un simulateur Ordonnancement Distribution Passage du simulateur à une plate-forme de Réalité Virtuelle Visualisation Gestion des périphériques de RV
La simulation Les principes
Principes Élément de base : L’objet de simulation Fonctionnalités : Distribution (localisé sur un process) Appel fréquentiel Communications avec des pairs Flux (entrées/sorties) Messages (émission/réception)
La distribution Distribuer c’est simple Indiquer le processus sur lequel l’objet doit être simulé Comment ça marche !? Création des objets Création des miroirs à la demande Différence entre miroir et référence
A { Class ObjetAvecSortie Scheduling { Frequency 75 Process process1 } UserParams {... } #OpenMASK3 root { Class Controller Scheduling { Latency 0 Machines { process1 portalux.localdomain process2 portalux.localdomain } B { Class ObjetAvecEntree Scheduling { Frequency 75 Process process2 } UserParams {... } Distribution : Création des objets Deux processus 1 et 2 Un objet A possédant une sortie c sur 1 Un objet B possédant une entrée d sur A B d c
Distribution : Création de miroirs B veut connecter son entrée d à la sortie c de A B demande à son processus 2 de lui fournir une référence pour se connecter à c 2 ne possède pas A 2 crée le miroir A et informe 1 B peut se connecter Par la suite A synchronise son miroir A à chaque fois que c est mise à jour 1 2 A BA dc c miroir référence Synchronisation ? B { Class ObjetAvecEntree Scheduling { Frequency 75 Process process2 } UserParams { dConnectTo [A c] }
Distribution : Miroir / Référence Référence Cycle de vie Construction constructeur & postConstruction() Initialisation init() Appel récurrent compute() Caractéristiques Possède des entrées et sorties Lit les paramètres de configuration Met à jour ses sorties lors de l’appel fréquentiel Miroir Cycle de vie Construction constructeur & postConstruction() Caractéristiques Possède seulement les sorties N’est pas initialisé N’est pas calculé Ses sorties sont synchronisées par le contrôleur =>Les sorties doivent et ne peuvent être créées que durant la phase de construction des objets
L’exécution fréquentielle Fréquence d’appel Chaque objet de a sa propre fréquence de simulation Le contrôleur effectue les appels à la fréquence spécifiée Temps simulé ≠ Temps réel Ce n’est pas parce que l’objet est à 50Hz que les appels se feront à 50Hz Un objet horloge permet de synchroniser la simulation en « perdant » du temps
Les communications Synchrones Entrée/sortie = Flux de données N entrées connectées à 1 sortie Récupération possible des données via les entrées à chaque appel fréquentiel Asynchrones Message = identifiant [+ données] Événements : envoi spécifique à un objet Signaux : envoi général, diffusion via le contrôleur aux objets abonnés Appel à une méthode dédiée à chaque réception de message
Le type de base OMK::Type::Base Deux fonctions : Sérialisation En distribué : les données transitent par des flux entre process Polation En multi-fréquentiel : interpolation et extrapolation des données numériques pour une date donnée Tous les types de données en héritent
Nouvelle version Granularité & simplicité
Le type étendu Encapsulation d’un type quelconque OMK::Type::SimpleTypeT Assurer les deux fonctions de base : Sérialisation T doit fournir les opérateurs de flux >> et << Polation Polateur par défaut (aucune interpolation) Possibilité de définir son propre polateur
Nouvel objet étendu Extension de l’objet Attributs Faciliter la manipulation des données Automatiser de certaines fonctions Extensions Modifier la granularité Composants plus petits et plus facile à concevoir Construction des objets par assemblage plutôt que par codage
Les attributs Définition Identifiant Type Valeur Fonctionnalités : Accesseurs (identifiant, valeur) Connectivité (entrée, sortie, connexion) Messagerie (mise à jour, lecture, connexion) Permet Introspection Automatisation de tâches
Les attributs Attribut : « id » « id » Valeur : 2 Listener SetValue Listener SetValueOf Listener Disconnect Listener ConnectTo Listener GetValue « pos » « Obj1 »« Obj2 » connect_to_id {« Obj2 », « pos »} current_value {« id »,« 3 »} current_value_of_id {« 4 »} get_value_of_id [« id’ »] disconnect_id current_value_of_id’ {« 4 »} Valeur : 3Valeur : 4
Les extensions Sous-objets de simulation Fonctionnalités Création Initialisation Exécution Possibilités (via l’objet propriétaire) Création d’attributs, extensions, listeners Émission de messages Accès aux attributs et autres extensions
Les extensions Exemples de ce qu’elle peut faire : Étendre l’initialisation d’un objet Offrir une nouvelle syntaxe de configuration Ajouter des listeners Étendre les fonctionnalités Ajouter un attribut Ajouter des entrées ou des sorties Ajouter un paramètre pour contrôler le comportement de l’objet Modifier la valeur d’un attribut Convertir une valeur d'attribut avant ou après qu'elle soit employée par l'objet …
La visualisation Ogre
Création dynamique par messages Objets visuels (≠ Objet de simulation) Animateurs Mise à jour par les animateurs Basée sur le moteur de rendu Ogre
L’objet visuel Rôle Appeler ses Animateurs pour la mise à jour Afficher un objet graphique 3D Pas d’accès direct aux données des objets simulés (rôle de ses animateurs) Avec Ogre Lit un scene ( format des objets 3D d’Ogre) Insère le scene dans la scène hiérarchique qu’utilise Ogre L’affichage du scene est alors géré par Ogre
L’animateur Rôle Création d’un plug de récupération de données Entrée (Flux depuis une s orties) Listener (écoute d’un événement ou signal valués ou non) Autre (plug spécifique, base de données par exemple) Récupération des données de simulation via son plug Mise à jour de l’objet à afficher (peu importe la manière dont la donnée est récupérée par le plug) Avec Ogre Associé à un nœud dans la scène d’Ogre Met à jour le nœud associé en fonction des valeurs récupérées par le plug
Visualisation : Créations Add Visual Object Visual Objects Factory Animator Factory Add Animator Visu Visual Object Animator Plug Input Animator Plug Event Ajout d’un Objet Visuel Réception du message Création Ajout d’Animateurs Réception du message Création Création automatique de plugs Input => Entrée Event => Listener Listener
Visualisation : Mise à jour Objet Visu Visual Object Animator Plug Input Animator Plug Event Récupération des données par les plugs Mise à jour de l’affichage Utilisation des données par les plugs Listener
L’attribut de visualisation Attribut spécialisé pour la visualisation Crée un animateur défini par configuration Choisit le type de plug Présence d’une sortie Flux de donnée => Connexion du plug à la sortie Pas de sortie définie Message => Abonnement à l’événement Lors d’un set de l’attribut Mise à jour de la sortie Ou Émission d’un message
Créer une simulation Nouveau modules &Configuration
Structure d’une application Configuration Lecture de la configuration Plugins enregistrement des créateurs d’objets Contrôleur Création Configuration Exécution
Configuration : Arbre de simulation Arbre de simulation Structure hiérarchique Description de la structure de la simulation Description des objets, extensions, etc. Création des objets A partir de leur description Initialisation grâce aux paramètres spécifiques Multi-processus Cohérence des arbres entre processus Cohérence des objets sur l’ensemble des processus => sinon création de miroirs différents des références
Configuration : Format du fichier Fichier texte avec une syntaxe hiérarchique Permet de créer l’arbre de simulation Mot clé d’identification de fichier (sur la première ligne) #OpenMASK3 Commentaires // Syntaxe des commentaires identiques au C++ /* On peut utiliser les deux types */ Nœud hiérarchique identifiant {... } Nœud de donnée simple identifiant valeur Nœud de donnée multiple identifiant [valeur1 valeur2...]
Configuration : Objet de simulation Tous les objets obéissent à cette syntaxe, y compris le contrôleur objectName // identifiant de l’objet { Class ObjectClassId // identifiant de la classe de l’objet Scheduling // paramètres d’ordonnancement de l’objet {... } UserParams // paramètres de configuration de l’objet {... } Extensions // paramètres des extensions de l’objet {... } Sons // Enfants de l’objet, en pratique seul le contrôleur en possède {... }
Configuration : Contrôleur Objet racine de la simulation #OpenMASK3 controller // identifiant du contrôleur { Class Controller // identifiant de la classe de contrôleur UserParams // paramètres de configuration du contrôleur { Plugins [... ] // plugins utilisés... // autres paramètres pour les traces, etc. } Scheduling {... // paramètres pour la définition du multiprocessus } Sons // liste des objets de la simulation {... }
Configuration : Extensions Elles sont déclarées dans le nœud Extensions de l’objet Elles sont définies par : Un identifiant pour l’extension Un identifiant du type d’extension Des paramètres dépendants du type d’extension Extensions { extensionId // identifiant { Class EntensionClassId // type d’extension... // paramètres propres au type d’extension }
Exemples Objets & Extensions
SimplePoint / Un point dans l’espace OMK::SimplePoint Cahier des charges Offrir une position dans l’espace 3D Codage Héritage de ExtensibleSimulatedObject Agrègation d’un attribut OMK::Transform Création d’une sortie
SimplePoint / Déclaration 1/ class SimplePoint : public ExtensibleSimulatedObject 2/ { 3/ DECLARE_OBJECT_FACTORY( SimplePoint ) ; 4/ protected: 5/ ///\brief The "Position" attribute. 6/ OMK::AttributeT _position ; 7/ } ; Commentaires: 1/ Héritage direct de ExtensibleSimulatedObject 3/ Déclaration de la macro : CLASS_ID, constructeur, destructeur 6/ Ajout de l’attribut de position
SimplePoint / Implémentation (1/2) 1/ REGISTER_OBJECT_FACTORY( SimplePoint, "SimplePoint" ) ; 2/ 3/ SimplePoint::~SimplePoint() 4/ { 5/ } Commentaires : 1/Macro d’enregistrement dans la factory Déclare aussi la valeur de l’id de classe "SimplePoint" qui sera utilisé dans la configuration 3/Destructeur : rien à faire tout est fait dans l’ancêtre
SimplePoint / Implémentation (2/2) 1/ SimplePoint::SimplePoint( Controller& ctrl, const ObjectDescriptor& objectDescriptor ) 2/ : ExtensibleSimulatedObject( ctrl, objectDescriptor ), 3/ _position( "Position", Transform( Wm4::Vector3f::ZERO ) ) 4/ { 5/ addAttribute( _position ) ; 6/ _position.createOutput() ; 7/ } Commentaires: 1/ Constructeur avec les paramètres utilisés par la factory 2/Héritage de ExtensibleSimulatedObject 3/Initialisation de l’attribut : Id + valeur initiale 5/Ajout de l’attribut de position à l’objet Les opérations liées à l’attribut sont gérés par l’objet 6/Création de la sortie de position associée à l’attribut Doit être dans le constructeur
SimplePoint / Fonctionnement Création Création de l’attribut Enregistrement
SimplePoint / Configuration (1/2) Identifiant de classe SimplePoint Scheduling hérité de SimulatedObject Extensions hérité de ExtensibleSimulatedObject Paramètres liés à l’attribut Position Position : Valeur intiale PositionConnect [ ] : Connection à la sortie d’un objet PositionConnectByEvent : Activation de la (dé)connexion de l’entrée associée à l’attribut par un événement Etc. autres activations par événements ou signaux
SimplePoint / Configuration (2/2) Exemple 1/ mon_point_dans_l_espace // id de l’objet 2/ { 3/ Class SimplePoint 4/ Scheduling 5/ { 6/ Frequency 60 // fréquence d’appel 7/ } 8/ UserParams 9/ { 10/ Position [[ ]] // position initiale 11/ } 12/ }