diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java index 30dcb16..9ac90fd 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java @@ -56,6 +56,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall private static String exerciseVideoUrl; private Animate animate; private VideoView videoView; + private QiContext qiContext; private final Object lock = new Object(); @@ -136,22 +137,6 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall motionProcessor.setRecording(true, 10); motionProcessor.startListening(); - if ( videoView.isPlaying() ) - { - Animation animationarmraise = AnimationBuilder.with(qiContext) // Create the builder with the context. - .withResources(R.raw.armraise) // Set the animation resource. - .build(); // Build the animation. - - animate = AnimateBuilder.with(qiContext) // Create the builder with the context. - .withAnimation(animationarmraise) // Set the animation. - .build(); // Build the animate action. - - Future animateFuture = animate.async().run(); - } - else - { - Log.e("FitnessActivity", "VideoView is null. Check your layout XML."); - } }, (n) -> { int randomMessageIndex = (int) Math.floor(Math.random() * EXERCISE_NOT_FOUND_MESSAGES.length); @@ -192,6 +177,25 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { ProgressBar loadingCircle = findViewById(R.id.loadingCircle); loadingCircle.setVisibility(View.GONE); + + if ( videoView.isPlaying() ) + { + QiContext qiContext = null; + Animation animationarmraise = AnimationBuilder.with(qiContext) // Create the builder with the context. + .withResources(R.raw.armraise) // Set the animation resource. + .build(); // Build the animation. + + animate = AnimateBuilder.with(qiContext) // Create the builder with the context. + .withAnimation(animationarmraise) // Set the animation. + .build(); // Build the animate action. + + Future animateFuture = animate.async().run(); + } + else + { + Log.e("FitnessActivity", "VideoView is null. Check your layout XML."); + } + return true; } return false; diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java index dc46191..cd81be9 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java @@ -112,6 +112,7 @@ public class InputProcessor { ExerciseManager.TOTAL_REPETITIONS_REQUIRED += ExerciseManager.DEFAULT_EXERCISE_REPETITIONS; ExerciseManager.TOTAL_EXERCISES_PREFORMED++; + this.selfRotationVectorPaths = new ArrayList[2]; this.selfRotationVectorPaths[0] = new ArrayList<>(); this.selfRotationVectorPaths[1] = new ArrayList<>(); @@ -130,14 +131,14 @@ public class InputProcessor { */ public void onAdequateRepetition() { ExerciseManager.TOTAL_REPETITIONS_PERFORMED++; - new FitnessActivity().incrementProgress(); + this.parentActivity.incrementProgress(); } /** * Method that is called whenever the user performs a bad repetition. */ public void onInadequateRepetition() { - new FitnessActivity().triggerColorBurst(false); + this.parentActivity.triggerColorBurst(false); } /** @@ -352,55 +353,33 @@ public class InputProcessor { }*/ /** - * Function for getting the error offsets of the user's path compared to the - * target path at a given point in time. * - * @param sensorId The sensor ID to get the error offsets from. - * @param time The time to get the error offsets from. - * This value must be >= 0 && <= exerciseTime, otherwise - * the error will be 0 by default. - * @return A list of error offsets of the motion data compared to the reference path. */ - public double getError(int sensorId, float time) { + public boolean isFaultyMovement(int sensorId, float time) { // Ensure the sensor ID is within the bounds of the array if (sensorId < 0 || sensorId >= selfRotationVectorPaths.length) - return 0.0d; + return false; - // Calculate the index of the rotational vector where we're currently at - int targetRotationIdx = + // Calculate the index of the reference rotation vector + // This is done by calculating the closest index of the last received vector + // to the current time. + // i = | (t % T) / T * N | - /* + int i, referenceIndex; - // Index of the current rotation vector - int targetIndex = (int) ((this.exerciseDurationInSeconds / this.targetRotationVectorPaths[sensorId].length) * time); - int selfIndex = (int) (this.selfRotationVectorPaths[sensorId].length / this.sampleRate * time); - - // Ensure the indexes are within the bounds of the array - if ( - targetIndex >= 0 && targetIndex <= this.targetRotationVectorPaths[sensorId].length - 1 && - selfIndex >= 0 && selfIndex <= this.selfRotationVectorPaths[sensorId].length - 1 && - this.selfRotationVectorPaths[sensorId][selfIndex] != null && - this.targetRotationVectorPaths[sensorId][targetIndex] != null - ) { - return this.selfRotationVectorPaths[sensorId][selfIndex].distance(this.targetRotationVectorPaths[sensorId][targetIndex]); - }*/ - return 0.0d; - } - - /** - * Method for getting the average error of the motion data - * compared to the reference path. - * - * @param sensorId The sensor ID to get the error offsets from. - * @return The average error of the motion data compared to the reference path. - */ - public double getAverageError(int sensorId) { - double error = 0; - for (int i = 0; i < this.exerciseRepetitionDurationInSeconds; i++) { - error += getError(sensorId, i); + for ( i = 0; i < selfRotationVectorPaths.length; i++) + { + referenceIndex = (int) (Math.round( + ((time % this.exerciseRepetitionDurationInSeconds) / + (this.exerciseRepetitionDurationInSeconds)) * this.targetRotationVectorPaths[i].length)) + % this.targetRotationVectorPaths[i].length; + // If distance is greater than the threshold, return true + if (this.selfRotationVectorPaths[i].get(this.selfRotationVectorPaths[i].size() - 1).distance( + this.targetRotationVectorPaths[i][referenceIndex]) > ExerciseManager.EXERCISE_ERROR_MARGIN) + return true; } - return error / this.exerciseRepetitionDurationInSeconds; + return false; } public float secondsPassed() {