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