// Update is called once per frame
    void Update()
    {
        if (this.SkeletonIsEnableScript.SkeletonIsEnable)
        {
            if (this.skeletonInfo_script.HipCenterPos.y > 1)
            {
                switch (this.currentfeetState)
                {
                case FeetState.RightRaise:
                    print(Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.y - this.skeletonInfo_script.KneeRightPos.y).ToString() + "," + Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.z - this.skeletonInfo_script.KneeRightPos.z).ToString());
                    if (Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.y - this.skeletonInfo_script.KneeRightPos.y) < 0.05f)
                    {
                        if (Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.z - this.skeletonInfo_script.KneeRightPos.z) < 0.05f)
                        {
                            print("RightDown");
                            this.currentfeetState              = FeetState.RightDown;
                            this.transform.rigidbody.velocity += this.transform.TransformDirection(new Vector3(0, 0, this.AddSpeed));
                        }
                    }
                    break;

                case FeetState.RightDown:
                    if (this.skeletonInfo_script.HipLeftPos.y - this.skeletonInfo_script.KneeLeftPos.y < this.Knne_Hip_Delta)
                    {
                        print("LeftRaise");
                        this.currentfeetState = FeetState.LeftRaise;
                        //this.transform.rigidbody.velocity += this.transform.TransformDirection(new Vector3(0, 0, this.AddSpeed));
                    }
                    break;

                case FeetState.LeftRaise:
                    print(Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.y - this.skeletonInfo_script.KneeRightPos.y).ToString() + "," + Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.z - this.skeletonInfo_script.KneeRightPos.z).ToString());

                    if (Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.y - this.skeletonInfo_script.KneeRightPos.y) < 0.05f)
                    {
                        if (Mathf.Abs(this.skeletonInfo_script.KneeLeftPos.z - this.skeletonInfo_script.KneeRightPos.z) < 0.05f)
                        {
                            print("LeftDown");
                            this.currentfeetState              = FeetState.LeftDown;
                            this.transform.rigidbody.velocity += this.transform.TransformDirection(new Vector3(0, 0, this.AddSpeed));
                        }
                    }
                    break;

                case FeetState.LeftDown:
                    if (this.skeletonInfo_script.HipRightPos.y - this.skeletonInfo_script.KneeRightPos.y < this.Knne_Hip_Delta)
                    {
                        print("RightRaise");
                        this.currentfeetState = FeetState.RightRaise;
                        //this.transform.rigidbody.velocity += this.transform.TransformDirection(new Vector3(0, 0, this.AddSpeed));
                    }
                    break;
                }
            }
            if (Input.GetKeyUp(KeyCode.A))
            {
                this.transform.rigidbody.velocity += this.transform.TransformDirection(new Vector3(0, 0, this.AddSpeed));
            }
        }
    }
예제 #2
0
    public List <intervalSpeeds> sessionIntervalSpeeds = new List <intervalSpeeds>(); //Combines all exercise intervals together


    //TODO: CHECK NORMALISED PARAMETERS
    //      IMPLEMENT AVERAGING

    /*----------------------------*/
    // Use this for initialization//
    void Start()
    {
        movementVector                    = transform.position;   //Sets initial movement vector to match player transform position
        initialAvatarHeight               = transform.position.y; //Sets initial avatar height
        previousKneeWaistDistance         = Mathf.Abs(avatarWaist.InverseTransformPoint(avatarKneeLeft.position).y) + Mathf.Abs(avatarWaist.InverseTransformPoint(avatarKneeRight.position).y);
        previousKneeWaistDisplacement     = 0;
        previousMeasuredKneeWaistDistance = previousKneeWaistDistance;
        previousHeadHeight                = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.position).y;
        previousFeetState                 = FeetState.leftUpRightDown; //TODO:CHANGE TO SOMETHING BETTER
        kinectManager           = KinectManager.Instance;              //sets kinect reference
        savedMovementParameters = Vector3.zero;
        StartCoroutine(speedCalculator());
        StartCoroutine(runningParameterCalculator());
    }
