Added Gson for JSON parsing, added Exercise retriever

This commit is contained in:
Luca Warmenhoven
2024-05-17 13:25:50 +02:00
parent 3edab82535
commit cfcbe7d51c
7 changed files with 89 additions and 94 deletions

View File

@@ -35,7 +35,11 @@ dependencies {
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'org.joml:joml:1.10.5'
implementation 'com.google.code.gson:gson:2.8.6'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.junit.jupiter:junit-jupiter'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.aldebaran:qisdk:1.7.5'

View File

@@ -15,8 +15,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Fitbot" >
<!--android:name=".ui.activities.MainActivity"-->
<activity
android:name=".ui.activities.MainActivity"
android:name=".ui.activities.FitnessActivity"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@@ -10,8 +10,7 @@ import java.util.Objects;
public abstract class AbstractExercise implements IWebSocketHandler {
private EMuscleGroup[] muscleGroups;
private EExerciseType exerciseType;
private EMuscleGroup muscleGroup;
private GesturePath path;
// Static fields.
@@ -22,13 +21,11 @@ public abstract class AbstractExercise implements IWebSocketHandler {
/**
* Constructor for the AbstractExercise class.
*
* @param muscleGroups The muscle group of the exercise.
* @param exerciseType The type of exercise.
* @param muscleGroup The muscle group of the exercise.
* @param path The path of the exercise.
*/
public AbstractExercise(EMuscleGroup[] muscleGroups, EExerciseType exerciseType, GesturePath path) {
this.muscleGroups = muscleGroups;
this.exerciseType = exerciseType;
public AbstractExercise(EMuscleGroup muscleGroup, GesturePath path) {
this.muscleGroup = muscleGroup;
this.path = path;
}
@@ -82,19 +79,8 @@ public abstract class AbstractExercise implements IWebSocketHandler {
webSocket = null;
}
currentExercise = null;
this.onStopExercise();
}
/**
* Method for checking whether the activity is finished.
*/
public abstract boolean isActivityFinished();
/**
* Method for stopping this exercise.
*/
public abstract void onStopExercise();
/**
* Check if the current exercise is the current activity.
*/
@@ -105,15 +91,8 @@ public abstract class AbstractExercise implements IWebSocketHandler {
/**
* Get the muscle group of the exercise.
*/
public EMuscleGroup[] getMuscleGroup() {
return muscleGroups;
}
/**
* Get the exercise type.
*/
public EExerciseType getExerciseType() {
return exerciseType;
public EMuscleGroup getMuscleGroup() {
return muscleGroup;
}
/**

View File

@@ -1,18 +0,0 @@
package com.example.fitbot.exercise;
public enum EExerciseType {
FITNESS("Fitness"),
POWER("Krachttrening");
private final String name;
EExerciseType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@@ -18,4 +18,13 @@ public enum EMuscleGroup {
return this.muscleGroupIdentifier;
}
public static EMuscleGroup parse(int identifier) {
for (EMuscleGroup muscleGroup : EMuscleGroup.values()) {
if (muscleGroup.getIdentifier() == identifier) {
return muscleGroup;
}
}
return null;
}
}

View File

@@ -1,11 +1,16 @@
package com.example.fitbot.exercise;
import com.example.fitbot.util.path.GesturePath;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.joml.Vector3f;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLConnection;
@@ -13,6 +18,11 @@ public class FitnessManager {
private static final String HOST_ADDRESS = "http://145.92.8.132";
private static final String PROPERTY_DESC = "description";
private static final String PROPERTY_VECTORS = "vector_data";
private static final String PROPERTY_NAME = "name";
private static final String PROPERTY_MUSCLE_GROUP = "muscle_group";
private static String sendHTTP(String url, String method, String contentType, String body) {
try {
URLConnection connection = new URL(url).openConnection();
@@ -34,15 +44,70 @@ public class FitnessManager {
return null;
}
public static GesturePath acquirePath(String uniqueIdentifier) {
/**
* Function for retrieving an exercise from the Raspberry Pi Database.
*
* @param uniqueIdentifier The unique identifier of the exercise
* @return The exercise, if it exists on the server. Otherwise null.
*/
public static <T extends AbstractExercise> AbstractExercise acquireExercise(String uniqueIdentifier, Class<T> referenceClass) {
String response = sendHTTP(
HOST_ADDRESS + "/acquire", "GET", "application/json", "{\"kind\":\"" + uniqueIdentifier + "\"}"
);
// Validate the response
if ( response != null ) {
if (response != null) {
try {
JsonObject content = JsonParser.parseString(response).getAsJsonObject();
Constructor<T> constructor = referenceClass.getConstructor(referenceClass);
T instance = null;
try {
instance = constructor.newInstance(
EMuscleGroup.parse(content.get(PROPERTY_MUSCLE_GROUP).getAsInt()),
gesturePathFromString(content.get(PROPERTY_VECTORS).getAsString())
);
} catch (Exception e) {
e.printStackTrace();
}
return instance;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* Function for converting a string to a GesturePath object.
* The input string bytes will be directly converted into 3d vectors.
* Every coordinate is composed of 32 bits, so four characters per coordinate.
*
* @param input The string to convert
* @return The GesturePath object
*/
private static GesturePath gesturePathFromString(String input) {
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");
}
GesturePath.Builder builder = new GesturePath.Builder();
float[] xyz = new float[3];
for (int i = 0; i < bytes.length; i += 12) {
for (int j = 0; j < 3; j++) {
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)
);
}
builder.addVector(new Vector3f(
xyz[0], xyz[1], xyz[2]
));
}
return builder.build();
}
}

View File

@@ -1,45 +0,0 @@
package com.example.fitbot.exercise.exercises;
import com.example.fitbot.exercise.AbstractExercise;
import com.example.fitbot.exercise.EExerciseType;
import com.example.fitbot.exercise.EMuscleGroup;
import com.example.fitbot.exercise.FitnessManager;
import com.example.fitbot.util.server.WebSocket;
import java.net.Socket;
public class BicepCurlExercise extends AbstractExercise {
private static final String UNIQUE_ID = "bicep_curl";
/**
* Constructor for the BicepCurlExercise class.
*/
public BicepCurlExercise() {
super(
new EMuscleGroup[] { EMuscleGroup.ARMS },
EExerciseType.POWER,
FitnessManager.acquirePath(UNIQUE_ID)
);
}
@Override
public boolean isActivityFinished() {
return false;
}
@Override
public void onStopExercise() {
}
@Override
public void onMessageReceived(WebSocket.Message message, WebSocket.MessageReply replier) {
}
@Override
public void onError(Socket socket, String error) {
}
}