/// <summary> /// Used to setup a new limb exercise /// </summary> /// <param name="config">Configuration of the limb that has to perform the exercise</param> public void ExerciseSetup(ExerciseConfiguration config) { LimbExercise exercise = new LimbExercise(); exercise.exerciseConfig = config; ArticolationTollerance[] tollerance = new ArticolationTollerance[config.limbConfiguration.sensors.Length]; for (int i = 0; i < config.limbConfiguration.sensors.Length; i++) { tollerance[i] = config.limbConfiguration.sensors[i].sensorTollerance; } exercise.aiManager.ExerciseTollerance = tollerance; _exercises.Add(exercise); }
void Update() { if (Input.GetKeyDown(keyIdeal)) { // settings // define tollerance (in this case is used the same tollerance for all variables and articulations float tolleranceRadius = 0.2f; ArticolationTollerance tollerance = new ArticolationTollerance(); tollerance.positionSpeedTolleranceRadius = tolleranceRadius; tollerance.positionTolleranceRadius = tolleranceRadius; tollerance.rotationSpeedTolleranceRadius = tolleranceRadius; tollerance.rotationTolleranceRadius = tolleranceRadius; // Configure limb, one per exercise per limb (if you want an exercise that involves to limbs, use two limbs configurations) // example made for the arm // instance sensors Sensor shoulderSensor = new Sensor(shoulder, tollerance, "spalla"); Sensor elbowSensor = new Sensor(elbow, tollerance, "gomito"); Sensor handSensor = new Sensor(hand, tollerance, "mano"); // with the sensors instances create a limb configuration LimbConfiguration config = new LimbConfiguration(shoulderSensor, elbowSensor, handSensor); // configure exercise ExerciseConfiguration exerciseConfiguration = new ExerciseConfiguration( config, (EvaluationResults results) => { AIProxy aiProxy = new AIProxy(); // should be taken from context //ArticolationError elbowError = aiProxy.UnwrapFromResults("gomito", results); } ); // to add more events handler: exerciseConfiguration.OnExecutionStepEvaluated += (EvaluationResults results) => { }; // exercise configuration should be taken from somewhere // configure the virtual physioteraphyst VirtualPhysioterphyst eval = VirtualPhysioterphyst.Instance; // define a timing for the sampling float timing = 0.5f, totalDuration = 2f; eval.timingBetweenSamples = timing; // setup the exercise with the built configuration eval.ExerciseSetup(exerciseConfiguration); // start recording eval.StartSetup(); // Start playing a new exercise (guided by the real physioteraphyst) Sequence sequence = DOTween.Sequence(); sequence.Append(hand.transform.DOMove(hand.transform.position * 2, totalDuration)); // once finished the exercise, stop setup sequence.OnComplete(() => { eval.EndSetup(); // stop registering // ... evaluating if the movement has to be saved or discarded eval.SaveSetup(); // save registration // eval.DiscardSetup(); // discard registration }); } if (Input.GetKeyDown(keyReal)) { // turn back to initial position hand.transform.position = initialPositionHand; elbow.transform.position = initialPositionElbow; shoulder.transform.position = initialPositionShoulder; // start evaluation of the exercise VirtualPhysioterphyst.Instance.StartEvaluation(); // play the exercise Sequence sequence = DOTween.Sequence(); sequence.Append(hand.transform.DOMove(hand.transform.position * 2, timing / 2)); // on finish stop evaluating sequence.OnComplete(() => VirtualPhysioterphyst.Instance.StopEvaluation()); } }
/// <summary> /// /// </summary> /// <param name="tollerances"></param> /// <param name="currentStep"></param> /// <param name="idealExerciseStep"></param> /// <returns></returns> public ArticolationError[] EvaluateExerciseStep(ArticolationTollerance[] tollerances, ExerciseStep currentStep, ExerciseStep idealExerciseStep = null) { // check abiity to evaluate the step if (_isRealTimeSampling && idealExerciseStep == null) { throw new Exception("Unable to evaluate exercise step without ideal sample or a training set!"); } PerformedMovementSteps.Add(currentStep); // eventually keep training the ai (doing this all the following code is the same in both cases) if (idealExerciseStep != null) { _trainingSet.idealMovementSteps.Add(idealExerciseStep); } ExerciseStep previousStep = GetPerformedStep(-1), currentIdealStep = GetIdealStep(0), previousIdealStep = GetIdealStep(-1); if (currentIdealStep == null) { int lastStepIndex = _trainingSet.idealMovementSteps.Count - 1; currentIdealStep = _trainingSet.idealMovementSteps[lastStepIndex]; previousIdealStep = _trainingSet.idealMovementSteps[lastStepIndex - 1]; } List <ArticolationError> articolationErrors = new List <ArticolationError>(); ArticolationPoint currentStepArticolationPoint = currentStep.Root, previousStepArticolationPoint = previousStep == null ? null : previousStep.Root, currentStepIdealArticolationPoint = currentIdealStep.Root, previousStepIdealArticolationPoint = previousIdealStep == null ? null : previousIdealStep.Root; int i = 0; while (currentStepArticolationPoint != null) { ArticolationError articolationError = new ArticolationError(); ArticolationTollerance tollerance = tollerances[i++]; articolationError.Position.Magnitude = currentStepIdealArticolationPoint.Position - currentStepArticolationPoint.Position; Debug.Log("Articolation [" + i + "]"); Debug.Log("ideal position (" + currentStepIdealArticolationPoint.Position.x + ", " + currentStepIdealArticolationPoint.Position.y + ", " + currentStepIdealArticolationPoint.Position.z + ")" ); Debug.Log("real position (" + currentStepArticolationPoint.Position.x + ", " + currentStepArticolationPoint.Position.y + ", " + currentStepArticolationPoint.Position.z + ")" ); articolationError.Position.IsMagnitudeCorrect = articolationError.Position.Magnitude.magnitude < tollerance.positionTolleranceRadius; articolationError.Angle.Magnitude = currentStepIdealArticolationPoint.Angle - currentStepArticolationPoint.Angle; articolationError.Angle.IsMagnitudeCorrect = articolationError.Angle.Magnitude.magnitude < tollerance.rotationTolleranceRadius; CalculateSpeedErrors(articolationError, currentStepArticolationPoint, previousStepArticolationPoint, currentStepIdealArticolationPoint, previousStepIdealArticolationPoint); articolationError.Position.IsSpeedCorrect = articolationError.Position.Speed.magnitude < tollerance.positionSpeedTolleranceRadius; articolationError.Angle.IsSpeedCorrect = articolationError.Angle.Speed.magnitude < tollerance.positionSpeedTolleranceRadius; articolationErrors.Add(articolationError); currentStepArticolationPoint = currentStepArticolationPoint.Substaining; previousStepArticolationPoint = previousStepArticolationPoint == null ? null : previousStepArticolationPoint.Substaining; currentStepIdealArticolationPoint = currentStepIdealArticolationPoint.Substaining; previousStepIdealArticolationPoint = previousStepIdealArticolationPoint == null ? null : previousStepIdealArticolationPoint.Substaining; } return(articolationErrors.ToArray()); }