diff --git a/code/arduino/Movement-sensor-code/Connectivity.cpp b/code/arduino/Movement-sensor-code/Connectivity.cpp
index 2e9b69d..1f7252d 100644
--- a/code/arduino/Movement-sensor-code/Connectivity.cpp
+++ b/code/arduino/Movement-sensor-code/Connectivity.cpp
@@ -23,7 +23,7 @@ void Connectivity::connectWiFi(char* ssid, char* pass){
const char* getServerURL = "http://145.92.8.132:443/get-ip";
String ipAddress = ""; // string that will hold the server's IP address
-String Connectivity::fetchIPAddress() {
+const char* Connectivity::fetchIPAddress() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
WiFiClient client;
diff --git a/code/arduino/Movement-sensor-code/Connectivity.h b/code/arduino/Movement-sensor-code/Connectivity.h
index 6de0109..37d528b 100644
--- a/code/arduino/Movement-sensor-code/Connectivity.h
+++ b/code/arduino/Movement-sensor-code/Connectivity.h
@@ -19,7 +19,7 @@ public:
void websocketSetup(char* ip, uint16_t port, char* adress);
void sendData(float roll, float pitch, float yaw);
int httpPost(const char *serverAddress, const char *serverSubPath, const unsigned short serverPort, const char *data, const size_t dataLength, const char *contentType);
- String fetchIPAddress();
+ const char* fetchIPAddress();
private:
ESP8266WiFiMulti wifi;
diff --git a/code/arduino/Movement-sensor-code/Movement-sensor-code.ino b/code/arduino/Movement-sensor-code/Movement-sensor-code.ino
index 061f12d..6540384 100644
--- a/code/arduino/Movement-sensor-code/Movement-sensor-code.ino
+++ b/code/arduino/Movement-sensor-code/Movement-sensor-code.ino
@@ -7,8 +7,6 @@ void setup() {
Serial.begin(9600);
}
-unsigned long lastTime = 0; // will store the last time the code was run
-
void loop() {
SensorManager::eulerAngles eulerRotation = sensorManager.getEulerAngles();
// SensorManager::acceleration rotationAcceleration = sensorManager.getAcelleration();
@@ -19,6 +17,11 @@ struct acceleration {
float z = 9;
} accelData;
+ if (!ipAquired) {
+ serverIp = connectivity.fetchIPAddress();
+ ipAquired = true;
+ }
+ unsigned long lastTime = 0; // will store the last time the code was run
unsigned long currentTime = millis();
if (currentTime - lastTime >= 100) { // 100 ms has passed
memset(buffer, 0, BUFFER_SIZE);
@@ -34,10 +37,10 @@ struct acceleration {
accelData.z,
"data");
// %d = int, %f = floatation, %s = string
- connectivity.httpPost(connectivity.fetchIPAddress(), "/", 3445, buffer, strlen(buffer), "application/json");
+ connectivity.httpPost(serverIp, "/", 3445, buffer, strlen(buffer), "application/json");
lastTime = currentTime;
}
}
//acceleration.X
//acceleration.Y
-//acceleration.Z
+//acceleration.Z
\ No newline at end of file
diff --git a/code/arduino/Movement-sensor-code/headerFIle.h b/code/arduino/Movement-sensor-code/headerFIle.h
index 8e3480e..bd6639b 100644
--- a/code/arduino/Movement-sensor-code/headerFIle.h
+++ b/code/arduino/Movement-sensor-code/headerFIle.h
@@ -15,3 +15,5 @@ WebSocketsClient webSocket;
#define IP_ADDRESS "192.168.137.12"
char *buffer = (char *)malloc(sizeof(char) * BUFFER_SIZE);
+const char* serverIp = NULL; // Declare serverIp here
+bool ipAquired = false;
\ No newline at end of file
diff --git a/code/src/Fitbot/.gitignore b/code/src/Fitbot/.gitignore
index 732c947..203dde6 100644
--- a/code/src/Fitbot/.gitignore
+++ b/code/src/Fitbot/.gitignore
@@ -14,4 +14,5 @@
.cxx
local.properties
.idea
-.vscode
\ No newline at end of file
+.vscode
+/.idea/
diff --git a/code/src/Fitbot/.idea/misc.xml b/code/src/Fitbot/.idea/misc.xml
index b1965d6..48993be 100644
--- a/code/src/Fitbot/.idea/misc.xml
+++ b/code/src/Fitbot/.idea/misc.xml
@@ -35,7 +35,7 @@
-
+
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/Exercise.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/Exercise.java
index 331d356..f0a1e7a 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/Exercise.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/Exercise.java
@@ -7,7 +7,7 @@ public class Exercise {
public final EMuscleGroup muscleGroup;
public final GesturePath leftPath;
public final GesturePath rightPath;
- public final String title;
+ public final String name;
public final String description;
public final String imageUrl;
public final String videoUrl;
@@ -19,14 +19,14 @@ public class Exercise {
* @param muscleGroup The muscle group 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 name The title of the exercise.
* @param description The description of the exercise.
* @param imageUrl The URL of the image.
* @param videoUrl The URL of the video.
*/
- public Exercise(EMuscleGroup muscleGroup, String title, String description, String imageUrl, String videoUrl, GesturePath leftPath, GesturePath rightPath, float exerciseTimeInSeconds) {
+ public Exercise(EMuscleGroup muscleGroup, String name, String description, String imageUrl, String videoUrl, GesturePath leftPath, GesturePath rightPath, float exerciseTimeInSeconds) {
+ this.name = name;
this.muscleGroup = muscleGroup;
- this.title = title;
this.description = description;
this.leftPath = leftPath;
this.rightPath = rightPath;
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 75b11ae..613eb36 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
@@ -13,7 +13,7 @@ import java.net.URLConnection;
public class ExerciseManager {
- private static final String HOST_ADDRESS = "http://145.92.8.132:443/";
+ private static final String HOST_ADDRESS = "http://145.92.8.132:443";
// The value of these property variables must be equivalent of
// the JSON data that the database sends back.
@@ -85,11 +85,12 @@ public class ExerciseManager {
*/
public static Exercise fetchExerciseFromDatabase() {
String response = sendHTTP(
- HOST_ADDRESS, "POST", "application/json",
+ HOST_ADDRESS, "POST", "application/json", "{}"
);
// Validate the response
if (response != null) {
try {
+ System.out.println(response);
JsonObject content = JsonParser.parseString(response).getAsJsonObject();
// Ensure all required properties are present
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java
index abde556..1d74427 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java
@@ -6,6 +6,7 @@ import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+import android.widget.TextView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
@@ -29,9 +30,10 @@ import org.joml.Vector3f;
public class FitnessActivity extends RobotActivity implements RobotLifecycleCallbacks {
// Private fields for the FitnessActivity class.
- private ExerciseStatusElement personalMotionPreviewElement;
+ private ExerciseStatusElement exerciseStatusElement;
private InputProcessor motionProcessor;
private Exercise currentExercise;
+ private TextView exerciseNameTextView;
// Some nice little messages for the user
private static final String[] EXERCISE_NOT_FOUND_MESSAGES = new String[]{
@@ -56,6 +58,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
// Remove the ugly ass bar on top of the view
setSpeechBarDisplayStrategy(SpeechBarDisplayStrategy.IMMERSIVE);
+ this.exerciseNameTextView = findViewById(R.id.textViewFitnessTitle);
// Find the VideoView by its ID
VideoView videoView = findViewById(R.id.videoView);
@@ -63,8 +66,10 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
NavigationManager.setupButtonNavigation(this, R.id.homeButtonFitness, MainActivity.class);
NavigationManager.setupButtonNavigation(this, R.id.skipButtonFitness, MainActivity.class); //Needs to skip exercises once those are implemented
+ // Hide system UI
NavigationManager.hideSystemUI(this);
+ // Initiate info button
Button infoButtonFitness = findViewById(R.id.infoButtonFitness);
infoButtonFitness.setOnClickListener(new View.OnClickListener() {
@Override
@@ -80,22 +85,24 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
// Provide the context so that all queued actions can be performed.
Pepper.provideContext(qiContext, this.getClass());
- personalMotionPreviewElement = findViewById(R.id.personalMotionPreviewElement);
+ exerciseStatusElement = findViewById(R.id.personalMotionPreviewElement);
// Initialize the element whenever it has been added to the screen.
// This will provide the element with the appropriate dimensions for drawing
// the canvas properly.
- personalMotionPreviewElement.post(() -> {
+ exerciseStatusElement.post(() -> {
this.fetchExerciseAsync((exercise) -> {
// Acquire paths from the exercise and provide them to the motion processor
Vector3f[][] vectors = new Vector3f[][]{exercise.leftPath.getVectors(), exercise.rightPath.getVectors()};
motionProcessor = new InputProcessor(vectors, exercise.exerciseTimeInSeconds, SENSOR_SAMPLE_RATE);
- personalMotionPreviewElement.initialize(exercise, motionProcessor, EXERCISE_COUNT);
-
+ exerciseStatusElement.initialize(exercise, motionProcessor, EXERCISE_COUNT);
+ motionProcessor.useExercise(exercise);
+ /* TODO: Remove if not needed */motionProcessor.setRecording(true, 10);
motionProcessor.startListening();
- motionProcessor.setInputHandler(personalMotionPreviewElement);
+ motionProcessor.setInputHandler(exerciseStatusElement);
+
}, (n) -> {
int randomMessageIndex = (int) Math.floor(Math.random() * EXERCISE_NOT_FOUND_MESSAGES.length);
Pepper.say(EXERCISE_NOT_FOUND_MESSAGES[randomMessageIndex]);
@@ -120,6 +127,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
if (exercise == null) {
onFailedFetch.handle(null);
} else {
+ exerciseNameTextView.setText(exercise.name);
onSuccessfulFetch.handle(exercise);
}
})).start();
@@ -177,12 +185,15 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_info);
+ // Hide the system UI
NavigationManager.hideSystemUI(this);
+ // Set the dialog options
dialog.getWindow().setDimAmount(0.5f);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCancelable(true);
+ // Close button for dialog
Button closeButton = dialog.findViewById(R.id.closeButtonDialog);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/ExerciseStatusElement.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/ExerciseStatusElement.java
index 606321b..c8b112b 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/ExerciseStatusElement.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/ExerciseStatusElement.java
@@ -38,16 +38,6 @@ public class ExerciseStatusElement extends View implements IInputHandler {
private final Paint borderPaint = new Paint();
private final Paint backgroundPaint = new Paint();
- // TODO: Remove
- private final Matrix4f viewMatrix = new Matrix4f(); // The view matrix for the 3D to 2D transformation.
- private final Matrix4f projectionMatrix = new Matrix4f(); // The projection matrix for the 3D to 2D transformation.
- private final Vector4f objectPosition = new Vector4f(0, 0, 0, 1); // The location of the object in 3D space.
- private final ConcurrentLinkedQueue vectors = new ConcurrentLinkedQueue<>();
-
- // TODO: Remove
- private Vector2f[] axisVectors = new Vector2f[0];
-
-
private static final String[] STARTING_PHRASES = {
"Veel success met de oefening!",
"Je kan het!",
@@ -93,16 +83,6 @@ public class ExerciseStatusElement extends View implements IInputHandler {
this.exercise = exercise;
this.exerciseCount = exerciseCount;
- /* TODO: Remove */
- this.axisVectors = new Vector2f[]{
- projectVertex(new Vector3f(-5.0f, 0, 0), getWidth(), getHeight()),
- projectVertex(new Vector3f(5.0f, 0, 0), getWidth(), getHeight()),
- projectVertex(new Vector3f(0, -5.0f, 0), getWidth(), getHeight()),
- projectVertex(new Vector3f(0, 5.0f, 0), getWidth(), getHeight()),
- projectVertex(new Vector3f(0, 0, -5.0f), getWidth(), getHeight()),
- projectVertex(new Vector3f(0, 0, 5.0f), getWidth(), getHeight())
- };
-
Pepper.say(STARTING_PHRASES[(int) Math.floor(Math.random() * STARTING_PHRASES.length)]);
// Handler that is called every time the motion processor receives new data.
@@ -111,6 +91,10 @@ public class ExerciseStatusElement extends View implements IInputHandler {
Log.i("MotionProcessor", "Rotation vector received: " + rotationVector);
Log.i("MotionProcessor", "Last error offset:" + this.motionProcessor.getError(deviceId, this.motionProcessor.secondsPassed()));
+ // Check whether the current exercise has been completed.
+ // This is determined by the duration of the exercise, and the amount of time that has passed.
+ // The duration of the exercise originates from the database, and is stored in seconds.
+ // Whenever 'useExercise' is called, the timer resets and this method will be called again.
if (this.motionProcessor.hasFinished()) {
// If for some reason the parent activity is not defined,
// move back to the main screen.
@@ -124,6 +108,8 @@ public class ExerciseStatusElement extends View implements IInputHandler {
this.exerciseCount--;
this.parentActivity.fetchExerciseAsync((newExercise) -> {
this.motionProcessor.useExercise(newExercise);
+
+ // Whenever the database retrieval failed, we return to the main screen.
}, (failed) -> {
// Move to main screen
NavigationManager.navigateToActivity(parentActivity, MainActivity.class);
@@ -131,21 +117,8 @@ public class ExerciseStatusElement extends View implements IInputHandler {
} else {
// Finish the exercise.
NavigationManager.navigateToActivity(parentActivity, EndScreenActivity.class);
- return;
}
}
-
- /* TODO: Use raw vector */
- vectors.add(projectVertex(rotationVector, this.getWidth(), this.getHeight()));
-
- /* TODO: Remove */
- Vector2f parsed = projectVertex(rotationVector, this.getWidth(), this.getHeight());
-
- this.vectors.add(parsed /* TODO: Add regular vertex once exercise data is stored in DB*/);
-
- // Remove the first element if the array is too big
- if (this.vectors.size() > 100)
- this.vectors.poll();
});
}
@@ -159,50 +132,12 @@ public class ExerciseStatusElement extends View implements IInputHandler {
this.exercise = exercise;
}
-
- private Vector2f projectVertex(Vector3f point, int virtualWidth, int virtualHeight) {
- viewMatrix
- .identity()
- .lookAt(new Vector3f(0, 0, -2), new Vector3f(0, 0, 0), new Vector3f(0, 1, 0));
-
- // Transform the projection matrix to a perspective projection matrix
- // Perspective transformation conserves the depth of the object
- projectionMatrix
- .identity()
- .perspective((float) Math.toRadians(70), (float) virtualWidth / virtualHeight, .01f, 1000.0f);
-
- // Convert world coordinates to screen-space using MVP matrix
- Vector4f screenCoordinates = new Vector4f(point, 1.0f)
- .mul(this.viewMatrix)
- .mul(this.projectionMatrix);
-
- // Normalize screen coordinates from (-1, 1) to (0, virtualWidth) and (0, virtualHeight)
- float normalizedX = (screenCoordinates.x / screenCoordinates.w + 1.0f) * 0.5f * virtualWidth;
- float normalizedY = (1.0f - screenCoordinates.y / screenCoordinates.w) * 0.5f * virtualHeight;
- return new Vector2f(normalizedX, normalizedY);
- }
-
-
@Override
public void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundPaint);
this.setBackgroundColor(0xFF000000); // Black
/*if (this.exercise == null)
return;*/
-
-
- /* TODO: Remove */
- for (int i = 0, startX, endX, startY, endY; i < axisVectors.length / 2; i++) {
- startX = (int) Math.max(0, Math.min(this.getWidth(), (int) axisVectors[i * 2].x));
- endX = (int) Math.max(0, Math.min(this.getWidth(), (int) axisVectors[i * 2 + 1].x));
- startY = (int) Math.max(0, Math.min(this.getHeight(), (int) axisVectors[i * 2].y));
- endY = (int) Math.max(0, Math.min(this.getHeight(), (int) axisVectors[i * 2 + 1].y));
- canvas.drawLine(startX, startY, endX, endY, this.borderPaint);
- }
-
- for (Vector2f point : this.vectors) {
- canvas.drawRect(point.x, point.y, point.x + 5, point.y + 5, this.userProgressPaint);
- }
/*
// Draw target circle
float targetRadius = (this.screenDimensions.x + this.screenDimensions.y) / 5.0f;
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java
index c78bd89..66c6d94 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/processing/InputProcessor.java
@@ -80,6 +80,8 @@ public class InputProcessor {
this.selfRotationVectorPaths = new Vector3f[2][(int) (exercise.exerciseTimeInSeconds * this.sampleRate)];
this.targetRotationVectorPaths = new Vector3f[2][exercise.rightPath.getVectors().length];
+ this.targetRotationVectorPaths[0] = exercise.leftPath.getVectors();
+ this.targetRotationVectorPaths[1] = exercise.rightPath.getVectors();
this.exerciseDurationInSeconds = exercise.exerciseTimeInSeconds;
this.secondsPassed = 0.0D;
this.lastTime = System.currentTimeMillis();
@@ -99,7 +101,6 @@ public class InputProcessor {
if (recording) {
this.secondsPassed = 0.0D;
this.lastTime = System.currentTimeMillis();
-
}
}
diff --git a/code/src/Fitbot/app/src/test/java/com/example/fitbot/DatabaseFetchingTest.java b/code/src/Fitbot/app/src/test/java/com/example/fitbot/DatabaseFetchingTest.java
index 4f5d387..03f2ffe 100644
--- a/code/src/Fitbot/app/src/test/java/com/example/fitbot/DatabaseFetchingTest.java
+++ b/code/src/Fitbot/app/src/test/java/com/example/fitbot/DatabaseFetchingTest.java
@@ -14,7 +14,7 @@ public class DatabaseFetchingTest {
assert exercise != null;
System.out.println("\n---------------------------------");
System.out.println("Exercise:");
- System.out.println("Name: " + exercise.title);
+ System.out.println("Name: " + exercise.name);
System.out.println("Description: " + exercise.description);
System.out.println("Muscle Group: " + exercise.muscleGroup);
System.out.println("Image URL: " + exercise.imageUrl);