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_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();

View File

@@ -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.
* <p>
* 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])};
}
}