Compare commits
40 Commits
53-als-geb
...
53-als-geb
Author | SHA1 | Date | |
---|---|---|---|
|
bead6a5a13 | ||
|
49f97b57dd | ||
|
0153b70578 | ||
|
39f3d4bb1d | ||
|
ba0ae4c6b7 | ||
59d7c4f1ec | |||
|
a4907f00c8 | ||
|
67045ed342 | ||
|
29c5e99017 | ||
180817d073 | |||
4f57b87265 | |||
90487db6f0 | |||
7b1a1f3f2b | |||
83a471ab06 | |||
72ca6bc77b | |||
|
1fea68d90a | ||
|
368067eb8b | ||
|
6e8a66e327 | ||
|
fb63b1364a | ||
|
13fca50d6f | ||
|
7442d1fca4 | ||
|
aa33bf2f12 | ||
|
2fdc8a7189 | ||
|
6b40c5c079 | ||
|
6720b2af3d | ||
|
f9e340a500 | ||
|
cfcbe7d51c | ||
|
3edab82535 | ||
|
3fe90ce547 | ||
|
59c374eb02 | ||
|
866484c85b | ||
|
87e8b725e4 | ||
03b056811d | |||
58f1b14ab6 | |||
ab73c5012b | |||
|
5cab887429 | ||
|
5dbbacd140 | ||
|
0f2f174ea9 | ||
|
f06287d562 | ||
|
c8d90c0992 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1 +1,8 @@
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
/.idea/.gitignore
|
||||
/.idea/dictionaries/lucawarm.xml
|
||||
/.idea/material_theme_project_new.xml
|
||||
/docs/documentation/assets/math-expression-location-calculation.png
|
||||
/.idea/modules.xml
|
||||
/.idea/muupooviixee66.iml
|
||||
/.idea/vcs.xml
|
||||
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/muupooviixee66-3.iml" filepath="$PROJECT_DIR$/.idea/muupooviixee66-3.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
9
.idea/muupooviixee66-3.iml
generated
Normal file
9
.idea/muupooviixee66-3.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
47
.idea/workspace.xml
generated
47
.idea/workspace.xml
generated
@@ -14,6 +14,7 @@
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="00599d5b-7eb5-44da-ad7f-98bf42384c16" name="Changes" comment="Final update onderzoek-formulier.md" />
|
||||
<list default="true" id="00599d5b-7eb5-44da-ad7f-98bf42384c16" name="Changes" comment="Updated onderzoek-voorbeeld.md & motion-tracking-system-analysis.md">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docs/documentation/research-questions/motion-tracking-system-analysis.md" beforeDir="false" afterPath="$PROJECT_DIR$/docs/documentation/research-questions/motion-tracking-system-analysis.md" afterDir="false" />
|
||||
@@ -26,6 +27,7 @@
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[C:\Users\Niels\.android\avd\Pepper_1.9_API_29.avd]" />
|
||||
<component name="ExternalProjectsData">
|
||||
<projectState path="$PROJECT_DIR$">
|
||||
<ProjectState />
|
||||
@@ -73,10 +75,6 @@
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 7
|
||||
}</component>
|
||||
<component name="ProjectId" id="2fE3N2CwEPDo9wBtexBLxU20tCJ" />
|
||||
<component name="ProjectLevelVcsManager">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
@@ -85,6 +83,13 @@
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="RunOnceActivity.cidr.known.project.marker" value="true" />
|
||||
<property name="cidr.known.project.marker" value="true" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/code/src/Fitbot" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
@@ -101,6 +106,13 @@
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="RunOnceActivity.cidr.known.project.marker" value="true" />
|
||||
<property name="cidr.known.project.marker" value="true" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/code/src/Fitbot" />
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/code/src/app/src/main/java/com/fitbot" />
|
||||
@@ -115,16 +127,40 @@
|
||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||
<option name="ALL_USERS" value="false" />
|
||||
<option name="ALWAYS_INSTALL_WITH_PM" value="false" />
|
||||
<option name="CLEAR_APP_STORAGE" value="false" />
|
||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||
<option name="MODE" value="default_activity" />
|
||||
<option name="CLEAR_LOGCAT" value="false" />
|
||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
|
||||
<option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
|
||||
<option name="FORCE_STOP_RUNNING_APP" value="true" />
|
||||
<option name="INSPECTION_WITHOUT_ACTIVITY_RESTART" value="false" />
|
||||
<option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
|
||||
<option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
|
||||
<option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
|
||||
<option name="DEBUGGER_TYPE" value="Java" />
|
||||
<Auto>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Auto>
|
||||
<Hybrid>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Hybrid>
|
||||
<Java />
|
||||
<Native>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Native>
|
||||
<Profilers>
|
||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
||||
@@ -275,6 +311,7 @@
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
<option name="oldMeFiltersMigrated" value="true" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="Changes" />
|
||||
|
3
.vscode/arduino.json
vendored
3
.vscode/arduino.json
vendored
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"port": "COM3",
|
||||
"board": "esp32:esp32:esp32s3"
|
||||
"board": "esp32:esp32:esp32s3",
|
||||
"sketch": "code\\arduino\\Position-tracking\\Position-tracking.ino"
|
||||
}
|
1
.vscode/c_cpp_properties.json
vendored
1
.vscode/c_cpp_properties.json
vendored
@@ -225,7 +225,6 @@
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\qio_qspi\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\cores\\esp32",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\variants\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\libraries\\BLE\\src",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\xtensa-esp32s3-elf\\include\\c++\\8.4.0",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\xtensa-esp32s3-elf\\include\\c++\\8.4.0\\xtensa-esp32s3-elf",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\xtensa-esp32s3-elf\\include\\c++\\8.4.0\\backward",
|
||||
|
12
code/arduino/Position-tracking/Position-tracking.ino
Normal file
12
code/arduino/Position-tracking/Position-tracking.ino
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "PositionSensor.h"
|
||||
|
||||
PositionSensor sensor(15); // Sensor Pin
|
||||
|
||||
void setup() {
|
||||
sensor.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sensor.Measure();
|
||||
delay(1000);
|
||||
}
|
13
code/arduino/Position-tracking/PositionSensor.cpp
Normal file
13
code/arduino/Position-tracking/PositionSensor.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "PositionSensor.h"
|
||||
|
||||
PositionSensor::PositionSensor(int pin) : _pin(pin) {}
|
||||
|
||||
void PositionSensor::begin() {
|
||||
Serial.begin(115200);
|
||||
pinMode(_pin, INPUT);
|
||||
}
|
||||
|
||||
void PositionSensor::Measure() {
|
||||
int value = analogRead(_pin);
|
||||
Serial.println(value);
|
||||
}
|
15
code/arduino/Position-tracking/PositionSensor.h
Normal file
15
code/arduino/Position-tracking/PositionSensor.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef PositionSensor_h
|
||||
#define PositionSensor_h
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
class PositionSensor {
|
||||
public:
|
||||
PositionSensor(int pin);
|
||||
void begin();
|
||||
void Measure();
|
||||
private:
|
||||
int _pin;
|
||||
};
|
||||
|
||||
#endif
|
0
code/arduino/Position-tracking/SendData.cpp
Normal file
0
code/arduino/Position-tracking/SendData.cpp
Normal file
0
code/arduino/Position-tracking/SendData.h
Normal file
0
code/arduino/Position-tracking/SendData.h
Normal file
46
code/arduino/Position-tracking/test/test.ino
Normal file
46
code/arduino/Position-tracking/test/test.ino
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEUtils.h>
|
||||
#include <BLEServer.h>
|
||||
|
||||
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
|
||||
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
|
||||
|
||||
#define LDR 15
|
||||
|
||||
BLECharacteristic *pCharacteristic;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
pinMode(LDR, INPUT);
|
||||
|
||||
Serial.println("Starting BLE work!");
|
||||
|
||||
BLEDevice::init("ESP32-Pepper");
|
||||
BLEServer *pServer = BLEDevice::createServer();
|
||||
BLEService *pService = pServer->createService(SERVICE_UUID);
|
||||
pCharacteristic = pService->createCharacteristic(
|
||||
CHARACTERISTIC_UUID,
|
||||
BLECharacteristic::PROPERTY_READ |
|
||||
BLECharacteristic::PROPERTY_WRITE
|
||||
);
|
||||
|
||||
pCharacteristic->setValue("Hello World");
|
||||
pService->start();
|
||||
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
|
||||
pAdvertising->addServiceUUID(SERVICE_UUID);
|
||||
pAdvertising->setScanResponse(true);
|
||||
pAdvertising->setMinPreferred(0x06);
|
||||
pAdvertising->setMinPreferred(0x12);
|
||||
BLEDevice::startAdvertising();
|
||||
Serial.println("Waiting a client connection to notify...");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int ldrValue = analogRead(LDR);
|
||||
Serial.println(ldrValue);
|
||||
char ldrValueChar[50];
|
||||
sprintf(ldrValueChar, "%d", ldrValue);
|
||||
pCharacteristic->setValue(ldrValueChar);
|
||||
delay(2000);
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEServer.h>
|
||||
|
||||
// Define the service UUID
|
||||
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
|
||||
|
||||
// Define the characteristic UUID
|
||||
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
|
||||
|
||||
void setup() {
|
||||
// Create a BLE server
|
||||
BLEServer *pServer = BLEDevice::createServer();
|
||||
|
||||
// Create a BLE service
|
||||
BLEService *pService = pServer->createService(SERVICE_UUID);
|
||||
|
||||
// Create a BLE characteristic
|
||||
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
|
||||
CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ);
|
||||
|
||||
// Set the characteristic value
|
||||
pCharacteristic->setValue("Hello, Bluetooth!");
|
||||
|
||||
// Start the service
|
||||
pService->start();
|
||||
|
||||
// Start advertising the service
|
||||
pServer->getAdvertising()->start();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Nothing to do here
|
||||
}
|
2
code/src/Fitbot/.gitignore
vendored
2
code/src/Fitbot/.gitignore
vendored
@@ -13,3 +13,5 @@
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
.idea
|
||||
.vscode
|
9
code/src/Fitbot/.idea/misc.xml
generated
9
code/src/Fitbot/.idea/misc.xml
generated
@@ -4,9 +4,18 @@
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="../../../../../../../../layout/custom_preview.xml" value="0.35989583333333336" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/drawable/button_background.xml" value="0.128" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/drawable/rectangle.xml" value="0.128" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/layout/activity_bicepvideo.xml" value="0.2015625" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/layout/activity_end_screen.xml" value="0.18" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/layout/activity_main.xml" value="0.2015625" />
|
||||
<entry key="..\:/Users/31687/muupooviixee66-1/code/src/Fitbot/app/src/main/res/layout/activity_main_screen.xml" value="0.358695652173913" />
|
||||
<entry key="..\:/Users/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/drawable/rectangle.xml" value="0.1665" />
|
||||
<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_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/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.25" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/darkred_button_gradient.xml" value="0.346" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/ic_baseline_home_48.xml" value="0.25" />
|
||||
|
@@ -34,8 +34,13 @@ dependencies {
|
||||
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
|
||||
implementation 'com.android.support:cardview-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
implementation 'com.android.support:support-v4:+'
|
||||
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'
|
||||
|
@@ -21,9 +21,16 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Fitbot" >
|
||||
<activity
|
||||
android:name=".EndScreenActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.activities.FitnessActivity"
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".ui.activities.MainActivity"
|
||||
android:exported="true" >
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
@@ -0,0 +1,24 @@
|
||||
package com.example.fitbot;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.example.fitbot.ui.activities.MainActivity;
|
||||
|
||||
public class EndScreenActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_end_screen);
|
||||
Button homeButton = findViewById(R.id.homeButton);
|
||||
|
||||
homeButton.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(EndScreenActivity.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2008 Nedim Jackman
|
||||
|
||||
This file is part of Wiiboard Simple
|
||||
|
||||
Wiiboard Simple is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Wiiboard Simple is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with Wiiboard Simple. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.example.fitbot.bluetooth;
|
||||
|
||||
/**
|
||||
* In very basic structure, all bluetooth devices have an address that the connection
|
||||
* is associated with.
|
||||
*/
|
||||
public interface BluetoothDevice {
|
||||
|
||||
/**
|
||||
* The fixed address of the device.
|
||||
* Constant throughout the connection of the device.
|
||||
*/
|
||||
public String getBluetoothAddress();
|
||||
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
package com.example.fitbot.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BluetoothManager {
|
||||
|
||||
private BluetoothAdapter bluetoothAdapter;
|
||||
private Context context;
|
||||
|
||||
public BluetoothManager(Context context) {
|
||||
this.context = context;
|
||||
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
public boolean isBluetoothSupported() {
|
||||
return bluetoothAdapter != null;
|
||||
}
|
||||
|
||||
public boolean isBluetoothEnabled() {
|
||||
return bluetoothAdapter.isEnabled();
|
||||
}
|
||||
|
||||
public void startDiscovery() {
|
||||
if (!isBluetoothEnabled()) {
|
||||
Log.e("BluetoothManager", "Bluetooth is not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bluetoothAdapter.isDiscovering()) {
|
||||
bluetoothAdapter.cancelDiscovery();
|
||||
Log.d("BluetoothManager", "Cancelling current discovery process...");
|
||||
}
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BluetoothDevice.ACTION_FOUND);
|
||||
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
|
||||
context.registerReceiver(receiver, filter);
|
||||
|
||||
bluetoothAdapter.startDiscovery();
|
||||
Log.d("BluetoothManager", "Starting discovery process...");
|
||||
}
|
||||
|
||||
public final BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
if (device.getName() != null && device.getName().contains("Nintendo RVL-WBC-01")) {
|
||||
Log.d("BluetoothManager", "Wii Balance Board found: " + device.getName() + " [" + device.getAddress() + "]");
|
||||
connectToDevice(device);
|
||||
}
|
||||
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
|
||||
context.unregisterReceiver(this);
|
||||
Log.d("BluetoothManager", "Discovery finished.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void connectToDevice(BluetoothDevice device) {
|
||||
new Thread(() -> {
|
||||
BluetoothSocket socket = null;
|
||||
final int MAX_RETRIES = 3;
|
||||
final long RETRY_DELAY_MS = 1000;
|
||||
boolean isConnected = false;
|
||||
|
||||
for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
||||
try {
|
||||
UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
||||
socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
bluetoothAdapter.cancelDiscovery();
|
||||
|
||||
byte[] pinBytes = getPinBytes(device.getAddress());
|
||||
try {
|
||||
Method setPinMethod = device.getClass().getDeclaredMethod("setPin", byte[].class);
|
||||
setPinMethod.invoke(device, pinBytes);
|
||||
Log.d("BluetoothManager", "PIN set successfully");
|
||||
} catch (Exception e) {
|
||||
Log.e("BluetoothManager", "Failed to set PIN", e);
|
||||
}
|
||||
|
||||
socket.connect();
|
||||
Log.d("BluetoothManager", "Connected to Wii Balance Board");
|
||||
isConnected = true;
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
Log.e("BluetoothManager", "Connection attempt " + attempt + " failed", e);
|
||||
if (attempt < MAX_RETRIES) {
|
||||
try {
|
||||
Thread.sleep(RETRY_DELAY_MS);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (!isConnected && socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e("BluetoothManager", "Could not close the client socket", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isConnected) {
|
||||
Log.e("BluetoothManager", "All connection attempts failed.");
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private byte[] getPinBytes(String address) {
|
||||
String[] addrParts = address.split(":");
|
||||
byte[] pin = new byte[addrParts.length];
|
||||
for (int i = 0; i < addrParts.length; i++) {
|
||||
pin[i] = (byte) Integer.parseInt(addrParts[addrParts.length - 1 - i], 16);
|
||||
}
|
||||
Log.i("BluetoothManager", "PIN: " + pin);
|
||||
return pin;
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
package com.example.fitbot.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DeviceScanner {
|
||||
private Context context;
|
||||
private static final UUID CORRECT_CHARACTERISTIC_UUID = UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"); // ESP UUID characteristic
|
||||
private BluetoothAdapter bluetoothAdapter;
|
||||
private BluetoothLeScanner bluetoothLeScanner;
|
||||
private boolean scanning;
|
||||
private Handler handler = new Handler();
|
||||
|
||||
// Stops scanning after 10 seconds.
|
||||
private static final long SCAN_PERIOD = 10000;
|
||||
|
||||
public DeviceScanner(Context context) {
|
||||
this.context = context;
|
||||
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
||||
}
|
||||
|
||||
public void scanLeDevice() {
|
||||
if (!scanning) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scanning = false;
|
||||
bluetoothLeScanner.stopScan(leScanCallback);
|
||||
Log.i("DeviceScanner", "Stopped scanning after scan period");
|
||||
}
|
||||
}, SCAN_PERIOD);
|
||||
scanning = true;
|
||||
bluetoothLeScanner.startScan(leScanCallback);
|
||||
Log.i("DeviceScanner", "Started scanning");
|
||||
} else {
|
||||
scanning = false;
|
||||
bluetoothLeScanner.stopScan(leScanCallback);
|
||||
Log.i("DeviceScanner", "Stopped scanning");
|
||||
}
|
||||
}
|
||||
|
||||
// Stops scanning for devices.
|
||||
public void stopScan() {
|
||||
if (scanning) {
|
||||
scanning = false;
|
||||
bluetoothLeScanner.stopScan(leScanCallback);
|
||||
Log.i("DeviceScanner", "Stopped scanning");
|
||||
}
|
||||
}
|
||||
|
||||
// Device scan callback to find the ESP32
|
||||
private ScanCallback leScanCallback =
|
||||
new ScanCallback() {
|
||||
@Override
|
||||
public void onScanResult(int callbackType, ScanResult result) {
|
||||
super.onScanResult(callbackType, result);
|
||||
BluetoothDevice device = result.getDevice();
|
||||
if (device.getName() != null && device.getName().equals("ESP32-Pepper")) {
|
||||
Log.i("DeviceScanner", "Device found: " + device.getName() + " (" + device.getAddress() + ")");
|
||||
connectToDevice(device);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GATT callback to connect to the ESP32 and read the characteristic
|
||||
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
|
||||
@Override
|
||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||
Log.i("DeviceScanner", "Connected to GATT server");
|
||||
gatt.discoverServices();
|
||||
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
Log.i("DeviceScanner", "Disconnected from GATT server");
|
||||
}
|
||||
}
|
||||
|
||||
// Discover services and characteristics
|
||||
@Override
|
||||
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
for (BluetoothGattService service : gatt.getServices()) {
|
||||
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
|
||||
if (isCorrectCharacteristic(characteristic)) {
|
||||
gatt.setCharacteristicNotification(characteristic, true);
|
||||
gatt.readCharacteristic(characteristic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read the characteristic
|
||||
@Override
|
||||
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
Log.i("DeviceScanner", "Characteristic read: " + new String(characteristic.getValue(), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
// Characteristic changed
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||
Log.i("DeviceScanner", "Characteristic changed: " + new String(characteristic.getValue(), StandardCharsets.UTF_8));
|
||||
}
|
||||
};
|
||||
|
||||
// Connect to the ESP32
|
||||
public void connectToDevice(BluetoothDevice device) {
|
||||
BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);
|
||||
}
|
||||
|
||||
// Check if the characteristic has the correct UUID
|
||||
private boolean isCorrectCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
// Log the UUID of the characteristic
|
||||
Log.i("DeviceScanner", String.valueOf(characteristic.getUuid()));
|
||||
|
||||
// Check if the characteristic has the correct UUID
|
||||
if (characteristic.getUuid().equals(CORRECT_CHARACTERISTIC_UUID)) {
|
||||
Log.i("DeviceScanner", "Correct characteristic found");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
package com.example.fitbot.exercise;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
import com.example.fitbot.util.server.IWebSocketHandler;
|
||||
import com.example.fitbot.util.server.WebSocket;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractExercise implements IWebSocketHandler {
|
||||
|
||||
private EMuscleGroup muscleGroup;
|
||||
private GesturePath path;
|
||||
|
||||
// Static fields.
|
||||
private static WebSocket webSocket;
|
||||
private static AbstractExercise currentExercise = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the AbstractExercise class.
|
||||
*
|
||||
* @param muscleGroup The muscle group of the exercise.
|
||||
* @param path The path of the exercise.
|
||||
*/
|
||||
public AbstractExercise(EMuscleGroup muscleGroup, GesturePath path) {
|
||||
this.muscleGroup = muscleGroup;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the exercise.
|
||||
* This method starts a WebSocket server
|
||||
*/
|
||||
public final void startExercise() {
|
||||
|
||||
// Ensure no other exercise is active.
|
||||
if (currentExercise != null && currentExercise != this) {
|
||||
currentExercise.__stopExercise();
|
||||
Log.i("Exercises", "Another exercise was started when another was still running.");
|
||||
}
|
||||
|
||||
// If a WebSocket server is already running, change the event handler to be this class.
|
||||
if (webSocket != null && webSocket.isConnected()) {
|
||||
webSocket.setEventHandler(this);
|
||||
}
|
||||
|
||||
try {
|
||||
webSocket = WebSocket.createServer();
|
||||
Objects.requireNonNull(webSocket, "WebSocket server could not be created.");
|
||||
|
||||
webSocket.startListening();
|
||||
webSocket.setEventHandler(this);
|
||||
currentExercise = this;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for ending this exercise and returning the grade of the performance
|
||||
* of this activity.
|
||||
*/
|
||||
public final double finishExercise() {
|
||||
this.__stopExercise();
|
||||
|
||||
// TODO: Implement grade calculation
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the exercise.
|
||||
* This method stops the WebSocket server.
|
||||
*/
|
||||
private void __stopExercise() {
|
||||
if (webSocket != null && webSocket.isConnected()) {
|
||||
webSocket.stop();
|
||||
webSocket = null;
|
||||
}
|
||||
currentExercise = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current exercise is the current activity.
|
||||
*/
|
||||
public final boolean isCurrentActivity() {
|
||||
return currentExercise == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the muscle group of the exercise.
|
||||
*/
|
||||
public EMuscleGroup getMuscleGroup() {
|
||||
return muscleGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path of the exercise.
|
||||
*/
|
||||
public GesturePath getPath() {
|
||||
return path;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.example.fitbot.exercise;
|
||||
|
||||
public enum EMuscleGroup {
|
||||
// TODO: Implement
|
||||
|
||||
TORSO(0),
|
||||
ARMS(1),
|
||||
LEGS(2),
|
||||
BALANCE(3);
|
||||
|
||||
int muscleGroupIdentifier;
|
||||
|
||||
EMuscleGroup(int identifier) {
|
||||
this.muscleGroupIdentifier = identifier;
|
||||
}
|
||||
|
||||
public int getIdentifier() {
|
||||
return this.muscleGroupIdentifier;
|
||||
}
|
||||
|
||||
public static EMuscleGroup parse(int identifier) {
|
||||
for (EMuscleGroup muscleGroup : EMuscleGroup.values()) {
|
||||
if (muscleGroup.getIdentifier() == identifier) {
|
||||
return muscleGroup;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package com.example.fitbot.exercise;
|
||||
|
||||
|
||||
/**
|
||||
* The ExerciseUser class represents a user of the exercise application.
|
||||
* This contains all necessary information of the current user.
|
||||
*/
|
||||
public class ExerciseUser {
|
||||
|
||||
public float upperArmLength;
|
||||
public float lowerArmLength;
|
||||
public float upperLegLength;
|
||||
public float lowerLegLength;
|
||||
public float height;
|
||||
|
||||
/**
|
||||
* Constructor for the ExerciseUser class.
|
||||
* @param upperArmLength The length of the upper arm.
|
||||
* @param lowerArmLength The length of the lower arm.
|
||||
* @param height The height of the user.
|
||||
* @param upperLegLength The length of the upper leg.
|
||||
* @param lowerLegLength The length of the lower leg.
|
||||
*/
|
||||
public ExerciseUser(float upperArmLength, float lowerArmLength, float height, float upperLegLength, float lowerLegLength) {
|
||||
this.upperArmLength = upperArmLength;
|
||||
this.lowerArmLength = lowerArmLength;
|
||||
this.upperLegLength = upperLegLength;
|
||||
this.lowerLegLength = lowerLegLength;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the ExerciseUser class.
|
||||
* @param height The height of the user.
|
||||
*/
|
||||
public ExerciseUser(float height) {
|
||||
this.height = height;
|
||||
this.upperArmLength = height * 0.2f;
|
||||
this.lowerArmLength = height * 0.2f;
|
||||
this.upperLegLength = height * 0.3f;
|
||||
this.lowerLegLength = height * 0.3f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for the ExerciseUser class.
|
||||
* This sets the default height to 180.0f. (1.80m)
|
||||
*/
|
||||
public ExerciseUser() {
|
||||
this(180.0f);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,113 @@
|
||||
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;
|
||||
|
||||
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();
|
||||
connection.addRequestProperty("Content-Type", contentType);
|
||||
connection.addRequestProperty("Request-Method", method);
|
||||
connection.getOutputStream().write(body.getBytes());
|
||||
connection.connect();
|
||||
InputStream stream = connection.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.example.fitbot.sports;
|
||||
|
||||
public enum ESportType {
|
||||
|
||||
FITNESS("Fitness"),
|
||||
POWER("Krachttrening");
|
||||
|
||||
private final String name;
|
||||
|
||||
ESportType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package com.example.fitbot.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.NavigationView;
|
||||
@@ -11,83 +12,57 @@ import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.fitbot.bluetooth.BluetoothDevice;
|
||||
import com.example.fitbot.wiiboard.WiiBoard;
|
||||
import com.example.fitbot.wiiboard.WiiBoardDiscoverer;
|
||||
import com.example.fitbot.wiiboard.WiiBoardDiscoveryListener;
|
||||
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.bluetooth.DeviceScanner;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private static final int REQUEST_LOCATION_PERMISSION = 1;
|
||||
private WiiBoardDiscoverer wiiBoardDiscoverer;
|
||||
|
||||
//Variables
|
||||
DrawerLayout drawerLayout;
|
||||
NavigationView navigationView;
|
||||
Toolbar toolbar;
|
||||
Button startButton;
|
||||
|
||||
private DeviceScanner deviceScanner;
|
||||
|
||||
@SuppressLint("WrongViewCast")
|
||||
@Override
|
||||
protected void onCreate (Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
setContentView(R.layout.activity_main );
|
||||
|
||||
// Check if the device supports Bluetooth
|
||||
if (BluetoothAdapter.getDefaultAdapter() == null) {
|
||||
Log.i("WiiBoardDiscoverer", "Device doesn't support Bluetooth. Exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Request location permissions for Bluetooth discovery on Android 6.0 and above
|
||||
// Check if we have the necessary permissions, if not, request them
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
|
||||
} else {
|
||||
// Initialize WiiBoardDiscoverer
|
||||
wiiBoardDiscoverer = new WiiBoardDiscoverer(this);
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
|
||||
}
|
||||
|
||||
deviceScanner = new DeviceScanner(this);
|
||||
deviceScanner.scanLeDevice();
|
||||
|
||||
setUpUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_LOCATION_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// Permission granted, initialize WiiBoardDiscoverer
|
||||
wiiBoardDiscoverer = new WiiBoardDiscoverer(this);
|
||||
} else {
|
||||
// Handle the case where the user denies the location permission
|
||||
Log.i("WiiBoardDiscoverer", "Location permission is required for Bluetooth discovery.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (wiiBoardDiscoverer != null) {
|
||||
wiiBoardDiscoverer.startWiiBoardSearch();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (wiiBoardDiscoverer != null) {
|
||||
wiiBoardDiscoverer.stopWiiBoardSearch();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpUi() {
|
||||
/*---Hooks---*/
|
||||
drawerLayout = findViewById(R.id.drawer_layout);
|
||||
navigationView = findViewById(R.id.nav_view);
|
||||
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);
|
||||
});
|
||||
|
||||
/*---Tool Bar---*/
|
||||
// setSupportActionBar(toolbar);
|
||||
|
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
@@ -24,6 +25,8 @@ public class PersonalMotionPreviewElement extends View {
|
||||
private Path referencePath, performingPath;
|
||||
private Paint referencePaint, performingPaint;
|
||||
|
||||
private Paint backgroundColor = new Paint();
|
||||
|
||||
/**
|
||||
* Constants for the preview path projection.
|
||||
*/
|
||||
@@ -42,6 +45,9 @@ public class PersonalMotionPreviewElement extends View {
|
||||
*/
|
||||
public PersonalMotionPreviewElement(Context context, GesturePath path) {
|
||||
super(context);
|
||||
Log.i("PersonalMotionPreviewElement", "Creating new PersonalMotionPreviewElement.");
|
||||
this.backgroundColor = new Paint();
|
||||
this.backgroundColor.setColor(0xFF000000); // Black
|
||||
this.path = path;
|
||||
this.motionProcessor = new MotionProcessor();
|
||||
this.motionProcessor.startListening();
|
||||
@@ -158,6 +164,7 @@ public class PersonalMotionPreviewElement extends View {
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundColor);
|
||||
// Draw the sport preview canvas
|
||||
canvas.drawPath(referencePath, referencePaint);
|
||||
canvas.drawPath(performingPath, performingPaint);
|
||||
|
@@ -10,7 +10,6 @@ public class GesturePath {
|
||||
|
||||
// The vectors that make up the path.
|
||||
private final PathSegment[] segments;
|
||||
private double curvature;
|
||||
|
||||
public GesturePath(Vector3f[] vectors) {
|
||||
this(vectors, 0.0D);
|
||||
@@ -27,7 +26,6 @@ public class GesturePath {
|
||||
if ( vectors.length < 2)
|
||||
throw new IllegalArgumentException("A path must have at least two points.");
|
||||
|
||||
this.curvature = curvature;
|
||||
this.segments = new PathSegment[vectors.length - 1];
|
||||
for ( int i = 0; i < vectors.length - 1; i++)
|
||||
segments[i] = new PathSegment(vectors[i], vectors[i + 1]);
|
||||
@@ -39,7 +37,6 @@ public class GesturePath {
|
||||
*/
|
||||
public GesturePath(PathSegment... segments) {
|
||||
this.segments = segments;
|
||||
this.curvature = 0.0d;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,10 +25,9 @@ public class PathSegment {
|
||||
* depending on the curvature of the curve. If the curvature is unset, or set to 0
|
||||
* then this method will use linear interpolation. Otherwise, it will use a curve.
|
||||
*
|
||||
* @param dst The destination vector to interpolate to.
|
||||
* @param t The interpolation value between 0 and 1.
|
||||
*/
|
||||
public Vector3f interpolate(Vector3f dst, double t) {
|
||||
public Vector3f interpolate(double t) {
|
||||
return new Vector3f(this.start)
|
||||
.lerp(this.end, (float) Math.min(1.0F, Math.max(0.0F, t)));
|
||||
}
|
||||
|
@@ -1,48 +0,0 @@
|
||||
package com.example.fitbot.wiiboard;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class WiiBoard {
|
||||
private static final String TAG = "WiiBoard";
|
||||
|
||||
public static void connectToExtension(String address) {
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
|
||||
BluetoothSocket socket = null;
|
||||
final int maxTries = 3;
|
||||
int currentTry = 0;
|
||||
|
||||
while (currentTry < maxTries) {
|
||||
try {
|
||||
// Use reflection to create a BluetoothSocket without UUID
|
||||
Method m = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
|
||||
socket = (BluetoothSocket) m.invoke(device, 1);
|
||||
|
||||
bluetoothAdapter.cancelDiscovery();
|
||||
socket.connect();
|
||||
|
||||
Log.i(TAG, "Connected to WiiBoard");
|
||||
// Handle your communication here
|
||||
|
||||
return; // Exit the method upon successful connection
|
||||
} catch (Exception e) { // Catching Exception to handle reflection exceptions too
|
||||
Log.e(TAG, "Attempt " + (currentTry + 1) + " failed to connect", e);
|
||||
currentTry++;
|
||||
try {
|
||||
// Wait a bit before retrying
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {
|
||||
Log.e(TAG, "Interrupted while waiting to retry connection", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.e(TAG, "Could not connect to WiiBoard after " + maxTries + " attempts.");
|
||||
}
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
package com.example.fitbot.wiiboard;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.util.Log;
|
||||
|
||||
public class WiiBoardDiscoverer {
|
||||
private BluetoothAdapter bluetoothAdapter;
|
||||
private Context context;
|
||||
private String discoveredAddress;
|
||||
private boolean isSearching;
|
||||
|
||||
private final BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String name = device.getName();
|
||||
if ("Nintendo RVL-WBC-01".equals(name)) {
|
||||
discoveredAddress = device.getAddress();
|
||||
Log.i("WiiBoardDiscoverer", "Discovered " + name + " " + discoveredAddress + ".");
|
||||
isSearching = false;
|
||||
bluetoothAdapter.cancelDiscovery();
|
||||
context.unregisterReceiver(this); // Important to unregister
|
||||
WiiBoard.connectToExtension(discoveredAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public WiiBoardDiscoverer(Context context) {
|
||||
this.context = context;
|
||||
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bluetoothAdapter == null) {
|
||||
Log.i("WiiBoardDiscoverer", "Device doesn't support Bluetooth. Exiting.");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void startWiiBoardSearch() {
|
||||
if (!isSearching && !bluetoothAdapter.isDiscovering()) {
|
||||
isSearching = true;
|
||||
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
|
||||
context.registerReceiver(receiver, filter);
|
||||
bluetoothAdapter.startDiscovery();
|
||||
Log.i("WiiBoardDiscoverer", "WiiBoard Discovery Started");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopWiiBoardSearch() {
|
||||
if (bluetoothAdapter.isDiscovering()) {
|
||||
bluetoothAdapter.cancelDiscovery();
|
||||
}
|
||||
isSearching = false;
|
||||
try {
|
||||
context.unregisterReceiver(receiver);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// This can happen if the receiver was not registered or already unregistered
|
||||
Log.i("WiiBoardDiscoverer", "Receiver was not registered or already unregistered");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package com.example.fitbot.wiiboard;
|
||||
|
||||
/**
|
||||
* Implement this interface to be notified of WiiBoards that are connected to. Register your
|
||||
* listener with an instance of WiiBoardDiscoverer.
|
||||
*/
|
||||
public interface WiiBoardDiscoveryListener {
|
||||
|
||||
/**
|
||||
* Is called by a WiiBoardDiscoverer when a WiiBoard has been found and successfully connected to.
|
||||
*/
|
||||
public void wiiBoardDiscovered(WiiBoard wiiboard);
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#F0E4E4" />
|
||||
<corners android:radius="15dp" />
|
||||
|
||||
</shape>
|
10
code/src/Fitbot/app/src/main/res/drawable/rectangle.xml
Normal file
10
code/src/Fitbot/app/src/main/res/drawable/rectangle.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listview_background_shape">
|
||||
<stroke android:width="2dp" android:color="#ff207d94" />
|
||||
<padding android:left="2dp"
|
||||
android:top="2dp"
|
||||
android:right="2dp"
|
||||
android:bottom="2dp" />
|
||||
<corners android:radius="45dp" />
|
||||
<solid android:color="#F0F0F0" />
|
||||
</shape>
|
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@color/red"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".EndScreenActivity">
|
||||
|
||||
<View
|
||||
android:id="@+id/myRectangleView"
|
||||
android:layout_width="720dp"
|
||||
android:layout_height="270dp"
|
||||
android:layout_marginStart="320dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginEnd="320dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:background="@drawable/rectangle"
|
||||
app:layout_constraintBottom_toTopOf="@+id/homeButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/homeButton"
|
||||
style="@style/ButtonStyle"
|
||||
android:layout_width="278dp"
|
||||
android:layout_height="117dp"
|
||||
android:layout_marginStart="501dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginEnd="501dp"
|
||||
android:layout_marginBottom="50dp"
|
||||
android:text="Home"
|
||||
app:layout_constraintBottom_toTopOf="@+id/continueButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/myRectangleView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/continueButton"
|
||||
style="@style/ButtonStyle"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginStart="500dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginEnd="500dp"
|
||||
android:layout_marginBottom="140dp"
|
||||
android:text="Continue"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/homeButton" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gefeliciteerdText"
|
||||
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_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/myRectangleView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/workoutText"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="u heeft de work out voltooid"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/myRectangleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/myRectangleView" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@@ -1,10 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#232323"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.activities.FitnessActivity"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.example.fitbot.ui.components.PersonalMotionPreviewElement
|
||||
android:id="@+id/personalMotionPreviewElement"
|
||||
android:visibility="visible"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
@@ -9,4 +9,6 @@
|
||||
<string name="start">Start</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="todo">TODO</string>
|
||||
<color name="red">#f22b1d</color>
|
||||
|
||||
</resources>
|
@@ -5,5 +5,24 @@
|
||||
<item name="android:statusBarColor">#00000000</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<style name="ButtonStyle">
|
||||
<item name="android:textSize">24sp</item>
|
||||
<item name="android:textColor">#000000</item>
|
||||
<item name="android:background">@drawable/button_background</item>
|
||||
<item name= "android:textStyle">bold</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
<item name="android:layout_margin">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextStyle">
|
||||
<item name="android:textSize">36sp</item>
|
||||
<item name="android:textColor">#000000</item>
|
||||
<item name= "android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
@@ -7,4 +7,7 @@
|
||||
<item name="colorAccent">@color/teal_200</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
<!-- Style for general buttons -->
|
||||
<!-- Add button styles here, if needed -->
|
||||
</resources>
|
@@ -0,0 +1,37 @@
|
||||
package com.example.fitbot;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
import com.example.fitbot.util.path.PathSegment;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PathSegmentTest {
|
||||
|
||||
@Test
|
||||
public void testPathSegment() {
|
||||
// Test the PathSegment class
|
||||
Vector3f[] vectors = new Vector3f[2];
|
||||
vectors[0] = new Vector3f(0, 0, 0);
|
||||
vectors[1] = new Vector3f(1, 1, 1);
|
||||
GesturePath path = new GesturePath(vectors);
|
||||
PathSegment[] segments = path.getSegments();
|
||||
assertEquals(1, segments.length);
|
||||
assertEquals(new Vector3f(0, 0, 0), segments[0].getStart());
|
||||
assertEquals(new Vector3f(1, 1, 1), segments[0].getEnd());
|
||||
assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segments[0].interpolate(0.5));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_pathSegmentInterpolation() {
|
||||
Vector3f start = new Vector3f(0, 0, 0);
|
||||
Vector3f end = new Vector3f(1, 1, 1);
|
||||
PathSegment segment = new PathSegment(start, end);
|
||||
assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segment.interpolate(0.5));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
# Creating Styles in android
|
||||
|
||||
Styles and themes on Android make it possible for you to separate the details of our app design from the UI structure and behavior, identical to stylesheets in web design. We will use this in our project to maintain a consistent style, so that we won't have to hardcode it to each element. A style is a set of attributes that determine the appearance of a single View. A style can define features like font color, font size, background color, and a lot more.
|
||||
|
||||
To make a style you want to navigate to res/values/styles.xml in this file you can make styles. Fot this example we will make a buttonstyle that we can implement across multiple buttons. To make a style you need to add this code to your style.xml file
|
||||
|
||||
```xml
|
||||
|
||||
<resources>
|
||||
<style name="ButtonStyle">
|
||||
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
```
|
||||
After that, you may add your styling items in the code.
|
||||
|
||||
|
||||
```xml
|
||||
<style name="ButtonStyle">
|
||||
<item name="android:textSize">24sp</item>
|
||||
<item name="android:textColor">#000000</item>
|
||||
<item name="android:background">#F0F0F0</item>
|
||||
<item name= "android:textStyle">bold</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
<item name="android:layout_margin">8dp</item>
|
||||
</style>
|
||||
```
|
||||
If you have done this, return to your activity.xml file and add the style element to your object. You will need to connect your style to the element.
|
||||
```xml
|
||||
<Button
|
||||
android:id="@+id/homeButton"
|
||||
style="@style/ButtonStyle"/>
|
||||
```
|
||||
You can now add this to multiple buttons to keep the same style and avoid copying and pasting the same feature
|
114
docs/documentation/android/javaClasses.md
Normal file
114
docs/documentation/android/javaClasses.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Java class modifiers
|
||||
|
||||
## How are classes build in java?
|
||||
There are a lot of classes with a lot of parameters
|
||||
|
||||
A class always begins with either the public or default or abstract access modifier. Then comes the class name
|
||||
|
||||
Example:
|
||||
```java
|
||||
public class MyClass {
|
||||
//methods and atributes
|
||||
}
|
||||
|
||||
```
|
||||
Then in a class you can have Methods or Atributes where the actual code is.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
0[~] --> a([Access Modifiers]) --> b([class]) --> c([Class name])
|
||||
0 --> b
|
||||
```
|
||||
|
||||
## Constructor
|
||||
A constructor in Java is a special method that is used to initialize objects. The constructor is called when an object of a class is created. It can be used to set initial values for object attributes.
|
||||
|
||||
The constructor Method is the first method that is called when a class is created. It has the same name as the class and no return type. It is automaticly called when a class is created.
|
||||
|
||||
### Methods
|
||||
A method is a block of code which only runs when it is called. You can pass data, known as parameters, into a method. Methods are used to perform certain actions, and they are also known as functions.
|
||||
|
||||
Methods are build like this
|
||||
```mermaid
|
||||
flowchart LR
|
||||
0([~]) --> A([Access Modifiers]) --> B([Method Modifier]) --> C([Return Type]) --> D([Method Name]) --> E([Parameters]) --> F([Method Body])
|
||||
A --> C
|
||||
0 --> C
|
||||
D --> F
|
||||
```
|
||||
|
||||
|
||||
Example:
|
||||
```java
|
||||
public class MyClass {
|
||||
// Method
|
||||
static void myMethod() {
|
||||
// print Hello World!
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
// Main method
|
||||
//access modifier, Method Modifier, return type, method name, parameters, method body
|
||||
public static void main(String[] args) {
|
||||
// Call the method
|
||||
myMethod();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Atributes
|
||||
Attributes are variables within a class. When an object is created from a class, the object will have these attributes.
|
||||
|
||||
Example:
|
||||
```java
|
||||
public class MyClass {
|
||||
int x = 5;
|
||||
}
|
||||
```
|
||||
|
||||
## Classes
|
||||
### Class modifiers
|
||||
|
||||
#### Non-access modifiers
|
||||
| Modifier | Description | | | |
|
||||
|---|---|---|---|---|
|
||||
| final | The class cannot be inherited by other classes (You will learn more about inheritance in the Inheritance chapter) | | | |
|
||||
| abstract | The class cannot be used to create objects (To access an abstract class, it must be inherited from another class. You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters) | | | |
|
||||
||||
|
||||
|
||||
#### Access modifiers
|
||||
| Modifier | Description | | | |
|
||||
|---|---|---|---|---|
|
||||
| public | The code is accessible for all classes | | | |
|
||||
| private | The code is only accessible within the declared class | | | |
|
||||
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
|
||||
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
|
||||
| | | | | |
|
||||
|
||||
|
||||
## Methods and attributes
|
||||
#### non access modifiers
|
||||
| Modifier | Description | | | |
|
||||
|---|---|---|---|---|
|
||||
| final | Attributes and methods cannot be overridden/modified | | | |
|
||||
| static | Attributes and methods belongs to the class, rather than an object. You don't really wanna use this one. | | | |
|
||||
| abstract | Can only be used in an abstract class, and can only be used on methods. The method does not have a body, for example abstract void run();. The body is provided by the subclass (inherited from). You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters | | | |
|
||||
| transient | Attributes and methods are skipped when serializing the object containing them | | | |
|
||||
| synchronized | Methods can only be accessed by one thread at a time | | | |
|
||||
| volatile | The value of an attribute is not cached thread-locally, and is always read from the "main memory" | | | |
|
||||
||||
|
||||
|
||||
#### Access modifiers
|
||||
| Modifier | Description | | | |
|
||||
|---|---|---|---|---|
|
||||
| public | The code is accessible for all classes | | | |
|
||||
| private | The code is only accessible within the declared class | | | |
|
||||
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
|
||||
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
|
||||
| | | | | |
|
||||
|
||||
|
||||
## Sources
|
||||
|
||||
* https://www.w3schools.com/java/java_modifiers.asp explanation of modifiers
|
||||
* https://en.wikipedia.org/wiki/Syntax_diagram For syntax diagram
|
BIN
docs/documentation/diagrams/positionTracking.fzz
Normal file
BIN
docs/documentation/diagrams/positionTracking.fzz
Normal file
Binary file not shown.
@@ -8,7 +8,7 @@
|
||||
#define PIN_IMU_INT_2 D6
|
||||
```
|
||||
## What does the pcb do
|
||||
The pcb on itself is a espd1mini with no sensors or battery. You need to manual solder a battery and sensor of your choice to the pcb.
|
||||
The pcb on itself is a ESP8266 with no sensors or battery. You need to manual solder a battery and sensor of your choice to the pcb.
|
||||
|
||||
## Original usage
|
||||
These pcb's where originally designed for virtual reality fullbody tracking. They are basicly movement trackers that can be used to track the movement of the body. We can also use this really well for our project.
|
||||
|
@@ -3,11 +3,11 @@
|
||||
Which sensor are we gonna use for this project and why?
|
||||
|
||||
|
||||
### What do we wanna measure?
|
||||
### What do we want to measure?
|
||||
|
||||
We wanna measure the movement of the people doing our exercises. We want to know how many times they have done the exercise and how many times they have done it correctly.
|
||||
|
||||
### What sensor are we gonna use?
|
||||
### What sensor are we going to use?
|
||||
To measure these movements we are gonna use gyroscopes. With gyroscopes we can measure the rotation of the body. With some math we can also measure the speed of the rotation. So we know how fast the person is doing the exercise.
|
||||
|
||||
### Which gyroscopes are there?
|
||||
|
@@ -2,25 +2,34 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
For this project we want to design an embedded system that can track a users position. We want to track their current position on the ground and see how they are shifting their weight. This system will be used to track their position to determine if a user is doing the exercises correctly.
|
||||
For this project we want to design an embedded system that can track a users position. We want to track their current position on the ground. This system will be used to track their position to determine if a user is doing the exercises correctly.
|
||||
|
||||
## Objectives
|
||||
|
||||
* Design an embedded system that can track user position.
|
||||
* Develop an algorithm to process the data from the Wii Fit Board and determine the user's position.
|
||||
- Design an embedded system that can track user position.
|
||||
- Develop an algorithm to process the data from the sensor and determine the user's position.
|
||||
- Sync the code to the current task for the user.
|
||||
|
||||
## Research and Analysis
|
||||
|
||||
### Choosing the Wii Fit Board
|
||||
### Choosing the sensor
|
||||
|
||||
For this project we have chosen the Wii Fit Board as our primary sensor. The Wii Fit Board is a balance board that can measure a user's weight and center of balance. It is a low-cost sensor that is easy to interface with a microcontroller. The Wii Fit Board communicates over Bluetooth, which makes it easy to connect to a microcontroller with Bluetooth capabilities.
|
||||
For this project we have chosen LDR's as our primary sensor. The LDR's will be placed on the ground in a board and the user will stand on top of the board. The LDR's will be used to track the user's position. The LDR's will be connected to the esp32s3 microcontroller and the data will be processed to determine the user's position.
|
||||
|
||||
We have chosen this sensor since it's one of the easiest and cheapest solutions to our problem. Other sensors like pressure sensors, accelerometers, and Wii Balance Board are either too expensive, not the most optimal for the task, or hard to integrate with other systems.
|
||||
|
||||
### Alternative Solutions
|
||||
|
||||
There are other sensors that can be used for position tracking, such as pressure sensors or accelerometers. However, these sensors are more expensive and may require additional processing to determine the user's position. The Wii Fit Board provides a simple and cost-effective solution for position tracking.
|
||||
There are other sensors that can be used for position tracking, such as pressure sensors, Wii Balance Board or accelerometers. However, these sensors are either too expensive, not the most optimal for the task or hard to integrate with other systems.
|
||||
|
||||
Example of other sensors that can be used for position tracking:
|
||||
|
||||
Wii Balance Board:
|
||||
- Description: The Wii Balance Board is a balance board that can measure a user's weight and center of balance.
|
||||
- Pros: Low-cost.
|
||||
- Cons: Very hard to intergrate with other systems.
|
||||
- Cost: ~ 20 euros (https://www.amazon.nl/Nintendo-Wii-Balance-Board-Wii/dp/B0013E9HP6)
|
||||
|
||||
Pressure sensors:
|
||||
- Description: Pressure sensors can be used to measure the force applied by the user on the ground. By measuring the pressure distribution, the user's position can be determined.
|
||||
- Pros: High accuracy, can measure force applied by the user.
|
||||
@@ -42,36 +51,31 @@ To be added
|
||||
### Hardware
|
||||
|
||||
The hardware of the system will consist of the following components:
|
||||
- Wii Fit Board: The primary sensor for position tracking.
|
||||
- Pepper: The controller that will process the data from the Wii Fit Board.
|
||||
- LDR: The sensor that will be used to track the user's position based on the light intensity.
|
||||
- ESP32S3: The microcontroller that will process the data from the LDR.
|
||||
- Pepper: The controller that will recieve the processed data from the ESP32S3 and will sync the data to the current task for the user.
|
||||
|
||||
#### Connection diagram
|
||||
|
||||
To be added
|
||||
|
||||
### Software
|
||||
|
||||
The software of the system will consist of the following:
|
||||
- Wiiboard-simple: A library that will be used to transfer data from the Wii Fit Board to pepper.
|
||||
- Position Tracking Algorithm: An algorithm that will process the sensor data and determine the user's position.
|
||||
To be added
|
||||
|
||||
### Integration
|
||||
|
||||
The Wii Fit Board will be connected to Pepper using the Wiiboard-simple library. The library will be used to read the sensor data from the Wii Fit Board and transfer it to Pepper. The position tracking algorithm will process the sensor data and determine the user's position.
|
||||
|
||||
Challenge:
|
||||
- Connecting to the wii fit board. It is not possible to connect directly to the Wii Fit Board, it is necessary to use a library that can interpret the data sent by the Wii Fit Board.
|
||||
- The Wii Fit Balance Board sends data in a specific format. To interpret this data, it's necessary to understand the format and how to convert it to a usable format.
|
||||
- The Wii Fit Balance Board uses Bluetooth 2.0 to communicate. Pepper uses Bluetooth 4.0 this means that there might be compatibility issues/latancy issues.
|
||||
To be added
|
||||
|
||||
## Implementation
|
||||
|
||||
### Prototyping
|
||||
|
||||
To start the implementation of the system, we will create a prototype that will read the sensor data from the Wii Fit Board and send it to your computer. Once we have the data, we will develop the position tracking algorithm to determine the user's position. After that, the algorithm will be integrated with pepper.
|
||||
To be added
|
||||
|
||||
### Testing and Validation
|
||||
|
||||
Tests:
|
||||
- Test the prototype to ensure that it can read the sensor data from the Wii Fit Board.
|
||||
- Test the position tracking algorithm to ensure that it can determine the user's position accurately.
|
||||
- Test the integrated system to ensure that it can track the user's position in real-time.
|
||||
To be added
|
||||
|
||||
## Conclusion
|
||||
|
||||
@@ -79,9 +83,8 @@ To be added
|
||||
|
||||
## References
|
||||
|
||||
[Wiiboard lib](https://code.google.com/archive/p/wiiboard-simple/wikis/Documentation.wiki)
|
||||
[BlueSoil](https://advanti-lab.sb.dfki.de/?page_id=64)
|
||||
[FitScales](https://github.com/paulburton/fitscales)
|
||||
[WiiRemoteJ](https://github.com/micromu/WiiRemoteJ)
|
||||
[Wiibrew Wiimote](https://wiibrew.org/wiki/Wiimote)
|
||||
[Wiibrew Balance Board](https://wiibrew.org/wiki/Wii_Balance_Board)
|
||||
[Bluetooth Discovery](https://developer.android.com/develop/connectivity/bluetooth/find-bluetooth-devices)
|
||||
|
||||
## Appendices
|
||||
|
||||
To be added
|
@@ -0,0 +1,62 @@
|
||||
# SKill ontwikkelplan (Persoonlijk leiderschap)
|
||||
|
||||
## Inhoudsopgave
|
||||
|
||||
- [Inleiding](#inleiding)
|
||||
- [Reflectie](#reflectie)
|
||||
* [Blok 1](#blok-1)
|
||||
* [Blok 2](#blok-2)
|
||||
* [Blok 3](#blok-3)
|
||||
- [Conclusie](#conclusie)
|
||||
|
||||
## Inleiding
|
||||
|
||||
In dit document zal ik een skill ontwikkelplan schrijven voor mijn persoonlijk leiderschap. Dit plan zal bestaan uit een reflectie van de afgelopen blokken, mijn sterke en zwakke punten en mijn smart leerdoelen voor de komende blokken.
|
||||
|
||||
## Reflectie
|
||||
|
||||
### Blok 1
|
||||
|
||||
In het eerste blok heb ik op veel verschillende vlakken geleerd wat mijn sterke en zwakke punten zijn. Groot en deels van de eerste periode in blok 1 heb ik gespendeerd aan mezelf leren kennen binnen de opleiding. Het werken binnen een nieuwe omgeving en met nieuwe mensen was voor mij goed te doen. Ik heb de leeromgeving snel leren kennen en heb geen moeite gehad met het communiceren met mijn medestudenten en docenten.
|
||||
|
||||
Als ik een aantal sterke en zwakke punten moet noemen van blok 1 dan zijn dat:
|
||||
|
||||
Sterke punten:
|
||||
- Goed kunnen communiceren
|
||||
- Snel kunnen schakelen tussen verschillende taken
|
||||
- Snelle ontwikkeling in nieuwe omgevingen
|
||||
- Documenteren van het werk
|
||||
- Voorbereiden van presentaties
|
||||
- Het beste uit mezelf halen
|
||||
|
||||
Zwakke punten:
|
||||
- Meer gebruik maken van coding conventions
|
||||
- Het noteren en verwerken van feedback
|
||||
|
||||
Ik heb in blok 1 enorm veel kunnen leren en heb echt het meeste uit mezelf kunnen halen. Ik ben erg tevreden met de resultaten die ik heb behaald en ben blij met de manier waarop ik mezelf heb kunnen ontwikkelen.
|
||||
|
||||
### Blok 2
|
||||
|
||||
Niet alles op mij nemen en meer vertrouwen hebben in anderen
|
||||
|
||||
### Blok 3
|
||||
|
||||
eerder aan de bel trekken wanneer het team niet goed functioneert
|
||||
|
||||
## Sterke en zwakke punten (Profesional skills)
|
||||
|
||||
## Smart leerdoelen
|
||||
|
||||
## Conclusie
|
||||
|
||||
|
||||
## Profesional skills
|
||||
|
||||
https://www.hva.nl/binaries/content/assets/serviceplein-a-z/media-creatie-en-informatie/hbo-ict/competenties/professional-skills-hbo-ict-2023-2024.pdf
|
||||
|
||||
De vier profecional skills:
|
||||
|
||||
- Toekomstgericht organiseren
|
||||
- Onderzoekend probleemoplossen
|
||||
- Persoonlijk leiderschap
|
||||
- Doelgericht interacteren
|
18
docs/personalDocs/Sam/Hoofd-deelvragen.md
Normal file
18
docs/personalDocs/Sam/Hoofd-deelvragen.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Hoofd en deelvragen met bronnen
|
||||
|
||||
## Hoofdvraag
|
||||
Hoe beïnvloedt de opkomst van robots in de ouderenzorg de kwaliteit van leven en menselijke interactie van ouderen
|
||||
|
||||
## Deelvragen
|
||||
1. Wat zijn de voor en nadelen van robots in de ouderenzorg?
|
||||
2. Wat zijn de verschillen in communicatie tussen mens en robot?
|
||||
3. Hoe voelen ouderen zich bij de vervanging van menselijke communicatie met robots?
|
||||
|
||||
## Bronnen
|
||||
* [Socially Assistive Robots in Elderly Care: A Systematic Review into Effects and Effectiveness](https://www.sciencedirect.com/science/article/abs/pii/S1525861010003476)
|
||||
* [Socially Assistive Robots in Elderly Care: A Mixed-Method Systematic Literature Review](https://www.tandfonline.com/doi/abs/10.1080/10447318.2013.873278)
|
||||
* [Scoping review on the use of socially assistive robot technology in elderly care](https://bmjopen.bmj.com/content/8/2/e018815.abstract)
|
||||
* [A critique of robotics in health care](https://link.springer.com/article/10.1007/s00146-021-01206-z)
|
||||
* [The use of care robots in aged care: A systematic review of argument-based ethics literature](https://www.sciencedirect.com/science/article/pii/S0167494317302790)
|
||||
* [Significant challenges when introducing care robots in Swedish elder care](https://www.tandfonline.com/doi/abs/10.1080/17483107.2020.1773549)
|
||||
* [Ethical challenges in the use of social service robots for elderly people](https://link.springer.com/article/10.1007/s00391-016-1066-5)
|
Reference in New Issue
Block a user