middleware/src/Communication/Server.cs
changeset 15 4b78f179e7ce
parent 14 10d5199d9874
child 16 a9ebacd6c089
equal deleted inserted replaced
14:10d5199d9874 15:4b78f179e7ce
     1 /*
       
     2 * This file is part of the TraKERS\Middleware package.
       
     3 *
       
     4 * (c) IRI <http://www.iri.centrepompidou.fr/>
       
     5 *
       
     6 * For the full copyright and license information, please view the LICENSE_MIDDLEWARE
       
     7 * file that was distributed with this source code.
       
     8 */
       
     9 
       
    10 /*
       
    11  * Projet : TraKERS
       
    12  * Module : MIDDLEWARE
       
    13  * Sous-Module : Communication
       
    14  * Classe : Server
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Reçoit des notifications du module sous-module Tracking.
       
    19  * Traduit les notifications sous forme de messages OSC et les envoie au Front Atelier.
       
    20  * Forme des messages :
       
    21  * - Notification de main dans le champ de recherche : Point3D indiquant la position de la main dans l'espace.
       
    22  */
       
    23 
       
    24 using System;
       
    25 using System.Collections.Generic;
       
    26 using System.Linq;
       
    27 using System.Text;
       
    28 using System.IO;
       
    29 using System.Net;
       
    30 using System.Net.Sockets;
       
    31 using System.Threading;
       
    32 using Tuio;
       
    33 using System.Windows;
       
    34 using Microsoft.Kinect;
       
    35 using Trakers.Tracking;
       
    36 using System.Windows.Media.Media3D;
       
    37 using Trakers.Tracking.Events;
       
    38 using System.Timers;
       
    39 using Trakers.Debug;
       
    40 using System.Resources;
       
    41 using System.Reflection;
       
    42 
       
    43 namespace Trakers.Communication
       
    44 {
       
    45     public class Server
       
    46     {
       
    47         //Serveur TUIO, provenant de la DLL TuioServer créé par Bespoke.
       
    48         private TuioServer server;
       
    49         //Affichage de debug.
       
    50         private DebugWindow debug;
       
    51 
       
    52         //Permet de savoir si un curseur pour la main gauche/droite a été créé.
       
    53         private bool leftHandCursorCreated;
       
    54         private bool rightHandCursorCreated;
       
    55         private bool messageCreated;
       
    56         private bool gestureLocked, modLocked;
       
    57         //Intervalle minimum entre les gestures.
       
    58         private int timerElapsing;
       
    59         //Timer.
       
    60         private System.Timers.Timer _timer;
       
    61         //Gestionnaire de ressources.
       
    62         private ResourceManager rm;
       
    63         //Dernier code envoyé.
       
    64         private String lastCode;
       
    65 
       
    66         /*
       
    67         * Constructeur : On initialise le serveur avec une adresse et un port, au début les curseurs
       
    68         * ne sont pas créés et on indique au ThreadPool une fonction de callback de manière à vérifier
       
    69         * s'il reçoit des notifications.
       
    70         */
       
    71         public Server(String host, int port, int _timerElapsing, DebugWindow _debug)
       
    72         {
       
    73             debug = _debug;
       
    74             rm = new ResourceManager("Trakers.Properties.resources", Assembly.GetExecutingAssembly());
       
    75             //Au départ, aucune main n'est dans le champ de recherche et aucune gesture n'est détectée.
       
    76             leftHandCursorCreated = false;
       
    77             rightHandCursorCreated = false;
       
    78             messageCreated = false;
       
    79             gestureLocked = false;
       
    80             modLocked = false;
       
    81             lastCode = "";
       
    82 
       
    83             timerElapsing = _timerElapsing;
       
    84 
       
    85             try
       
    86             {
       
    87                 //On démarre le serveur TUIO.
       
    88                 server = new TuioServer(host, port);
       
    89                 //On initialise le threadPool (appelé toutes les N ms).
       
    90                 ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
       
    91 
       
    92                 //On instancie le timer à N ms.
       
    93                 _timer = new System.Timers.Timer(timerElapsing);
       
    94                 //Dès que le timer est expiré, on appelle _timer_Elapsed.
       
    95                 _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
       
    96             }
       
    97             catch (Exception)
       
    98             {
       
    99                 debug.ExceptionLbl.Content = rm.GetString("serverCantStart");
       
   100             }
       
   101         }
       
   102 
       
   103         /*
       
   104         * Getter du serveur.
       
   105         */
       
   106         public TuioServer getServer()
       
   107         {
       
   108             return server;
       
   109         }
       
   110 
       
   111         /*
       
   112          * Méthode appelée à l'expiration du timer pour les gestures et modes.
       
   113          */
       
   114         public void _timer_Elapsed(object sender, ElapsedEventArgs e)
       
   115         {
       
   116             //On débloque la détection de gesture.
       
   117             gestureLocked = false;
       
   118             //On débloque la notification de nouveau mode.
       
   119             modLocked = false;
       
   120             //On arrête le timer.
       
   121             _timer.Stop();
       
   122         }
       
   123 
       
   124         /*
       
   125         * Méthode appelée lors d'une notification de type : main gauche entrée dans le champ.
       
   126         */
       
   127         public void LeftHandTracked(object sender, LeftHandTrackedEventArgs e)
       
   128         {
       
   129             //Si le curseur de la main gauche n'est pas créé, alors on le crée.
       
   130             if (!leftHandCursorCreated)
       
   131             {
       
   132                 server.AddTuioCursor(0, SkeletonPointToPoint3D(e.handJoint.Position));
       
   133                 leftHandCursorCreated = true;
       
   134             }
       
   135             //S'il existe, on le met simplement à jour.
       
   136             else
       
   137             {
       
   138                 server.UpdateTuioCursor(0, SkeletonPointToPoint3D(e.handJoint.Position));
       
   139             }
       
   140         }
       
   141 
       
   142         /*
       
   143         * Méthode appelée lors d'une notification de type : main droite entrée dans le champ.
       
   144         */
       
   145         public void RightHandTracked(object sender, RightHandTrackedEventArgs e)
       
   146         {
       
   147             //Si le curseur de la main droite n'est pas créé, alors on le crée.
       
   148             if (!rightHandCursorCreated)
       
   149             {
       
   150                 server.AddTuioCursor(1, SkeletonPointToPoint3D(e.handJoint.Position));
       
   151                 rightHandCursorCreated = true;
       
   152             }
       
   153             //S'il existe, on le met simplement à jour.
       
   154             else
       
   155             {
       
   156                 server.UpdateTuioCursor(1, SkeletonPointToPoint3D(e.handJoint.Position));
       
   157             }
       
   158         }
       
   159 
       
   160         /*
       
   161         * Méthode appelée lors d'une notification de type : main gauche sortie du champ.
       
   162         */
       
   163         public void LeftHandQuit(object sender, LeftHandQuitEventArgs e)
       
   164         {
       
   165             //Si le curseur de la main gauche existe, alors on le supprime.
       
   166             if (leftHandCursorCreated)
       
   167             {
       
   168                 server.DeleteTuioCursor(0);
       
   169                 leftHandCursorCreated = false;
       
   170             }
       
   171         }
       
   172 
       
   173         /*
       
   174         * Méthode appelée lors d'une notification de type : main droite sortie du champ.
       
   175         */
       
   176         public void RightHandQuit(object sender, RightHandQuitEventArgs e)
       
   177         {
       
   178             //Si le curseur de la main droite existe, alors on le supprime.
       
   179             if (rightHandCursorCreated)
       
   180             {
       
   181                 server.DeleteTuioCursor(1);
       
   182                 rightHandCursorCreated = false;
       
   183             }
       
   184         }
       
   185 
       
   186         /*
       
   187         * Méthode appelée lors d'une notification de type : l'utilisateur fait un swipe.
       
   188         */
       
   189         public void Swipe(object sender, SwipeEventArgs e)
       
   190         {
       
   191             if (e.direction == Tracking.Gestures.SwipeDetector.Direction.LEFT)
       
   192                 GesturePerformed("SWIPE LEFT");
       
   193             else if (e.direction == Tracking.Gestures.SwipeDetector.Direction.RIGHT)
       
   194                 GesturePerformed("SWIPE RIGHT");
       
   195         }
       
   196 
       
   197         /*
       
   198         * Méthode appelée lors d'une notification de type : l'utilisateur fait un push/pull.
       
   199         */
       
   200         public void Push(object sender, PushEventArgs e)
       
   201         {
       
   202             if(e.hand == Tracking.Gestures.PushDetector.Hand.NONE)
       
   203                 return;
       
   204 
       
   205             String pushPull = "", hand = "";
       
   206             if (e.direction == Tracking.Gestures.PushDetector.Direction.PUSH)
       
   207                 pushPull = "PUSH";
       
   208             else
       
   209                 pushPull = "PULL";
       
   210 
       
   211             if (e.hand == Tracking.Gestures.PushDetector.Hand.LEFT)
       
   212                 hand = "LEFT";
       
   213             else if (e.hand == Tracking.Gestures.PushDetector.Hand.RIGHT)
       
   214                 hand = "RIGHT";
       
   215             else
       
   216                 hand = "BOTH";
       
   217 
       
   218             GesturePerformed(pushPull + "-" + hand);
       
   219         }
       
   220 
       
   221         /*
       
   222         * Méthode appelée lorsqu'une gesture a été détectée et que l'événement approprié a été lancé.
       
   223         */
       
   224         public void GesturePerformed(String code)
       
   225         {
       
   226             //Si le code vient d'être envoyé, on passe.
       
   227             if (lastCode.Equals(code))
       
   228                 return;
       
   229             lastCode = code;
       
   230             //Si une gesture a été effectuée, on bloque un certain temps.
       
   231             if (!gestureLocked)
       
   232             {
       
   233                 gestureLocked = true;
       
   234                 
       
   235                 //On crée un message contenant le code à envoyer.
       
   236                 if (!messageCreated)
       
   237                 {
       
   238                     messageCreated = true;
       
   239                     Console.Out.WriteLine("A 2");
       
   240                     server.AddTuioString(2, code);
       
   241                     //On démarre le timer.
       
   242                     _timer.Start();
       
   243                 }
       
   244             }
       
   245         }
       
   246 
       
   247         /*
       
   248         * Méthode appelée lorsqu'on doit entrer dans un autre mode.
       
   249         */
       
   250         public void ModeNotification(String code)
       
   251         {
       
   252             //Si le code vient d'être envoyé, on passe.
       
   253             if (lastCode.Equals(code))
       
   254                 return;
       
   255             lastCode = code;
       
   256             //Si on a été notifié.
       
   257             if (!modLocked)
       
   258             {
       
   259                 modLocked = true;
       
   260 
       
   261                 //On crée un message contenant le code à envoyer.
       
   262                 if (!messageCreated)
       
   263                 {
       
   264                     messageCreated = true;
       
   265                     Console.Out.WriteLine("A 3");
       
   266                     server.AddTuioString(2, code);
       
   267                     //On démarre le timer.
       
   268                     _timer.Start();
       
   269                 }
       
   270             }
       
   271         }
       
   272 
       
   273         /*
       
   274         * Permet de convertir un point de position de noeud en Point3D.
       
   275         */
       
   276         private Point3D SkeletonPointToPoint3D(SkeletonPoint p)
       
   277         {
       
   278             return new Point3D((double)p.X, (double)p.Y, (double)p.Z);
       
   279         }
       
   280 
       
   281         /*
       
   282         * Méthode de callback vérifiant toutes les 25 ms les nouvelles notifications.
       
   283         * Il est à noter que si le temps de rafraîchissement des trop rapide, les messages n'ont pas
       
   284         * le temps d'être envoyés.
       
   285         */
       
   286         private void ThreadPoolCallback(Object threadContext)
       
   287         {
       
   288             while (true)
       
   289             {
       
   290                 //On initialise le message OSC.
       
   291                 server.InitFrame();
       
   292                 //On l'envoie au client (au host et au port spécifiés dans le constructeur).
       
   293                 server.CommitFrame();
       
   294                 //On attend 25 ms.
       
   295                 Thread.Sleep(25);
       
   296 
       
   297                 //Si une gesture a été effectuée et que le délai d'attente est expiré.
       
   298                 if (messageCreated && !gestureLocked && !modLocked)
       
   299                 {
       
   300                     //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture.
       
   301                     messageCreated = false;
       
   302                     server.DeleteTuioString(2);
       
   303                     //server.DeleteTuioString(3);
       
   304                     Console.Out.WriteLine("R");
       
   305                 }
       
   306             }
       
   307         }
       
   308     }
       
   309 }