Application du Protocole de Visualisation IRIDA
sur un réseau de capteur sans fil
Dallinge Laetitia
Université de Genève
Computer Science
4 Avril 2012
2
Table des matières
1 Introduction 3
2 Description du matériel 4
3 Les Waspmotes 6
3.1 Wapsmote Gateway 6
3.2 Wapsmote Router 6
4 IRIDA Visualisation Unit 7
5 IRIDA Control Unit 8
6 Programmation des Waspmotes 10
6.1 API 11
7 Résultats 16
8 Conclusion 19
9 Bibliographie 20
10 Annexes 20
3
1 Introduction
Le but de ce projet est de tester le protocole IRIDA sur un réseau de capteur sans fil à taille
réelle, en mettant en place les outils nécessaires et en implémentant des algorithmes
classiques de ce type de réseau.
Les utilisations des réseaux de capteurs sans fil sont nombreuses. Ils permettent, par exemple,
de deviner où se trouve le début d’un incendie, de détecter les craquelures dans un mur, de
capter les mouvements dans une pièce, et bien d’autres applications en fonctions des
senseurs.
Un réseau de capteur sans fil est formé d’un ensemble de capteurs appelés aussi nœuds, qui
communiquent entre eux par transmission radio. Un capteur possède plusieurs senseurs
(température, mouvement, sons…), un émetteur et récepteur radio avec une antenne, une
batterie, ainsi qu’une unité de calcul et une mémoire. Les capteurs d’un réseau peuvent
communiquer entre eux ou avec une station pour faire transiter les données récupérées des
senseurs.
Un capteur doit être programmé minutieusement pour qu’il réponde au besoin du réseau et le
fonctionnement du réseau doit être doit être testé. Il existe de nombreuses raisons pour
lesquelles un réseau de capteur WIFI peut échouer dans sa tâche et il est difficile de le
déboguer avec juste des informations textuelles.
Le protocole de visualisation IRIDA intervient pour faciliter la compréhension du réseau en
fournissant une image représentant son état courant. Pour mener à bien ce projet, nous avons
créé deux logiciels (Irida Visualisation Unit, Irida Control Unit), et mis en place un réseau sans
fil de 49 nœuds que nous avons programmé.
4
2 Description du matériel
Afin de construire le réseau de capteur sans fil, nous avons commandé le matériel suivant :
6 planches de bois blanches de 100cm par 150cm
49 capteurs Waspmote livrés avec 5 Waspmote Gateway (Interface USB-PC) chez
l’entreprise Libellium
49 câbles USB pour alimenter les capteurs en électricité
7 switchs USB pour relier les cables USB par groupes de 7 à une multiprise.
Nous avons fixé les planches de bois pour créer un grand panneau blanc de 3m par 3m et nous
y avons collé les 49 câbles USB à l’aide de scotch.
Ensuite, nous avons branché les câbles USB sur les switchs connectés à une multiprise
alimentée en électricité. Voici le schéma de l’installation :
Figure 1 : Schéma de l'installation du réseau de capteur
5
Comme on peut le voir sur la figure 1, chacun des capteurs est alimenté en électricité. On peut
éteindre certaines parties du réseau ou le réseau entier en débranchant des câbles sur la
multiprise.
Figure 2: Photo de l'installation réelle
6
3 Les Waspmotes
3.1 Wapsmote Gateway
Avec les 50 Waspmote Router commandés, nous avons reçu 5
Wapsmote Gateway. Les Waspmote Gateway permettent de
faire le lien entre l’ordinateur et le réseau. Un Waspmote
Gateway est une interface qui se connecte à l’ordinateur par
port USB. On y branche un modem avec une antenne pour
recevoir les messages du réseau envoyé à cette interface. Tous
les messages reçus sont envoyés dans le port USB et peuvent
être lu avec un logiciel.
3.2 Wapsmote Router
Les 50 Waspmotes router que nous avons commandés sont des
cartes sur lesquelles peuvent être placés des modems,
senseurs divers, carte mémoire SD 2GO et batterie.
Ces Waspmotes sont programmables en c++ via le logiciel
Waspmote IDE. Ils doivent être connectés à l’ordinateur par
USB pour la programmation. Une fois programmés et allumés,
ils peuvent communiquer entre eux de la façon souhaitée.
Voici leurs spécifications d’après la documentation des
Wapsmotes sur le site de Libelium :
Figure 3: Wapsmote Gateway
Figure 4 : Waspmote Router
Figure 5 : Waspmote routeur vidé (vue d’en dessus)
7
Bien que les capteurs puissent être personnalisés, nous n’utilisons comme senseur que
l’accélérateur puisque c’est le plus simple à tester. Sur ces cartes, nous avons placé une
batterie, un modem munit d’une antenne pour les communications ainsi qu’une carte SD pour
y contenir nos programmes.
4 IRIDA Visualisation Unit
Irida Visualisation Unit ou « IVU » est un logiciel écrit par Marios Karagiannis indispensable. Il
permet de visualiser l’état du réseau en traduisant le protocole IRIDA en images. Il a été codé
en C# en utilisant le framework XNA de Microsoft.
L’IVU reçoit par socket UDP des commandes respectant le protocole IRIDA. Il peut afficher les
nœuds d’un réseau à une position précise, changer leurs couleurs, écrire du texte sur les
nœuds et paquets, représenter les liens de voisinage ainsi que l’envoi des paquets d’un nœud
à un autre.
Les commandes que nous utilisons dans notre réseau sont les suivantes :
heartBeat x,y : Affiche un nœud à la position x, y et le fait « Briller ».
sendPacket x, y, z : Montre l’envoi du nœud x au nœud y d’un paquet nommé z.
addNeighbor x,y : Affiche un lien de voisinage entre le nœud x et y.
changeColor x, r,g,b : Change la couleur du nœud x avec les composantes R,G,B.
Pour utiliser l’IVU, il faut lancer le logiciel sur un ordinateur en précisant quel est le port et
l’adresse IP à laquelle il doit se connecter pour recevoir les messages IRIDA par socket UDP.
Les commandes IRIDA obtenues du réseau doivent lui sont envoyées dans ce socket pour voir
les changements à l’écran.
Les messages qui proviennent d’un réseau de capteurs doivent être traités car ils ne sont pas
toujours du format correct et n’ont parfois rien à voir avec le protocole IRIDA (message de
debug, messages erronés, messages broadcast). Dans le cas de notre expérience, ce tri des
paquets est effectué par l’ICU et seules les informations correctes sont transmises à l’IVU, les
autres étant ignorées.
8
5 IRIDA Control Unit
L’IRIDA Control Unit est un autre programme écrit en C# qui permet le traitement des
informations transmises par le réseau de capteurs. Ce programme a été écrit par mes soins et
effectue le travail suivant :
Permet l’inscription et la désinscription d’une ou plusieurs IVU, indépendamment de leur support, via une requête passant par socket UDP, « register » et « unregister ». Le programme stocke le port et l’adresse de chaque IVU dans une liste.
Lit sur le port USB les informations reçues par le Wapsmote Gateway et transmet aux IVU enregistrées tous les paquets de la forme IRIDAxxx, xxx étant une commande écrite avec le protocole IRIDA.
Il écrit sur la console de sortie les informations des paquets envoyés et reçus, ainsi que les différents événements (inscriptions, désinscriptions), dans des couleurs différentes pour plus de lisibilité.
Ce schéma décrit l’envoi des messages du réseau de capteurs à la Waspmote Gateway, qui
sont lus par l’ICU via port USB, puis envoyés aux différentes IVUs enregistrées.
Voici une image de l’ICU en pleine action :
IVU
ICU
Réseau de capteur sans fil
IVU IVU Transmission socket
UDP
Transmission COM
port
Transmission WIFI Waspmote
Gateway
Figure 6 : Schéma du fonctionnement de l’installation finale
10
6 Programmation des Waspmotes
Afin de tester le protocole IRIDA, les capteurs doivent être programmés pour qu’ils
communiquent entre eux, exécutent des algorithmes et envoient des réponses à la Gateway.
Sur le site de Libelium nous avons récupéré le logiciel Wapsmote IDE, qui est un
environnement de travail pour programmer les Wapsmotes.
Ce logiciel est fourni avec une interface de programmation (waspmote-api-v.021) qui permet
d’utiliser toutes les fonctionnalités d’une Wapsmote comme les LEDs, l’accélérateur, l’envoi et
la réception de paquets, etc. Cette librairie open-source s’est avérée très pratique pour la
réalisation de notre programme malgré deux problèmes majeurs internes à celle-ci que nous
avons contournés : une fuite de mémoire sur la réception des paquets et une impossibilité de
lire certaines cartes SD.
Pour programmer un waspmote, celui-ci doit être branché à l’ordinateur et son modem retiré.
Après avoir cliqué sur le bouton « Upload » dans le logiciel Wapsmote IDE et sélectionné le
bon COM port sur lequel le waspmote est relié, le programme met environs une minute à être
compilé, puis deux minutes à être envoyé sur le wapsmote. Une fois le processus d’envoi
terminé, le modem est branché à nouveau sur le waspmote qui doit être réinitialisé et testé.
Nous avons tenté de mettre en place un système permettant la programmation de plusieurs
wapsmotes en même temps avec l’ Over The Air Programming, un système fournit par
Libelium. Cela s’est avéré impossible en raison de l’instabilité de l’API fournie par Libelium, de
la taille du programme final (environ 200KO) et le nombre de nœuds dans le réseau (49). Les
quelques essais n’étaient pas concluants : l’envoi d’un programme sans erreur par
transmission radio pouvait prendre jusqu’à 5 minutes pour un nœud unique et pouvait
Figure 8 : Environnement de travail Wapsmote IDE
11
échouer plusieurs fois. Nous n’avons pas réussi à envoyer un programme à plusieurs nœuds
simultanément. Autant dire que la programmation de chaque Waspmote individuellement par
la méthode basique fut une longue tâche.
6.1 API
Après avoir constaté l’instabilité de l’API de Libelium, nous avons décidé d’écrire notre propre
système en utilisant les fonctions de l’API dont nous étions sûrs du fonctionnement. Voici
l’ensemble des fichiers de notre librairie personnelle, écrite en c++.
coordinate.cpp
A partir de l’ID d’un nœud ou de son adresse MAC, il est possible de déduire sa position dans l’espace 2D. Pour faciliter la mise en place du réseau, nous avons décidé que chacun des nœuds aurait une position fixe.
Fonction Description Void getCoordsFromNumber(int number, int * xNew, int * yNew)
Retourne la position d’un noeud en fournissant son ID.
Void getCoordsFromMac(const char * mac, int * xNew, int * yNew)
Retourne la position d’un noeud en fournissant son adresse MAC.
mac.cpp
A chaque adresse MAC est associé un nombre de 1 à 49 afin de manipuler les nœuds plus aisément.
Fonction Description Void setMac(); Stoque l’ID du nœud courant dans myId, et l’adresse
mac dans la variable mac. Ces variables peuvent être réutilisées partout dans le programme.
Int mac2id(const char * mac) ; Transforme une adresse MAC en l’ID correspondante.
const char * dynmac2staticmac(char * mac) ; Obtient l’adresse MAC statique depuis une chaine contenant une adresse MAC.
Math.cpp
Ce fichier regroupe quelques fonctions en lien avec les mathématiques, principalement du calcul de distance entre deux nœuds.
Fonction Description Int isNear(const char * mac1, const char * mac2) ; Indique si un nœud est proche d’un autre nœud avec
une distance euclidienne.
Float distanceBetweenStationAndANode(const char * mac1) ;
Retourne la distance entre un nœud et une station (position quelconque spécifiée par le programme).
Int isNearMe(const char * sourceMac) ; Indique si un nœud est proche du nœud courant.
Neighbor.cpp
Chaque nœud possède une liste de voisins. Afin d’établir cette liste, un nœud lance un appel et chaque nœud qui y répond est ajouté à cette liste.
Fonction Description void clearNeighbors() ; Vide la liste de voisins.
int isNeighborKnown(const char * mac) ; Indique si un voisin est connu ou pas.
12
const char* closestNeighborFromStation() ; Indique quel est le voisin le plus proche d’une station.
int canAddNeighbor() ; Indique s’il est possible ou non d’ajouter un voisin à la liste de voisin.
void addNeighbor(const char * mac) ; Ajoute un voisin à la liste de voisins.
void neighborDiscovery(long intervalMillis) ; Effectue un appel pour découvrir les voisins du nœud courant.
Sense.cpp
Ce fichier regroupe majoritairement les fonctions qui testent les senseurs du nœud.
Fonction Description void senseACC(long interval); Vérifie si l’accélérateur a changé et notifie les voisins si
c’est le cas.
void setStartAcc(); Initialise les valeurs par défaut de l’accélérateur.
void heartBeat(int interval); Réinitialise la couleur du nœud à noir et envoie à la Gateway dans le protocole IRIDA que le nœud est vivant (heatBeat)
Packet.cpp
Ce fichier regroupe toutes les méthodes utilisées pour l’écriture et l’envoi des paquets.
Fonction Description void IRIDA_sendPacket(int nodeId1, int nodeId2); Envoie un paquet à la Wapsmote Gateway respectant
le protocole IRIDA qui indique que le nœud 1 a envoyé un message au nœud 2.
void IRIDA_sendPacketMessage(int nodeId1, int nodeId2, char * message);
Envoie un paquet à la Wapsmote Gateway respectant le protocole IRIDA i qui indique que le nœud 1 a envoyé un message au nœud 2. Un message est ajouté au paquet et il sera affiché à l’écran.
void IRIDA_heartBeat(int nodeId, int x, int y); Envoie un paquet à la Wapsmote Gateway respectant le protocole IRIDA qui indique qu’un nœud est en vie.
void IRIDA_addNeighbor(int nodeId1, int nodeId2); Envoie un paquet à la Wapsmote Gateway respectant le protocole IRIDA qui indique que le nœud 1 et le nœud 2 sont maintenant voisins.
void IRIDA_changeColor(int nodeId, int r, int g, int b); Envoie un paquet à la Wapsmote Gateway respectant le protocole IRIDA qui indique qu’un nœud change de couleur.
uint8_t generatePacketId(); Génère un nombre qui permet de créer un identifiant unique pour un paquet, et ainsi éviter les boucles infinies de paquets dans le réseau.
uint8_t isPacketKnown(uint8_t packetId, const char * srcMac);
Indique si un paquet est connu en vérifiant l’adresse de l’envoyeur et son identifiant.
void setPacketReceived(uint8_t packetId, const char * srcMac);
Indique qu’un paquet a été reçu. Ses informations sont stockées dans une liste temporairement afin d’éviter les boucles infinies de paquet dans le réseau.
void sendTo(const char * dstMac, uint8_t packetId, char * message);
Envoie un message à un noeud avec l’adresse mac spécifiée et un identifiant de paquet spécifié.
void broadcast(uint8_t packetId, char * message); Broadcast un message avec un identifiant de paquet spécifié.
void sendToNeighbors(uint8_t packetId, char * message); Envoie un message à tous les voisins.
void forwardToNeighbors(uint8_t packetId, char * message, const char * source);
Retransmet un message à tous les voisins.
void rawSendTo(const char * dstMac, char aux[MAX_MESSAGE_SIZE]);
Ecrit un message directement sur le buffer d’envoi, sans passer par les paquets XBee.
void iridaSend(char aux[MAX_MESSAGE_SIZE]); Envoie un message IRIDA à la Gateway.
13
Parse.cpp
Ce fichier s’occupe de traiter les paquets entrant et sortant et de lancer le programme principal.
Fonction Description void treatPacket(); Cette méthode vérifie s’il y a un paquet à traiter dans
la queue. Si c’est le cas, elle récupère les données de ce paquet (message, id, envoyeur), le sauvegarde et le traite.
void receiveAndSend(); Lance la boucle du programme principal qui consiste à :
- HeartBeat si 10s se sont écoulées - Faire une recherche de voisin toutes les 15
secondes - Traiter les paquets reçus - Vider la mémoire
void parse_forwarding(PacketData data); Transmet le paquet reçu à tous les voisins.
void parse_discoveryPacketSyn(PacketData packetData); Traite le paquet reçu d’un nœud adjacent qui demande à vérifier si l’on est son voisin.
void parse_discoveryPacketAck(PacketData packetData); Traite le paquet reçu d’un nœud adjacent qui indique qu’il est notre voisin. Il est ajouté dans la liste de voisins.
void parse(PacketData data); Traite un paquet précis en faisant appel aux fonctions de type « parse_xxx ».
void parse_changeStation(PacketData data); Traite un paquet qui change la station à laquelle router les paquets.
void parse_routing(PacketData data); Reçoit un paquet à router et l’envoie au voisin le plus proche de la station.
Dans les tableaux précédents nous avons survolé l’ensemble des fonctions de notre API. Nous
allons maintenant décrire le fonctionnement du programme des wapsmotes et son but à l’aide
d’un organigramme et une description précise de chacune des étapes.
14
Y
Y
Start
Setup
15s écoulées ?
5s écoulées ? heartBeat
neighborDiscovery
Loop
1)
éco
2)
éco
3)
éco
4)
éco
Y Stocker les données
Attendre pour des paquets
entrants pendant environs
500ms
Données reçues ?
Traiter les paquets s’il
y en a
Vider la mémoire
6)
éco
7)
éco
8)
9)
ACC activé ? Forwarding ou routing
Y 5)
éco
Figure 9 : Organigramme du programme des waspmotes
15
1) Avant le lancement de la boucle principale quelques variables doivent être initialisées :
- Initialiser le modem XBee, stocker l’adresse mac et l’id du nœud
2) Une fois la boucle du programme lancée, le waspmote n’en ressort jamais à moins de
planter ou d’être réinitialisé.
3) Si 5 secondes se sont écoulées, le waspmote montre signe de vie :
- Il envoie un message à IRIDA indiquant que sa couleur est noire.
- Il envoie un message à IRIDA « heartBeat mapositionx, mapositiony »
Dès que la Gateway reçoit ces messages, elle les transmet à l’ICU qui les transmet aux
IVU connectées. A cet instant, un point noir va apparaitre sur l’écran de l’IVU et une
vague va l’entourer un court instant pour montrer qu’il est vivant.
4) Si 15 secondes se sont écoulées, le nœud va faire une recherche de voisins. C’est-à-
dire qu’il va envoyer un message broadcast « Hello » à tous les nœuds, et seuls les
nœuds les plus proches de lui vont répondre à sa requête avec le message « Hello
too ».
5) Si l’accélérateur a été activé pendant la boucle, le nœud va envoyer un message à tous
ses voisins, soit de type flooding, soit de type routing. Seule la dernière ligne de nœud
(42-49) envoie des messages de type routing.
Flooding :
Le nœud envoie un message à tous ses voisins qui vont à leur tour envoyer ce message
à tous leurs voisins.
Routing :
Le nœud envoie un message au voisin le plus proche de la station, et le voisin va faire
de même jusqu’à atteindre la station.
6) - 7) Le programme entre ici dans une nouvelle boucle. Il attend de recevoir des
données dans son buffer de réception pendant 500ms. S’il reçoit des données, il les
stocke et continue d’attendre pour des données jusqu’à ce qu’il n’y en ait plus. Les
paquets reçus sont stockés dans une liste en attente d’être traités.
8) Une fois la boucle terminée, la liste de paquets reçus est traitée si elle n’est pas vide.
Chaque paquet possède sa propre fonction de traitement. Le programme lit la
première lettre du message du paquet et appelle la fonction correspondante. Chaque
paquet possède une ID entre 1 et 255 ainsi qu’une adresse mac qui indique celui qui l’a
envoyé. Pour éviter de traiter deux fois le même paquet, la clé ID-MAC est stockée
dans une liste qui est vidée périodiquement. S une clé enregistrée apparait dans un
autre paquet reçu il est ignoré.
9) La boucle se termine avec un vidage de la mémoire et du buffer qui permet l’envoi et
la réception.
16
7 Résultats
Tout au long de la préparation de notre projet, nous avons testé le système avec de petits
réseaux intermédiaires de taille 2x2, 4x4, et finalement, 7x7. Nous pouvons sans hésiter
affirmer que le protocole IRIDA et le système de visualisation se sont avéré très utile pour le
débogage de notre système.
En effet, plus il y a de nœuds, plus il y a de paquets transmis à la Gateway et il est impossible
de comprendre ce qui se passe sur le réseau juste en observant la console de l’ICU et les lignes
qui défilent à une vitesse très rapide (voir Figure 3). Grace au protocole d’affichage, une fois un
réseau installé, nous recevons immédiatement une image claire représentant son état.
Les nœuds en vie sont périodiquement entourés d’un halo qui leur donne une couleur noire.
Tant qu’aucun signal heartbeat ne provient d’eux, ils deviennent progressivement transparents
et finissent à peine visible. En un clin d’œil, on peut voir quels sont les nœuds actifs et les
nœuds morts.
Les messages « Hello » apparaissent comme des petits points avec une légende « Hello ».
Certains sont envoyés avec succès et reçoivent une réponse, d’autres n’en reçoivent aucune,
ce qui signifie que le message « Hello too » a été perdu.
Figure 11 : Nœuds vivants. Ils sont entourés d'un halo noir périodiquement
Figure 10 : Nœuds mort. On distingue à peine un rond noir.
Figure 12: Envoi avec succès d'un message "hello" qui reçoit une réponse "hello too" immédiate
17
Le voisinage apparait comme des traits rouges. Un trait rouge léger indique un lien
unidirectionnel, alors qu’un trait plus foncé indique un lien bidirectionnel. Les liens de
voisinage disparaissent périodiquement et sont renouvelés par le programme des waspmotes.
Avec un voisinage stable, nous pouvons tester le forwarding et routing. Quand un nœud
envoie un message dans le cadre d’un forwarding a tous ses voisins, ceux-ci deviennent bleus.
Dans le cadre d’un routing, soit de l’envoi d’un paquet vers une station, les nœuds qui
reçoivent le paquet à transmettre deviennent verts.
Figure 13 : Le noeud 21 reçoit les réponses « Hello too » de tous ses voisins après leur avoir envoyé la requête « hello ».
Figure 14 : Les traits rouges marqués par B sont bidirectionnels et par U, Unidirectionnels.
18
Figure 15 : Exemple de routing jusqu'à la position (0,0)
Nous avons cependant rencontrés quelques problèmes liés au grand nombre de nœuds dans
notre réseau (49). Quand tous les nœuds sont allumés en même temps, certains nœuds se
synchronisent et ne montrent aucun signe de vie car tous leurs paquets sont perdus à cause
des collisions. Quand deux nœuds tentent d’envoyer au même instant un paquet à travers le
réseau, il a une chance que ces paquets se collisionnent et finissent perdus ou ignorés en
raison de leur corruption. Pour améliorer cette situation, nous relancions les nœuds
problématiques. Toutefois, avec 49 nœuds, le risque de collision était élevé et il arrivait que la
gateway ne reçoive pas un paquet IRIDA, rendant alors l’affichage légèrement inconsistant.
Figure 16: Exemple de forwarding depuis le noeud 17
19
8 Conclusion
Tout au long de ce travail, nous avons eu pour but de tester le protocole IRIDA sur un réseau à
taille réelle et de prouver son efficacité. Cette tache réussie, nous pouvons maintenant
affirmer que le protocole IRIDA est indispensable pour le développement d’un réseau de
capteurs sans fil à grande échelle. Une fois la mise en place des logiciels et du protocole qui est
simple et intuitive, celui-ci est d’une grande d’aide pour voir si le réseau réalise bien les taches
qui lui sont demandées. Il fournit une preuve du bon fonctionnement du réseau et facilite
grandement son débogage.
20
9 Bibliographie
Marios Kargiannis, Laetitia Dallinge, Jose Rolim. « Irida: A real-time Wireless Sensor Network
visualization feedback protocol » arXiv, 19 Mars 2012.
Brad Karp, H. T. Kung. « GPSR: Greedy Perimeter Stateless Routing for Wireless Networks »
Mobicom 2000.
Stefan Rührup. « Theory and Practice of Geographic Routing » University of Freiburg,
Germany, February 2009.
Kazem Sohraby, Daniel Minoli, Taieb Znati. « WIRELESS SENSOR NETWORK, Technology,
Protocols, and applications » Johh Wiley & Sons, Canada, 2007.$
Libelium. Site Web. Libelium Comunicaciones Distribuidas S.L, 2012 [consulté fin 2011/Début 2012]. http://www.libelium.com/ Zigbee Networking Guide. Documentation PDF en ligne. Libelium Comunicaciones Distribuidas S.L, 2012 [consulté fin 2011/Début 2012]. http://www.libelium.com/documentation/waspmote/waspmote-zigbee-networking_guide.pdf
Over the Air Programming, with 802.15.4 and ZigBee. Documentation PDF en ligne. Libelium
Comunicaciones Distribuidas S.L, 2012 [consulté fin 2011/Début 2012].
http://www.libelium.com/documentation/waspmote/over_the_air_programming.pdf
10 Annexes
Le code source de l’API, les logiciels utilisés et des videos du projet sont trouvables sur le site
http://tcslab.unige.ch/irida/