예제 #3
0
    /*---------------------------------------*/
    //Record User Parameters during exercise //
    private void recordUserParams()
    {
        //While Exercise protocol Hasn't ended --------------------------------------------------------
        if (HIITController.Instance.currentState != ExerciseProtocolState.finish)
        {
            //As long as we are successfully tracking information
            if (motionTypeTracker.Tracking)
            {
                //countSteps -- Detect alternation in feet state ============================================
                FeetState currentFeetState = getFeetState();
                if ((previousFeetState == FeetState.leftUpRightDown && currentFeetState == FeetState.rightUpLeftDown) || (previousFeetState == FeetState.rightUpLeftDown && currentFeetState == FeetState.leftUpRightDown))
                {
                    //Step Count for Low Intensity
                    if (HIITController.Instance.currentState == ExerciseProtocolState.lowIntensity)
                    {
                        stepNoLow++;
                    }

                    //Step count for High Intensity
                    else if (HIITController.Instance.currentState == ExerciseProtocolState.highIntensity)
                    {
                        stepNoHigh++;
                    }
                }

                //knee height, disposition ========================================================
                float kneeWaistDistance = Mathf.Abs(avatarWaist.InverseTransformPoint(avatarKneeLeft.position).y) + Mathf.Abs(avatarWaist.InverseTransformPoint(avatarKneeRight.position).y);
                //Takes relative distance from waist to the knees , higher value indicates standing still, closer value reaches 0
                //the more it indicates that both knees match waist height
                movementParamPanels[0].GetComponent <Text>().text = avatarWaist.transform.position.ToString();
                float kneeWaistDisplacement = Mathf.Abs(kneeWaistDistance - previousKneeWaistDistance);
                previousMeasuredKneeWaistDistance = kneeWaistDistance;

                //Average Knee height and displacement for low intensity
                if (HIITController.Instance.currentState == ExerciseProtocolState.lowIntensity)
                {
                    avgKneeHeightRunLow  += kneeWaistDistance;
                    avgKneeDispRunLow    += kneeWaistDisplacement;
                    kneeMeasurementNoLow += 1;
                }

                //Average Knee height and waist displacement for high intensity
                else if (HIITController.Instance.currentState == ExerciseProtocolState.highIntensity)
                {
                    avgKneeHeightRunHigh  += kneeWaistDistance;
                    avgKneeDispRunHigh    += kneeWaistDisplacement;
                    kneeMeasurementNoHigh += 1;
                }

                //height jump ========================================================
                if (currentState == motionTypeTracker.LocomotionState.Jumping)
                {
                    bool currentHeadDirection = motionTypeTracker.headGoingUp;
                    if (currentHeadDirection == false && previousHeadDirection == true)
                    {
                        if (protocolController.currentState == ExerciseProtocolState.lowIntensity)
                        {
                            avgMaxHeadHeightJumpLow = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
                            jumpNoLow++;
                        }
                    }
                    previousHeadDirection = currentHeadDirection;
                }//------------------------------------------------------------------
            }
            //If Exercise has ended and we are saving values
        }
        else if (!saved)
        {
            avgMaxHeadHeightJumpLow /= jumpNoLow;
            avgKneeHeightRunLow     /= kneeMeasurementNoLow;
            avgKneeHeightRunHigh    /= kneeMeasurementNoHigh;
            avgKneeDispRunLow       /= kneeMeasurementNoLow;
            avgKneeDispRunHigh      /= kneeMeasurementNoHigh;
            //save paremeters to file
            saveToFile();
            saved = true;
        }
    }
