middleware/Tracking/Gestures/JumpDetector.cs
changeset 15 4b78f179e7ce
child 17 fda26bfcabef
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/Gestures
       
    14  * Classe : JumpDetector
       
    15  * 
       
    16  * Auteur : alexandre.bastien@iri.centrepompidou.fr
       
    17  * 
       
    18  * Fonctionnalités : Permet de détecter si l'utilisateur a sauté, en se basant sur
       
    19  * des règles appliquées à la positions des noeuds dans le temps.
       
    20  * 
       
    21  * P.S : Cette partie est encore en développement.
       
    22  */
       
    23 
       
    24 using System;
       
    25 using System.Collections.Generic;
       
    26 using System.Linq;
       
    27 using System.Text;
       
    28 using Microsoft.Kinect;
       
    29 
       
    30 namespace Trakers.MainModule.Gestures
       
    31 {
       
    32     public class JumpDetector : GestureDetector
       
    33     {
       
    34         static int n = 0;
       
    35 
       
    36         public JumpDetector() : base()
       
    37         {
       
    38             gesturePeriod = (float)1;
       
    39             indexesPerSecond = 30;
       
    40             indexesToCheck = (int)(gesturePeriod * indexesPerSecond);
       
    41         }
       
    42 
       
    43         /*
       
    44          * Lit les noeuds de l'historique du squelette afin de détecter un Jump.
       
    45          * Règles :
       
    46          * .
       
    47          */
       
    48         public bool CheckForJump()
       
    49         {
       
    50             //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
       
    51             List<List<Joint>> localHistory = new List<List<Joint>>(history);
       
    52             
       
    53             //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
       
    54             if (localHistory.Count < indexesToCheck)
       
    55                 return false;
       
    56 
       
    57             /* (HeadBelowBaseLine || LeftKneeBelowBaseLine || RightKneeBelowBaseLine ||
       
    58              * LeftAnkleBelowBaseLine || RightAnkleBelowBaseLine || BodyFaceUpwards
       
    59              * 
       
    60              * NOT
       
    61              * 
       
    62              * AND
       
    63              * 
       
    64              * HeadAboveBaseLine && LeftKneeAboveBaseLine && RightKneeAboveBaseLine &&
       
    65              * LegsStraightPreviouslyBent)
       
    66              * 
       
    67              * OR
       
    68              * 
       
    69              * HeadFarAboveBaseLine
       
    70              */
       
    71 
       
    72             //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
       
    73             refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y);
       
    74             //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
       
    75 
       
    76             int beginIdx = localHistory.Count - indexesToCheck + 1;
       
    77             int middleIdx = localHistory.Count - indexesToCheck / 2;
       
    78 
       
    79             //bool middleOK = true
       
    80             bool topOfJump = false;
       
    81 
       
    82             
       
    83 
       
    84             //De la position p1 à pn, on suit l'algorithme.
       
    85             for (int i = beginIdx ; i < localHistory.Count ; i++)
       
    86             {
       
    87 
       
    88                 if (localHistory[i][(int)JointType.HandRight].Position.Y < localHistory[beginIdx][(int)JointType.HandRight].Position.Y + refDistance &&
       
    89                    localHistory[i - 1][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.HandRight].Position.Y)
       
    90                 {
       
    91                     topOfJump = true;
       
    92                     //Console.Out.WriteLine("TOP");
       
    93                 }
       
    94 
       
    95                 if (localHistory[i - 1][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HandRight].Position.Y && !topOfJump)
       
    96                     return false;
       
    97 
       
    98                 //Si la position Y de la main est plus haute que la tête
       
    99                 //OU si la position Y de la main est plus basse que la hanche
       
   100                 //OU si la nouvelle position Z de la main est moins profonde que la précédente
       
   101                 //OU si la nouvelle position X de la main est plus éloignée de la distance N par rapport à la première position X
       
   102                 //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
       
   103                 //Alors la main en question ne fait pas de push.
       
   104                 if (localHistory[i - 1][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HandRight].Position.Y &&
       
   105                     topOfJump || localHistory[i - 1][(int)JointType.HandRight].Position.Y < localHistory[i][(int)JointType.HandRight].Position.Y &&
       
   106                     !topOfJump)
       
   107                     return false;
       
   108             }
       
   109 
       
   110             //Console.Out.WriteLine("OK");
       
   111 
       
   112             //Si la distance en Z du geste a été plus courte que la distance N
       
   113             //Alors on retourne faux.
       
   114             //float dist = (localHistory[localHistory.Count - 1][handRightID].Position.X - localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X);
       
   115 
       
   116             //Console.WriteLine(Math.Abs(localHistory[0][handLeftID].Position.Z - localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.Z) * 100 + " " + refDistance);
       
   117 
       
   118             //Si la dernière position de la main droite/gauche est sur le côté gauche/droit du corps
       
   119             //OU si la première position calculée de la main droite/gauche est sur le côté gauche/droit du corps
       
   120             //Alors on retourne faux.
       
   121             
       
   122             //On supprime l'historique local.
       
   123             
       
   124             return false;
       
   125         }
       
   126     }
       
   127 }