diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/AbstractExercise.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/AbstractExercise.java new file mode 100644 index 0000000..2265269 --- /dev/null +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/AbstractExercise.java @@ -0,0 +1,123 @@ +package com.example.fitbot.exercise; + +import android.util.Log; + +import com.example.fitbot.util.path.GesturePath; +import com.example.fitbot.util.server.IWebSocketHandler; +import com.example.fitbot.util.server.WebSocket; + +import java.util.Objects; + +public abstract class AbstractExercise implements IWebSocketHandler { + + private EMuscleGroup muscleGroup; + private EExerciseType exerciseType; + private GesturePath path; + + // Static fields. + private static WebSocket webSocket; + private static AbstractExercise currentExercise = null; + + + /** + * Constructor for the AbstractExercise class. + * + * @param muscleGroup The muscle group of the exercise. + * @param exerciseType The type of exercise. + * @param path The path of the exercise. + */ + public AbstractExercise(EMuscleGroup muscleGroup, EExerciseType exerciseType, GesturePath path) { + this.muscleGroup = muscleGroup; + this.exerciseType = exerciseType; + this.path = path; + } + + /** + * Start the exercise. + * This method starts a WebSocket server + */ + public void startExercise() { + + // Ensure no other exercise is active. + if (currentExercise != null && currentExercise != this) { + currentExercise.__stopExercise(); + Log.i("Exercises", "Another exercise was started when another was still running."); + } + + // If a WebSocket server is already running, change the event handler to be this class. + if (webSocket != null && webSocket.isConnected()) { + webSocket.setEventHandler(this); + } + + try { + webSocket = WebSocket.createServer(); + Objects.requireNonNull(webSocket, "WebSocket server could not be created."); + + webSocket.startListening(); + webSocket.setEventHandler(this); + currentExercise = this; + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Method for ending this exercise and returning the grade of the performance + * of this activity. + */ + public final double finishExercise() { + this.__stopExercise(); + + // TODO: Implement grade calculation + return 0.0; + } + + /** + * Stop the exercise. + * This method stops the WebSocket server. + */ + private void __stopExercise() { + if (webSocket != null && webSocket.isConnected()) { + webSocket.stop(); + webSocket = null; + } + } + + /** + * Method for checking whether the activity is finished. + */ + public abstract boolean isActivityFinished(); + + /** + * Method for stopping this exercise. + */ + public abstract void stopExercise(); + + /** + * Check if the current exercise is the current activity. + */ + public final boolean isCurrentActivity() { + return currentExercise == this; + } + + /** + * Get the muscle group of the exercise. + */ + public EMuscleGroup getMuscleGroup() { + return muscleGroup; + } + + /** + * Get the exercise type. + */ + public EExerciseType getExerciseType() { + return exerciseType; + } + + /** + * Get the path of the exercise. + */ + public GesturePath getPath() { + return path; + } +} diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/sports/ESportType.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EExerciseType.java similarity index 64% rename from code/src/Fitbot/app/src/main/java/com/example/fitbot/sports/ESportType.java rename to code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EExerciseType.java index 4ea7606..ee4b7b1 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/sports/ESportType.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EExerciseType.java @@ -1,13 +1,13 @@ -package com.example.fitbot.sports; +package com.example.fitbot.exercise; -public enum ESportType { +public enum EExerciseType { FITNESS("Fitness"), POWER("Krachttrening"); private final String name; - ESportType(String name) { + EExerciseType(String name) { this.name = name; } diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EMuscleGroup.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EMuscleGroup.java new file mode 100644 index 0000000..3a25740 --- /dev/null +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/EMuscleGroup.java @@ -0,0 +1,5 @@ +package com.example.fitbot.exercise; + +public enum EMuscleGroup { + // TODO: Implement +} diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseUser.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseUser.java new file mode 100644 index 0000000..bcf3320 --- /dev/null +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseUser.java @@ -0,0 +1,53 @@ +package com.example.fitbot.exercise; + + +/** + * The ExerciseUser class represents a user of the exercise application. + * This contains all necessary information of the current user. + */ +public class ExerciseUser { + + public float upperArmLength; + public float lowerArmLength; + public float upperLegLength; + public float lowerLegLength; + public float height; + + /** + * Constructor for the ExerciseUser class. + * @param upperArmLength The length of the upper arm. + * @param lowerArmLength The length of the lower arm. + * @param height The height of the user. + * @param upperLegLength The length of the upper leg. + * @param lowerLegLength The length of the lower leg. + */ + public ExerciseUser(float upperArmLength, float lowerArmLength, float height, float upperLegLength, float lowerLegLength) { + this.upperArmLength = upperArmLength; + this.lowerArmLength = lowerArmLength; + this.upperLegLength = upperLegLength; + this.lowerLegLength = lowerLegLength; + this.height = height; + } + + /** + * Constructor for the ExerciseUser class. + * @param height The height of the user. + */ + public ExerciseUser(float height) { + this.height = height; + this.upperArmLength = height * 0.2f; + this.lowerArmLength = height * 0.2f; + this.upperLegLength = height * 0.3f; + this.lowerLegLength = height * 0.3f; + } + + /** + * Default constructor for the ExerciseUser class. + * This sets the default height to 180.0f. (1.80m) + */ + public ExerciseUser() { + this(180.0f); + } + + +} diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/FitnessManager.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/FitnessManager.java new file mode 100644 index 0000000..e8404d1 --- /dev/null +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/FitnessManager.java @@ -0,0 +1,48 @@ +package com.example.fitbot.exercise; + +import com.example.fitbot.util.path.GesturePath; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + +public class FitnessManager { + + private static final String HOST_ADDRESS = "http://145.92.8.132"; + + private static String sendHTTP(String url, String method, String contentType, String body) { + try { + URLConnection connection = new URL(url).openConnection(); + connection.addRequestProperty("Content-Type", contentType); + connection.addRequestProperty("Request-Method", method); + connection.getOutputStream().write(body.getBytes()); + connection.connect(); + InputStream stream = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + } + return builder.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static GesturePath acquirePath(String uniqueIdentifier) { + String response = sendHTTP( + HOST_ADDRESS + "/acquire", "GET", "application/json", "{\"kind\":\"" + uniqueIdentifier + "\"}" + ); + // Validate the response + if ( response != null ) { + + } + return null; + } + +} diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/GesturePath.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/GesturePath.java index 5507c71..88c41ad 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/GesturePath.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/GesturePath.java @@ -10,7 +10,6 @@ public class GesturePath { // The vectors that make up the path. private final PathSegment[] segments; - private double curvature; public GesturePath(Vector3f[] vectors) { this(vectors, 0.0D); @@ -27,7 +26,6 @@ public class GesturePath { if ( vectors.length < 2) throw new IllegalArgumentException("A path must have at least two points."); - this.curvature = curvature; this.segments = new PathSegment[vectors.length - 1]; for ( int i = 0; i < vectors.length - 1; i++) segments[i] = new PathSegment(vectors[i], vectors[i + 1]); @@ -39,7 +37,6 @@ public class GesturePath { */ public GesturePath(PathSegment... segments) { this.segments = segments; - this.curvature = 0.0d; } /** diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java index 9f0c361..11183ca 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java @@ -25,10 +25,9 @@ public class PathSegment { * depending on the curvature of the curve. If the curvature is unset, or set to 0 * then this method will use linear interpolation. Otherwise, it will use a curve. * - * @param dst The destination vector to interpolate to. * @param t The interpolation value between 0 and 1. */ - public Vector3f interpolate(Vector3f dst, double t) { + public Vector3f interpolate(double t) { return new Vector3f(this.start) .lerp(this.end, (float) Math.min(1.0F, Math.max(0.0F, t))); } diff --git a/code/src/Fitbot/app/src/test/java/com/example/fitbot/PathSegmentTest.java b/code/src/Fitbot/app/src/test/java/com/example/fitbot/PathSegmentTest.java new file mode 100644 index 0000000..a7d7bca --- /dev/null +++ b/code/src/Fitbot/app/src/test/java/com/example/fitbot/PathSegmentTest.java @@ -0,0 +1,35 @@ +package com.example.fitbot; + +import com.example.fitbot.util.path.GesturePath; +import com.example.fitbot.util.path.PathSegment; + +import org.joml.Vector3f; + +public class PathSegmentTest { + + @Test + public void testPathSegment() { + // Test the PathSegment class + Vector3f[] vectors = new Vector3f[2]; + vectors[0] = new Vector3f(0, 0, 0); + vectors[1] = new Vector3f(1, 1, 1); + GesturePath path = new GesturePath(vectors); + PathSegment[] segments = path.getSegments(); + assertEquals(1, segments.length); + assertEquals(new Vector3f(0, 0, 0), segments[0].getStart()); + assertEquals(new Vector3f(1, 1, 1), segments[0].getEnd()); + assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segments[0].interpolate(0.5)); + } + + + @Test + @DisplayName("Test Path Segment Interpolation") + public void test_pathSegmentInterpolation() { + Vector3f start = new Vector3f(0, 0, 0); + Vector3f end = new Vector3f(1, 1, 1); + PathSegment segment = new PathSegment(start, end); + assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segment.interpolate(0.5)); + } + + +}