예제 #4
0
    //private float forwardVelocity;


    /*----------------------------------------------------------------------------------------------*/
    //Updates the current motion vector of the player dependent on locomotion state & prior factors //
    private void updateMovementVector()
    {
        recordUserParams();

        //dealing with lateral motion -- Left & Right (made adjustments to fit them in the
        float xOffset   = kinectManager.GetUserPosition(kinectManager.GetPrimaryUserID()).x;    //the offset of the player from the center of the kinect camera
        float xPosition = Mathf.Lerp(-2.4f, 2.4f, Mathf.InverseLerp(-1f, 1f, xOffset));         //Inverse lerp to find ratio position of kinect to lerp and find x position

        //Sets new Vector 3 position to match new x position and existing y/z
        movementVector = new Vector3(xPosition, movementVector.y, movementVector.z);


        //Find Users current locomotion state
        previousState = currentState;
        currentState  = motionTypeTracker.getCurrentState();
        if (previousState == null)
        {
            previousState = currentState;
        }


        //Determine actions based on transition of states
        switch (currentState)
        {
        case motionTypeTracker.LocomotionState.PreJump:         //Winding up to jump ------------------------------------------------------
            //TODO: FIND MAGNITUDES AND RATES OF INCREASE FOR EACH FACTOR AND NORMALISE

            //Determines headheight by adding head offset to locally converted avatar head y position
            headHeightBeforeJump = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
            float decay = decayAtPrejump;

            //If previous state was Jumping
            if (previousState == motionTypeTracker.LocomotionState.Jumping)
            {
                //implicitly we continue moving forward with our jumping forward velocity
                decay           += jumpEnhancement;      //lessen the decay effect to recover from running pose
                retainedVelocity = finalVelocity;        //retain our jumping velocity
                //retainedVelocity = 0;//after a jump we need to gather some velocity by running to jump ahead again
            }
            //If previous state was running
            else if (previousState == motionTypeTracker.LocomotionState.Running)
            {
                //implicitly we continue moving forward with our final velocity
                retainedVelocity = finalVelocity;
            }

            finalVelocity    *= decay;          //Offsets our final velocity by decay factor
            retainedVelocity *= retainedDecay;  //old jump

            //Adjusts final movement vector by pre-jump locomotion velocity
            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);
            break;


        case motionTypeTracker.LocomotionState.Running:         //Running ---------------------------------------------------------------------------
            //TODO: FIND MAGNITUDES AND RATES OF INCREASE FOR EACH FACTOR AND NORMALISE

            //Determines headheight by adding head offset to locally converted avatar head y position
            headHeightBeforeJump = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;

            //If Previous state was jumping
            if (previousState == motionTypeTracker.LocomotionState.Jumping)
            {
                feetAlternationFactor += 0.3f;                //for smooth transition to running
            }

            previousVelocity = finalVelocity;            //velocity we had at the last frame

            //feet factors (added in running to avoid having abrupt cuts when returning from a jump)
            feetAlternationFactor -= feetAlternationDecayFactor * Time.deltaTime;
            FeetState currentFeetState = getFeetState();

            //If Previous feet state include one foot up && current feet state includes opposite foot up --- I.E Running
            if ((previousFeetState == FeetState.leftUpRightDown && currentFeetState == FeetState.rightUpLeftDown) || (previousFeetState == FeetState.rightUpLeftDown && currentFeetState == FeetState.leftUpRightDown))
            {
                feetAlternationFactor += feetAlternationReward;
                previousFeetState      = currentFeetState;
            }
            feetAlternationFactor = Mathf.Clamp(feetAlternationFactor, 0, feetAlternationCap);
            performanceBars[2].GetComponent <Slider>().value = feetAlternationFactor;

            if (feetAlternationFactor == 0)
            {
                currentVelocity = 0f;
            }
            else
            {
                //head displacement and feet alternation weights need to be minimal since they dont bear much impact on the rate of speed
                currentVelocity = runFactor * (w1 * feetAlternationFactor + w2 * headDisplacementNormalised + w3 * kneeWaistDisplacementNormalised + w4 * kneeWaistDistanceNormalised);                //different speed system based on addition of params instead of mult. (WORK MORE ON THIS, I.E TRY REMOVING KNEE-WAIST PARAM)
            }
            //final velocity is a weighted sum of our previous frame velocity and the newly calculated velocity
            finalVelocity = previousVelocityWeight * previousVelocity + (1 - previousVelocityWeight) * currentVelocity * Time.deltaTime;

            //combination of factors
            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);
            break;


        case motionTypeTracker.LocomotionState.Jumping:         //Jumping -------------------------------------------------------------------

            //If Previous state was preparing to jump
            if (previousState == motionTypeTracker.LocomotionState.PreJump)
            {
                //this jumping mechanism was added since as we are scaling the avatar position upwards, we create an infinite scaling since we are constantly moving upwards - need the relative position of a limb relative to the avatar position to eliminate the constant upward motion affect.
                baseJumpHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
                //jumpForwardVelocity = baseJumpHeight - headHeightBeforeJump;
                finalVelocity = retainedVelocity;
            }
            //Previous state was running or something else
            else if (previousState == motionTypeTracker.LocomotionState.Running || previousState == motionTypeTracker.LocomotionState.Ambiguous)
            {
                //this jumping mechanism was added since as we are scaling the avatar position upwards, we create an infinite scaling since we are constantly moving upwards - need the relative position of a limb relative to the avatar position(which is what keeps moving upwards) to eliminate the constant upward motion affect.
                baseJumpHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
                //jumpForwardVelocity = baseJumpHeight - headHeightBeforeJump;
            }

            //Determines height by adding head offset to locally converted avatar head y position
            currentHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
            float nextHeight = (currentHeight - baseJumpHeight) * jumpFactor;            //CLASSIC JUMP MECHANISM (COMPROMISES PLAYER JUMPING ABLILITY)

            //Decays Jump velocity and sets final movement vector
            finalVelocity *= jumpingForwardDecay;            //another decay for the forward movement when jumping
            movementVector = new Vector3(movementVector.x, nextHeight, movementVector.z + finalVelocity);
            break;

        case motionTypeTracker.LocomotionState.Ambiguous:         //Other -------------------------
            //stay with previous velocity if in ambiguous state
            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);
            break;
        }

