Prérequis

Pour réaliser ce tutoriel vous avez besoin de télécharger le pack de développement :


Ce pack contient 3 dossiers :

  • Library qui contient un ensemble de librairies nécessaires au développement
  • Sample qui contient le résultat final MyUobject.sln de ce tutoriel.
  • Software qui contient l'ensemble des exécutables nécessaires pour la réalisation de ce tutoriel : l'installateur du SDK version 2.1, l'installateur de Visual Studio 2008 Express Edition (vcsetup.exe), et depends22_x86 pour le débugage de librairies.

Enfin ce tutoriel a été testé et réalisé sous Windows 7.

1 - Installation des outils de développement

Le SDK Urbi s'installe facilement en cliquant sur l'exécutable urbi-sdk-2.1-windows-x86-vcxx2008.exe fourni dans le dossier Software du pack.

  • Note: Par défaut le dossier d'installation est C:\Program Files\Gostai Engine Runtime qui sera écrit sous la forme <urbi_dir> dans la suite de ce tutoriel.


Visual Studio 2008 est disponible en 2 versions :

  • VisualStudio2008Logo.jpgVisual Studio 2008 : Avec la version complète de l'éditeur, les templates sont automatiquement installés avec le SDK dans les modèles de création de projets.[1]


  • VisualC-logo.jpgVisual Studio 2008 Express : Malheureusement la version express ne gère pas les templates, mais vous pouvez utiliser la solution MyUObject.sln fourni dans le dossier Sample du pack.


Enfin, le dossier Library du pack contient plusieurs librairies nécessaires à la compilation, qui sont à placer dans le dossier <urib_dir>\bin.

2 - Création du composant

  • Avec Visual Studio : Faites Fichier > nouveau > Projet pour créer un nouveau projet. Sélectionnez Visual C++ dans la colonne de gauche et sélectionnez uobject parmi les modèles proposés. Saisissez un nom de projet dans le champ prévu à cet effet, par exemple MyUObject, et finissez en cliquant sur OK. Une fenêtre s'ouvre alors en vous invitant à saisir un nom pour votre composant, qui est par défaut le nom du projet. Cliquez sur Finish pour créer un exemple de composant MyObject.cpp.

UObject

  • Avec Visual Studio Express : La version Express ne gérant pas les templates, le modèle UObject n’apparaît pas dans les modèles, mais vous pouvez utiliser le projet MyUObject.sln fourni dans le dossier Sample du pack.

2.jpg
Le projet contient alors un fichier uobject.cpp qui se présente sous la forme :

#include <urbi/uobject.hh>
 
class MyUObject: public urbi::UObject
{
  public:
    MyUObject(const std::string& str);
    int init();
};
 
MyUObject::MyUObject(const std::string& s)
 : urbi::UObject(s)
{
  UBindFunction(MyUObject, init);
};
 
int MyUObject::init()
{
  return 0;
};
 
UStart(MyUObject);


3 - Compilation

On remarque qu'un composant Urbi hérite de la classe UObject et qu'il faut donc ajouter les fichiers d'en-tête correspondants pour le développement et les librairies pour la compilation.

  • Note : Pour plus de clarté je ne traiterai pas dans ce tutoriel de la génération en mode debug qui possède ses propres mécanismes, mais uniquement la génération en mode Release.[2]

3.jpg
Allez dans les propriétés du projet et éditez les paramètres suivants :

  • C++->Général->Autres repertoires Include : <urbi_dir>\include pour inclure les en-têtes.


  • 4.jpg Éditeur de lien->Général->Répertoire de bibliothèques supplémentaires : <urbi_dir>\bin;<urbi_dir>\bin\gostai\engine pour définir les répertoires de librairies.


  • 4.jpg Éditeur de lien->Entrée->Dépendances supplémentaires : libjpeg4urbi-vc90.lib libport-vc90.lib libsched-vc90.lib libuobject-vc90.lib pour indiquer quelles sont les librairies qui seront utilisées.


Le composant est une bibliothèque dynamique qui peut exécuter plusieurs threads, alors vérifiez les paramètres suivants :

  • 4.jpg 4.jpg Général->Type de configuration: bibliothèque dynamique (.dll)
  • C++ > Génération de code > Bibliothèque Runtime : DLL multithread (/MD)


Voilà, le composant est prêt à être exporté. Exécutez alors Générez > Générez la solution pour créer le composant, ce qui donne dans le panneau sortie :

8.jpg
Si vos traces de sortie sont identiques c'est que tout s'est bien passé et que votre environnement est correctement configuré. Le composant est alors créé dans le dossier Release du répertoire de projet, sauf que pour le moment il ne fait rien !

4 - La classe UObject

La classe UObject possède un ensemble de méthodes et de types spécifiques à l'architecture URBI.

  • UVar : C'est le type pour une variable que vous souhaitez partager avec Urbi. C'est un conteneur qui fournit les opérateurs pour les types suivants : double, std::string, char*


  • UBindVar(Classname, Varname) : Cette méthode permet de déclarer les UVar qui seront visibles par le serveur. Les modifications d'une variable UVar déclenchent alors des évènements, avant et après le changement, qui peuvent être interceptés par le serveur ou par un autre composant.


  • UBindFunction(Classname,Functionname) : cette méthode permet de déclarer les fonctions qui seront accessibles de l’extérieur.


  • UStart(ClassName) : Cette macro permet de déclarer une nouvelle classe dans l'environnement Urbi.


Pour en savoir plus sur les UObjects, consultez la documentation : UObject API.

5 - HelloUrbi!

Reprenons le code de notre composant et ajoutons une fonction basique d'addition :

#include <urbi/uobject.hh>
 
