middleware/src/Tracking/KinectMain.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 : Tracking
       
    14  * Classe : KinectMain
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Récupère les trames de données de la Kinect, les squelettes détectés via le SDK 1.0 de Microsoft.
       
    19  * Interprète ces trames de façon à afficher le flux vidéo couleurs, et récupérer la distance de l'utilisateur et les
       
    20  * noeuds de son squelette. Lance des événements lorsque la main gauche/droite entre dans/quitte le champ.
       
    21  * Envoie des données au sous-module de debug de manière a afficher un retour visuel sur la position de l'utilisateur,
       
    22  * son squelette, la détection de ses mains.
       
    23  * Découpe l'interaction avec le middleware en différents modes.
       
    24  */
       
    25 
       
    26 using System;
       
    27 using System.Collections.Generic;
       
    28 using System.Linq;
       
    29 using System.Text;
       
    30 using System.Windows;
       
    31 using System.Windows.Controls;
       
    32 using System.Windows.Data;
       
    33 using System.Windows.Documents;
       
    34 using System.Windows.Input;
       
    35 using System.Windows.Media;
       
    36 using System.Windows.Media.Imaging;
       
    37 using System.Windows.Navigation;
       
    38 using System.Windows.Shapes;
       
    39 using System.Drawing;
       
    40 using System.Windows.Media.Media3D;
       
    41 using Microsoft.Kinect;
       
    42 
       
    43 using Coding4Fun.Kinect.Wpf;
       
    44 using System.ComponentModel;
       
    45 
       
    46 using Trakers.Debug;
       
    47 using Tuio;
       
    48 using Trakers.Communication;
       
    49 using System.IO;
       
    50 using Trakers.Tracking.Gestures;
       
    51 using Trakers.Tracking.Events;
       
    52 using System.Configuration;
       
    53 using System.Resources;
       
    54 using System.Reflection;
       
    55 
       
    56 namespace Trakers.Tracking
       
    57 {
       
    58     //Il s'agit des fonctions permettant d'appeler les fonctions des événements Main droite/gauche entre/quitte le champ.
       
    59     public delegate void LeftHandTrackedHandler(object o, LeftHandTrackedEventArgs e);
       
    60     public delegate void RightHandTrackedHandler(object o, RightHandTrackedEventArgs e);
       
    61     public delegate void LeftHandQuitHandler(object o, LeftHandQuitEventArgs e);
       
    62     public delegate void RightHandQuitHandler(object o, RightHandQuitEventArgs e);
       
    63     //Il s'agit de la fonction permettant d'appeler les fonctions des événements Swipe left/right/up/down.
       
    64     public delegate void SwipeHandler(object o, SwipeEventArgs e);
       
    65     //Il s'agit de la fonction permettant d'appeler les fonctions des événements Push/Pull.
       
    66     public delegate void PushHandler(object o, PushEventArgs e);
       
    67     //Il s'agit de la fonction permettant d'appeler les fonctions des événements Jump.
       
    68     public delegate void JumpHandler(object o, JumpEventArgs e);
       
    69     //Il s'agit de la fonction permettant d'appeler les fonctions des événements de proximité.
       
    70     public delegate void UserPositionHandler(object o, UserPositionEventArgs e);
       
    71 
       
    72     public class KinectMain
       
    73     {
       
    74         //Gestionnaire de ressources.
       
    75         private ResourceManager rm;
       
    76         //Fenêtre de debug.
       
    77         private Debug.DebugWindow debug;
       
    78         //Squelettes (Il y en a 6 par défaut).
       
    79         private Skeleton[] skeletons;
       
    80         //Caméra infrarouge (sensor) de la Kinect.
       
    81         private KinectSensor kinectSensor;
       
    82 
       
    83         //Détecteur de swipes.
       
    84         private SwipeDetector swipeDetector;
       
    85         //Détecteur de pushes.
       
    86         private PushDetector pushDetector;
       
    87         //Détecteur de jumps.
       
    88         private JumpDetector jumpDetector;
       
    89         //Détecteur de proximité.
       
    90         private UserPositionDetector userPositionDetector;
       
    91 
       
    92         //Distances min/max délimitant le champ de recherche.
       
    93         private float minDistHands;
       
    94         private float maxDistHands;
       
    95         private float minDist;
       
    96         private float maxDist;
       
    97         private float zeroPoint;
       
    98         private int imagesToShow;
       
    99         private int takenPoints;
       
   100         private int directionChangeTresholdXY;
       
   101         private float directionChangeTresholdZ;
       
   102 
       
   103         //Temps de rafraichissement pour le timer (Détection de gesture dans le serveur TUIO).
       
   104         private int timerElapsing;
       
   105 
       
   106         //Serveur TUIO pour la connexion du Middleware vers le Front Atelier.
       
   107         private Server server;
       
   108 
       
   109         //Gestionnaire de modes.
       
   110         private ModeManagement modeManagement;
       
   111 
       
   112         //Les événements des mains pour la recherche.
       
   113         public static event LeftHandTrackedHandler LeftHandTrackedEvent;
       
   114         public static event RightHandTrackedHandler RightHandTrackedEvent;
       
   115         public static event LeftHandQuitHandler LeftHandQuitEvent;
       
   116         public static event RightHandQuitHandler RightHandQuitEvent;
       
   117         //L'événement swipe.
       
   118         public static event SwipeHandler SwipeEvent;
       
   119         //L'événement push.
       
   120         public static event PushHandler PushEvent;
       
   121         //L'événement jump.
       
   122         public static event JumpHandler JumpEvent;
       
   123         //L'événement l'utilisateur se déplace dans la zone de détection.
       
   124         public static event UserPositionHandler UserPositionEvent;
       
   125 
       
   126         private string connexionHost;
       
   127         private int connexionPort;
       
   128 
       
   129         /*
       
   130         *  Initialisation de la classe principale.
       
   131         *  Affiche l'écran de debug dans lequel on voit la distance à la Kinect,
       
   132         *  les mains détectées et le squelette de l'utilisateur.
       
   133         */
       
   134         public KinectMain()
       
   135         {
       
   136             //On fait appel au gestionnaire de ressources.
       
   137             rm = new ResourceManager("Trakers.Properties.resources", Assembly.GetExecutingAssembly());
       
   138             
       
   139             //On tente de charger les paramètres du fichier params.ini.
       
   140             //Si on n'y arrive pas, on affiche une erreur et on charge les paramètres par défaut.
       
   141             if (!loadParameters())
       
   142             {
       
   143                 debug.ExceptionLbl.Content = rm.GetString("loadParametersFail");
       
   144                 //Distances de détection des mains par défaut pour la recherche (ici de 1m à 2m de la Kinect).
       
   145                 minDistHands = 1.0f;
       
   146                 maxDistHands = 1.5f;
       
   147                 minDist = 1.0f;
       
   148                 maxDist = 4.0f;
       
   149                 zeroPoint = 1.7f;
       
   150                 connexionHost = "127.0.0.1";
       
   151                 connexionPort = 80;
       
   152                 timerElapsing = 1000;
       
   153                 imagesToShow = 25;
       
   154                 takenPoints = 10;
       
   155                 directionChangeTresholdXY = 10;
       
   156                 directionChangeTresholdZ = 0.01f;
       
   157             }
       
   158 
       
   159             //On crée la fenêtre de debug.
       
   160             debug = new Debug.DebugWindow(this);
       
   161 
       
   162             //On crée les détecteurs de gestes.
       
   163             swipeDetector = new SwipeDetector(debug);
       
   164             pushDetector = new PushDetector(debug);
       
   165             jumpDetector = new JumpDetector(debug);
       
   166             //On crée le détecteur de proximité.
       
   167             userPositionDetector = new UserPositionDetector(debug, minDist, maxDist, zeroPoint, minDistHands, maxDistHands);
       
   168 
       
   169             //On affiche la fenêtre de debug.
       
   170             try
       
   171             {
       
   172                 debug.ShowDialog();
       
   173             }
       
   174             catch(Exception){}
       
   175         }
       
   176 
       
   177         /*
       
   178         *  Initialisation de la classe principale avec comme argument le gestionnaire de ressources.
       
   179         */
       
   180         public KinectMain(ResourceManager _rm) : this()
       
   181         {
       
   182             rm = _rm;
       
   183         }
       
   184 
       
   185         /*
       
   186         *  Initialisation du sensor de la Kinect.
       
   187         */
       
   188         public void KinectInitialization()
       
   189         {
       
   190             try
       
   191             {
       
   192                 //On sélectionne la première kinect détectée.
       
   193                 kinectSensor = KinectSensor.KinectSensors.FirstOrDefault(s => s.Status == KinectStatus.Connected);
       
   194                 //La caméra couleur est activée avec une résolution 640x480 et un framerate de 30 FPS.
       
   195                 kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
       
   196                 //La caméra de profondeur est activée.
       
   197                 kinectSensor.DepthStream.Enable();
       
   198                 //Le squelette est activé.
       
   199                 kinectSensor.SkeletonStream.Enable();
       
   200 
       
   201                 //Quand le Middleware reçoit des trames de la Kinect, on va dans cette fonction.
       
   202                 kinectSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(AllFramesReady);
       
   203 
       
   204                 //On applique des paramètres d'ajustement pour le squelette.
       
   205                 TransformSmoothParameters parameters = new TransformSmoothParameters();
       
   206                 parameters.Smoothing = 0.2f;
       
   207                 parameters.Correction = 0.8f;
       
   208                 parameters.Prediction = 0.0f;
       
   209                 parameters.JitterRadius = 0.5f;
       
   210                 parameters.MaxDeviationRadius = 0.5f;
       
   211                 kinectSensor.SkeletonStream.Enable(parameters);
       
   212                 //On démarre la Kinect.
       
   213                 kinectSensor.Start();
       
   214                 debug.ExceptionLbl.Content = "";
       
   215             }
       
   216             catch (System.Exception)
       
   217             {
       
   218                 debug.ExceptionLbl.Content = rm.GetString("KinectNotConnected");
       
   219             }
       
   220 
       
   221             //Pour les événements main gauche/droite entre dans/quitte le champ, on a 4 listeners.
       
   222             //Fonction appelée lorsque la main gauche entre dans le champ de recherche.
       
   223             LeftHandTrackedListener leftHandTrackedListener = new LeftHandTrackedListener();
       
   224             LeftHandTrackedEvent += new LeftHandTrackedHandler(leftHandTrackedListener.ShowOnScreen);
       
   225 
       
   226             //Fonction appelée lorsque la main droite entre dans le champ de recherche.
       
   227             RightHandTrackedListener rightHandTrackedListener = new RightHandTrackedListener();
       
   228             RightHandTrackedEvent += new RightHandTrackedHandler(rightHandTrackedListener.ShowOnScreen);
       
   229 
       
   230             //Fonction appelée lorsque la main gauche quitte le champ de recherche.
       
   231             LeftHandQuitListener leftHandQuitListener = new LeftHandQuitListener();
       
   232             LeftHandQuitEvent += new LeftHandQuitHandler(leftHandQuitListener.ShowOnScreen);
       
   233 
       
   234             //Fonction appelée lorsque la main droite quitte le champ de recherche.
       
   235             RightHandQuitListener rightHandQuitListener = new RightHandQuitListener();
       
   236             RightHandQuitEvent += new RightHandQuitHandler(rightHandQuitListener.ShowOnScreen);
       
   237 
       
   238             //Fonction appelée lorsque l'utilisateur effectue un Swipe right/left/up/down.
       
   239             SwipeListener swipeListener = new SwipeListener();
       
   240             SwipeEvent += new SwipeHandler(swipeListener.ShowOnScreen);
       
   241 
       
   242             //Fonction appelée lorsque l'utilisateur effectue un Push/Pull.
       
   243             PushListener pushListener = new PushListener();
       
   244             PushEvent += new PushHandler(pushListener.ShowOnScreen);
       
   245 
       
   246             //Fonction appelée lorsque l'utilisateur effectue un Jump.
       
   247             JumpListener jumpListener = new JumpListener();
       
   248             JumpEvent += new JumpHandler(jumpListener.ShowOnScreen);
       
   249 
       
   250             //Fonction appelée lorsque l'utilisateur se déplace dans la zone de détection.
       
   251             UserPositionListener userPositionListener = new UserPositionListener();
       
   252             UserPositionEvent += new UserPositionHandler(userPositionListener.ShowOnScreen);
       
   253 
       
   254             //On connecte le serveur à l'adresse locale sur le port 80.
       
   255             server = new Server(connexionHost, connexionPort, timerElapsing, debug);
       
   256 
       
   257             //On crée le gestionnaire de modes.
       
   258             modeManagement = new ModeManagement(this, server, debug);
       
   259             modeManagement.DetectProximityBasedModes(0);
       
   260         }
       
   261 
       
   262         /*
       
   263         *  Fermeture du sensor de la Kinect.
       
   264         */
       
   265         public void KinectClose()
       
   266         {
       
   267             try
       
   268             {
       
   269                 //On stoppe la Kinect.
       
   270                 kinectSensor.Stop();
       
   271                 //On met a zero l'image d'affichage et le serveur.
       
   272                 debug.DebugImage.Source = null;
       
   273                 //server = null;
       
   274                 debug.ExceptionLbl.Content = "";
       
   275             }
       
   276             catch (System.Exception)
       
   277             {
       
   278                 debug.ExceptionLbl.Content = rm.GetString("KinectNotConnected");
       
   279             }
       
   280         }
       
   281 
       
   282         /*
       
   283         *  Récupère le premier squelette.
       
   284         */
       
   285         Skeleton GetFirstSkeleton(object sender, AllFramesReadyEventArgs e)
       
   286         {
       
   287             using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
       
   288             {
       
   289                 if (skeletonFrameData == null)
       
   290                     return null;
       
   291                 if ((skeletons == null) || (skeletons.Length != skeletonFrameData.SkeletonArrayLength))
       
   292                     skeletons = new Skeleton[skeletonFrameData.SkeletonArrayLength];
       
   293                 skeletonFrameData.CopySkeletonDataTo(skeletons);
       
   294 
       
   295                 //On obtient le premier skelette.
       
   296                 Skeleton first = (from s in skeletons where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault();
       
   297 
       
   298                 return first;
       
   299             }
       
   300         }
       
   301 
       
   302         /*
       
   303         *  Récupère le squelette le plus proche.
       
   304         */
       
   305         Skeleton GetNearestSkeleton(object sender, AllFramesReadyEventArgs e)
       
   306         {
       
   307             using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
       
   308             {
       
   309                 if (skeletonFrameData == null)
       
   310                     return null;
       
   311                 if ((skeletons == null) || (skeletons.Length != skeletonFrameData.SkeletonArrayLength))
       
   312                     skeletons = new Skeleton[skeletonFrameData.SkeletonArrayLength];
       
   313                 skeletonFrameData.CopySkeletonDataTo(skeletons);
       
   314 
       
   315                 Skeleton s;
       
   316                 float minDist = (float)-1.0;
       
   317                 int minID = 0;
       
   318                     
       
   319                 //Pour tous les squelettes.
       
   320                 for(int i = 0 ; i < skeletons.Count() ; i++)
       
   321                 {
       
   322                     s = skeletons.ElementAt(i);
       
   323                     //S'il est tracké.
       
   324                     if(s.TrackingState == SkeletonTrackingState.Tracked)
       
   325                     {
       
   326                         //On récupère sa position et on obtient la distance min et l'ID du squelette qui est à la distance min.
       
   327                         float dist = skeletons.ElementAt(i).Position.Z;
       
   328                         if (minDist == -1)
       
   329                         {
       
   330                             minDist = dist;
       
   331                             minID = i;
       
   332                         }
       
   333                         else if(minDist > dist)
       
   334                         {
       
   335                             minDist = dist;
       
   336                             minID = i;
       
   337                         }
       
   338                     }
       
   339                 }
       
   340 
       
   341                 //On renvoie le skelette le plus proche.
       
   342                 return skeletons.ElementAt(minID);
       
   343             }
       
   344         }
       
   345 
       
   346         /*
       
   347         *  Récupère le squelette le plus proche.
       
   348         */
       
   349         private void AllFramesReady(object sender, AllFramesReadyEventArgs e)
       
   350         {
       
   351             //On ne calcule rien si la fenêtre de debug se ferme.
       
   352             if (debug.isClosing())
       
   353                 return;
       
   354 
       
   355             //On met à jour la vidéo de debug.
       
   356             debug.RefreshVideo(e);
       
   357             //On récupère le premier squelette tracké.
       
   358             //Skeleton first = GetFirstSkeleton(e);
       
   359             //On récupère le plus proche squelette tracké.
       
   360             Skeleton first = GetNearestSkeleton(sender, e);
       
   361             //Si celui-ci n’est pas nul
       
   362             if (first == null)
       
   363                 return;
       
   364             
       
   365             //Si ce squelette est tracké (donc suivi et reconnu par la camera)
       
   366             if (first.TrackingState == SkeletonTrackingState.Tracked)
       
   367             {
       
   368                 //Ensemble des noeuds du squelette.
       
   369                 Joint hipCenter = getJoint(first, JointType.HipCenter), spine = getJoint(first, JointType.Spine), shoulderCenter = getJoint(first, JointType.ShoulderCenter), head = getJoint(first, JointType.Head);
       
   370                 Joint shoulderLeft = getJoint(first, JointType.ShoulderLeft), elbowLeft = getJoint(first, JointType.ElbowLeft), wristLeft = getJoint(first, JointType.WristLeft), handLeft = getJoint(first, JointType.HandLeft);
       
   371                 Joint shoulderRight = getJoint(first, JointType.ShoulderRight), elbowRight = getJoint(first, JointType.ElbowRight), wristRight = getJoint(first, JointType.WristRight), handRight = getJoint(first, JointType.HandRight);
       
   372                 Joint hipLeft = getJoint(first, JointType.HipLeft), kneeLeft = getJoint(first, JointType.KneeLeft), ankleLeft = getJoint(first, JointType.AnkleLeft), footLeft = getJoint(first, JointType.FootLeft);
       
   373                 Joint hipRight = getJoint(first, JointType.HipRight), kneeRight = getJoint(first, JointType.KneeRight), ankleRight = getJoint(first, JointType.AnkleRight), footRight = getJoint(first, JointType.FootRight);
       
   374 
       
   375                 //On construit l'historique des postures.
       
   376                 List<Joint> joints = new List<Joint>();
       
   377                 joints.Clear();
       
   378                 joints.Insert((int)JointType.HipCenter, hipCenter);
       
   379                 joints.Insert((int)JointType.Spine, spine);
       
   380                 joints.Insert((int)JointType.ShoulderCenter, shoulderCenter);
       
   381                 joints.Insert((int)JointType.Head, head);
       
   382                 joints.Insert((int)JointType.ShoulderLeft, shoulderLeft);
       
   383                 joints.Insert((int)JointType.ElbowLeft, elbowLeft);
       
   384                 joints.Insert((int)JointType.WristLeft, wristLeft);
       
   385                 joints.Insert((int)JointType.HandLeft, handLeft);
       
   386                 joints.Insert((int)JointType.ShoulderRight, shoulderRight);
       
   387                 joints.Insert((int)JointType.ElbowRight, elbowRight);
       
   388                 joints.Insert((int)JointType.WristRight, wristRight);
       
   389                 joints.Insert((int)JointType.HandRight, handRight);
       
   390                 joints.Insert((int)JointType.HipLeft, hipLeft);
       
   391                 joints.Insert((int)JointType.KneeLeft, kneeLeft);
       
   392                 joints.Insert((int)JointType.AnkleLeft, ankleLeft);
       
   393                 joints.Insert((int)JointType.FootLeft, footLeft);
       
   394                 joints.Insert((int)JointType.HipRight, hipRight);
       
   395                 joints.Insert((int)JointType.KneeRight, kneeRight);
       
   396                 joints.Insert((int)JointType.AnkleRight, ankleRight);
       
   397                 joints.Insert((int)JointType.FootRight, footRight);
       
   398                 GestureDetector.UpdateSkeletonHistory(joints);
       
   399 
       
   400                 //Si la main gauche est dans le champ, on lance l'événement approprié.
       
   401                 if (handLeft.Position.Z < maxDistHands && handLeft.Position.Z > minDistHands)
       
   402                 {
       
   403                     LeftHandTrackedEventArgs leftHandTrackedEvent = new LeftHandTrackedEventArgs(handLeft, handLeft.Position.Z, debug, server);
       
   404                     OnLeftHandTrackedEvent(leftHandTrackedEvent);
       
   405                 }
       
   406                 //Si la main gauche quitte le champ, on lance l'événement approprié.
       
   407                 else
       
   408                 {
       
   409                     LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
       
   410                     OnLeftHandQuitEvent(leftHandQuitEvent);
       
   411                 }
       
   412                 //Si la main droite est dans le champ, on lance l'événement approprié.
       
   413                 if (handRight.Position.Z < maxDistHands && handRight.Position.Z > minDistHands)
       
   414                 {
       
   415                     RightHandTrackedEventArgs rightHandTrackedEvent = new RightHandTrackedEventArgs(handRight, handRight.Position.Z, debug, server);
       
   416                     OnRightHandTrackedEvent(rightHandTrackedEvent);
       
   417                 }
       
   418                 //Si la main droite quitte le champ, on lance l'événement approprié.
       
   419                 else
       
   420                 {
       
   421                     RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
       
   422                     OnRightHandQuitEvent(rightHandQuitEvent);
       
   423                 }
       
   424 
       
   425                 //Si l'utilisateur effectue un swipe left.
       
   426                 if (swipeDetector.CheckForSwipeLeft())
       
   427                 {
       
   428                     SwipeEventArgs swipeEvent = new SwipeEventArgs(debug, server, SwipeDetector.Direction.LEFT);
       
   429                     OnSwipeEvent(swipeEvent);
       
   430                 }
       
   431 
       
   432                 //Si l'utilisateur effectue un swipe right.
       
   433                 if (swipeDetector.CheckForSwipeRight())
       
   434                 {
       
   435                     SwipeEventArgs swipeEvent = new SwipeEventArgs(debug, server, SwipeDetector.Direction.RIGHT);
       
   436                     OnSwipeEvent(swipeEvent);
       
   437                 }
       
   438 
       
   439                 //Enum sur la main qui effectue le geste.
       
   440                 PushDetector.Hand handPush;
       
   441                 //Si l'utilisateur effectue un push.
       
   442                 if ((handPush = pushDetector.CheckForPush()) != PushDetector.Hand.NONE)
       
   443                 {
       
   444                     PushEventArgs pushEvent = new PushEventArgs(debug, server, PushDetector.Direction.PUSH, handPush);
       
   445                     OnPushEvent(pushEvent);
       
   446                 }
       
   447                 //Si l'utilisateur effectue un pull.
       
   448                 if ((handPush = pushDetector.CheckForPull()) != PushDetector.Hand.NONE)
       
   449                 {
       
   450                     PushEventArgs pushEvent = new PushEventArgs(debug, server, PushDetector.Direction.PULL, handPush);
       
   451                     OnPushEvent(pushEvent);
       
   452                 }
       
   453 
       
   454                 //Si l'utilisateur effectue un saut.
       
   455                 /*if (jumpDetector.CheckForJump())
       
   456                 {
       
   457                     JumpEventArgs jumpEvent = new JumpEventArgs(debug, server);
       
   458                     OnJumpEvent(jumpEvent);
       
   459                 }*/
       
   460 
       
   461                 //Si l'utilisateur se déplace dans la zone de détection.
       
   462                 //On traite le problème en plusieurs limites, on discrétise la zone.
       
   463                 if (first.TrackingState == SkeletonTrackingState.Tracked)
       
   464                 {
       
   465                     float proximity = userPositionDetector.CalcProximity(first.Position.Z);
       
   466                     int numberOfImages = userPositionDetector.ImagesToShow(proximity, imagesToShow);
       
   467 
       
   468                     modeManagement.DetectProximityBasedModes(proximity);
       
   469 
       
   470                     if (proximity > 0f)
       
   471                     {
       
   472                         UserPositionEventArgs userPositionEvent = new UserPositionEventArgs(debug, server, proximity, numberOfImages);
       
   473                         OnUserPositionEvent(userPositionEvent);
       
   474                     }
       
   475                     else if(proximity < 10f)
       
   476                     {
       
   477                         debug.hideSkeleton();
       
   478                         modeManagement.DetectProximityBasedModes(0);
       
   479                         LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
       
   480                         OnLeftHandQuitEvent(leftHandQuitEvent);
       
   481                         RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
       
   482                         OnRightHandQuitEvent(rightHandQuitEvent);
       
   483                     }
       
   484                 }
       
   485 
       
   486                 //Dessine le squelette dans le debug.
       
   487                 debug.drawJoints(first.Joints, first);
       
   488                 debug.showSkeleton(hipCenter, spine, shoulderCenter, head, shoulderLeft, elbowLeft, wristLeft, handLeft, shoulderRight, elbowRight, wristRight, handRight, hipLeft, kneeLeft, ankleLeft, footLeft, hipRight, kneeRight, ankleRight, footRight);
       
   489             }
       
   490             else
       
   491             {
       
   492                 debug.hideSkeleton();
       
   493                 modeManagement.DetectProximityBasedModes(0);
       
   494                 LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
       
   495                 OnLeftHandQuitEvent(leftHandQuitEvent);
       
   496                 RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
       
   497                 OnRightHandQuitEvent(rightHandQuitEvent);
       
   498             }
       
   499         }
       
   500 
       
   501         /*
       
   502         *  Change l'échelle des coordonnées d'un noeud pour qu'en X et Y il corresponde à la résolution et en Z à la distance à la Kinect.
       
   503         */
       
   504         public Joint getJoint(Skeleton ske, JointType jointID)
       
   505         {
       
   506             return Coding4Fun.Kinect.Wpf.SkeletalExtensions.ScaleTo(ske.Joints[jointID], 600, 400, 0.75f, 0.75f);
       
   507         }
       
   508 
       
   509         /*
       
   510         *  Initialise l'événement et fait appel aux fonctions du listener quand la main gauche entre dans le champ.
       
   511         */
       
   512         public static void OnLeftHandTrackedEvent(LeftHandTrackedEventArgs e)
       
   513         {
       
   514             if (LeftHandTrackedEvent != null)
       
   515                 LeftHandTrackedEvent(new object(), e);
       
   516         }
       
   517 
       
   518         /*
       
   519         *  Initialise l'événement et fait appel aux fonctions du listener quand la main droite entre dans le champ.
       
   520         */
       
   521         public static void OnRightHandTrackedEvent(RightHandTrackedEventArgs e)
       
   522         {
       
   523             if (RightHandTrackedEvent != null)
       
   524                 RightHandTrackedEvent(new object(), e);
       
   525         }
       
   526 
       
   527         /*
       
   528         *  Initialise l'événement et fait appel aux fonctions du listener quand la main gauche quitte le champ.
       
   529         */
       
   530         public static void OnLeftHandQuitEvent(LeftHandQuitEventArgs e)
       
   531         {
       
   532             if (LeftHandQuitEvent != null)
       
   533                 LeftHandQuitEvent(new object(), e);
       
   534         }
       
   535 
       
   536         /*
       
   537         *  Initialise l'événement et fait appel aux fonctions du listener quand la main droite quitte le champ.
       
   538         */
       
   539         public static void OnRightHandQuitEvent(RightHandQuitEventArgs e)
       
   540         {
       
   541             if (RightHandQuitEvent != null)
       
   542                 RightHandQuitEvent(new object(), e);
       
   543         }
       
   544 
       
   545         /*
       
   546         *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un swipe right.
       
   547         */
       
   548         public static void OnSwipeEvent(SwipeEventArgs e)
       
   549         {
       
   550             if (SwipeEvent != null)
       
   551                 SwipeEvent(new object(), e);
       
   552         }
       
   553 
       
   554         /*
       
   555         *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un push.
       
   556         */
       
   557         public static void OnPushEvent(PushEventArgs e)
       
   558         {
       
   559             if (PushEvent != null)
       
   560                 PushEvent(new object(), e);
       
   561         }
       
   562 
       
   563         /*
       
   564         *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un saut.
       
   565         */
       
   566         public static void OnJumpEvent(JumpEventArgs e)
       
   567         {
       
   568             if (JumpEvent != null)
       
   569                 JumpEvent(new object(), e);
       
   570         }
       
   571 
       
   572         /*
       
   573         *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur se déplace
       
   574          *  dans la zone de détection.
       
   575         */
       
   576         public static void OnUserPositionEvent(UserPositionEventArgs e)
       
   577         {
       
   578             if (UserPositionEvent != null)
       
   579                 UserPositionEvent(new object(), e);
       
   580         }
       
   581 
       
   582         /*
       
   583         *  Méthode de chargement des paramètres (position du champ de recherche...).
       
   584         */
       
   585         public bool loadParameters()
       
   586         {
       
   587             try
       
   588             {
       
   589                 minDistHands = (float)double.Parse(ConfigurationManager.AppSettings["searchMinDistance"]);
       
   590                 maxDistHands = (float)double.Parse(ConfigurationManager.AppSettings["searchMaxDistance"]);
       
   591                 minDist = (float)double.Parse(ConfigurationManager.AppSettings["minDistance"]);
       
   592                 maxDist = (float)double.Parse(ConfigurationManager.AppSettings["maxDistance"]);
       
   593                 zeroPoint = (float)double.Parse(ConfigurationManager.AppSettings["zeroPoint"]);
       
   594                 connexionHost = ConfigurationManager.AppSettings["connexionHost"];
       
   595                 connexionPort = int.Parse(ConfigurationManager.AppSettings["connexionPort"]);
       
   596                 timerElapsing = int.Parse(ConfigurationManager.AppSettings["timerElapsing"]);
       
   597                 imagesToShow = int.Parse(ConfigurationManager.AppSettings["imagesToShow"]);
       
   598                 takenPoints = int.Parse(ConfigurationManager.AppSettings["takenPoints"]);
       
   599                 directionChangeTresholdXY = int.Parse(ConfigurationManager.AppSettings["directionChangeTresholdXY"]);
       
   600                 directionChangeTresholdZ = (float)double.Parse(ConfigurationManager.AppSettings["directionChangeTresholdZ"]);
       
   601             }
       
   602             catch (Exception)
       
   603             {
       
   604                 return false;
       
   605             }
       
   606 
       
   607             if (maxDistHands <= 0f || minDistHands <= 0f || maxDistHands > maxDist || minDistHands > maxDist ||
       
   608                 minDistHands >= maxDistHands || zeroPoint < maxDistHands || minDistHands < minDist ||
       
   609                 zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1 ||
       
   610                 takenPoints <= 0 || directionChangeTresholdXY < 0 || directionChangeTresholdZ < 0)
       
   611             {
       
   612                 debug.ExceptionLbl.Content = rm.GetString("loadParametersIncorrect");
       
   613                 return false;
       
   614             }
       
   615             return true;
       
   616         }
       
   617 
       
   618         /*
       
   619          * Met à jour les nouveaux paramètres dans la configuration.
       
   620          */
       
   621         public void updateParameters()
       
   622         {
       
   623             userPositionDetector.setParams(minDist, maxDist, minDistHands, maxDistHands, zeroPoint);
       
   624             //segmenter.setParams(takenPoints, directionChangeTresholdXY, directionChangeTresholdZ);
       
   625 
       
   626             //On récupère la config.
       
   627             Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
       
   628             //On met à jour.
       
   629             config.AppSettings.Settings.Remove("searchMinDistance");
       
   630             config.AppSettings.Settings.Add("searchMinDistance", minDistHands.ToString());
       
   631             config.AppSettings.Settings.Remove("searchMaxDistance");
       
   632             config.AppSettings.Settings.Add("searchMaxDistance", maxDistHands.ToString());
       
   633             config.AppSettings.Settings.Remove("minDistance");
       
   634             config.AppSettings.Settings.Add("minDistance", minDist.ToString());
       
   635             config.AppSettings.Settings.Remove("maxDistance");
       
   636             config.AppSettings.Settings.Add("maxDistance", maxDist.ToString());
       
   637             config.AppSettings.Settings.Remove("zeroPoint");
       
   638             config.AppSettings.Settings.Add("zeroPoint", zeroPoint.ToString());
       
   639             config.AppSettings.Settings.Remove("connexionHost");
       
   640             config.AppSettings.Settings.Add("connexionHost", connexionHost);
       
   641             config.AppSettings.Settings.Remove("connexionPort");
       
   642             config.AppSettings.Settings.Add("connexionPort", connexionPort.ToString());
       
   643             config.AppSettings.Settings.Remove("timerElapsing");
       
   644             config.AppSettings.Settings.Add("timerElapsing", timerElapsing.ToString());
       
   645             config.AppSettings.Settings.Remove("imagesToShow");
       
   646             config.AppSettings.Settings.Add("imagesToShow", imagesToShow.ToString());
       
   647             config.AppSettings.Settings.Remove("takenPoints");
       
   648             config.AppSettings.Settings.Add("takenPoints", takenPoints.ToString());
       
   649             config.AppSettings.Settings.Remove("directionChangeTresholdXY");
       
   650             config.AppSettings.Settings.Add("directionChangeTresholdXY", directionChangeTresholdXY.ToString());
       
   651             config.AppSettings.Settings.Remove("directionChangeTresholdZ");
       
   652             config.AppSettings.Settings.Add("directionChangeTresholdZ", directionChangeTresholdZ.ToString());
       
   653 
       
   654             //Sauvegarde la configuration.
       
   655             config.Save(ConfigurationSaveMode.Modified);
       
   656             ConfigurationManager.RefreshSection("appSettings");
       
   657         }
       
   658 
       
   659         /*
       
   660          * Getters et setters des paramètres du Middleware.
       
   661          */
       
   662         public void setMinDistHands(float min)
       
   663         {
       
   664             minDistHands = min;
       
   665         }
       
   666         public void setMaxDistHands(float max)
       
   667         {
       
   668             maxDistHands = max;
       
   669         }
       
   670         public void setMinDist(float min)
       
   671         {
       
   672             minDist = min;
       
   673         }
       
   674         public void setMaxDist(float max)
       
   675         {
       
   676             maxDist = max;
       
   677         }
       
   678         public void setZeroPoint(float zero)
       
   679         {
       
   680             zeroPoint = zero;
       
   681         }
       
   682         public void setConnexionHost(String host)
       
   683         {
       
   684             connexionHost = host;
       
   685         }
       
   686         public void setConnexionPort(int port)
       
   687         {
       
   688             connexionPort = port;
       
   689         }
       
   690         public void setTimerElapsing(int time)
       
   691         {
       
   692             timerElapsing = time;
       
   693         }
       
   694         public void setImagesToShow(int _imagesToShow)
       
   695         {
       
   696             imagesToShow = _imagesToShow;
       
   697         }
       
   698         public void setTakenPoints(int _takenPoints)
       
   699         {
       
   700             takenPoints = _takenPoints;
       
   701         }
       
   702         public void setDirectionChangeTresholdXY(int _directionChangeTresholdXY)
       
   703         {
       
   704             directionChangeTresholdXY = _directionChangeTresholdXY;
       
   705         }
       
   706         public void setDirectionChangeTresholdZ(float _directionChangeTresholdZ)
       
   707         {
       
   708             directionChangeTresholdZ = _directionChangeTresholdZ;
       
   709         }
       
   710 
       
   711         public float getMinDistHands()
       
   712         {
       
   713             return minDistHands;
       
   714         }
       
   715         public float getMaxDistHands()
       
   716         {
       
   717             return maxDistHands;
       
   718         }
       
   719         public float getMinDist()
       
   720         {
       
   721             return minDist;
       
   722         }
       
   723         public float getMaxDist()
       
   724         {
       
   725             return maxDist;
       
   726         }
       
   727         public float getZeroPoint()
       
   728         {
       
   729             return zeroPoint;
       
   730         }
       
   731         public String getConnexionHost()
       
   732         {
       
   733             return connexionHost;
       
   734         }
       
   735         public int getConnexionPort()
       
   736         {
       
   737             return connexionPort;
       
   738         }
       
   739         public int getTimerElapsing()
       
   740         {
       
   741             return timerElapsing;
       
   742         }
       
   743         public int getImagesToShow()
       
   744         {
       
   745             return imagesToShow;
       
   746         }
       
   747         public int getTakenPoints()
       
   748         {
       
   749             return takenPoints;
       
   750         }
       
   751         public int getDirectionChangeTresholdXY()
       
   752         {
       
   753             return directionChangeTresholdXY;
       
   754         }
       
   755         public float getDirectionChangeTresholdZ()
       
   756         {
       
   757             return directionChangeTresholdZ;
       
   758         }
       
   759     }
       
   760 }