From 20a28874015b30533cd5e9764a0b048a372c9386 Mon Sep 17 00:00:00 2001 From: Luca Warmenhoven Date: Wed, 5 Jun 2024 11:44:52 +0200 Subject: [PATCH] Added JSON parsing for path instead of binary decoding --- .../fitbot/exercise/ExerciseManager.java | 16 +++--- .../example/fitbot/util/path/AnglePath.java | 54 ++++++++++--------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseManager.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseManager.java index 8a9750e..b69e4c0 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseManager.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseManager.java @@ -28,9 +28,6 @@ public class ExerciseManager { private static final String PROPERTY_PATH = "path"; private static final String PROPERTY_NAME = "name"; - // The delimiter used to separate the paths of the sensors. - public static final String PATH_DELIMITER = ":"; - public static final int SENSOR_COUNT = 2; private static final String[] REQUIRED_PROPERTIES = { @@ -40,8 +37,8 @@ public class ExerciseManager { }; public static final int DEFAULT_EXERCISE_REPETITIONS = 10; - public static final float DEFAULT_SEGMENT_SPEED = 1.0f; public static final float EXERCISE_ERROR_MARGIN = 1.0f; + public static final float EXERCISE_TIME_SCALING_FACTOR = 1.0f; /** * Function for sending an HTTP request to the server. @@ -104,9 +101,10 @@ public class ExerciseManager { // If one wants to add support for more sensors, one will have to adjust the Exercise // class to support more paths. System.out.println(content.get(PROPERTY_PATH).getAsString()); - String[] leftRightData = content.get(PROPERTY_PATH).getAsString().split(PATH_DELIMITER); - if (leftRightData.length != SENSOR_COUNT) { + AnglePath[] paths = AnglePath.fromString(content.get(PROPERTY_PATH).getAsString()); + + if (paths.length != SENSOR_COUNT) { System.out.println("Invalid path data."); return null; } @@ -118,9 +116,9 @@ public class ExerciseManager { content.get(PROPERTY_DESC).getAsString(), content.get(PROPERTY_IMAGE_URL).getAsString(), content.get(PROPERTY_VIDEO_URL).getAsString(), - AnglePath.fromString(leftRightData[0]), - AnglePath.fromString(leftRightData[1]), - DEFAULT_SEGMENT_SPEED + paths[0], + paths[1], + content.get(PROPERTY_EXERCISE_DURATION).getAsInt() ); } catch (Exception e) { e.printStackTrace(); diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/AnglePath.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/AnglePath.java index 7df8ef9..1eb15e4 100644 --- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/AnglePath.java +++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/AnglePath.java @@ -1,5 +1,11 @@ package com.example.fitbot.util.path; +import com.example.fitbot.exercise.ExerciseManager; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + import org.joml.Vector3f; public class AnglePath { @@ -25,39 +31,37 @@ public class AnglePath { /** * Function for converting a string to a GesturePath object. - * The input string bytes will be directly converted into 3d vectors. - * Every scalar is composed of 32 bits (4 characters), meaning 96 bits per vector. - *

- * Note: ASCII to Vector conversion is done in Big Endian format (most significant byte first). + * This function has been updated to convert Json strings to AnglePath objects. + * The JSON must be in the following format: + * [ + * { "deviceId": number, "data": [ [x, y, z], [x, y, z], ... ] }, + * ] * - * @param input The string to convert - * @return The GesturePath object + * @param jsonInput The string to convert + * @return The AnglePath object */ - public static AnglePath fromString(String input) { - if (input == null) + public static AnglePath[] fromString(String jsonInput) { + if (jsonInput == null) throw new IllegalArgumentException("Input string cannot be null"); - byte[] bytes = input.getBytes(); - // Check if the input string contains a valid amount of bytes (12 bytes per vector) - if (input.length() % 12 != 0) { - throw new IllegalArgumentException("Invalid input string length (" + input.length() + " bytes provided - must be a multiple of 12)"); - } - Vector3f[] vectors = new Vector3f[input.length() / 12]; + JsonElement parsed = JsonParser.parseString(jsonInput); + if (!parsed.isJsonArray()) + throw new IllegalArgumentException("Input string must be a JSON array"); - float[] xyz = new float[3]; - for (int i = 0; i < bytes.length; i += 12) { - for (int j = 0; j < 3; j++) { + if ( parsed.getAsJsonArray().size() != ExerciseManager.SENSOR_COUNT) + throw new IllegalArgumentException("Input string must contain 2 elements"); - xyz[j] = Float.intBitsToFloat( - (bytes[i + j * 4] & 0xFF) << 24 | - (bytes[i + j * 4 + 1] & 0xFF) << 16 | - (bytes[i + j * 4 + 2] & 0xFF) << 8 | - (bytes[i + j * 4 + 3] & 0xFF) - ); + Vector3f[][] angles = new Vector3f[ExerciseManager.SENSOR_COUNT][]; + for ( int dataArrayIdx = 0; dataArrayIdx < parsed.getAsJsonArray().size(); dataArrayIdx++) + { + JsonArray array = parsed.getAsJsonArray().get(dataArrayIdx).getAsJsonObject().get("data").getAsJsonArray(); + angles[dataArrayIdx] = new Vector3f[array.size()]; + for (int i = 0; i < array.size(); i++) { + JsonArray vec = array.get(i).getAsJsonArray(); + angles[dataArrayIdx][i] = new Vector3f(vec.get(0).getAsFloat(), vec.get(1).getAsFloat(), vec.get(2).getAsFloat()); } - vectors[i / 12] = new Vector3f(xyz[0], xyz[1], xyz[2]); } - return new AnglePath(vectors); + return new AnglePath[] {new AnglePath(angles[0]), new AnglePath(angles[1])}; } }