// 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)); } } }
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()); }
/*---------------------------------------*/ //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; } }
//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; }
/// <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); } }