Merge remote-tracking branch 'origin/main'

# Conflicts:
#	code/src/Fitbot/app/src/main/java/com/example/fitbot/exercise/ExerciseManager.java
#	code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/activities/FitnessActivity.java
This commit is contained in:
Luca Warmenhoven
2024-06-03 14:27:34 +02:00
15 changed files with 180 additions and 58 deletions

View File

@@ -21,9 +21,9 @@ void Connectivity::connectWiFi(char* ssid, char* pass){
// }
const char* getServerURL = "http://145.92.8.132:443/get-ip";
String ipAddress = "";
char* ipAddress = "";
String Connectivity::fetchIPAddress() {
const char* Connectivity::fetchIPAddress() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
WiFiClient client;
@@ -32,7 +32,7 @@ String Connectivity::fetchIPAddress() {
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
ipAddress = http.getString();
ipAddress = strdup(http.getString().c_str());
}
} else {
Serial.printf("GET request failed, error: %s\n", http.errorToString(httpCode).c_str());

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -1,3 +1,6 @@
const databaseQuery = 'SELECT * FROM `Exercise` ORDER BY RAND() LIMIT 1';
/**
*
* @param {Request} request The incoming request
@@ -8,45 +11,33 @@
function handleIncoming(request, response, app, pool)
{
let query = 'SELECT * FROM Exercise WHERE ExerciseID = ?';
let parameters = [];
if (!request.hasOwnProperty('uid') || typeof request.uid !== 'number')
{
query = 'SELECT * FROM Exercise ORDER BY RAND() LIMIT 1';
} else parameters.push(request.uid);
// Acquire database connection
pool.getConnection()
.then(conn => {
conn.query(query, parameters)
conn.query(
databaseQuery)
.then(rows => {
if (rows.length === 0)
{
response
.status(404)
.send(JSON.stringify({error: 'Exercise not found'}));
.send(JSON.stringify({error: 'No exercises found in the database.'}));
}
else
{
// Send back the data in the right format
let converted = rows.map(row => {
return {
exerciseId: row.ExerciseID,
name: row.Name,
muscleGroup: row.MuscleGroup,
shortDescription: row.ShortDescription,
description: row.Description,
imageUrl: row.ImageURL,
videoUrl: row.VideoURL,
path: row.Path,
duration: row.Duration
};
});
response
.status(200)
.send(JSON.stringify(converted));
let row = rows[0];
response.status(200)
.send(JSON.stringify({
exerciseId: row['ExerciseID'],
name: row['Name'],
muscleGroup: row['MuscleGroup'],
shortDescription: row['ShortDescription'],
description: row['Description'],
imageUrl: row['ImageURL'],
videoUrl: row['VideoURL'],
path: row['Path'],
duration: row['Duration']
}))
}
})
.catch(error => {

View File

@@ -35,13 +35,15 @@
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/red_button_gradient.xml" value="0.346" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_bicepvideo.xml" value="0.22826086956521738" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_end_screen.xml" value="0.4" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml" value="0.4" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml" value="0.1" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_help.xml" value="0.4" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_info_dialog.xml" value="0.264" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_main.xml" value="0.4" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_main_screen.xml" value="0.1" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_power_screen.xml" value="0.1" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_sport_item.xml" value="0.1" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/activity_sport_menu.xml" value="0.1" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/dialog_info.xml" value="0.4" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/header.xml" value="0.264" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/toolbar.xml" value="0.264" />
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/menu/main_menu.xml" value="0.4" />

View File

@@ -1,10 +1,15 @@
package com.example.fitbot.ui.activities;
import android.app.Dialog;
import android.content.Context;
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;
import android.widget.VideoView;
import com.aldebaran.qi.sdk.QiContext;
@@ -59,7 +64,17 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
VideoView videoView = findViewById(R.id.videoView);
playVideo(videoView, this);
NavigationManager.setupButtonNavigation(this, R.id.homeButtonFitness, MainActivity.class);
NavigationManager.setupButtonNavigation(this, R.id.skipButtonFitness, MainActivity.class); //Needs to skip exercises once those are implemented
NavigationManager.hideSystemUI(this);
Button infoButtonFitness = findViewById(R.id.infoButtonFitness);
infoButtonFitness.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showInfoDialog();
}
});
}
@Override
@@ -163,4 +178,24 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
super.onDestroy();
}
private void showInfoDialog() {
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_info);
NavigationManager.hideSystemUI(this);
dialog.getWindow().setDimAmount(0.5f);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCancelable(true);
Button closeButton = dialog.findViewById(R.id.closeButtonDialog);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}

View File

@@ -0,0 +1,5 @@
<vector android:height="48dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="800dp"
android:layout_height="wrap_content"
android:background="@drawable/red_button_gradient"
android:orientation="vertical"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textViewTitleDialog"
style="@style/TextStyleTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="@string/descriptionTitle" />
<Button
android:id="@+id/closeButtonDialog"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:background="@color/transparent"
android:drawableTop="@drawable/ic_baseline_close_48"
android:drawableTint="@color/white" />
</RelativeLayout>
<TextView
android:id="@+id/textViewDialog"
style="@style/TextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="800dp"
android:text="@string/description"
android:layout_marginHorizontal="10dp"
android:layout_marginBottom="10dp"/>
</LinearLayout>

View File

@@ -14,5 +14,6 @@
<color name="invertedBackground">#FFFFFF</color>
<color name="invertedTextColor">#000000</color>
<color name="invertedIconTint">#000000</color>
<color name="transparent">#00000000</color>
</resources>

View File

@@ -26,4 +26,6 @@
<string name="title">Title</string>
<string name="context">ContextContextContext</string>
<string name="description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</string>
<string name="descriptionTitle">Description</string>
</resources>

View File

@@ -1,24 +1,22 @@
const address = 'http://145.92.8.135:3445/';
const data = {
rotationX: 1,
rotationY: .4,
rotationZ: .1,
accelerationX: 1,
accelerationY: 2,
accelerationZ: 4,
deviceId: 1,
type: 'data'
};
for ( let i = 0; i < 10; i++)
const address = 'http://192.168.137.45:3445';
const amount = 10;
for ( let i = 0; i < amount; i++)
{
setTimeout(() => {
console.log("Sending data");
fetch(address, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
body: JSON.stringify({
rotationX: 0,
rotationY: 0,
rotationZ: 0,
accelerationX: Math.PI / amount * i,
accelerationY: 0,
accelerationZ: 0,
type: 'data',
deviceId: 0
})
});
}, i * 1000);
}