class MyUObject: public urbi::UObject {
  public:
    MyUObject(const std::string& str);
    int init();
 
   // Our variable. 
   urbi::UVar v; 
 
   // Our method. 
   double add (double); 
};
 
MyUObject::MyUObject(const std::string& s) : urbi::UObject(s) {
  UBindFunction(MyUObject, init);
};
 
int MyUObject::init() {
  // Bind the variable. 
  UBindVar (MyUObject, v); 
 
  // Bind the function. 
  UBindFunction (MyUObject, add); 
 
  return 0;
};
 
double MyUObject::add (double rhs) { 
  return (double) v + rhs; 
}
 
UStart(MyUObject);

Et lancez la compilation : Générez > Regénérez la solution. Votre composant est prêt à être chargé ! Il est contenu dans le dossier Release du répertoire de projet sous le nom MyUobject.dll.

  • Note : Dans la suite de ce tutoriel, j'utiliserai <uobject_path> pour qualifier le chemin du répertoire qui contient le composant.


6 - Chargement du composant

integrateurbi.jpg Il existe 2 méthodes pour charger un composant. La première consiste à connecter le composant directement au serveur urbi grâce à la fonction loadModule, alors que la deuxième consiste à connecter le périphérique grâce à un serveur distant en utilisant urbi-lanch.exe et le mode remote.
Avec la deuxième solution, le périphérique distant peut être exécuté sur une autre machine du moment qu'elle peut communiquer avec le serveur Urbi principal.

6.1 - Directement par le serveur

9.jpg Pour charger le composant, il faut d'abord définir la variable système qui définit le chemin du répertoire où le serveur ira chercher les bibliothèques. Cette variable s’appelle URBI_UOBJECT_PATH et se change par la commande set.

set URBI_UOBJECT_PATH=<uobject_path>[3]

Ensuite allez dans le dossier <urbi_dir> et lancez le serveur grâce à la commande suivante :

bin\urbi.exe --interactive --port 54000 -d=3

Cette commande lance alors un serveur urbi en mode interactif --interactive, c'est à dire que l'on peut directement taper les commandes à partir de la ligne de commande. Le deuxième paramètre --port définit le port d'écoute à 54000 (à l'adresse par défaut : 127.0.0.1). Le dernier paramètre permet de définir le niveau de trace pour afficher les actions du serveur et faciliter le débogage[4].
Pour connaître toutes les options de lancement d'un serveur urbi, consultez la page : Running an Urbi Server
Une fois le serveur lancé, exécutez la commande suivante :

loadModule("MyUobject.dll");

Cette commande va demander au serveur de charger le composant MyUobject.dll contenu dans le dossier URBI_UOBJECT_PATH
10.jpg

6.2 - À partir d'un serveur distant

11.jpg L'un des points forts d'Urbi est de pouvoir utiliser un composant situé sur un autre serveur, local ou non, du moment que les 2 serveurs peuvent communiquer entre eux. La procédure est donc de lancer un serveur urbi principal, puis de connecter le composant par l’intermédiaire d'un serveur distant.
Pour lancer le serveur principal, ouvrez une invite de commande et rendez-vous dans le dossier <urbi_dir>. Lancez alors le serveur grâce à la commande suivante :

bin\urbi.exe --interactive --port 54000 -d=3

Une fois le serveur lancé, ouvrez une nouvelle ligne de commande et rendez-vous à nouveau dans le dossier <urbi_dir>. Cette fois-ci, exécutez la commande suivante :

bin\urbi-launch.exe -r "<uobject_path>\MyUobject.dll"

Cette commande lance un serveur qui va connecter le composant au serveur principal, en utilisant le mode remote (-r). Le composant sera donc charger par le serveur distant mais utilisable dans le serveur principal.
12.jpg
Une fois le composant chargé, il reste à le manipuler.

7 - Manipulation du composant

Bien que l'on puisse manipuler le composant directement depuis le serveur, l'occasion est ici de découvrir un dernier élément du SDK, la UrbiConsole. Cette console permet de se connecter à un serveur Urbi pour exécuter des commandes et donc de manipuler les composants.
13.jpg Commencez par lancer la console grâce au raccourci du menu démarrer de Windows et connectez-vous au serveur Urbi en cliquant sur le bouton vert en haut à droite de la fenêtre. La console affiche alors les messages d’informations du serveur, vous êtes prêt à manipuler le composant.

Pour instancier le composant, tapez la commande suivante :

  • var obj = MyUObject.new();


Affectation de la variable v :

  • obj.v = 0;


Appel de fonction :

  • obj.add(5);


Ce qui doit afficher :
14.jpg

  • Note : Attention à ne pas oublier le point-virgule en fin de commande, sans quoi elle ne sera pas prise en compte.


8 - Conclusion

Ce tutoriel permet de mettre en place les bases du développement de composant URBI, mais beaucoup de mécanismes liés au fonctionnement des UObjects, ou plus généralement d'URBI, n'ont pas été abordés. Si vous voulez en savoir plus sur le développement URBI, je vous invite à consulter les pages suivantes :

Notes

[1] Si ce n'est pas le cas, vous pourrez les trouver dans le dossier ''<urbi_dir>\share\templates\Visual Studio'' et les importer dans les configurations de Visual Studio.

[2] Pour passer en Release, sélectionnez la bonne configuration dans la liste déroulante Configurations de solutions (cf screenshot).

[3] Attention à enlever les guillemets qui entoure le chemin

[4] Il existe 4 niveaux de trace : NONE, LOG (default), TRACE, DEBUG, DUMP (ou 0,1,2,3,4). Vous pouvez également définir une fois pour toute le niveau de verbose grâce à une variable système en exécutant la commande suivante : set GD_LEVEL=<value>