/// <summary> /// Updates the difficulty depending if answer was correct or not. /// </summary> /// <param name="correct">If set to <c>true</c> correct.</param> protected virtual void UpdateDifficulty(bool correct) { if (!correct) { // reset current good runs CurrentGoodRuns = 0; // both conditions have to be combined in one if to have only one else condition if ((++CurrentBadRuns >= ExerciseConfiguration.GetBadRunsByLevel(CurrentDifficulty)) && (CurrentDifficulty > ExerciseConfiguration.MinDifficulty)) { CurrentBadRuns = 0; CurrentDifficulty--; } else { _lastRoundLevelChange = LevelState.EQUAL; } } else { CurrentBadRuns = 0; // both conditions have to be combined in one if to have only one else condition if ((++CurrentGoodRuns >= ExerciseConfiguration.GetGoodRunsByLevel(CurrentDifficulty)) && (CurrentDifficulty < ExerciseConfiguration.MaxDifficulty)) { CurrentGoodRuns = 0; CurrentDifficulty++; } else { _lastRoundLevelChange = LevelState.EQUAL; } } _logger.LogMessage(LogLevel.Informational, "Last round level change: " + _lastRoundLevelChange.ToString()); }
public void Exercise_Done_PercentageCompletedIsHundred() { // Arrange var stubConfiguration = new ExerciseConfiguration() { NoOfRepetitions = 8, DurationPerStance = 8, PreparationDuration = 3 }; const int expectedPercentage = 100; var unitUnderTest = new Exercise(stubConfiguration) { LongLeftCount = 0, LongRightCount = 0, ShortLeftCount = 0, ShortRightCount = 0, RemainingPreparationTime = 0, RemainingSubExerciseTime = 0 }; // Assert Assert.AreEqual(expectedPercentage, unitUnderTest.PercentageCompleted); }
public void ExerciseService_PrepareExerciseServiceFromJsonWithEmptyString_CreatesDefault() { // Arrange var eventThrown = false; var exerciseConfiguration = new ExerciseConfiguration { NoOfRepetitions = 8, DurationPerStance = 10, PreparationDuration = 3 }; Exercise actualExercise = null; var expectedExercise = new Exercise(exerciseConfiguration); var stubTimerService = Substitute.For <ITimerService>(); var stubExerciseTrackerService = Substitute.For <IExerciseTrackerService>(); var unitUnderTest = ExerciseService.ExerciseServiceFromString(string.Empty, exerciseConfiguration, stubTimerService, stubExerciseTrackerService); unitUnderTest.ExerciseChanged += (sender, args) => { eventThrown = true; actualExercise = args.Exercise; }; // Act unitUnderTest.PrepareForNewExercise(); // Assert // TODO: Move this to a sepparate test Assert.IsTrue(eventThrown, "Expected exercise changed event thrown"); Assert.AreEqual(expectedExercise.ToString(), actualExercise.ToString()); }
/// <summary> /// Completes the round. /// </summary> /// <param name="wasCorrect">If set to <c>true</c> was correct.</param> /// <param name="isTutorial">If set to <c>true</c> is tutorial.</param> protected virtual void CompleteRound(bool wasCorrect, bool isTutorial) { if (_warmUpState == WarmUpState.Enabled) { WarmUpRoundsCounter++; _lastRoundLevelChange = LevelState.EQUAL; return; } if (_warmUpEnabeld) { WarmUpRoundsCounter++; } if (wasCorrect) { _multiplier.OnCorrectSolution((ExerciseConfiguration.GetGoodRunsByLevel(CurrentDifficulty) - 1) == CurrentGoodRuns); GoodRunsInARow++; TotalGoodRuns++; } else { _multiplier.OnWrongSolution(); GoodRunsInARow = 0; AddPropertyUpdate(new TotalBadRunsUpdateVO(TotalRuns + 1 - TotalGoodRuns, 1)); } TotalRuns++; if (!isTutorial) { UpdateDifficulty(wasCorrect); } else { _lastRoundLevelChange = LevelState.EQUAL; } }
public override void CreateRound(Action <IExerciseRoundDataVO> callback, IExerciseRoundConfigurationVO exerciseRoundConfiguration = null) { ValidateMinItemsOnRound(); int timeout = ExerciseConfiguration.GetTimeoutByLevel(CurrentDifficulty); List <IRoundItem> solutions = new List <IRoundItem> { _solutionChain[_currentSolutionIndex] }; if (_lastRoundLevelChange != LevelState.EQUAL) { _colorIndex = CurrentDifficulty % _colors.Length; for (int i = _solutionChain.IndexOf(_allItems[0]); i < _solutionChain.Count; i++) { _solutionChain[i].Color = _colors[_colorIndex]; } } _currentRound = new FlashGlanceRoundDataVO(CloneItems(_allItems), solutions, _lastRoundLevelChange, _warmUpState, timeout, _solutionChain, _currentSolutionIndex, _castedConfig.MapHeight, _castedConfig.MapWidth); base.CreateRound(callback, exerciseRoundConfiguration); }
protected virtual void UpdateStepGoodrunPercent(int currentStep) { //update substep good run for the hud float percent = (float)CurrentGoodRuns / (float)ExerciseConfiguration.GetGoodRunsByLevel(CurrentDifficulty); //add the porcent for the step percent += ((float)currentStep / (float)_currentRound.Solutions.Count) / (float)ExerciseConfiguration.GetGoodRunsByLevel(CurrentDifficulty); }
protected ExerciseService(Exercise exercise, ExerciseConfiguration configuration, ITimerService timerService, IExerciseTrackerService exerciseTrackerService) { mExercise = exercise; mExerciseConfiguration = configuration; mTimerService = timerService; mExerciseTrackerService = exerciseTrackerService; mTimerService.Elapsed += TimerServiceElapsed; }
/// <summary> /// Optional override to create listeners (like tcp, http) for this service instance. /// </summary> /// <returns>The collection of listeners.</returns> protected override IEnumerable <ServiceInstanceListener> CreateServiceInstanceListeners() { var config = new ExerciseConfiguration(); var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config"); var connectionStringParameter = configurationPackage.Settings.Sections["ExerciseDatabase"].Parameters["ExerciseDatabaseConnectionString"]; config.ConnectionString = connectionStringParameter.Value; return(new ServiceInstanceListener[] { new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(a => Startup.ConfigureApp(a, config), serviceContext, ServiceEventSource.Current, "ServiceEndpoint")) }); }
// This code configures Web API. The Startup class is specified as a type // parameter in the WebApp.Start method. public static void ConfigureApp(IAppBuilder appBuilder, ExerciseConfiguration exerciseConfig) { // Configure Web API for self-host. var config = new HttpConfiguration(); DependecyProvider.Config(config, exerciseConfig); MappingConfig.Config(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.EnableCors(); appBuilder.UseWebApi(config); }
public void Exercise_Started_PercentageCompletedIsZero() { // Arrange var stubConfiguration = new ExerciseConfiguration() { NoOfRepetitions = 8, DurationPerStance = 8, PreparationDuration = 3 }; var expectedPercentage = 0; var unitUnderTest = new Exercise(stubConfiguration); // Assert Assert.AreEqual(expectedPercentage, unitUnderTest.PercentageCompleted); }
/// <summary> /// Updates the score depending on the answer. /// </summary> /// <param name="increase">If set to <c>true</c> increase.</param> protected virtual void UpdateScore(bool increase = true) { int scoreAdd = ExerciseConfiguration.GetScoresByLevel(_currentDifficulty); if (scoreAdd == -1) { return; } if (increase) { Score += scoreAdd * _multiplier.MultiplierValue; } else { Score -= scoreAdd * _multiplier.MultiplierValue; } }
public void Exercise_ExerciseFromString_ReturnsCorrectObject() { // Arrange const string exerciseAsString = "LongLeftCount=1;LongRightCount=2;ShortLeftCount=3;ShortRightCount=4;RemainingPreparationTime=5;RemainingSubExerciseTime=6;CurrentSubExercise=2"; var stubConfiguration = new ExerciseConfiguration(); // Act var unitUnderTest = Exercise.ExerciseFromString(exerciseAsString, stubConfiguration); // Assert Assert.AreEqual(1, unitUnderTest.LongLeftCount); Assert.AreEqual(2, unitUnderTest.LongRightCount); Assert.AreEqual(3, unitUnderTest.ShortLeftCount); Assert.AreEqual(4, unitUnderTest.ShortRightCount); Assert.AreEqual(5, unitUnderTest.RemainingPreparationTime); Assert.AreEqual(6, unitUnderTest.RemainingSubExerciseTime); Assert.AreEqual((SubExercise)2, unitUnderTest.CurrentSubExercise); }
public void Exercise_ToString_ReturnsCorrectString() { // Arrange var stubConfiguration = new ExerciseConfiguration() { NoOfRepetitions = 2109, DurationPerStance = 19, PreparationDuration = 78 }; var unitUnderTest = new Exercise(stubConfiguration); const string expectedResult = "LongLeftCount=2109;LongRightCount=2109;ShortLeftCount=2109;ShortRightCount=2109;RemainingPreparationTime=78;RemainingSubExerciseTime=19;CurrentSubExercise=0"; // Act var actualResult = unitUnderTest.ToString(); // Assert Assert.AreEqual(expectedResult, actualResult); }
public void Exercise_HalfWay_PercentageCompletedIsFifty() { // Arrange var stubConfiguration = new ExerciseConfiguration() { NoOfRepetitions = 8, DurationPerStance = 8, PreparationDuration = 3 }; var expectedPercentage = 50; var unitUnderTest = new Exercise(stubConfiguration) { LongLeftCount = 0, LongRightCount = 0 }; // Assert Assert.AreEqual(expectedPercentage, unitUnderTest.PercentageCompleted); }
/// <summary> /// Gets the score for starting difficulty. /// This is the sum of the scores for each step, needed to reach the given difficulty level. /// In the course starting in a higher difficulty means a score bonus at the start. /// /// NOTE: init the multiplier before this function is called. It uses the multiplier settings in the model. /// /// </summary> /// <returns>The score for starting difficulty.</returns> /// <param name="difficulty">Difficulty.</param> protected virtual int GetScoreForStartingDifficulty(int difficulty) { if (difficulty == -1) { return(0); } int score = 0; int curMultiplier = 1; int multiplierCounter = 0; int goodRuns = 0; int currentDifficulty = 0; // while (currentDifficulty < difficulty) { // Increase score. score += ExerciseConfiguration.GetScoresByLevel(currentDifficulty) * curMultiplier; // Check if multiplier should update. if (++multiplierCounter > _multiplier.CorrectStepsNeededForIncrease(curMultiplier) && curMultiplier < _multiplier.MultiplierMaxValue) { curMultiplier += _multiplier.MultiplierIncrement; multiplierCounter = 0; } // Check if difficulty should increase. if (++goodRuns >= ExerciseConfiguration.GetGoodRunsByLevel(currentDifficulty)) { currentDifficulty++; if (_multiplier.ResetMultiplierWhenDifficultyIncreases) { multiplierCounter = 0; curMultiplier = 1; } goodRuns = 0; } } return(score); }
public void Exercise_Constructed_CountersSet() { // Arrange var stubConfiguration = new ExerciseConfiguration() { NoOfRepetitions = 2109, DurationPerStance = 19, PreparationDuration = 78 }; // Act var unitUnderTest = new Exercise(stubConfiguration); // Assert Assert.AreEqual(SubExercise.Undefined, unitUnderTest.CurrentSubExercise); Assert.AreEqual(stubConfiguration.NoOfRepetitions, unitUnderTest.LongLeftCount); Assert.AreEqual(stubConfiguration.NoOfRepetitions, unitUnderTest.LongRightCount); Assert.AreEqual(stubConfiguration.NoOfRepetitions, unitUnderTest.ShortLeftCount); Assert.AreEqual(stubConfiguration.NoOfRepetitions, unitUnderTest.ShortRightCount); Assert.AreEqual(stubConfiguration.DurationPerStance, unitUnderTest.RemainingSubExerciseTime); Assert.AreEqual(stubConfiguration.PreparationDuration, unitUnderTest.RemainingPreparationTime); }
public void ActiveTrackersFeedbackPanel(BodyPart bp) { SenderExerciseAI.EventSendResultAI += ColorLimbAIResult; ExerciseConfiguration configuration = FindObjectOfType <SenderExerciseAI>().exerciseConfiguration; TrackersFeedbackPanel.SetActive(true); colorizers.Clear(); if (TrackersFeedbackPanel.transform.Find("Panel/Viewport/Content").childCount <= 0) { foreach (string lp in bp.LimbPart) { limbPart = Instantiate(Resources.Load("UIPrefabs/LimbPart")) as GameObject; limbPart.GetComponentInChildren <Text>().text = lp; Image colorizer = limbPart.transform.GetChild(0).GetComponent <Image>(); colorizer.color = Color.yellow; colorizers[lp] = colorizer; Transform parent = TrackersFeedbackPanel.transform.GetChild(0).GetChild(0).GetChild(0); limbPart.transform.parent = parent; } } //StopTrackingFeedback(bp.LimbPart, configuration); }
private void CreateAI() { Sensor shoulderSensor = new Sensor(shoulder, shoulderTollerance, "spalla"); Sensor elbowSensor = new Sensor(elbow, elbowTollerance, "gomito"); Sensor handSensor = new Sensor(hand, handTollerance, "mano"); LimbConfiguration config = new LimbConfiguration(shoulderSensor, elbowSensor, handSensor); // check that there is the ghost if (sampleRecorder.trackersPreview.Count != 3) { throw new System.Exception("Ghost non correttamente configurato"); } LimbConfiguration ghostConfig = new LimbConfiguration(new Sensor(sampleRecorder.trackersPreview[0]), new Sensor(sampleRecorder.trackersPreview[1]), new Sensor(sampleRecorder.trackersPreview[2])); exerciseConfiguration = new ExerciseConfiguration( config, (EvaluationResults results) => { AIProxy aiProxy = new AIProxy(); // should be taken from context List <string> articolationNames = new List <string>() { "spalla", "gomito", "mano" }; foreach (string articolationName in articolationNames) { ArticolationError error = aiProxy.UnwrapFromResults(articolationName, results, articolationNames); bool isPositionCorrect = error.Position.IsSpeedCorrect && error.Position.IsMagnitudeCorrect, isRotationCorrect = error.Angle.IsSpeedCorrect && error.Angle.IsMagnitudeCorrect; Debug.Log(articolationName + ": POSITION IS CORRECT - " + isPositionCorrect.ToString() + " # ROTATION IS CORRECT - " + isRotationCorrect.ToString()); GameObject trackerOb; string nameID = ""; switch (articolationName) { case "spalla": nameID = "Shoulder"; trackerOb = shoulder; break; case "gomito": nameID = "Elbow"; trackerOb = elbow; break; case "mano": nameID = "Wrist"; trackerOb = hand; break; default: trackerOb = hand; break; } //Genera evento con risultati AI -> contesto SendResult(nameID, isPositionCorrect); if (isPositionCorrect) { trackerOb.GetComponent <MeshRenderer>().material.color = Color.green; } else { trackerOb.GetComponent <MeshRenderer>().material.color = Color.red; } } }, ghostConfig ); VirtualPhysioterphyst.Instance.ExerciseSetup(exerciseConfiguration); }
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()); } }
public static ExerciseService ExerciseServiceFromString(string stateAsString, ExerciseConfiguration configuration, ITimerService timerService, IExerciseTrackerService exerciseTrackerService) { return(string.IsNullOrEmpty(stateAsString) ? new ExerciseService(new Exercise(configuration), configuration, timerService, exerciseTrackerService) : new ExerciseService(Exercise.ExerciseFromString(stateAsString, configuration), configuration, timerService, exerciseTrackerService)); }
public void StopTrackingFeedback(List <string> limbIDs, ExerciseConfiguration configuration) { ArmListIDs = limbIDs; }
public TestableExercise(ExerciseConfiguration configuration) : base(configuration) { }