//        if (currentState == motionTypeTracker.LocomotionState.PreJump)
//        {
//            headHeightBeforeJump = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
//            float decay = decayAtPrejump;
//            if(previousState == motionTypeTracker.LocomotionState.Jumping)
//            {
//                //movementVector = new Vector3(movementVector.x, initialAvatarHeight, transform.position.z);//also freezing the position in order to not carry any additional forward motion from jumping
//                //feet alternation capping
//                //if (feetAlternationFactor > feetAlternationCapAfterJump)
//                //{
//                //    feetAlternationFactor = feetAlternationCapAfterJump;
//                //}
//
//                //implicitly we continue moving forward with our jumping forward velocity
//                decay += jumpEnhancement;//lessen the decay effect to recover from running pose
//                retainedVelocity = finalVelocity;//retain our jumping velocity
//                //retainedVelocity = 0;//after a jump we need to gather some velocity by running to jump ahead again
//            }
//            else if(previousState== motionTypeTracker.LocomotionState.Running)
//            {
//                //feet alternation capping
//                //if (feetAlternationFactor > feetAlternationCapAfterJump)
//                //{
//                //    feetAlternationFactor = feetAlternationCapAfterJump;
//                //}
//
//                //implicitly we continue moving forward with our final velocity
//
//                retainedVelocity = finalVelocity;
//            }
//
//            finalVelocity *= decay;
//            retainedVelocity *= retainedDecay;//old jump
//
//            //combination of factors
//            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);//TODO: FIND MAGNITUDES AND RATES OF INCREASE FOR EACH FACTOR AND NORMALISE
//        }
//        else if (currentState == motionTypeTracker.LocomotionState.Running)
//        {
//            headHeightBeforeJump = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
//            if (previousState == motionTypeTracker.LocomotionState.Jumping)
//            {
//                feetAlternationFactor += 0.3f;//for smooth transition to running
//                //feet alternation capping
//                //if (feetAlternationFactor > feetAlternationCapAfterJump)
//                //{
//                //    feetAlternationFactor = feetAlternationCapAfterJump;
//                //}
//                //movementVector = new Vector3(movementVector.x, initialAvatarHeight, transform.position.z);//also freezing the position in order to not carry any additional forward motion from jumping
//
//                //implicitly we continue moving forward with our forward jumping velocity
//            }
//            else if (previousState == motionTypeTracker.LocomotionState.PreJump)
//            {
//                //nothing to add here yet
//            }
//            previousVelocity = finalVelocity;//velocity we had at the last frame
//
//            //feet factors (added in running to avoid having abrupt cuts when returning from a jump)
//            feetAlternationFactor -= feetAlternationDecayFactor * Time.deltaTime;
//            FeetState currentFeetState = getFeetState();
//            if ((previousFeetState == FeetState.leftUpRightDown && currentFeetState == FeetState.rightUpLeftDown) || (previousFeetState == FeetState.rightUpLeftDown && currentFeetState == FeetState.leftUpRightDown))
//            {
//                feetAlternationFactor += feetAlternationReward;
//                previousFeetState = currentFeetState;
//            }
//            feetAlternationFactor = Mathf.Clamp(feetAlternationFactor, 0, feetAlternationCap);
//            //movementParamPanels[2].GetComponent<Text>().text = "Feet Alternation: " + feetAlternationFactor;
//            performanceBars[2].GetComponent<Slider>().value = feetAlternationFactor;
//
//            //currentVelocity = feetAlternationFactor * headDisplacementNormalised * kneeWaistDisplacement * runFactor;//this can be too abrupt, so it is partially added to the final velocity to smoothen out the running motion
//            //currentVelocity = w1 * feetAlternationFactor + w2 * headDisplacementNormalised + w3 * kneeWaistDisplacement * kneeWaistDistanceWeighted;//different speed system based on addition of params instead of mult. (WORK MORE ON THIS, I.E TRY REMOVING KNEE-WAIST PARAM)
//
//            if (feetAlternationFactor == 0)
//            {
//                currentVelocity = 0f;
//            }
//            else
//            {
//                //head displacement and feet alternation weights need to be minimal since they dont bear much impact on the rate of speed
//                currentVelocity = runFactor * (w1 * feetAlternationFactor + w2 * headDisplacementNormalised + w3 * kneeWaistDisplacementNormalised + w4 * kneeWaistDistanceNormalised);//different speed system based on addition of params instead of mult. (WORK MORE ON THIS, I.E TRY REMOVING KNEE-WAIST PARAM)
//            }
//
//
//
//            finalVelocity = previousVelocityWeight * previousVelocity + (1 - previousVelocityWeight) * currentVelocity * Time.deltaTime;//next velocity is a weighted sum of our previous frame velocity and the newly calculated velocity
//            //retainedVelocity = finalVelocity;//saving in case of a prejump (not necessary here since its done in initial enter on prejump)
//
//
//            //combination of factors
//            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);//TODO: FIND MAGNITUDES AND RATES OF INCREASE FOR EACH FACTOR AND NORMALISE
//
//        }
//        else if(currentState == motionTypeTracker.LocomotionState.Jumping)
//        {
//
//            if (previousState == motionTypeTracker.LocomotionState.PreJump)
//            {
//                //this jumping mechanism was added since as we are scaling the avatar position upwards, we create an infinite scaling since we are constantly moving upwards - need the relative position of a limb relative to the avatar position to eliminate the constant upward motion affect.
//                baseJumpHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
//                //jumpForwardVelocity = baseJumpHeight - headHeightBeforeJump;
//                finalVelocity = retainedVelocity;
//            }
//            else if (previousState == motionTypeTracker.LocomotionState.Running|| previousState == motionTypeTracker.LocomotionState.Ambiguous)
//            {
//                //this jumping mechanism was added since as we are scaling the avatar position upwards, we create an infinite scaling since we are constantly moving upwards - need the relative position of a limb relative to the avatar position(which is what keeps moving upwards) to eliminate the constant upward motion affect.
//                baseJumpHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
//                //jumpForwardVelocity = baseJumpHeight - headHeightBeforeJump;
//            }
//
//
//
//            currentHeight = headOffsetCalculator.getOffset() + transform.InverseTransformPoint(avatarHead.transform.position).y;
//            float nextHeight = (currentHeight - baseJumpHeight) * jumpFactor;//CLASSIC JUMP MECHANISM (COMPROMISES PLAYER JUMPING ABLILITY)
//            //float nextHeight =Mathf.Lerp(0, motionTypeTracker.headHeightJumping.z+jumpEnhancement, Mathf.InverseLerp(baseJumpHeight,motionTypeTracker.headHeightJumping.z,currentHeight));
//            //float finalHeight = (nextHeight < 0) ? baseJumpHeight + nextHeight : baseJumpHeight + nextHeight;//negative next height indicates real life head height lower than the real life head height the jump was identified at. Both if conditions do the same thing to indicate that although unintuitive, i want to continue the rate of decrease so that there is no change in smoothed speed of the jump
//
//            finalVelocity *= jumpingForwardDecay;//another decay for the forward movement when jumping
//            //finalVelocity =jumpForwardScale* Mathf.Abs(nextHeight - currentHeight);
//            //movementVector = new Vector3(movementVector.x, nextHeight, movementVector.z + jumpForwardScale * Mathf.Abs(nextHeight - currentHeight));
//            movementVector = new Vector3(movementVector.x, nextHeight, movementVector.z + finalVelocity);
//
//        }
//        else if (currentState == motionTypeTracker.LocomotionState.Ambiguous)
//        {
//            //stay with previous velocity if in ambiguous state
//            movementVector = new Vector3(movementVector.x, movementVector.y, movementVector.z + finalVelocity);
//        }
    }
    // Use this for initialization
    void Start()
    {
        this.skeletonInfo_script = this.skeletonInfoObject.GetComponent <SkeletonInformation>();

        this.currentfeetState = FeetState.LeftDown;
    }
