Added JSON parsing for path instead of binary decoding

This commit is contained in:
Luca Warmenhoven
2024-06-05 11:44:52 +02:00
parent 0410b23c0d
commit 20a2887401
2 changed files with 36 additions and 34 deletions

View File

@@ -28,9 +28,6 @@ public class ExerciseManager {
private static final String PROPERTY_PATH = "path"; private static final String PROPERTY_PATH = "path";
private static final String PROPERTY_NAME = "name"; 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; public static final int SENSOR_COUNT = 2;
private static final String[] REQUIRED_PROPERTIES = { private static final String[] REQUIRED_PROPERTIES = {
@@ -40,8 +37,8 @@ public class ExerciseManager {
}; };
public static final int DEFAULT_EXERCISE_REPETITIONS = 10; 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_ERROR_MARGIN = 1.0f;
public static final float EXERCISE_TIME_SCALING_FACTOR = 1.0f;
/** /**
* Function for sending an HTTP request to the server. * 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 // If one wants to add support for more sensors, one will have to adjust the Exercise
// class to support more paths. // class to support more paths.
System.out.println(content.get(PROPERTY_PATH).getAsString()); 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."); System.out.println("Invalid path data.");
return null; return null;
} }
@@ -118,9 +116,9 @@ public class ExerciseManager {
content.get(PROPERTY_DESC).getAsString(), content.get(PROPERTY_DESC).getAsString(),
content.get(PROPERTY_IMAGE_URL).getAsString(), content.get(PROPERTY_IMAGE_URL).getAsString(),
content.get(PROPERTY_VIDEO_URL).getAsString(), content.get(PROPERTY_VIDEO_URL).getAsString(),
AnglePath.fromString(leftRightData[0]), paths[0],
AnglePath.fromString(leftRightData[1]), paths[1],
DEFAULT_SEGMENT_SPEED content.get(PROPERTY_EXERCISE_DURATION).getAsInt()
); );
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -1,5 +1,11 @@
package com.example.fitbot.util.path; 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; import org.joml.Vector3f;
public class AnglePath { public class AnglePath {
@@ -25,39 +31,37 @@ public class AnglePath {
/** /**
* Function for converting a string to a GesturePath object. * Function for converting a string to a GesturePath object.
* The input string bytes will be directly converted into 3d vectors. * This function has been updated to convert Json strings to AnglePath objects.
* Every scalar is composed of 32 bits (4 characters), meaning 96 bits per vector. * The JSON must be in the following format:
* <p> * [
* Note: ASCII to Vector conversion is done in Big Endian format (most significant byte first). * { "deviceId": number, "data": [ [x, y, z], [x, y, z], ... ] },
* ]
* *
* @param input The string to convert * @param jsonInput The string to convert
* @return The GesturePath object * @return The AnglePath object
*/ */
public static AnglePath fromString(String input) { public static AnglePath[] fromString(String jsonInput) {
if (input == null) if (jsonInput == null)
throw new IllegalArgumentException("Input string cannot be 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) JsonElement parsed = JsonParser.parseString(jsonInput);
if (input.length() % 12 != 0) { if (!parsed.isJsonArray())
throw new IllegalArgumentException("Invalid input string length (" + input.length() + " bytes provided - must be a multiple of 12)"); throw new IllegalArgumentException("Input string must be a JSON array");
}
Vector3f[] vectors = new Vector3f[input.length() / 12];
float[] xyz = new float[3]; if ( parsed.getAsJsonArray().size() != ExerciseManager.SENSOR_COUNT)
for (int i = 0; i < bytes.length; i += 12) { throw new IllegalArgumentException("Input string must contain 2 elements");
for (int j = 0; j < 3; j++) {
xyz[j] = Float.intBitsToFloat( Vector3f[][] angles = new Vector3f[ExerciseManager.SENSOR_COUNT][];
(bytes[i + j * 4] & 0xFF) << 24 | for ( int dataArrayIdx = 0; dataArrayIdx < parsed.getAsJsonArray().size(); dataArrayIdx++)
(bytes[i + j * 4 + 1] & 0xFF) << 16 | {
(bytes[i + j * 4 + 2] & 0xFF) << 8 | JsonArray array = parsed.getAsJsonArray().get(dataArrayIdx).getAsJsonObject().get("data").getAsJsonArray();
(bytes[i + j * 4 + 3] & 0xFF) 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])};
} }
} }