2024-05-28 15:39:28 +02:00
3 changed files with 19 additions and 70 deletions

View File

@@ -13,7 +13,8 @@ import java.util.function.Consumer;
public class Exercise implements IWebServerHandler {
private EMuscleGroup muscleGroup;
private GesturePath path;
private GesturePath leftPath;
private GesturePath rightPath;
private String title;
private String description;
private float segmentsPerSecond;
@@ -27,18 +28,19 @@ public class Exercise implements IWebServerHandler {
* Constructor for the AbstractExercise class.
*
* @param muscleGroup The muscle group of the exercise.
* @param path The path of the exercise.
* @param leftPath The path of the left hand.
* @param rightPath The path of the right hand.
* @param title The title of the exercise.
* @param description The description of the exercise.
* @param segmentsPerSecond The number of segments per second.
* This determines how fast the exercise should be performed.
*/
public Exercise(EMuscleGroup muscleGroup, String title, String description, GesturePath path, float segmentsPerSecond) {
public Exercise(EMuscleGroup muscleGroup, String title, String description, GesturePath leftPath, GesturePath rightPath) {
this.muscleGroup = muscleGroup;
this.title = title;
this.description = description;
this.path = path;
this.segmentsPerSecond = segmentsPerSecond;
this.leftPath = leftPath;
this.rightPath = rightPath;
}
/**
@@ -109,8 +111,8 @@ public class Exercise implements IWebServerHandler {
/**
* Get the path of the exercise.
*/
public GesturePath getPath() {
return path;
public GesturePath[] getPath() {
return new GesturePath[]{leftPath, rightPath};
}
public String getTitle() {

View File

@@ -24,7 +24,7 @@ import org.joml.Vector4f;
public class PersonalMotionPreviewElement extends View {
private GesturePath path;
private GesturePath[] paths;
private MotionProcessor motionProcessor;
private double pathTime = 0.0D; // The timestamp at which the path is currently at.
@@ -88,7 +88,7 @@ public class PersonalMotionPreviewElement extends View {
this.startingTime = System.nanoTime(); // Set the last time to the current time
this.exercise = exercise;
this.path = exercise.getPath();
this.paths = exercise.getPath();
}
/**
@@ -104,8 +104,10 @@ public class PersonalMotionPreviewElement extends View {
this.motionProcessor.stopListening();
this.motionProcessor = new MotionProcessor();
this.motionProcessor.startListening();
// Handler that is called every time the motion processor receives new data.
this.motionProcessor.setMotionDataEventHandler((processed, preprocessed, sampleIndex, sampleRate, deviceId) -> {
// TODO: Implement the calculation of the `performingPath` based on the motion data
this.exerciseProgress = Math.min(1, this.motionProcessor.getAverageError(this.paths[0], 0) / 10);
});
saySomethingNice();
}
@@ -152,7 +154,6 @@ public class PersonalMotionPreviewElement extends View {
);
timePassed = (System.nanoTime() - startingTime) / 1E9D;
this.exerciseProgress = Math.min(1, this.motionProcessor.getAverageError() / 10);
this.invalidate(); // Causes a redraw.
}

View File

@@ -19,8 +19,6 @@ public class MotionProcessor {
public static final String DELIMITER = ";";
private final List<MotionData> preprocessedData = new ArrayList<>(); // Preprocessed motion data
private final List<Vector3f> relativeLeftPath = new ArrayList<>(); // Relative path of the left motion data
private final List<Vector3f> relativeRightPath = new ArrayList<>(); // Relative path of the motion data
@@ -28,14 +26,11 @@ public class MotionProcessor {
private final float sampleRate = 10.0F; // samples/second
private IMotionDataConsumer motionDataConsumer = (p1, p2, p3, p4, p5) -> {
};
private GesturePath path;
private IMotionDataConsumer motionDataConsumer = (p1, p2, p3, p4, p5) -> { };
private WebServer server;
public MotionProcessor() {
}
public MotionProcessor() {}
/**
@@ -118,22 +113,12 @@ public class MotionProcessor {
}
}
/**
* Function for setting the gesture path of the processor.
*
* @param path The path to set.
*/
public void setGesturePath(GesturePath path) {
this.path = path;
}
/**
* Function for adding motion data to the processor.
*
* @param data The motion data to add.
*/
public void addMotionData(MotionData data) {
preprocessedData.add(data);
List<Vector3f> target;
if (data.sensorId == 0)
target = relativeLeftPath;
@@ -149,7 +134,7 @@ public class MotionProcessor {
*
* @param relativeRightPath The new relative path.
*/
public void setRelativeRightPath(List<Vector3f> relativeLeftPath, List<Vector3f> relativeRightPath) {
public void setRelativePaths(List<Vector3f> relativeLeftPath, List<Vector3f> relativeRightPath) {
this.relativeRightPath.clear();
this.relativeLeftPath.clear();
this.relativeLeftPath.addAll(relativeLeftPath);
@@ -204,19 +189,6 @@ public class MotionProcessor {
return errors;
}
/**
* Function for getting the error offsets of the motion data compared to the
* reference path.
*
* @return A list of error offsets of the motion data compared to the reference path.
* If no path is set, an empty list will be returned.
*/
public List<Double> getErrors() {
if (path == null)
return new ArrayList<>();
return getErrors(path);
}
/**
* Function for getting the error of the motion data compared to the reference path.
*
@@ -228,19 +200,6 @@ public class MotionProcessor {
return path.getError(referencePoint);
}
/**
* Function for getting the error of the provided vector and the set path.
* If no path is set, the error will be 0.
*
* @param referencePoint The reference point to compare the path data to.
* @return The error of the motion data compared to the reference path.
*/
public double getError(Vector3f referencePoint) {
if (path == null)
return 0;
return path.getError(referencePoint);
}
/**
* Function for calculating the average error of the motion data
* compared to the reference path.
@@ -248,24 +207,12 @@ public class MotionProcessor {
* @param referencePath The reference path to compare the motion data to.
* @return The average error of the motion data compared to the reference path.
*/
public double getAverageError(GesturePath referencePath) {
public double getAverageError(GesturePath referencePath, int sensorId) {
double error = 0;
for (Double e : getErrors(referencePath)) {
error += e;
}
return error / Math.max(1, relativeRightPath.size());
}
/**
* Function for calculating the average error of the motion data
* compared to the reference path.
*
* @return The average error of the motion data compared to the reference path.
*/
public double getAverageError() {
if (path == null)
return 0;
return getAverageError(path);
return error / Math.max(1, (sensorId == 0 ? relativeLeftPath : relativeRightPath).size());
}
/**
@@ -274,7 +221,6 @@ public class MotionProcessor {
* @param referencePath The reference path to compare the motion data to.
*/
public void logStatistics(GesturePath referencePath) {
Log.i("MotionProcessor", "Average path error: " + getAverageError(referencePath));
Log.i("MotionProcessor", "Path length: " + relativeRightPath.size());
Log.i("MotionProcessor", "Sample rate: " + sampleRate);
Log.i("MotionProcessor", "Calibration point: " + ZERO.toString());