예제 #6
0
        /// <summary>
        /// calculate the feet-state and push to walking queue
        /// </summary>
        /// <param name="leftFootY">y-coordinate of left foot</param>
        /// <param name="rightFootY">y-coordinate of right foot</param>
        internal void pushToWalkingQueue(float leftFootY, float rightFootY)
        {
            //calc datetime of now
            DateTime timeStamp = DateTime.Now;

            FeetState.footPosition left, right;
            //if the difference between the coordinates in greater than threshold,
            //then one feet is considered up and the other is considered down.
            //otherwise, both considered down
            if (leftFootY - rightFootY > 0.1)
            {
                left = FeetState.footPosition.Up;
                right = FeetState.footPosition.Down;
            }
            else if (rightFootY - leftFootY > 0.1)
            {
                right = FeetState.footPosition.Up;
                left = FeetState.footPosition.Down;
            }
            else
            {
                left = FeetState.footPosition.Down;
                right = FeetState.footPosition.Down;
            }

            FeetState last = walkHistory.Last();
            //push the current feet-state to queue only if it is different from the last one pushed,
            //or if the difference between the timestamps is greater than a certain threshold
            if (left != last.left || right != last.right || timeStamp - last.timeStamp >= TIME_DIFF)
            {
                Console.WriteLine("l:" + leftFootY + "r:" + rightFootY + ",(" + left + "," + right + ")");
                FeetState fs = new FeetState(left, right, timeStamp);
                walkHistory.Enqueue(fs);
            }
        }