Esempio n. 1
0
 protected override bool Recognise(FeatureData data)
 {
     switch (_motionState)
     {
         case MotionState.Initial:
             float footHeight = data.CalculateDifferY(JointType.AnkleRight, JointType.AnkleLeft);
             // 判断是否抬高脚data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 15) == 1
             if (footHeight > MinFootHeight &&
                 footHeight < MaxFootHeight) // 用Y判断脚抬高度,脚离地阈值为15
             {
                 _motionState = MotionState.Invalid;// 标记为无效,等待放下脚恢复初始状态
                 if (data.CompareThresholdZ(JointType.AnkleRight, JointType.HipRight, 30) == 0 && // 用Z排除非前踢腿
                 data.CompareThresholdX(JointType.AnkleRight, JointType.HipRight, 15) == 0) // 用X排除非左右侧踢腿
                 {
                     return true;
                 }
             }
             break;
         default:
             // 放下脚恢复初始状态
             if (data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 5) == 0)
             {
                 _motionState = MotionState.Initial;
             }
             break;
     }
     return false;
 }
Esempio n. 2
0
        private const float LegRadianThreshold = 0.57f; //30, 0.64f; //弧度阈值;40度约为0.64左右,45度约为0.707

        #endregion Fields

        #region Methods

        protected override bool Recognise(FeatureData data)
        {
            switch (_motionState)
            {
                case MotionState.Initial:
                    // 判断是否抬高脚
                    if (data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 10) == 1) // 用Y判断脚抬高度,脚离地阈值为10
                    {
                        _motionState = MotionState.Valid;
                    }
                    break;
                case MotionState.Valid:
                    // 区别抬脚动作
                    if (data.CompareThresholdZ(JointType.AnkleRight, JointType.HipRight, 30) == 0 &&
                        data.CompareThresholdX(JointType.AnkleRight, JointType.HipRight, 15) == 0)
                    {
                        _motionState = MotionState.Invalid;
                        return false;
                    }
                    // 大概的腿长,从踝开始计算
                    float legLength = data.CalculateDifferY(JointType.HipLeft, JointType.AnkleLeft);
                    if (legLength <= 0) // 腿长不适合理论数据
                    {
                        return false;
                    }
                    // 在x和z轴上的映射投影距离差值
                    float ankleDifferX = Math.Abs(data.CalculateDifferX(JointType.AnkleRight, JointType.AnkleLeft));
                    float ankleDifferZ = Math.Abs(data.CalculateDifferZ(JointType.AnkleRight, JointType.AnkleLeft));

                    if (ankleDifferX >= ankleDifferZ) // 排除向前或后踢的情况
                    {
                        // 计算腿抬起后裸相差的水平距离
                        float ankleHorizontalDistance = (float)Math.Sqrt(ankleDifferX * ankleDifferX + ankleDifferZ * ankleDifferZ);

                        // 计算腿抬起的弧度
                        float legRadian = ankleHorizontalDistance / legLength;

                        // 当抬起角度超过弧度阈值后生效
                        if (legRadian > LegRadianThreshold)
                        {
                            _motionState = MotionState.Invalid;
                            return true;
                        }
                    }
                    else
                    {
                        _motionState = MotionState.Invalid;
                    }
                    break;
                default:
                    // 放下脚恢复初始状态
                    if (data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 5) == 0)
                    {
                        _motionState = MotionState.Initial;
                    }
                    break;
            }
            return false;
        }
Esempio n. 3
0
        protected override bool Recognise(FeatureData data)
        {
            // 计算两脚高度差
            float ankleDifferY = Math.Abs(data.CalculateDifferY(JointType.AnkleRight, JointType.AnkleLeft));
            // 计算两脚的绝对坐标
            float absoluteAnkleRightY = data.RelativeJoints[(int)JointType.AnkleRight].Position.Y + data.AbsoluteOrigin.Y;
            float absoluteAnkleLeftY = data.RelativeJoints[(int)JointType.AnkleLeft].Position.Y + data.AbsoluteOrigin.Y;
            bool tracked = data.IsJointTracked(JointType.AnkleRight);
            // 两脚绝对坐标Y的较小值
            float minAbsoluteAnkleY = Math.Min(absoluteAnkleLeftY, absoluteAnkleRightY);

            // 当一只脚超过另一脚时
            if (ankleDifferY > MaxHeightThreshold)
            {
                // 当想站上某个高处时即开始准备重设地面,获取较大值
                _groundLevel = Math.Max(absoluteAnkleLeftY, absoluteAnkleRightY);
            }
            switch(_motionState)
            {
                case MotionState.Initial:
                    // 当两脚高度差不超过阈值时
                    if (ankleDifferY < MinHeightThreshold)
                    {
                        // 获取左右脚以及地面中最小的值来重设地面
                        _groundLevel = Math.Min(minAbsoluteAnkleY, _groundLevel);
                        // 直接判断
                        if (minAbsoluteAnkleY - _groundLevel > JumpHeightThreshold && tracked)
                        {
                            // 重置地面,用于判断是否开始落下,否则跳太高会二次识别
                            _groundLevel = minAbsoluteAnkleY;
                            _counter = 0;
                            _motionState = MotionState.Invalid;
                            return true;
                        }
                    }
                    break;
                default:
                    if ( minAbsoluteAnkleY < _groundLevel) // 当开始落下时才生效
                    {
                        _motionState = MotionState.Initial;
                    }
                    else if (++_counter >= CounterThreshold) // 可能跳到了一个较高的地方,需要一段时间来重置
                    {
                        _counter = 0;
                        _groundLevel = minAbsoluteAnkleY;
                        _motionState = MotionState.Initial;
                    }
                    break;
            }
            return false;
        }