Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
#include "headerFile.h"
|
||||
|
||||
// SensorManager::Rotation offset;
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
#define DEVICE_ID 1
|
||||
|
||||
char *buffer = (char *)malloc(sizeof(char) * BUFFER_SIZE);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("startup");
|
||||
// Serial.println("startup");
|
||||
//connect to internet and start sensor
|
||||
connectivity.connectWiFi(ssid, pass);
|
||||
sensorManager.sensorSetup();
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -16,22 +20,26 @@ void loop() {
|
||||
SensorManager::acceleration rotationAcceleration = sensorManager.getAcelleration();
|
||||
unsigned long lastTime = 0; // will store the last time the code was run
|
||||
|
||||
Serial.print(eulerRotation.roll);
|
||||
Serial.print(" ");
|
||||
Serial.print(eulerRotation.yaw);
|
||||
Serial.print(" ");
|
||||
Serial.print(eulerRotation.pitch);
|
||||
Serial.println();
|
||||
|
||||
unsigned long currentTime = millis();
|
||||
if (currentTime - lastTime >= 100) { // 100 ms has passed
|
||||
String message = "{\"deviceId\": 1, \"rotationX\":\"" + String(eulerRotation.roll) + "\",\"rotationY\":\"" + String(eulerRotation.pitch) + "\",\"rotationZ\":\"" + String(eulerRotation.yaw) + "\",\"accelerationX\":\"" + String(rotationAcceleration.x) + "\",\"accelerationY\":\"" + String(rotationAcceleration.y) + "\",\"accelerationZ\":\"" + String(rotationAcceleration.z) + "\",\"type\":\"data\"}";
|
||||
Serial.println(connectivity.httpPost("192.168.137.146", "/", 3445, message.c_str(), message.length(), "json"));
|
||||
Serial.println(message);
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
sprintf(
|
||||
buffer,
|
||||
"{\"deviceId\": %d, \"rotationX\": %d, \"rotationY\": %d, \"rotationZ\": %d, \"accelerationX\": %d, \"accelerationY\": %d, \"accelerationZ\": %d, \"type\": %s}",
|
||||
DEVICE_ID,
|
||||
eulerRotation.roll,
|
||||
eulerRotation.pitch,
|
||||
eulerRotation.yaw,
|
||||
rotationAcceleration.x,
|
||||
rotationAcceleration.y,
|
||||
rotationAcceleration.z,
|
||||
"data");
|
||||
// Serial.println(connectivity.httpPost("192.168.137.45", "/", 3445, message.c_str(), message.length(), "json"));
|
||||
// Serial.println(message);
|
||||
connectivity.httpPost("192.168.137.45", "/", 3445, buffer, strlen(buffer), "application/json");
|
||||
lastTime = currentTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
//acceleration.X
|
||||
//acceleration.Y
|
||||
//acceleration.Z
|
||||
|
||||
|
@@ -9,15 +9,15 @@ void SensorManager::sensorSetup() {
|
||||
//wait for the sensor to start before continue
|
||||
if (myIMU.begin() == false) {
|
||||
delay(1000);
|
||||
Serial.println(".");
|
||||
// Serial.println(".");
|
||||
}
|
||||
//start sensorfunction and start autocalibration
|
||||
//once calibration is enabled it attempts to every 5 min
|
||||
|
||||
Wire.setClock(400000);
|
||||
myIMU.enableGyroIntegratedRotationVector(100); //send data every 100ms
|
||||
myIMU.enableAccelerometer(100); //Send data update every 100ms
|
||||
Serial.println(F("magnetometer rotation enabled"));
|
||||
myIMU.enableStepCounter(500); //Send data update every 500ms
|
||||
}
|
||||
//get sensordata
|
||||
SensorManager::RotationQuintillions SensorManager::getQuintillions() {
|
||||
@@ -39,7 +39,7 @@ SensorManager::RotationQuintillions SensorManager::getQuintillions() {
|
||||
return rotation;
|
||||
}
|
||||
}
|
||||
//calculate Quintillions to Euler angles from -1π to +1π
|
||||
//calculate Quintillions to Euler angles from -1π to +1π
|
||||
SensorManager::eulerAngles SensorManager::getEulerAngles() {
|
||||
SensorManager::RotationQuintillions rotation = getQuintillions();
|
||||
float roll = atan2(2.0f * (rotation.w * rotation.i + rotation.j * rotation.k), 1.0f - 2.0f * (rotation.i * rotation.i + rotation.j * rotation.j));
|
||||
@@ -48,11 +48,24 @@ SensorManager::eulerAngles SensorManager::getEulerAngles() {
|
||||
eulerAngles EulerAngles = { roll, pitch, yaw };
|
||||
return EulerAngles;
|
||||
}
|
||||
SensorManager::acceleration SensorManager::getAcelleration(){
|
||||
float x = myIMU.getAccelX();
|
||||
float y = myIMU.getAccelY();
|
||||
float z = myIMU.getAccelZ();
|
||||
acceleration Acceleration = { x, y, z };
|
||||
SensorManager::acceleration SensorManager::getAcelleration() {
|
||||
float x = myIMU.getAccelX();
|
||||
float y = myIMU.getAccelY();
|
||||
float z = myIMU.getAccelZ();
|
||||
acceleration Acceleration = { x, y, z };
|
||||
|
||||
return Acceleration;
|
||||
return Acceleration;
|
||||
}
|
||||
|
||||
bool SensorManager::sensorTap() {
|
||||
int taps = 0;
|
||||
if (myIMU.dataAvailable() == true) {
|
||||
int taps = myIMU.getStepCount();
|
||||
}
|
||||
if (taps) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -21,7 +21,7 @@ public:
|
||||
|
||||
eulerAngles getEulerAngles();
|
||||
acceleration getAcelleration();
|
||||
|
||||
bool sensorTap();
|
||||
private:
|
||||
struct RotationQuintillions {
|
||||
float i;
|
||||
|
1
code/src/Fitbot/.idea/misc.xml
generated
1
code/src/Fitbot/.idea/misc.xml
generated
@@ -16,6 +16,7 @@
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/activity_end_screen.xml" value="0.165" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/activity_endscreen.xml" value="0.1" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml" value="0.1234375" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/activity_help.xml" value="0.1" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/activity_main.xml" value="0.1" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/header.xml" value="0.1234375" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/toolbar.xml" value="0.1234375" />
|
||||
|
@@ -45,6 +45,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
|
||||
GesturePath.Builder gesturePathBuilder = new GesturePath.Builder();
|
||||
|
||||
/* Generate a random path to test the tracking system */
|
||||
for ( int i = 0; i < 40; i++)
|
||||
{
|
||||
gesturePathBuilder.addVector(
|
||||
@@ -70,8 +71,10 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
public void onRobotFocusGained(QiContext qiContext) {
|
||||
|
||||
// Find the VideoView by its ID
|
||||
CompletableFuture.runAsync(() -> FitnessCycle.executeMovement("bicepcurl", 10, qiContext));
|
||||
// CompletableFuture.runAsync(() -> FitnessCycle.executeMovement("bicepcurl", 10, qiContext));
|
||||
Log.i("Motion", "qiContext provided");
|
||||
personalMotionPreviewElement.provideQiContext(qiContext);
|
||||
|
||||
// FitnessCycle.playVideo(qiContext, videoView, this);
|
||||
}
|
||||
|
||||
@@ -88,5 +91,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
QiSDK.unregister(this, this);
|
||||
this.personalMotionPreviewElement.onDestroy();
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.util.ButtonNavigation;
|
||||
|
||||
public class HelpActivity extends AppCompatActivity {
|
||||
|
||||
@@ -11,5 +12,8 @@ public class HelpActivity extends AppCompatActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_help);
|
||||
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.homeButton, MainActivity.class);
|
||||
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@ import android.util.Log;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.util.ButtonNavigation;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@@ -48,11 +49,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
toolbar = findViewById(R.id.toolbar);
|
||||
startButton = findViewById(R.id.startButton);
|
||||
|
||||
startButton.setOnClickListener(v -> { // Switch to fitness activity
|
||||
Log.i("MainActivity", "Switching to FitnessActivity");
|
||||
Intent intent = new Intent(MainActivity.this, FitnessActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.startButton, FitnessActivity.class);
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.helpButton, HelpActivity.class);
|
||||
|
||||
/*---Tool Bar---*/
|
||||
setSupportActionBar(toolbar); // Make the toolbar act as the action bar
|
||||
|
@@ -22,13 +22,16 @@ import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class PersonalMotionPreviewElement extends View {
|
||||
|
||||
private GesturePath[] paths;
|
||||
private MotionProcessor motionProcessor;
|
||||
|
||||
private double pathTime = 0.0D; // The timestamp at which the path is currently at.
|
||||
private double exerciseProgress = 0.0D; // The progress of the exercise. Ranges from 0 to 1.
|
||||
private final AtomicInteger exerciseProgress = new AtomicInteger(0); // The progress of the exercise. Ranges from 0 to 1000.
|
||||
|
||||
private QiContext qiContext;
|
||||
|
||||
@@ -86,12 +89,19 @@ public class PersonalMotionPreviewElement extends View {
|
||||
this.targetPath = new Path();
|
||||
|
||||
this.startingTime = System.nanoTime(); // Set the last time to the current time
|
||||
this.exerciseProgress = 0.0d;
|
||||
|
||||
this.exercise = exercise;
|
||||
this.paths = exercise.getPath();
|
||||
}
|
||||
|
||||
public void onDestroy()
|
||||
{
|
||||
if ( this.motionProcessor != null )
|
||||
this.motionProcessor.stopListening();
|
||||
|
||||
this.motionProcessor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for providing a QiContext to the PersonalMotionPreviewElement.
|
||||
* This function will be called by the parent activity when the QiContext is available.
|
||||
@@ -100,20 +110,24 @@ public class PersonalMotionPreviewElement extends View {
|
||||
* @param context The QiContext to provide.
|
||||
*/
|
||||
public void provideQiContext(QiContext context) {
|
||||
this.qiContext = context;
|
||||
if ( this.motionProcessor != null )
|
||||
this.motionProcessor.stopListening();
|
||||
this.motionProcessor = new MotionProcessor();
|
||||
this.motionProcessor.startListening();
|
||||
try {
|
||||
this.qiContext = context;
|
||||
if (this.motionProcessor != null)
|
||||
this.motionProcessor.stopListening();
|
||||
|
||||
// Handler that is called every time the motion processor receives new data.
|
||||
this.motionProcessor.setMotionDataEventHandler((processed, preprocessed, sampleIndex, sampleRate, deviceId) -> {
|
||||
double progress = this.motionProcessor.getAverageError(this.paths[0], 0);
|
||||
this.exerciseProgress = Math.min(1, Math.max(0, progress));
|
||||
this.invalidate();
|
||||
Log.i("MotionProcessor", "Processed data: " + progress + " (" + preprocessed + ")");
|
||||
});
|
||||
saySomethingNice();
|
||||
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) -> {
|
||||
int progress = (int) this.motionProcessor.getError(this.paths[0], processed);
|
||||
this.exerciseProgress.set(Math.min(1000, Math.max(0, progress)));
|
||||
Log.i("MotionProcessor", "Processed data: " + progress + " (" + preprocessed + ")");
|
||||
});
|
||||
saySomethingNice();
|
||||
} catch (Exception e) {
|
||||
Log.e("MotionProcessor", "An error occurred whilst attempting to provide QiContext:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,16 +161,18 @@ public class PersonalMotionPreviewElement extends View {
|
||||
// Draw target circle
|
||||
float targetRadius = (this.screenDimensions.x + this.screenDimensions.y) / 5.0f;
|
||||
canvas.drawCircle(this.screenDimensions.x / 2, this.screenDimensions.y / 2, targetRadius, this.targetPaint);
|
||||
canvas.drawCircle(this.screenDimensions.x / 2, this.screenDimensions.y / 2, (float)(targetRadius * exerciseProgress), this.referencePaint);
|
||||
canvas.drawCircle(this.screenDimensions.x / 2, this.screenDimensions.y / 2, (targetRadius * exerciseProgress.get()/1000.0f), this.referencePaint);
|
||||
referencePaint.setColor(
|
||||
Color.argb(
|
||||
255,
|
||||
(int)(255 * (1.0 - exerciseProgress)),
|
||||
(int)(255 * exerciseProgress),
|
||||
(int)(255 * (1.0 - exerciseProgress.get()/1000.0f)),
|
||||
(int)(255 * exerciseProgress.get()/1000.0f),
|
||||
0
|
||||
)
|
||||
);
|
||||
|
||||
this.invalidate();
|
||||
|
||||
timePassed = (System.nanoTime() - startingTime) / 1E9D;
|
||||
}
|
||||
}
|
||||
|
@@ -71,6 +71,9 @@ public class MotionProcessor {
|
||||
public void parsePacket(@NotNull String data) {
|
||||
|
||||
try {
|
||||
|
||||
Log.i("MotionProcessor", "Received packet data: " + data);
|
||||
|
||||
JsonElement json = JsonParser.parseString(data);
|
||||
|
||||
if (!json.isJsonObject())
|
||||
@@ -106,6 +109,7 @@ public class MotionProcessor {
|
||||
addMotionData(motionData);
|
||||
} catch (Exception e) {
|
||||
// Don't do anything ... just ignore the exception
|
||||
Log.i("MotionProcessor", "Failed to parse packet data.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
@@ -63,6 +64,7 @@ public class WebServer implements Runnable {
|
||||
// Find a new connection
|
||||
Socket newSocket = this.serverSocket.accept();
|
||||
InputStream streamIn = newSocket.getInputStream();
|
||||
OutputStream streamOut = newSocket.getOutputStream();
|
||||
|
||||
// Read the incoming data
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(streamIn));
|
||||
@@ -71,7 +73,14 @@ public class WebServer implements Runnable {
|
||||
while ((line = reader.readLine()) != null)
|
||||
builder.append(line).append("\n");
|
||||
|
||||
// Send generic message back
|
||||
streamOut.write("HTTP/1.1 200 OK\n".getBytes());
|
||||
streamOut.write("Content-Type: text/html\n".getBytes());
|
||||
streamOut.write("Connection: close\n".getBytes());
|
||||
|
||||
streamIn.close(); // Closes the reader, stream and socket connection.
|
||||
streamOut.close();
|
||||
newSocket.close();
|
||||
|
||||
String[] data = builder.toString().split("\n\n");
|
||||
|
||||
|
@@ -56,14 +56,12 @@
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="539dp"
|
||||
android:layout_marginEnd="533dp"
|
||||
android:text="Gefeliciteerd"
|
||||
app:layout_constraintBottom_toTopOf="@+id/workoutText"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/myRectangleView" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.155" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/workoutText"
|
||||
|
@@ -4,6 +4,61 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
tools:context=".ui.activities.HelpActivity">
|
||||
|
||||
<View
|
||||
android:id="@+id/myRectangleView"
|
||||
android:layout_width="1075dp"
|
||||
android:layout_height="510dp"
|
||||
android:background="@drawable/rectangle"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.502"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.168"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/homeButton"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="75dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:text="@string/home"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.852" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView4.2"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="1053dp"
|
||||
android:layout_height="191dp"
|
||||
android:text="@string/uitleg"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.502"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.133" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView4"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="1053dp"
|
||||
android:layout_height="191dp"
|
||||
android:text="Als je klaar bent kunt u op de COMPLETE knop drukken in het sport scherm en dan kunt u uw punten inzien"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.502"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.482" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@@ -13,6 +13,8 @@
|
||||
<string name="home">Home</string>
|
||||
<string name="skip">Skip</string>
|
||||
<string name="complete">Complete</string>
|
||||
|
||||
<string name="uitleg">Als je op de startknop drukt komen oefingen op het scherm. Het doel is om die zo goedmogelijk na te doen zodat je punten verzameld. Als je klaar bent kunt u op de COMPLETE knop drukken in het sport scherm en dan kunt u uw punten inzien</string>
|
||||
<color name="red">#f22b1d</color>
|
||||
|
||||
</resources>
|
@@ -7,7 +7,7 @@ app.use(bodyParser.json());
|
||||
const serverPort = 3000;
|
||||
|
||||
const databaseCredentials = {
|
||||
host: 'localhost',
|
||||
host: '127.0.0.1',
|
||||
user: 'fitbot',
|
||||
password: 'fitbot123',
|
||||
database: 'fitbot',
|
||||
|
@@ -1,19 +1,45 @@
|
||||
# Infrastructure
|
||||
|
||||
The infrastructure of the database is composed of the following components:
|
||||
This document describes the infrastructure of the database and server components of the project.
|
||||
|
||||
- User
|
||||
- Pepper
|
||||
- Interface
|
||||
- Robot
|
||||
- Raspberry Pi
|
||||
- Database
|
||||
- MariaDB
|
||||
- Server
|
||||
- Apache
|
||||
- phpMyAdmin
|
||||
- Node.js
|
||||
## Components
|
||||
|
||||
User interacts with Pepper through the interface. The interface sends the user input to the robot. The robot processes the input (java) and sends the output (xml) back to the interface. The interface displays the output to the user. The Raspberry Pi hosts the server and database. The database stores the data and the server hosts the website. The server runs Apache, phpMyAdmin, and Node.js. The interface makes a request to the server (HTTP GET) to retrieve the data in the database. The server processes the request (HTTP GET) and retrieves (SQL) the data from the database. The interface displays the data to the user.
|
||||
The database component of the project consists of the following components:
|
||||
|
||||
- Node.js (Server)
|
||||
- Apache2 (Web Server)
|
||||
- phpMyAdmin (Database Management Tool)
|
||||
- MariaDB (Database)
|
||||
|
||||
## Diagrams
|
||||
|
||||
Architecture application diagram of the project.
|
||||
|
||||

|
||||
|
||||
Deyplomment application diagram of the project.
|
||||
|
||||

|
||||
|
||||
## Database
|
||||
|
||||
The database component of the project is responsible for storing and managing the data used by the application. The database is implemented using MariaDB. The database is responsible for storing data such as exercises, names, descriptions, images, videos and exercise paths. The database is accessed by the server component of the project to retrieve data.
|
||||
|
||||
## Server
|
||||
|
||||
The server components of the project are responsible for handling requests from the client application and interacting with the database. The server is implemented using Node.js and is responsible for handling requests to retrieve exercises. The server is also responsible for serving the client application to the user.
|
||||
|
||||
The web server component of the project is implemented using Apache2 and is responsible for hosting phpMyAdmin, a database management tool used to interact with the database.
|
||||
|
||||
## Problems/Solutions
|
||||
|
||||
During the setup of the infrastructure, the following problems were encountered.
|
||||
|
||||
### Reverse proxy
|
||||
|
||||
The initial problem is that the Pi has a limeted amount of ports that can be used. This means that the server can only be accessed through port 80. This is a problem because the server is running on port 3000. To solve this problem, a reverse proxy was used to redirect traffic from port 80 to port 3000. This was done by creating a virtual host in the Apache2 configuration file that listens on port 80 and redirects traffic to port 3000.
|
||||
|
||||
When implementing the reverse proxy a problem was encountered where everything on port 80 was being redirected to port 3000. This was a problem because the server was also running on port 80. The initial solution was to remove the reverse proxy from sites-enabled and restart the server. However this caused the reverse proxy to stop working. Eventually it took too long to fix the problem and the reverse proxy was removed.
|
||||
|
||||
Running the server on port 443 was also considered as a solution. At the first sight this dind't seem possible since the access to port 443 is restricted. However, after some research it was found that it is possible to run the server on port 443 by starting the node with sudo. This was the solution that was chosen.
|
||||
|
||||

|
File diff suppressed because one or more lines are too long
@@ -1,99 +1,105 @@
|
||||
<mxfile host="Electron" modified="2024-05-17T10:24:38.560Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.2 Chrome/114.0.5735.289 Electron/25.9.4 Safari/537.36" etag="vTrgfPgpC1M9saCyJqTJ" version="22.1.2" type="device">
|
||||
<mxfile host="Electron" modified="2024-05-29T11:03:46.287Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.2 Chrome/114.0.5735.289 Electron/25.9.4 Safari/537.36" etag="Sie7uAwi7Ncv96kRBi84" version="22.1.2" type="device">
|
||||
<diagram name="Page-1" id="jecpyCyVafvbFtGhV645">
|
||||
<mxGraphModel dx="1941" dy="638" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<mxGraphModel dx="2069" dy="713" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-2" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-390" y="240" width="430" height="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-34" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-34" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-360" y="420" width="161.25" height="230" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-1" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-1" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-690" y="240" width="220" height="160" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-10" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-10" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-640" y="300" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-3" value="Server Node (Raspberry Pi)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-3" value="Server Node (Raspberry Pi)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-277.5" y="250" width="205" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-4" value="Client Node" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-4" value="Client Node (Pepper)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" parent="1" vertex="1">
|
||||
<mxGeometry x="-660" y="250" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-9" value="<b style="font-size: 14px;"><font style="font-size: 14px;">Android App</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-9" value="<b style="font-size: 14px;"><font style="font-size: 14px;">Android App</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
|
||||
<mxGeometry x="-626.87" y="325" width="93.75" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-11" value="&lt;&lt;client&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-11" value="&lt;&lt;client&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-610" y="300" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-14" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-14" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-339.37" y="490" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-15" value="<b style="font-size: 14px;"><font style="font-size: 14px;">Apache2</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-15" value="<b style="font-size: 14px;"><font style="font-size: 14px;">Apache2</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
|
||||
<mxGeometry x="-319.05" y="515" width="76.87" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-16" value="&lt;&lt;web server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-16" value="&lt;&lt;web server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-330.62" y="490" width="102.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-20" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-20" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-132.5" y="300" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-21" value="<b style="font-size: 14px;"><font style="font-size: 14px;">MariaDB</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-21" value="<b style="font-size: 14px;"><font style="font-size: 14px;">MariaDB</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
|
||||
<mxGeometry x="-107.5" y="325" width="70" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-22" value="&lt;&lt;database&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-22" value="&lt;&lt;database&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-102.5" y="300" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="JqL7afyQoL-OOYxCKZbi-23" target="JqL7afyQoL-OOYxCKZbi-14">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="JqL7afyQoL-OOYxCKZbi-23" target="JqL7afyQoL-OOYxCKZbi-14" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-23" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="S5-NwbH-4CbKXiQop9ow-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="JqL7afyQoL-OOYxCKZbi-34" target="JqL7afyQoL-OOYxCKZbi-20">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-23" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-340" y="570" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-24" value="<b style="font-size: 14px;"><font style="font-size: 14px;">phpMyAdmin</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-24" value="<b style="font-size: 14px;"><font style="font-size: 14px;">phpMyAdmin</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
|
||||
<mxGeometry x="-330.62" y="600" width="97.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-25" value="&lt;&lt;DBMS&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-25" value="&lt;&lt;DBMS&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-310" y="570" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-26" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-26" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="-340" y="300" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-27" value="<b style="font-size: 14px;"><font style="font-size: 14px;">NodeJs</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-27" value="<b style="font-size: 14px;"><font style="font-size: 14px;">NodeJs</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;" parent="1" vertex="1">
|
||||
<mxGeometry x="-307.5" y="325" width="57.5" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-28" value="&lt;&lt;server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-28" value="&lt;&lt;server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-310" y="300" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-32" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="JqL7afyQoL-OOYxCKZbi-9" target="JqL7afyQoL-OOYxCKZbi-27">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-32" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" parent="1" source="JqL7afyQoL-OOYxCKZbi-9" target="JqL7afyQoL-OOYxCKZbi-27" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-450" y="370" as="sourcePoint" />
|
||||
<mxPoint x="-400" y="320" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-33" value="HTTP&nbsp;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-470" y="315" width="70" height="30" as="geometry" />
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-33" value="HTTP POST<br><br>JSON" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-466" y="325" width="76" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-35" value="Database Management" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-35" value="Database Management" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1" parent="1" vertex="1">
|
||||
<mxGeometry x="-330.62" y="450" width="100" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-36" value="&lt;&lt;server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-36" value="&lt;&lt;server&gt;&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-310.62" y="420" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-39" value="Uses" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-39" value="Uses" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-288.12" y="545" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-40" value="Js/SQL" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-205" y="316" width="60" height="30" as="geometry" />
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-40" value="Js/SQL<br><br>JSON" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="-205" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-41" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="JqL7afyQoL-OOYxCKZbi-27" target="JqL7afyQoL-OOYxCKZbi-21">
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-41" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="JqL7afyQoL-OOYxCKZbi-27" target="JqL7afyQoL-OOYxCKZbi-21" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-200" y="410" as="sourcePoint" />
|
||||
<mxPoint x="-150" y="360" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="S5-NwbH-4CbKXiQop9ow-4" value="Maneges" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-167.5" y="505" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
|
BIN
docs/documentation/diagrams/assets/.$appDiagramV4.png.bkp
Normal file
BIN
docs/documentation/diagrams/assets/.$appDiagramV4.png.bkp
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
docs/documentation/diagrams/assets/appDiagramV4.png
Normal file
BIN
docs/documentation/diagrams/assets/appDiagramV4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Reference in New Issue
Block a user