Compare commits
197 Commits
51-als-geb
...
59-als-stu
Author | SHA1 | Date | |
---|---|---|---|
|
5753f7047d | ||
|
7b72554110 | ||
|
59c906918e | ||
|
7efdf3579e | ||
|
447ef3a6af | ||
|
426725a632 | ||
|
4b46738bf0 | ||
|
34dc294d06 | ||
|
2426e7b2e2 | ||
|
6ffbb503c9 | ||
|
bd9ace61e9 | ||
|
60a45fd510 | ||
|
a6977b057c | ||
7e60d5e5e6 | |||
9ad44897ff | |||
0441133744 | |||
c3329a4c52 | |||
|
4c8c9d9f32 | ||
|
447a021b10 | ||
49eb09b105 | |||
ea9a35030b | |||
|
940202d9f4 | ||
|
4983162ac9 | ||
|
95ed46d9ac | ||
|
d6fc5098dd | ||
|
b8e3e89bb2 | ||
|
c362a41f06 | ||
|
bd74b0b5aa | ||
|
d080f0af8d | ||
|
e4ee419e2d | ||
|
58c80ed60c | ||
|
f1570aaea9 | ||
1a56a05409 | |||
cdd8ac9d49 | |||
|
3d01749aa2 | ||
004d216767 | |||
|
5789f4c0dd | ||
|
5a226dd56b | ||
6961801a67 | |||
|
3c0e07336d | ||
48848de44d | |||
|
c527289c68 | ||
83b233e275 | |||
|
80ef0ac99e | ||
|
565d19ec00 | ||
|
62e1320b3c | ||
|
31135d1aa7 | ||
|
4c9a256d6c | ||
bcfc622c90 | |||
9397028c1b | |||
|
d9c05b2975 | ||
|
8c1e4332aa | ||
|
eb6ffcf4c8 | ||
|
976d5b1ef1 | ||
|
20906379d3 | ||
|
1b955baf6b | ||
df8a7a6395 | |||
f66f167812 | |||
1a086a9f57 | |||
2be0efc37e | |||
|
fcb5c7f61b | ||
|
c3cf6e3cf9 | ||
|
d1e0c5b08e | ||
|
29944bce57 | ||
|
caa7599518 | ||
|
652d7c501d | ||
|
b85219d013 | ||
|
774329699a | ||
|
7090bccdb8 | ||
|
4a53ea1420 | ||
fc47353e98 | |||
74d6cda049 | |||
ebd6ae7a12 | |||
|
d7e22dac6e | ||
|
8d5cecce27 | ||
|
ff5d1ed31f | ||
|
8b02096a98 | ||
|
d69701b60d | ||
|
a62b46fcf9 | ||
|
856f0af4b2 | ||
|
5462a6fbcc | ||
dd91639fb2 | |||
02c2cff330 | |||
1fb1d5d02d | |||
82731ee176 | |||
|
04bdf656f4 | ||
|
38e70e3b53 | ||
|
a8e7f6d8b8 | ||
|
f96d6ec394 | ||
|
f5900bf50e | ||
|
04054c862b | ||
3ee81d0e48 | |||
|
cb53000eb3 | ||
fdfb216617 | |||
1a62421c90 | |||
|
25f9f098b0 | ||
|
9795ccb490 | ||
|
8cc571bb3b | ||
|
58f8ff0054 | ||
b4a69ed975 | |||
869164b2d6 | |||
73f563249e | |||
3f6f61fb27 | |||
71871661ca | |||
062a793552 | |||
|
372beceeae | ||
|
b0caed783f | ||
9925fcd637 | |||
40cf9f37fc | |||
|
981b4670e3 | ||
|
390bd3c667 | ||
6d79b0f762 | |||
|
60747d07c5 | ||
|
60fa1cec2c | ||
|
54df52736f | ||
|
bc8763927b | ||
|
5552865fd2 | ||
|
bcf394ef29 | ||
|
fdd67d3e7e | ||
|
4a904be8f0 | ||
|
904e4e98ed | ||
|
f72879d66e | ||
|
7064fa3b97 | ||
|
37ed64cd50 | ||
|
53d5e48b9b | ||
|
ccaf302558 | ||
|
64412a849a | ||
|
5432b0656e | ||
|
03c14d12eb | ||
|
3826adb891 | ||
f97686aa74 | |||
cb3c4ca99f | |||
d1f5f76eea | |||
851541923c | |||
|
bbe3a8127c | ||
|
5d966ea3b9 | ||
f288535c44 | |||
183d5b826b | |||
|
fc06974af1 | ||
|
831fd06489 | ||
|
9f87fb5e6f | ||
|
ab82bdce43 | ||
|
1edaf096b2 | ||
|
af596ea67c | ||
|
d08e8dd50f | ||
|
f50f332664 | ||
8e92cbee7d | |||
|
d718046402 | ||
bad3346475 | |||
|
e00b15480c | ||
|
a854c9b5e1 | ||
|
ba0ae4c6b7 | ||
|
0bdd1664dc | ||
59d7c4f1ec | |||
|
c398f8ff70 | ||
|
3e791f8ac0 | ||
|
67045ed342 | ||
|
29c5e99017 | ||
|
a901c0f205 | ||
|
14f46775dd | ||
|
536c8c75af | ||
180817d073 | |||
4f57b87265 | |||
90487db6f0 | |||
7b1a1f3f2b | |||
|
f87e4e5309 | ||
83a471ab06 | |||
72ca6bc77b | |||
|
a62c4e1b77 | ||
|
1fea68d90a | ||
|
368067eb8b | ||
|
d0ed34ec95 | ||
|
60bdf860d3 | ||
|
6e8a66e327 | ||
|
fb63b1364a | ||
|
13fca50d6f | ||
|
7442d1fca4 | ||
|
aa33bf2f12 | ||
|
2fdc8a7189 | ||
|
6b40c5c079 | ||
|
6720b2af3d | ||
|
f9e340a500 | ||
|
cfcbe7d51c | ||
|
7dc0c7bc72 | ||
|
3edab82535 | ||
|
031d766205 | ||
|
3fe90ce547 | ||
|
59c374eb02 | ||
|
866484c85b | ||
|
87e8b725e4 | ||
|
54cf012288 | ||
|
01498b5643 | ||
|
5cab887429 | ||
|
5dbbacd140 | ||
|
0f2f174ea9 | ||
|
f06287d562 | ||
|
c8d90c0992 |
10
.gitignore
vendored
@@ -1 +1,9 @@
|
||||
.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
|
||||
/node_modules/
|
||||
|
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
@@ -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
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
160
.idea/workspace.xml
generated
@@ -14,9 +14,10 @@
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="00599d5b-7eb5-44da-ad7f-98bf42384c16" name="Changes" comment="Updated onderzoek-voorbeeld.md & motion-tracking-system-analysis.md">
|
||||
<list default="true" id="00599d5b-7eb5-44da-ad7f-98bf42384c16" name="Changes" comment="Crack butt">
|
||||
<change afterPath="$PROJECT_DIR$/code/web/pepper_data_test.js" afterDir="false" />
|
||||
<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" />
|
||||
<change beforePath="$PROJECT_DIR$/code/web/incoming_request_handlers.js" beforeDir="false" afterPath="$PROJECT_DIR$/code/web/incoming_request_handlers.js" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -48,6 +49,8 @@
|
||||
<list>
|
||||
<option value="Interface" />
|
||||
<option value="Class" />
|
||||
<option value="package.json" />
|
||||
<option value="JavaScript File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@@ -74,8 +77,7 @@
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 7
|
||||
"associatedIndex": 5
|
||||
}</component>
|
||||
<component name="ProjectId" id="2fE3N2CwEPDo9wBtexBLxU20tCJ" />
|
||||
<component name="ProjectLevelVcsManager">
|
||||
@@ -87,17 +89,15 @@
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"Node.js.pepper_data_test.js.executor": "Run",
|
||||
"git-widget-placeholder": "main",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "/Users/lucawarm/Jetbrains/Android Studio/muupooviixee66",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"settings.editor.selected.configurable": "preferences.lookFeel",
|
||||
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
@@ -106,7 +106,7 @@
|
||||
<recent name="$PROJECT_DIR$/code/src/app/src/main/java/com/fitbot" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<component name="RunManager" selected="Node.js.pepper_data_test.js">
|
||||
<configuration name="Fitbot" type="AndroidRunConfigurationType" factoryName="Android App">
|
||||
<option name="DEPLOY" value="true" />
|
||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
|
||||
@@ -115,16 +115,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" />
|
||||
@@ -139,6 +163,14 @@
|
||||
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="pepper_data_test.js" type="NodeJSConfigurationType" temporary="true" nameIsGenerated="true" path-to-js-file="$PROJECT_DIR$/code/web/pepper_data_test.js" working-dir="$PROJECT_DIR$/code/web">
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Node.js.pepper_data_test.js" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
@@ -166,6 +198,19 @@
|
||||
<workItem from="1715765990621" duration="8538000" />
|
||||
<workItem from="1715777647522" duration="725000" />
|
||||
<workItem from="1715779408605" duration="3840000" />
|
||||
<workItem from="1715957538891" duration="2000" />
|
||||
<workItem from="1716126955744" duration="1102000" />
|
||||
<workItem from="1716286107331" duration="6057000" />
|
||||
<workItem from="1716308427931" duration="28000" />
|
||||
<workItem from="1716318640952" duration="7000" />
|
||||
<workItem from="1716363591734" duration="658000" />
|
||||
<workItem from="1716538507910" duration="2194000" />
|
||||
<workItem from="1716547378856" duration="243000" />
|
||||
<workItem from="1716648462646" duration="8555000" />
|
||||
<workItem from="1716674767699" duration="21000" />
|
||||
<workItem from="1716889548355" duration="3475000" />
|
||||
<workItem from="1716904079045" duration="2259000" />
|
||||
<workItem from="1716977405893" duration="336000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="Changes">
|
||||
<created>1713528225837</created>
|
||||
@@ -259,7 +304,87 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1715780873394</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="13" />
|
||||
<task id="LOCAL-00013" summary="Merge">
|
||||
<option name="closed" value="true" />
|
||||
<created>1715951036170</created>
|
||||
<option name="number" value="00013" />
|
||||
<option name="presentableId" value="LOCAL-00013" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1715951036170</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00014" summary="nonsense">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716363685668</created>
|
||||
<option name="number" value="00014" />
|
||||
<option name="presentableId" value="LOCAL-00014" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716363685669</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00015" summary="Added Skills Ontwikkelings Plan.docx">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716363757016</created>
|
||||
<option name="number" value="00015" />
|
||||
<option name="presentableId" value="LOCAL-00015" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716363757016</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00016" summary="Added NodeJS Server files">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716540796495</created>
|
||||
<option name="number" value="00016" />
|
||||
<option name="presentableId" value="LOCAL-00016" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716540796495</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00017" summary="killed my brain doing literature">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716658275320</created>
|
||||
<option name="number" value="00017" />
|
||||
<option name="presentableId" value="LOCAL-00017" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716658275320</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00018" summary="updated gay">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716658499589</created>
|
||||
<option name="number" value="00018" />
|
||||
<option name="presentableId" value="LOCAL-00018" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716658499589</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00019" summary="Commit crack cocaine">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716889664199</created>
|
||||
<option name="number" value="00019" />
|
||||
<option name="presentableId" value="LOCAL-00019" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716889664199</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00020" summary="Commit war crimes in formal Yugoslavia">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716890009616</created>
|
||||
<option name="number" value="00020" />
|
||||
<option name="presentableId" value="LOCAL-00020" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716890009616</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00021" summary="Crack butt">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716890828736</created>
|
||||
<option name="number" value="00021" />
|
||||
<option name="presentableId" value="LOCAL-00021" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716890828736</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00022" summary="Crack butt">
|
||||
<option name="closed" value="true" />
|
||||
<created>1716891155110</created>
|
||||
<option name="number" value="00022" />
|
||||
<option name="presentableId" value="LOCAL-00022" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1716891155110</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="23" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -290,6 +415,15 @@
|
||||
<MESSAGE value="Renamed files, added motion-tracking-system-analysis.md" />
|
||||
<MESSAGE value="Updated onderzoek-voorbeeld.md and motion-tracking-system-analysis.md" />
|
||||
<MESSAGE value="Updated onderzoek-voorbeeld.md & motion-tracking-system-analysis.md" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Updated onderzoek-voorbeeld.md & motion-tracking-system-analysis.md" />
|
||||
<MESSAGE value="Merge" />
|
||||
<MESSAGE value="nonsense" />
|
||||
<MESSAGE value="Added Skills Ontwikkelings Plan.docx" />
|
||||
<MESSAGE value="Added NodeJS Server files" />
|
||||
<MESSAGE value="killed my brain doing literature" />
|
||||
<MESSAGE value="updated gay" />
|
||||
<MESSAGE value="Commit crack cocaine" />
|
||||
<MESSAGE value="Commit war crimes in formal Yugoslavia" />
|
||||
<MESSAGE value="Crack butt" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Crack butt" />
|
||||
</component>
|
||||
</project>
|
4
.vscode/arduino.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"port": "COM3",
|
||||
"board": "esp32:esp32:esp32s3"
|
||||
}
|
593
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,593 @@
|
||||
{
|
||||
"version": 4,
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Arduino",
|
||||
"compilerPath": "C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\bin\\xtensa-esp32s3-elf-g++",
|
||||
"compilerArgs": [
|
||||
"-mlongcalls",
|
||||
"-ffunction-sections",
|
||||
"-fdata-sections",
|
||||
"-Wno-error=unused-function",
|
||||
"-Wno-error=unused-variable",
|
||||
"-Wno-error=deprecated-declarations",
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-sign-compare",
|
||||
"-freorder-blocks",
|
||||
"-Wwrite-strings",
|
||||
"-fstack-protector",
|
||||
"-fstrict-volatile-bitfields",
|
||||
"-Wno-error=unused-but-set-variable",
|
||||
"-fno-jump-tables",
|
||||
"-fno-tree-switch-conversion",
|
||||
"-std=gnu++11",
|
||||
"-fexceptions",
|
||||
"-fno-rtti"
|
||||
],
|
||||
"intelliSenseMode": "gcc-x64",
|
||||
"includePath": [
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\newlib\\platform_include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freertos\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freertos\\include\\esp_additions\\freertos",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freertos\\port\\xtensa\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freertos\\include\\esp_additions",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include\\soc",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\include\\soc\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\port\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hw_support\\port\\esp32s3\\private_include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\heap\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\log\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\lwip\\include\\apps",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\lwip\\include\\apps\\sntp",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\lwip\\lwip\\src\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\lwip\\port\\esp32\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\lwip\\port\\esp32\\include\\arch",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\soc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\soc\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\soc\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\hal\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\hal\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\hal\\platform_port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_rom\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_rom\\include\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_rom\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_system\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_system\\port\\soc",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_system\\port\\public_compat",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\xtensa\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\xtensa\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\driver\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\driver\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_pm\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_ringbuf\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\efuse\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\efuse\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\vfs\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_wifi\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_event\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_netif\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_eth\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\tcpip_adapter\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_phy\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_phy\\esp32s3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_ipc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\app_trace\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_timer\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\mbedtls\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\mbedtls\\mbedtls\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\mbedtls\\esp_crt_bundle\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\app_update\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\spi_flash\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bootloader_support\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\nvs_flash\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\pthread\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\xtensa",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_gdbstub\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espcoredump\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espcoredump\\include\\port\\xtensa",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\wpa_supplicant\\esp_supplicant\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\ieee802154\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\console",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\asio\\asio\\asio\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\asio\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\common\\osi\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\include\\esp32c3\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\common\\api\\include\\api",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\common\\btc\\profile\\esp\\blufi\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\common\\btc\\profile\\esp\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\host\\bluedroid\\api\\include\\api",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_common\\tinycrypt\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_core\\storage",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\btc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\client\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\mesh_models\\server\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api\\core\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api\\models\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\bt\\esp_ble_mesh\\api",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\cbor\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\unity\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\unity\\unity\\src",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\cmock\\CMock\\src",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\coap\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\coap\\libcoap\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\nghttp\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\nghttp\\nghttp2\\lib\\includes",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-tls",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-tls\\esp-tls-crypto",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_adc_cal\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_hid\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\tcp_transport\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_http_client\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_http_server\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_https_ota\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_https_server\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_lcd\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_lcd\\interface",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\protobuf-c\\protobuf-c",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\common",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\security",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\protocomm\\include\\transports",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\mdns\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_local_ctrl\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\sdmmc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_serial_slave_link\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_websocket_client\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\expat\\expat\\expat\\lib",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\expat\\port\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\wear_levelling\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\fatfs\\diskio",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\fatfs\\vfs",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\fatfs\\src",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freemodbus\\freemodbus\\common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\idf_test\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\idf_test\\include\\esp32s3",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\jsmn\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\json\\cJSON",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\libsodium\\libsodium\\src\\libsodium\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\libsodium\\port_include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\mqtt\\esp-mqtt\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\openssl\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\perfmon\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\spiffs\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\usb\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\ulp\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\wifi_provisioning\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\rmaker_common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_diagnostics\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\rtc_store\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_insights\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\json_parser\\upstream\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\json_parser\\upstream",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\json_generator\\upstream",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_schedule\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp_secure_cert_mgr\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_rainmaker\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\gpio_button\\button\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\qrcode\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\ws2812_led",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\freertos\\include\\freertos",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\arduino_tinyusb\\tinyusb\\src",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\arduino_tinyusb\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp_littlefs\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\tool",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\typedef",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\image",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\math",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\nn",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\layer",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\detect",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp-dl\\include\\model_zoo",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp32-camera\\driver\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\esp32-camera\\conversions\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\dotprod\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\support\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\support\\mem\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\hann\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman_harris\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\blackman_nuttall\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\nuttall\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\windows\\flat_top\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\iir\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\fir\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\add\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\sub\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\mul\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\addc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\mulc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\math\\sqrt\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mul\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\add\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\addc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mulc\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\sub\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\fft\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\dct\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\conv\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\common\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\matrix\\mul\\test\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\kalman\\ekf\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\espressif__esp-dsp\\modules\\kalman\\ekf_imu13states\\include",
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\tools\\sdk\\esp32s3\\include\\fb_gfx\\include",
|
||||
"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",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\lib\\gcc\\xtensa-esp32s3-elf\\8.4.0\\include",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\lib\\gcc\\xtensa-esp32s3-elf\\8.4.0\\include-fixed",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\xtensa-esp32s3-elf\\sys-include",
|
||||
"c:\\users\\sebas\\appdata\\local\\arduino15\\packages\\esp32\\tools\\xtensa-esp32s3-elf-gcc\\esp-2021r2-patch5-8.4.0\\xtensa-esp32s3-elf\\include"
|
||||
],
|
||||
"forcedInclude": [
|
||||
"C:\\Users\\sebas\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.16\\cores\\esp32\\Arduino.h"
|
||||
],
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"defines": [
|
||||
"HAVE_CONFIG_H",
|
||||
"MBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"",
|
||||
"UNITY_INCLUDE_CONFIG_H",
|
||||
"WITH_POSIX",
|
||||
"_GNU_SOURCE",
|
||||
"IDF_VER=\"v4.4.7-dirty\"",
|
||||
"ESP_PLATFORM",
|
||||
"_POSIX_READER_WRITER_LOCKS",
|
||||
"F_CPU=240000000L",
|
||||
"ARDUINO=10607",
|
||||
"ARDUINO_ESP32S3_DEV",
|
||||
"ARDUINO_ARCH_ESP32",
|
||||
"ARDUINO_BOARD=\"ESP32S3_DEV\"",
|
||||
"ARDUINO_VARIANT=\"esp32s3\"",
|
||||
"ARDUINO_PARTITION_default",
|
||||
"ESP32",
|
||||
"CORE_DEBUG_LEVEL=0",
|
||||
"ARDUINO_RUNNING_CORE=1",
|
||||
"ARDUINO_EVENT_RUNNING_CORE=1",
|
||||
"ARDUINO_USB_MODE=1",
|
||||
"ARDUINO_USB_CDC_ON_BOOT=0",
|
||||
"ARDUINO_USB_MSC_ON_BOOT=0",
|
||||
"ARDUINO_USB_DFU_ON_BOOT=0",
|
||||
"__DBL_MIN_EXP__=(-1021)",
|
||||
"__FLT32X_MAX_EXP__=1024",
|
||||
"__cpp_attributes=200809",
|
||||
"__UINT_LEAST16_MAX__=0xffff",
|
||||
"__ATOMIC_ACQUIRE=2",
|
||||
"__FLT_MIN__=1.1754943508222875e-38F",
|
||||
"__GCC_IEC_559_COMPLEX=0",
|
||||
"__cpp_aggregate_nsdmi=201304",
|
||||
"__UINT_LEAST8_TYPE__=unsigned char",
|
||||
"__INTMAX_C(c)=c ## LL",
|
||||
"__CHAR_BIT__=8",
|
||||
"__UINT8_MAX__=0xff",
|
||||
"__WINT_MAX__=0xffffffffU",
|
||||
"__FLT32_MIN_EXP__=(-125)",
|
||||
"__cpp_static_assert=200410",
|
||||
"__ORDER_LITTLE_ENDIAN__=1234",
|
||||
"__SIZE_MAX__=0xffffffffU",
|
||||
"__WCHAR_MAX__=0xffff",
|
||||
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1",
|
||||
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1",
|
||||
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1",
|
||||
"__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
|
||||
"__GCC_ATOMIC_CHAR_LOCK_FREE=2",
|
||||
"__GCC_IEC_559=0",
|
||||
"__FLT32X_DECIMAL_DIG__=17",
|
||||
"__FLT_EVAL_METHOD__=0",
|
||||
"__cpp_binary_literals=201304",
|
||||
"__FLT64_DECIMAL_DIG__=17",
|
||||
"__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2",
|
||||
"__cpp_variadic_templates=200704",
|
||||
"__UINT_FAST64_MAX__=0xffffffffffffffffULL",
|
||||
"__SIG_ATOMIC_TYPE__=int",
|
||||
"__DBL_MIN_10_EXP__=(-307)",
|
||||
"__FINITE_MATH_ONLY__=0",
|
||||
"__cpp_variable_templates=201304",
|
||||
"__GNUC_PATCHLEVEL__=0",
|
||||
"__FLT32_HAS_DENORM__=1",
|
||||
"__UINT_FAST8_MAX__=0xffffffffU",
|
||||
"__has_include(STR)=__has_include__(STR)",
|
||||
"__DEC64_MAX_EXP__=385",
|
||||
"__INT8_C(c)=c",
|
||||
"__INT_LEAST8_WIDTH__=8",
|
||||
"__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
|
||||
"__SHRT_MAX__=0x7fff",
|
||||
"__LDBL_MAX__=1.7976931348623157e+308L",
|
||||
"__UINT_LEAST8_MAX__=0xff",
|
||||
"__GCC_ATOMIC_BOOL_LOCK_FREE=2",
|
||||
"__UINTMAX_TYPE__=long long unsigned int",
|
||||
"__DEC32_EPSILON__=1E-6DF",
|
||||
"__FLT_EVAL_METHOD_TS_18661_3__=0",
|
||||
"__CHAR_UNSIGNED__=1",
|
||||
"__UINT32_MAX__=0xffffffffU",
|
||||
"__GXX_EXPERIMENTAL_CXX0X__=1",
|
||||
"__LDBL_MAX_EXP__=1024",
|
||||
"__WINT_MIN__=0U",
|
||||
"__INT_LEAST16_WIDTH__=16",
|
||||
"__SCHAR_MAX__=0x7f",
|
||||
"__WCHAR_MIN__=0",
|
||||
"__INT64_C(c)=c ## LL",
|
||||
"__DBL_DIG__=15",
|
||||
"__GCC_ATOMIC_POINTER_LOCK_FREE=2",
|
||||
"__SIZEOF_INT__=4",
|
||||
"__SIZEOF_POINTER__=4",
|
||||
"__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2",
|
||||
"__USER_LABEL_PREFIX__",
|
||||
"__STDC_HOSTED__=1",
|
||||
"__LDBL_HAS_INFINITY__=1",
|
||||
"__XTENSA_EL__=1",
|
||||
"__FLT32_DIG__=6",
|
||||
"__FLT_EPSILON__=1.1920928955078125e-7F",
|
||||
"__GXX_WEAK__=1",
|
||||
"__SHRT_WIDTH__=16",
|
||||
"__LDBL_MIN__=2.2250738585072014e-308L",
|
||||
"__DEC32_MAX__=9.999999E96DF",
|
||||
"__cpp_threadsafe_static_init=200806",
|
||||
"__FLT32X_HAS_INFINITY__=1",
|
||||
"__INT32_MAX__=0x7fffffff",
|
||||
"__INT_WIDTH__=32",
|
||||
"__SIZEOF_LONG__=4",
|
||||
"__UINT16_C(c)=c",
|
||||
"__PTRDIFF_WIDTH__=32",
|
||||
"__DECIMAL_DIG__=17",
|
||||
"__FLT64_EPSILON__=2.2204460492503131e-16F64",
|
||||
"__INTMAX_WIDTH__=64",
|
||||
"__FLT64_MIN_EXP__=(-1021)",
|
||||
"__has_include_next(STR)=__has_include_next__(STR)",
|
||||
"__LDBL_HAS_QUIET_NAN__=1",
|
||||
"__FLT64_MANT_DIG__=53",
|
||||
"__GNUC__=8",
|
||||
"__GXX_RTTI=1",
|
||||
"__cpp_delegating_constructors=200604",
|
||||
"__FLT_HAS_DENORM__=1",
|
||||
"__SIZEOF_LONG_DOUBLE__=8",
|
||||
"__BIGGEST_ALIGNMENT__=16",
|
||||
"__STDC_UTF_16__=1",
|
||||
"__FLT64_MAX_10_EXP__=308",
|
||||
"__FLT32_HAS_INFINITY__=1",
|
||||
"__DBL_MAX__=double(1.7976931348623157e+308L)",
|
||||
"__cpp_raw_strings=200710",
|
||||
"__INT_FAST32_MAX__=0x7fffffff",
|
||||
"__DBL_HAS_INFINITY__=1",
|
||||
"__DEC32_MIN_EXP__=(-94)",
|
||||
"__INTPTR_WIDTH__=32",
|
||||
"__FLT32X_HAS_DENORM__=1",
|
||||
"__INT_FAST16_TYPE__=int",
|
||||
"__LDBL_HAS_DENORM__=1",
|
||||
"__cplusplus=201402L",
|
||||
"__cpp_ref_qualifiers=200710",
|
||||
"__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
|
||||
"__INT_LEAST32_MAX__=0x7fffffff",
|
||||
"__DEC32_MIN__=1E-95DF",
|
||||
"__DEPRECATED=1",
|
||||
"__cpp_rvalue_references=200610",
|
||||
"__DBL_MAX_EXP__=1024",
|
||||
"__WCHAR_WIDTH__=16",
|
||||
"__FLT32_MAX__=3.4028234663852886e+38F32",
|
||||
"__DEC128_EPSILON__=1E-33DL",
|
||||
"__PTRDIFF_MAX__=0x7fffffff",
|
||||
"__FLT32_HAS_QUIET_NAN__=1",
|
||||
"__GNUG__=8",
|
||||
"__LONG_LONG_MAX__=0x7fffffffffffffffLL",
|
||||
"__SIZEOF_SIZE_T__=4",
|
||||
"__cpp_rvalue_reference=200610",
|
||||
"__cpp_nsdmi=200809",
|
||||
"__SIZEOF_WINT_T__=4",
|
||||
"__LONG_LONG_WIDTH__=64",
|
||||
"__cpp_initializer_lists=200806",
|
||||
"__FLT32_MAX_EXP__=128",
|
||||
"__cpp_hex_float=201603",
|
||||
"__GXX_ABI_VERSION=1013",
|
||||
"__FLT_MIN_EXP__=(-125)",
|
||||
"__cpp_lambdas=200907",
|
||||
"__INT_FAST64_TYPE__=long long int",
|
||||
"__FP_FAST_FMAF=1",
|
||||
"__FLT64_DENORM_MIN__=4.9406564584124654e-324F64",
|
||||
"__DBL_MIN__=double(2.2250738585072014e-308L)",
|
||||
"__FLT32X_EPSILON__=2.2204460492503131e-16F32x",
|
||||
"__FLT64_MIN_10_EXP__=(-307)",
|
||||
"__DEC128_MIN__=1E-6143DL",
|
||||
"__REGISTER_PREFIX__",
|
||||
"__UINT16_MAX__=0xffff",
|
||||
"__DBL_HAS_DENORM__=1",
|
||||
"__FLT32_MIN__=1.1754943508222875e-38F32",
|
||||
"__UINT8_TYPE__=unsigned char",
|
||||
"__NO_INLINE__=1",
|
||||
"__FLT_MANT_DIG__=24",
|
||||
"__LDBL_DECIMAL_DIG__=17",
|
||||
"__VERSION__=\"8.4.0\"",
|
||||
"__UINT64_C(c)=c ## ULL",
|
||||
"__cpp_unicode_characters=200704",
|
||||
"__cpp_decltype_auto=201304",
|
||||
"__GCC_ATOMIC_INT_LOCK_FREE=2",
|
||||
"__FLT32_MANT_DIG__=24",
|
||||
"__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||
"__SCHAR_WIDTH__=8",
|
||||
"__INT32_C(c)=c",
|
||||
"__DEC64_EPSILON__=1E-15DD",
|
||||
"__ORDER_PDP_ENDIAN__=3412",
|
||||
"__DEC128_MIN_EXP__=(-6142)",
|
||||
"__FLT32_MAX_10_EXP__=38",
|
||||
"__INT_FAST32_TYPE__=int",
|
||||
"__UINT_LEAST16_TYPE__=short unsigned int",
|
||||
"__INT16_MAX__=0x7fff",
|
||||
"__cpp_rtti=199711",
|
||||
"__SIZE_TYPE__=unsigned int",
|
||||
"__UINT64_MAX__=0xffffffffffffffffULL",
|
||||
"__INT8_TYPE__=signed char",
|
||||
"__cpp_digit_separators=201309",
|
||||
"__ELF__=1",
|
||||
"__xtensa__=1",
|
||||
"__FLT_RADIX__=2",
|
||||
"__INT_LEAST16_TYPE__=short int",
|
||||
"__LDBL_EPSILON__=2.2204460492503131e-16L",
|
||||
"__UINTMAX_C(c)=c ## ULL",
|
||||
"__SIG_ATOMIC_MAX__=0x7fffffff",
|
||||
"__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2",
|
||||
"__SIZEOF_PTRDIFF_T__=4",
|
||||
"__FLT32X_MANT_DIG__=53",
|
||||
"__FLT32X_MIN_EXP__=(-1021)",
|
||||
"__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
|
||||
"__INT_FAST16_MAX__=0x7fffffff",
|
||||
"__FLT64_DIG__=15",
|
||||
"__UINT_FAST32_MAX__=0xffffffffU",
|
||||
"__UINT_LEAST64_TYPE__=long long unsigned int",
|
||||
"__FLT_HAS_QUIET_NAN__=1",
|
||||
"__FLT_MAX_10_EXP__=38",
|
||||
"__LONG_MAX__=0x7fffffffL",
|
||||
"__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
|
||||
"__FLT_HAS_INFINITY__=1",
|
||||
"__cpp_unicode_literals=200710",
|
||||
"__UINT_FAST16_TYPE__=unsigned int",
|
||||
"__DEC64_MAX__=9.999999999999999E384DD",
|
||||
"__INT_FAST32_WIDTH__=32",
|
||||
"__CHAR16_TYPE__=short unsigned int",
|
||||
"__PRAGMA_REDEFINE_EXTNAME=1",
|
||||
"__SIZE_WIDTH__=32",
|
||||
"__INT_LEAST16_MAX__=0x7fff",
|
||||
"__DEC64_MANT_DIG__=16",
|
||||
"__INT64_MAX__=0x7fffffffffffffffLL",
|
||||
"__UINT_LEAST32_MAX__=0xffffffffU",
|
||||
"__FLT32_DENORM_MIN__=1.4012984643248171e-45F32",
|
||||
"__GCC_ATOMIC_LONG_LOCK_FREE=2",
|
||||
"__SIG_ATOMIC_WIDTH__=32",
|
||||
"__INT_LEAST64_TYPE__=long long int",
|
||||
"__INT16_TYPE__=short int",
|
||||
"__INT_LEAST8_TYPE__=signed char",
|
||||
"__DEC32_MAX_EXP__=97",
|
||||
"__INT_FAST8_MAX__=0x7fffffff",
|
||||
"__INTPTR_MAX__=0x7fffffff",
|
||||
"__cpp_sized_deallocation=201309",
|
||||
"__cpp_range_based_for=200907",
|
||||
"__FLT64_HAS_QUIET_NAN__=1",
|
||||
"__FLT32_MIN_10_EXP__=(-37)",
|
||||
"__EXCEPTIONS=1",
|
||||
"__LDBL_MANT_DIG__=53",
|
||||
"__DBL_HAS_QUIET_NAN__=1",
|
||||
"__FLT64_HAS_INFINITY__=1",
|
||||
"__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
|
||||
"__cpp_return_type_deduction=201304",
|
||||
"__INTPTR_TYPE__=int",
|
||||
"__UINT16_TYPE__=short unsigned int",
|
||||
"__WCHAR_TYPE__=short unsigned int",
|
||||
"__SIZEOF_FLOAT__=4",
|
||||
"__UINTPTR_MAX__=0xffffffffU",
|
||||
"__INT_FAST64_WIDTH__=64",
|
||||
"__DEC64_MIN_EXP__=(-382)",
|
||||
"__cpp_decltype=200707",
|
||||
"__FLT32_DECIMAL_DIG__=9",
|
||||
"__INT_FAST64_MAX__=0x7fffffffffffffffLL",
|
||||
"__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
|
||||
"__FLT_DIG__=6",
|
||||
"__UINT_FAST64_TYPE__=long long unsigned int",
|
||||
"__INT_MAX__=0x7fffffff",
|
||||
"__INT64_TYPE__=long long int",
|
||||
"__FLT_MAX_EXP__=128",
|
||||
"__DBL_MANT_DIG__=53",
|
||||
"__cpp_inheriting_constructors=201511",
|
||||
"__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
|
||||
"__FP_FAST_FMAF32=1",
|
||||
"__DEC64_MIN__=1E-383DD",
|
||||
"__WINT_TYPE__=unsigned int",
|
||||
"__UINT_LEAST32_TYPE__=unsigned int",
|
||||
"__SIZEOF_SHORT__=2",
|
||||
"__LDBL_MIN_EXP__=(-1021)",
|
||||
"__FLT64_MAX__=1.7976931348623157e+308F64",
|
||||
"__WINT_WIDTH__=32",
|
||||
"__INT_LEAST8_MAX__=0x7f",
|
||||
"__FLT32X_MAX_10_EXP__=308",
|
||||
"__WCHAR_UNSIGNED__=1",
|
||||
"__LDBL_MAX_10_EXP__=308",
|
||||
"__ATOMIC_RELAXED=0",
|
||||
"__DBL_EPSILON__=double(2.2204460492503131e-16L)",
|
||||
"__XTENSA_WINDOWED_ABI__=1",
|
||||
"__UINT8_C(c)=c",
|
||||
"__FLT64_MAX_EXP__=1024",
|
||||
"__INT_LEAST32_TYPE__=int",
|
||||
"__SIZEOF_WCHAR_T__=2",
|
||||
"__INT_FAST8_TYPE__=int",
|
||||
"__GNUC_STDC_INLINE__=1",
|
||||
"__FLT64_HAS_DENORM__=1",
|
||||
"__FLT32_EPSILON__=1.1920928955078125e-7F32",
|
||||
"__DBL_DECIMAL_DIG__=17",
|
||||
"__STDC_UTF_32__=1",
|
||||
"__INT_FAST8_WIDTH__=32",
|
||||
"__DEC_EVAL_METHOD__=2",
|
||||
"__FLT32X_MAX__=1.7976931348623157e+308F32x",
|
||||
"__XTENSA__=1",
|
||||
"__ORDER_BIG_ENDIAN__=4321",
|
||||
"__cpp_runtime_arrays=198712",
|
||||
"__UINT64_TYPE__=long long unsigned int",
|
||||
"__UINT32_C(c)=c ## U",
|
||||
"__INTMAX_MAX__=0x7fffffffffffffffLL",
|
||||
"__cpp_alias_templates=200704",
|
||||
"__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||
"__FLT_DENORM_MIN__=1.4012984643248171e-45F",
|
||||
"__INT8_MAX__=0x7f",
|
||||
"__LONG_WIDTH__=32",
|
||||
"__UINT_FAST32_TYPE__=unsigned int",
|
||||
"__CHAR32_TYPE__=unsigned int",
|
||||
"__FLT_MAX__=3.4028234663852886e+38F",
|
||||
"__cpp_constexpr=201304",
|
||||
"__INT32_TYPE__=int",
|
||||
"__SIZEOF_DOUBLE__=8",
|
||||
"__cpp_exceptions=199711",
|
||||
"__FLT_MIN_10_EXP__=(-37)",
|
||||
"__FLT64_MIN__=2.2250738585072014e-308F64",
|
||||
"__INT_LEAST32_WIDTH__=32",
|
||||
"__INTMAX_TYPE__=long long int",
|
||||
"__DEC128_MAX_EXP__=6145",
|
||||
"__FLT32X_HAS_QUIET_NAN__=1",
|
||||
"__ATOMIC_CONSUME=1",
|
||||
"__GNUC_MINOR__=4",
|
||||
"__INT_FAST16_WIDTH__=32",
|
||||
"__UINTMAX_MAX__=0xffffffffffffffffULL",
|
||||
"__DEC32_MANT_DIG__=7",
|
||||
"__FLT32X_DENORM_MIN__=4.9406564584124654e-324F32x",
|
||||
"__DBL_MAX_10_EXP__=308",
|
||||
"__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
|
||||
"__INT16_C(c)=c",
|
||||
"__cpp_generic_lambdas=201304",
|
||||
"__STDC__=1",
|
||||
"__FLT32X_DIG__=15",
|
||||
"__PTRDIFF_TYPE__=int",
|
||||
"__ATOMIC_SEQ_CST=5",
|
||||
"__UINT32_TYPE__=unsigned int",
|
||||
"__FLT32X_MIN_10_EXP__=(-307)",
|
||||
"__UINTPTR_TYPE__=unsigned int",
|
||||
"__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
|
||||
"__DEC128_MANT_DIG__=34",
|
||||
"__LDBL_MIN_10_EXP__=(-307)",
|
||||
"__SIZEOF_LONG_LONG__=8",
|
||||
"__cpp_user_defined_literals=200809",
|
||||
"__GCC_ATOMIC_LLONG_LOCK_FREE=1",
|
||||
"__FLT32X_MIN__=2.2250738585072014e-308F32x",
|
||||
"__LDBL_DIG__=15",
|
||||
"__FLT_DECIMAL_DIG__=9",
|
||||
"__UINT_FAST16_MAX__=0xffffffffU",
|
||||
"__GCC_ATOMIC_SHORT_LOCK_FREE=2",
|
||||
"__INT_LEAST64_WIDTH__=64",
|
||||
"__UINT_FAST8_TYPE__=unsigned int",
|
||||
"__cpp_init_captures=201304",
|
||||
"__ATOMIC_ACQ_REL=4",
|
||||
"__ATOMIC_RELEASE=3",
|
||||
"USBCON"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -4,7 +4,7 @@ void Connectivity::connectWiFi(char* ssid, char* pass){
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, pass);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.println("connecting to wifi");
|
||||
// Serial.println("connecting to wifi");
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println(WiFi.localIP());
|
||||
@@ -20,4 +20,21 @@ void Connectivity::websocketSetup(char* ip, uint16_t port, char* adress){
|
||||
void Connectivity::sendData(float roll, float pitch, float yaw){
|
||||
String message = "{\"Sensor\": 1, \"roll\":\"" + String(roll) + "\",\"pitch\":\"" + String(pitch) + "\",\"yaw\":\"" + String(yaw) + "\"}";
|
||||
webSocket.sendTXT(message);
|
||||
}
|
||||
|
||||
/** Send a POST request to a server with provided data */
|
||||
int Connectivity::httpPost(const char *serverAddress, const char *serverSubPath, const unsigned short serverPort,
|
||||
const char *data, const size_t dataLength, const char *contentType)
|
||||
{
|
||||
if ( wifi_client.connect(serverAddress, serverPort)) {
|
||||
wifi_client.printf("POST %s HTTP/1.1\r\n", serverSubPath);
|
||||
wifi_client.printf("Content-Type: %s\r\n", contentType);
|
||||
wifi_client.printf("Content-Length: %d\r\n", dataLength);
|
||||
wifi_client.printf("Host: %s\r\n\n", serverAddress);
|
||||
wifi_client.println(data);
|
||||
wifi_client.stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@@ -6,25 +6,25 @@
|
||||
#include <ArduinoWiFiServer.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiGeneric.h>
|
||||
#include <ESP8266WiFiGratuitous.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <ESP8266WiFiSTA.h>
|
||||
#include <ESP8266WiFiScan.h>
|
||||
#include <ESP8266WiFiType.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <WiFiServer.h>
|
||||
#include <WiFiServerSecure.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
|
||||
class Connectivity {
|
||||
public:
|
||||
void connectWiFi(char* ssid, char* pass);
|
||||
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);
|
||||
|
||||
|
||||
private:
|
||||
ESP8266WiFiMulti wifi;
|
||||
WiFiClient wifi_client;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,62 +1,40 @@
|
||||
#include "headerFile.h"
|
||||
|
||||
SensorManager::Rotation offset;
|
||||
// SensorManager::Rotation offset;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("startup");
|
||||
|
||||
// Serial.begin(9600);
|
||||
// Serial.println("startup");
|
||||
//connect to internet and start sensor
|
||||
connectivity.connectWiFi(ssid, pass);
|
||||
sensorManager.sensorSetup();
|
||||
|
||||
//ws server address, port and URL
|
||||
webSocket.begin("145.3.245.22", 8001, "");
|
||||
// try every 500 again if connection has failed
|
||||
webSocket.setReconnectInterval(500);
|
||||
}
|
||||
|
||||
unsigned long lastTime = 0; // will store the last time the code was run
|
||||
|
||||
void loop() {
|
||||
SensorManager::Rotation rotation = sensorManager.readLoop();
|
||||
SensorManager::eulerAngles eulerRotation = sensorManager.getEulerAngles();
|
||||
SensorManager::acceleration rotationAcceleration = sensorManager.getAcelleration();
|
||||
|
||||
// Subtract offset
|
||||
rotation.i -= offset.i;
|
||||
rotation.j -= offset.j;
|
||||
rotation.k -= offset.k;
|
||||
rotation.w -= offset.w;
|
||||
|
||||
// Convert quaternion to Euler angles in radians
|
||||
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));
|
||||
float pitch = asin(2.0f * (rotation.w * rotation.j - rotation.k * rotation.i));
|
||||
float yaw = atan2(2.0f * (rotation.w * rotation.k + rotation.i * rotation.j), 1.0f - 2.0f * (rotation.j * rotation.j + rotation.k * rotation.k));
|
||||
|
||||
// Convert to degrees
|
||||
float rollDegrees = roll * 180.0f / PI;
|
||||
float pitchDegrees = pitch * 180.0f / PI;
|
||||
float yawDegrees = yaw * 180.0f / PI;
|
||||
|
||||
Serial.print(roll);
|
||||
Serial.print(" ");
|
||||
Serial.print(pitch);
|
||||
Serial.print(" ");
|
||||
Serial.print(yaw);
|
||||
sendData(roll, pitch, yaw);
|
||||
|
||||
Serial.println();
|
||||
webSocket.loop();
|
||||
|
||||
if (Serial.available()) {
|
||||
String command = Serial.readStringUntil('\n');
|
||||
command.trim(); // remove any trailing whitespace
|
||||
if (command == "setZeroPoint") {
|
||||
setZeroPoint();
|
||||
}
|
||||
unsigned long currentTime = millis();
|
||||
if (currentTime - lastTime >= 100) { // 100 ms has passed
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
sprintf(
|
||||
buffer,
|
||||
"{\"deviceId\": %d, \"rotationX\": %f, \"rotationY\": %f, \"rotationZ\": %f, \"accelerationX\": %f, \"accelerationY\": %f, \"accelerationZ\": %f, \"type\": %s}",
|
||||
DEVICE_ID,
|
||||
eulerRotation.roll,
|
||||
eulerRotation.pitch,
|
||||
eulerRotation.yaw,
|
||||
rotationAcceleration.x,
|
||||
rotationAcceleration.y,
|
||||
rotationAcceleration.z,
|
||||
"data");
|
||||
// %d = int, %f = floatation, %s = string
|
||||
connectivity.httpPost("192.168.137.45", "/", 3445, buffer, strlen(buffer), "application/json");
|
||||
lastTime = currentTime;
|
||||
}
|
||||
}
|
||||
void setZeroPoint() {
|
||||
offset = sensorManager.readLoop();
|
||||
}
|
||||
|
||||
void sendData(float roll, float pitch, float yaw){
|
||||
String message = "{\"Sensor\": 1, \"roll\":\"" + String(roll) + "\",\"pitch\":\"" + String(pitch) + "\",\"yaw\":\"" + String(yaw) + "\"}";
|
||||
webSocket.sendTXT(message);
|
||||
}
|
||||
//acceleration.X
|
||||
//acceleration.Y
|
||||
//acceleration.Z
|
||||
|
@@ -5,47 +5,67 @@
|
||||
SensorManager::SensorManager() {}
|
||||
|
||||
void SensorManager::sensorSetup() {
|
||||
Wire.setClockStretchLimit(150000L); // Default stretch limit 150mS
|
||||
Wire.begin();
|
||||
//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); //Increase I2C data rate to 400kHz
|
||||
myIMU.calibrateAll(); //Turn on cal for Accel, Gyro, and Mag
|
||||
myIMU.enableGyroIntegratedRotationVector(100); //send data every 100ms
|
||||
myIMU.enableMagnetometer(100); //Send data update every 100ms
|
||||
myIMU.saveCalibration(); //Saves the current dynamic calibration data (DCD) to memory
|
||||
myIMU.requestCalibrationStatus(); //Sends command to get the latest calibration status
|
||||
|
||||
if (myIMU.calibrationComplete() == true) {
|
||||
Serial.println("Calibration data successfully stored");
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
SensorManager::Rotation SensorManager::readLoop() {
|
||||
//get sensordata
|
||||
SensorManager::RotationQuintillions SensorManager::getQuintillions() {
|
||||
if (myIMU.dataAvailable() == true) {
|
||||
float i = myIMU.getQuatI();
|
||||
float j = myIMU.getQuatJ();
|
||||
float k = myIMU.getQuatK();
|
||||
float w = myIMU.getQuatReal();
|
||||
|
||||
Rotation rotation = { i, j, k, w };
|
||||
RotationQuintillions rotation = { i, j, k, w };
|
||||
return rotation;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
float i = myIMU.getQuatI();
|
||||
float j = myIMU.getQuatJ();
|
||||
float k = myIMU.getQuatK();
|
||||
float w = myIMU.getQuatReal();
|
||||
|
||||
Rotation rotation = { i, j, k, w };
|
||||
RotationQuintillions rotation = { i, j, k, w };
|
||||
return rotation;
|
||||
}
|
||||
}
|
||||
//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));
|
||||
float pitch = asin(2.0f * (rotation.w * rotation.j - rotation.k * rotation.i));
|
||||
float yaw = atan2(2.0f * (rotation.w * rotation.k + rotation.i * rotation.j), 1.0f - 2.0f * (rotation.j * rotation.j + rotation.k * rotation.k));
|
||||
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 };
|
||||
|
||||
return Acceleration;
|
||||
}
|
||||
|
||||
bool SensorManager::sensorTap() {
|
||||
int taps = 0;
|
||||
if (myIMU.dataAvailable() == true) {
|
||||
int taps = myIMU.getStepCount();
|
||||
}
|
||||
if (taps) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -5,18 +5,32 @@
|
||||
#include "SparkFun_BNO080_Arduino_Library.h"
|
||||
|
||||
class SensorManager {
|
||||
public:
|
||||
SensorManager();
|
||||
void sensorSetup();
|
||||
struct Rotation {
|
||||
float i;
|
||||
float j;
|
||||
float k;
|
||||
float w;
|
||||
};
|
||||
Rotation readLoop();
|
||||
private:
|
||||
BNO080 myIMU;
|
||||
public:
|
||||
SensorManager();
|
||||
void sensorSetup();
|
||||
struct eulerAngles {
|
||||
float roll;
|
||||
float pitch;
|
||||
float yaw;
|
||||
};
|
||||
struct acceleration {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
eulerAngles getEulerAngles();
|
||||
acceleration getAcelleration();
|
||||
bool sensorTap();
|
||||
private:
|
||||
struct RotationQuintillions {
|
||||
float i;
|
||||
float j;
|
||||
float k;
|
||||
float w;
|
||||
};
|
||||
RotationQuintillions getQuintillions();
|
||||
BNO080 myIMU;
|
||||
};
|
||||
|
||||
#endif
|
@@ -8,6 +8,8 @@ Connectivity connectivity;
|
||||
WebSocketsClient webSocket;
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
#define ssid "1235678i"
|
||||
#define pass "12345678"
|
||||
#define BUFFER_SIZE 1024
|
||||
#define DEVICE_ID 1
|
||||
char *buffer = (char *)malloc(sizeof(char) * BUFFER_SIZE);
|
||||
|
33
code/arduino/bluetoothEsp/bluetoothEsp.ino
Normal file
@@ -0,0 +1,33 @@
|
||||
#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
@@ -13,3 +13,5 @@
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
.idea
|
||||
.vscode
|
17
code/src/Fitbot/.idea/deploymentTargetDropDown.xml
generated
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="C:\Users\sebas\.android\avd\Pepper_1.9_API_29.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2024-04-26T10:10:48.222593700Z" />
|
||||
</component>
|
||||
</project>
|
66
code/src/Fitbot/.idea/misc.xml
generated
@@ -4,24 +4,45 @@
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="../../../../../../../../layout/custom_preview.xml" value="0.35989583333333336" />
|
||||
<entry key="../../../../../../.gradle/caches/transforms-3/9c4b978f8e84c8bb9ebef5f19e8c189e/transformed/qisdk-design-1.7.5/res/layout/activity_robot.xml" value="0.1" />
|
||||
<entry key="../../../../../../.gradle/caches/transforms-3/9c4b978f8e84c8bb9ebef5f19e8c189e/transformed/qisdk-design-1.7.5/res/layout/view_always_top_speech_bar.xml" value="0.167877197265625" />
|
||||
<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/Niels/muupooviixee66-3/code/src/Fitbot/app/src/main/res/layout/toolbar.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/box_background.xml" value="0.2555" />
|
||||
<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/help2_background.xml" value="0.2395" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/help_background.xml" value="0.2395" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/ic_baseline_home_48.xml" value="0.25" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/ic_baseline_settings_48.xml" value="0.25" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/ic_baseline_star_rate_48.xml" value="0.25" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/ic_launcher_background.xml" value="0.25" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/drawable/rectangle.xml" value="0.2395" />
|
||||
<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_main.xml" value="0.176" />
|
||||
<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.264" />
|
||||
<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_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/header.xml" value="0.125" />
|
||||
<entry key="..\:/Users/sebas/Documents/HvA/Reposetories/muupooviixee66/code/src/Fitbot/app/src/main/res/layout/toolbar.xml" value="0.125" />
|
||||
<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" />
|
||||
<entry key="app/src/main/res/layout/activity_end_screen.xml" value="0.1" />
|
||||
<entry key="app/src/main/res/layout/activity_fitness.xml" value="0.23550724637681159" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.1" />
|
||||
<entry key="app/src/main/res/layout/activity_sport_item.xml" value="0.2341485507246377" />
|
||||
@@ -31,6 +52,45 @@
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="androidx.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="12">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
||||
<item index="1" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
|
||||
<item index="5" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||
<item index="7" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
<item index="8" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="9" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
||||
<item index="11" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="11">
|
||||
<item index="0" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||
<item index="4" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
||||
<item index="5" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
||||
<item index="7" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="9" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="10" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
|
@@ -7,7 +7,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.fitbot"
|
||||
minSdk 29
|
||||
minSdk 23
|
||||
targetSdk 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@@ -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'
|
||||
|
@@ -1,12 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.fitbot" >
|
||||
package="com.example.fitbot">
|
||||
|
||||
<uses-feature android:name="com.softbank.hardware.pepper" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@@ -14,10 +24,19 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Fitbot" >
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".ui.activities.HelpActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.activities.EndScreenActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.activities.FitnessActivity"
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".ui.activities.MainActivity"
|
||||
android:exported="true" >
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
@@ -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,137 @@
|
||||
package com.example.fitbot.exercise;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
import com.example.fitbot.util.processing.IMotionDataConsumer;
|
||||
import com.example.fitbot.util.server.IWebServerHandler;
|
||||
import com.example.fitbot.util.server.WebServer;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Exercise implements IWebServerHandler {
|
||||
|
||||
private EMuscleGroup muscleGroup;
|
||||
private GesturePath leftPath;
|
||||
private GesturePath rightPath;
|
||||
private String title;
|
||||
private String description;
|
||||
private float segmentsPerSecond;
|
||||
|
||||
// Static fields.
|
||||
private static WebServer webSocket;
|
||||
private static Exercise currentExercise = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the AbstractExercise class.
|
||||
*
|
||||
* @param muscleGroup The muscle group of the exercise.
|
||||
* @param leftPath The path of the left hand.
|
||||
* @param rightPath The path of the right hand.
|
||||
* @param title The title of the exercise.
|
||||
* @param description The description of the exercise.
|
||||
* @param segmentsPerSecond The number of segments per second.
|
||||
* This determines how fast the exercise should be performed.
|
||||
*/
|
||||
public Exercise(EMuscleGroup muscleGroup, String title, String description, GesturePath leftPath, GesturePath rightPath) {
|
||||
this.muscleGroup = muscleGroup;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.leftPath = leftPath;
|
||||
this.rightPath = rightPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = WebServer.createServer();
|
||||
Objects.requireNonNull(webSocket, "WebSocket server could not be created.");
|
||||
|
||||
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 new GesturePath[]{leftPath, rightPath};
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the speed of the exercise.
|
||||
*/
|
||||
public double getSegmentsPerSecond() {
|
||||
return segmentsPerSecond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(String message) {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,125 @@
|
||||
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 ExerciseManager {
|
||||
|
||||
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 final String PROPERTY_SEGMENT_SPEED = "segment_speed";
|
||||
|
||||
private static final float DEFAULT_SEGMENT_SPEED = 1.0f;
|
||||
|
||||
/**
|
||||
* Function for sending an HTTP request to the server.
|
||||
*
|
||||
* @param url The URL to send the request to.
|
||||
* @param method The method to use for the request, e.g. GET or POST.
|
||||
* @param contentType The content type of the request.
|
||||
* @param body The body of the request.
|
||||
*
|
||||
* @return The response from the server.
|
||||
*/
|
||||
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 Exercise retrieveExercise(String uniqueIdentifier) {
|
||||
String response = sendHTTP(
|
||||
HOST_ADDRESS + "/acquire", "GET", "application/json", "{\"kind\":\"" + uniqueIdentifier + "\"}"
|
||||
);
|
||||
// Validate the response
|
||||
if (response != null) {
|
||||
try {
|
||||
JsonObject content = JsonParser.parseString(response).getAsJsonObject();
|
||||
return new Exercise(
|
||||
EMuscleGroup.parse(content.get(PROPERTY_MUSCLE_GROUP).getAsInt()),
|
||||
content.get(PROPERTY_NAME).getAsString(),
|
||||
content.get(PROPERTY_DESC).getAsString(),
|
||||
gesturePathFromString(content.get(PROPERTY_VECTORS).getAsString()),
|
||||
gesturePathFromString(content.get(PROPERTY_SEGMENT_SPEED).getAsString())
|
||||
);
|
||||
} 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 scalar is composed of 32 bits (4 characters), meaning 96 bits per vector.
|
||||
*
|
||||
* Note: ASCII to Vector conversion is done in Big Endian format (most significant byte first).
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
package com.example.fitbot.speech;
|
||||
|
||||
import com.aldebaran.qi.sdk.QiContext;
|
||||
import com.aldebaran.qi.sdk.builder.SayBuilder;
|
||||
import com.aldebaran.qi.sdk.object.locale.Language;
|
||||
import com.aldebaran.qi.sdk.object.locale.Locale;
|
||||
import com.aldebaran.qi.sdk.object.locale.Region;
|
||||
|
||||
/**
|
||||
* SpeechGenerator class for generating speech for the robot
|
||||
*/
|
||||
public class SpeechGenerator {
|
||||
|
||||
private static final Locale DUTCH_LOCALE = new Locale(Language.DUTCH, Region.NETHERLANDS);
|
||||
private SayBuilder builder;
|
||||
|
||||
/**
|
||||
* Function for making the robot say something with DUTCH_LOCALE as locale
|
||||
* @param phrase The phrase to make the robot say
|
||||
* @param ctx The QiContext to use
|
||||
*/
|
||||
public static void say(String phrase, QiContext ctx)
|
||||
{
|
||||
say(phrase, ctx, DUTCH_LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for making the robot say something with a specific locale
|
||||
* @param phrase The phrase to make the robot say
|
||||
* @param ctx The QiContext to use
|
||||
* @param locale The locale to use
|
||||
*/
|
||||
public static void say(String phrase, QiContext ctx, Locale locale)
|
||||
{
|
||||
SayBuilder
|
||||
.with(ctx)
|
||||
.withLocale(locale)
|
||||
.withText(phrase)
|
||||
.build()
|
||||
.run();
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.example.fitbot.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.ui.activities.FitnessActivity;
|
||||
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);
|
||||
|
||||
com.example.fitbot.util.ButtonNavigation.setupButtonNavigation(this, R.id.homeButton, MainActivity.class);
|
||||
com.example.fitbot.util.ButtonNavigation.setupButtonNavigation(this, R.id.continueButton, FitnessActivity.class);
|
||||
}
|
||||
}
|
@@ -1,20 +1,80 @@
|
||||
package com.example.fitbot.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.aldebaran.qi.sdk.QiContext;
|
||||
import com.aldebaran.qi.sdk.QiSDK;
|
||||
import com.aldebaran.qi.sdk.RobotLifecycleCallbacks;
|
||||
import com.aldebaran.qi.sdk.design.activity.RobotActivity;
|
||||
import com.aldebaran.qi.sdk.design.activity.conversationstatus.SpeechBarDisplayStrategy;
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.exercise.EMuscleGroup;
|
||||
import com.example.fitbot.exercise.Exercise;
|
||||
import com.example.fitbot.ui.components.PersonalMotionPreviewElement;
|
||||
import com.example.fitbot.util.ButtonNavigation;
|
||||
import com.example.fitbot.util.FitnessCycle;
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FitnessActivity extends RobotActivity implements RobotLifecycleCallbacks {
|
||||
|
||||
PersonalMotionPreviewElement personalMotionPreviewElement;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
QiSDK.register(this, this);
|
||||
setContentView(R.layout.activity_fitness);
|
||||
|
||||
// Remove the ugly ass bar on top of the view
|
||||
setSpeechBarDisplayStrategy(SpeechBarDisplayStrategy.IMMERSIVE);
|
||||
|
||||
// Find the VideoView by its ID
|
||||
VideoView videoView = findViewById(R.id.videoView);
|
||||
|
||||
FitnessCycle.playVideo(videoView, this);
|
||||
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.homeButton, MainActivity.class);
|
||||
// Implement your logic when the robot focus is gained
|
||||
|
||||
GesturePath.Builder gesturePathBuilder = new GesturePath.Builder();
|
||||
|
||||
/* Generate a random path to test the tracking system */
|
||||
for ( int i = 0; i < 40; i++)
|
||||
{
|
||||
gesturePathBuilder.addVector(
|
||||
new Vector3f(
|
||||
(float)Math.cos(Math.PI + (Math.PI / 40.0f) * i),
|
||||
(float)Math.sin(Math.PI + (Math.PI / 40.0f) * i),
|
||||
0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
personalMotionPreviewElement = findViewById(R.id.personalMotionPreviewElement);
|
||||
personalMotionPreviewElement.post(() -> {
|
||||
Log.i("FitnessActivity", "PersonalMotionPreviewElement.post()");
|
||||
|
||||
Exercise exercise = new Exercise(EMuscleGroup.ARMS, "Bicep Curls", "Oefening voor de biceps.", gesturePathBuilder.build(), gesturePathBuilder.build());
|
||||
|
||||
personalMotionPreviewElement.initialize(exercise);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRobotFocusGained(QiContext qiContext) {
|
||||
// Implement your logic when the robot focus is gained
|
||||
|
||||
// Find the VideoView by its ID
|
||||
// CompletableFuture.runAsync(() -> FitnessCycle.executeMovement("bicepcurl", 10, qiContext));
|
||||
Log.i("Motion", "qiContext provided");
|
||||
personalMotionPreviewElement.provideQiContext(qiContext);
|
||||
|
||||
// FitnessCycle.playVideo(qiContext, videoView, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,4 +86,11 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
public void onRobotFocusRefused(String reason) {
|
||||
// Implement your logic when the robot focus is refused
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
QiSDK.unregister(this, this);
|
||||
this.personalMotionPreviewElement.onDestroy();
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.example.fitbot.ui.activities;
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_help);
|
||||
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.homeButton, MainActivity.class);
|
||||
|
||||
}
|
||||
}
|
@@ -1,6 +1,8 @@
|
||||
package com.example.fitbot.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
@@ -8,46 +10,110 @@ 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.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.example.fitbot.R;
|
||||
import com.example.fitbot.util.ButtonNavigation;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
//Variables
|
||||
// Variables
|
||||
DrawerLayout drawerLayout;
|
||||
NavigationView navigationView;
|
||||
Toolbar toolbar;
|
||||
Button startButton;
|
||||
|
||||
@SuppressLint("WrongViewCast")
|
||||
@Override
|
||||
protected void onCreate (Bundle savedInstanceState) {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Set full screen mode
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
// Hide system UI
|
||||
hideSystemUI();
|
||||
|
||||
startButton = findViewById(R.id.startButton);
|
||||
startButton.setOnClickListener(v -> {
|
||||
Uri videoUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bicepvideo);
|
||||
Intent intent = new Intent(MainActivity.this, FitnessActivity.class);
|
||||
intent.putExtra("videoUri", videoUri);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
setUpUi(); // Set up the UI
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Hide the action bar
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().hide();
|
||||
}
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.startButton, FitnessActivity.class);
|
||||
ButtonNavigation.setupButtonNavigation(this, R.id.helpButton, HelpActivity.class);
|
||||
|
||||
/*---Tool Bar---*/
|
||||
// setSupportActionBar(toolbar);
|
||||
setSupportActionBar(toolbar); // Make the toolbar act as the action bar
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false); // Remove the title from the toolbar
|
||||
}
|
||||
|
||||
/*---Navigation Drawer Menu---*/
|
||||
navigationView.bringToFront();
|
||||
navigationView.bringToFront(); // Make the navigation drawer menu clickable
|
||||
|
||||
ActionBarDrawerToggle toggle=new
|
||||
ActionBarDrawerToggle(this,drawerLayout,toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
||||
ActionBarDrawerToggle toggle = new // Create a toggle for the navigation drawer
|
||||
ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
|
||||
@Override
|
||||
public void onDrawerOpened(View drawerView) {
|
||||
super.onDrawerOpened(drawerView);
|
||||
hideSystemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawerClosed(View drawerView) {
|
||||
super.onDrawerClosed(drawerView);
|
||||
hideSystemUI();
|
||||
}
|
||||
};
|
||||
drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
toggle.syncState(); // Synchronize the state of the navigation drawer
|
||||
}
|
||||
|
||||
private void hideSystemUI() {
|
||||
View decorView = getWindow().getDecorView();
|
||||
// Hide the status bar and navigation bar
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
decorView.setSystemUiVisibility(uiOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed(){
|
||||
if(drawerLayout.isDrawerOpen(GravityCompat.START)){
|
||||
drawerLayout.closeDrawer(GravityCompat.START);
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
hideSystemUI();
|
||||
}
|
||||
else
|
||||
{super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() { // Close the navigation drawer when the back button is pressed
|
||||
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
drawerLayout.closeDrawer(GravityCompat.START);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,11 +4,14 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.aldebaran.qi.sdk.QiContext;
|
||||
import com.example.fitbot.exercise.Exercise;
|
||||
import com.example.fitbot.util.FitnessCycle;
|
||||
import com.example.fitbot.util.path.GesturePath;
|
||||
import com.example.fitbot.util.path.PathSegment;
|
||||
import com.example.fitbot.util.processing.MotionData;
|
||||
import com.example.fitbot.util.processing.MotionProcessor;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
@@ -16,150 +19,214 @@ import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class PersonalMotionPreviewElement extends View {
|
||||
|
||||
private GesturePath path;
|
||||
private double pathTime = 0.0D; // The timestamp at which the path is currently at.
|
||||
private GesturePath[] paths;
|
||||
private MotionProcessor motionProcessor;
|
||||
private Path referencePath, performingPath;
|
||||
private Paint referencePaint, performingPaint;
|
||||
|
||||
/**
|
||||
* Constants for the preview path projection.
|
||||
*/
|
||||
private final float FOV = 70.0f; // The field of view of the preview path
|
||||
private final float Z_NEAR = 0.1f; // The near clipping plane
|
||||
private final float Z_FAR = 1000.0f; // The far clipping plane
|
||||
private Vector3f cameraPosition = new Vector3f(0.0f, 0.0f, 0.0f); // The position of the camera
|
||||
private double pathTime = 0.0D; // The timestamp at which the path is currently at.
|
||||
private final AtomicInteger exerciseProgress = new AtomicInteger(0); // The progress of the exercise. Ranges from 0 to 1000.
|
||||
|
||||
private QiContext qiContext;
|
||||
|
||||
private Exercise exercise;
|
||||
|
||||
private Path targetPath; // The path the user is supposed to follow.
|
||||
private Path actualPath; // The path the user is currently following.
|
||||
|
||||
private final Paint referencePaint = new Paint();
|
||||
private final Paint targetPaint = new Paint();
|
||||
private final Paint backgroundColor = new Paint();
|
||||
|
||||
private Matrix4f modelMatrix = new Matrix4f(); // The model view matrix for the 3D to 2D transformation.
|
||||
private Matrix4f viewMatrix = new Matrix4f()
|
||||
.lookAt(new Vector3f(4, 4, 4), new Vector3f(0, 0, 0), new Vector3f(0, 1, 0)); // The view matrix for the 3D to 2D transformation.
|
||||
private Matrix4f projectionMatrix = new Matrix4f(); // The projection matrix for the 3D to 2D transformation.
|
||||
private final Vector4f objectPosition = new Vector4f(0, 0, 0, 1); // The location of the object in 3D space.
|
||||
private ConcurrentLinkedQueue<Vector2f> vectors = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private Vector2f[] axisVectors;
|
||||
|
||||
|
||||
|
||||
private static final String[] USER_PHRASES = {
|
||||
"Veel success met de oefening!",
|
||||
"Je kan het!",
|
||||
"Veel plezier!"
|
||||
};
|
||||
|
||||
private double timePassed = 0.0D; // The time that has passed since the start of the exercise, in seconds.
|
||||
private long startingTime = 0L;
|
||||
|
||||
private Vector2f screenDimensions = new Vector2f(); // Width and height dimensions of the screen
|
||||
private Vector2f rotation = new Vector2f(); // Rotation vector (yaw, pitch)
|
||||
|
||||
/**
|
||||
* Constructor for the PersonalMotionPreviewElement class.
|
||||
*
|
||||
* @param context The context in which this element is created.
|
||||
* @param path The gesture path that will be drawn on the canvas.
|
||||
*/
|
||||
public PersonalMotionPreviewElement(Context context, GesturePath path) {
|
||||
super(context);
|
||||
this.path = path;
|
||||
this.motionProcessor = new MotionProcessor();
|
||||
this.motionProcessor.startListening();
|
||||
this.motionProcessor.setMotionDataEventHandler((processed, preprocessed, sampleIndex, sampleRate) -> {
|
||||
// TODO: Implement the calculation of the `performingPath` based on the motion data
|
||||
});
|
||||
public PersonalMotionPreviewElement(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
this.referencePath = getDrawablePath(path.getSegments());
|
||||
this.performingPath = new Path();
|
||||
|
||||
this.referencePaint = new Paint();
|
||||
this.referencePaint.setColor(-1); // White
|
||||
this.referencePaint.setStyle(Paint.Style.STROKE);
|
||||
this.referencePaint.setColor(0xFFFF0000); // Red
|
||||
this.referencePaint.setStyle(Paint.Style.FILL);
|
||||
this.referencePaint.setStrokeWidth(5.0f);
|
||||
this.performingPaint = new Paint();
|
||||
this.performingPaint.setColor(0xFF0000FF); // Blue
|
||||
this.performingPaint.setStyle(Paint.Style.STROKE);
|
||||
this.performingPaint.setStrokeWidth(5.0f);
|
||||
this.referencePaint.setAntiAlias(true);
|
||||
|
||||
// Target paint is the filling of the target path.
|
||||
this.targetPaint.setColor(-1);
|
||||
this.targetPaint.setStyle(Paint.Style.STROKE);
|
||||
this.targetPaint.setStrokeWidth(5.0f);
|
||||
this.targetPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that calculates the path that will be drawn on the
|
||||
* canvas. This method will be called every time new motion data is received.
|
||||
* Method for initializing the PersonalMotionPreviewElement.
|
||||
* This method has to be called with a "post" function when the element has been
|
||||
* created, otherwise the dimensions of the element aren't initialized yet, which
|
||||
* will cause the vertex projections to fail (0 width and height).
|
||||
*
|
||||
* @param exercise The exercise that the user is currently performing.
|
||||
*/
|
||||
private void calculateDrawingPath(Vector3f transformedVector, MotionData motionData, int sampleIndex, double sampleRate) {
|
||||
// Recalculate the personal path based on the new motion data
|
||||
public void initialize(Exercise exercise) {
|
||||
Log.i("PersonalMotionPreviewElement", "Creating new PersonalMotionPreviewElement.");
|
||||
this.backgroundColor.setColor(0xFF000000); // Black
|
||||
|
||||
this.screenDimensions.x = this.getWidth();
|
||||
this.screenDimensions.y = this.getHeight();
|
||||
this.actualPath = new Path();
|
||||
this.targetPath = new Path();
|
||||
|
||||
this.startingTime = System.nanoTime(); // Set the last time to the current time
|
||||
|
||||
this.exercise = exercise;
|
||||
this.paths = exercise.getPath();
|
||||
|
||||
this.axisVectors = new Vector2f[] {
|
||||
|
||||
projectVertex(new Vector3f(-100.0f, 0, 0), getWidth(), getHeight()),
|
||||
projectVertex(new Vector3f(100.0f, 0, 0), getWidth(), getHeight()),
|
||||
projectVertex(new Vector3f(0, -100.0f, 0), getWidth(), getHeight()),
|
||||
projectVertex(new Vector3f(0, 100.0f, 0), getWidth(), getHeight()),
|
||||
projectVertex(new Vector3f(0, 0, -100.0f), getWidth(), getHeight()),
|
||||
projectVertex(new Vector3f(0, 0, 100.0f), getWidth(), getHeight())
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
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.
|
||||
* Also say something nice to the user :)
|
||||
*
|
||||
* @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();
|
||||
|
||||
// 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 + ")");
|
||||
Vector2f parsed = projectVertex(processed, this.getWidth(), this.getHeight());
|
||||
this.vectors.add(parsed);
|
||||
// Remove the first element if the array is too big
|
||||
if (this.vectors.size() > 100)
|
||||
this.vectors.poll();
|
||||
});
|
||||
saySomethingNice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to say something nice to the user :)
|
||||
*/
|
||||
private void saySomethingNice()
|
||||
{
|
||||
if (this.qiContext == null)
|
||||
return;
|
||||
|
||||
FitnessCycle.say(USER_PHRASES[(int) Math.floor(Math.random() * USER_PHRASES.length)], this.qiContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for setting the gesture path that will be drawn on the canvas.
|
||||
*
|
||||
* @param path The gesture path to draw.
|
||||
* @param exercise The exercise that the user is currently performing.
|
||||
*/
|
||||
public void setGesturePath(GesturePath path) {
|
||||
this.path = path;
|
||||
this.referencePath = getDrawablePath(path.getSegments());
|
||||
public void setExercise(Exercise exercise) {
|
||||
this.exercise = exercise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for setting the rotation of the preview path.
|
||||
*
|
||||
* @param yaw The yaw rotation of the preview path.
|
||||
* @param pitch The pitch rotation of the preview path.
|
||||
*/
|
||||
public void setRotation(float yaw, float pitch) {
|
||||
this.rotation.set(Math.toRadians(yaw), Math.toRadians(pitch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for projecting a 3D point onto the screen.
|
||||
* This method converts the 3D point to 2D space using a Model-View-Projection matrix transformation.
|
||||
*
|
||||
* @param point The point to cast to the screen.
|
||||
* @param virtualWidth The width of the virtual screen.
|
||||
* This is used to normalize the screen coordinates.
|
||||
* @param virtualHeight The height of the virtual screen.
|
||||
* @return The transformed vector in screen coordinates ranging from (0, 0) to (virtualWidth, virtualHeight).
|
||||
*/
|
||||
private Vector2f projectVertex(Vector3f point, int virtualWidth, int virtualHeight) {
|
||||
modelMatrix
|
||||
.identity()
|
||||
.translate(-objectPosition.x, -objectPosition.y, -objectPosition.z);
|
||||
|
||||
Matrix4f modelViewMatrix = new Matrix4f()
|
||||
.rotateX((float) Math.toRadians(rotation.x))
|
||||
.rotateY((float) Math.toRadians(rotation.y))
|
||||
.translate(cameraPosition);
|
||||
// Transform the projection matrix to a perspective projection matrix
|
||||
// Perspective transformation conserves the depth of the object
|
||||
projectionMatrix
|
||||
.identity()
|
||||
.perspective((float) Math.toRadians(70), (float) virtualWidth / virtualHeight, .01f, 10000.0f);
|
||||
|
||||
Matrix4f projectionMatrix = new Matrix4f()
|
||||
.perspective((float) Math.toRadians(FOV), (float) virtualWidth / virtualHeight, Z_NEAR, Z_FAR);
|
||||
|
||||
// Calculate Model-View-Projection matrix
|
||||
Matrix4f MVP = new Matrix4f()
|
||||
.set(projectionMatrix)
|
||||
.mul(modelViewMatrix);
|
||||
|
||||
// Convert to screen coordinates
|
||||
// Convert world coordinates to screen-space using MVP matrix
|
||||
Vector4f screenCoordinates = new Vector4f(point, 1.0f)
|
||||
.mul(MVP);
|
||||
.mul(this.projectionMatrix)
|
||||
.mul(this.viewMatrix)
|
||||
.mul(this.modelMatrix);
|
||||
|
||||
// Normalize screen coordinates from (-1, 1) to (0, virtualWidth) and (0, virtualHeight)
|
||||
float normalizedX = (screenCoordinates.x / screenCoordinates.w + 1.0f) * 0.5f * virtualWidth;
|
||||
float normalizedY = (1.0f - screenCoordinates.y / screenCoordinates.w) * 0.5f * virtualHeight;
|
||||
|
||||
return new Vector2f(normalizedX, normalizedY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that converts a sequence of vectors to a Path object.
|
||||
* This path is a set of bezier curves that will be drawn on the canvas.
|
||||
*
|
||||
* @param segments The path segments in the path.
|
||||
* These segments will be connected by bezier curves, which
|
||||
* all have unique curvature values.
|
||||
* @return The generated path object.
|
||||
*/
|
||||
private Path getDrawablePath(PathSegment... segments) {
|
||||
|
||||
Path calculatedPath = new Path();
|
||||
|
||||
// Starting point
|
||||
Vector2f origin = projectVertex(segments[0].getStart(), getWidth(), getHeight());
|
||||
calculatedPath.moveTo(origin.x, origin.y);
|
||||
|
||||
// Draw the path segments
|
||||
for (PathSegment segment : segments) {
|
||||
Vector2f startProjected = projectVertex(segment.getStart(), getWidth()/2, getHeight());
|
||||
Vector2f endProjected = projectVertex(segment.getEnd(), getWidth()/2, getHeight());
|
||||
calculatedPath.lineTo(startProjected.x, startProjected.y);
|
||||
calculatedPath.lineTo(endProjected.x, endProjected.y);
|
||||
}
|
||||
|
||||
return calculatedPath;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
// Draw the sport preview canvas
|
||||
canvas.drawPath(referencePath, referencePaint);
|
||||
canvas.drawPath(performingPath, performingPaint);
|
||||
canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundColor);
|
||||
this.setBackgroundColor(0xFF000000); // Black
|
||||
if (this.exercise == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < axisVectors.length/2; i++)
|
||||
{
|
||||
canvas.drawLine(axisVectors[i*2].x, axisVectors[i*2].y, axisVectors[i*2+1].x, axisVectors[i*2+1].y, this.targetPaint);
|
||||
}
|
||||
|
||||
for ( Vector2f point : this.vectors)
|
||||
{
|
||||
canvas.drawRect(point.x, point.y, point.x + 5, point.y + 5, this.referencePaint);
|
||||
}
|
||||
/*
|
||||
// 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, (targetRadius * exerciseProgress.get()/1000.0f), this.referencePaint);
|
||||
referencePaint.setColor(
|
||||
Color.argb(
|
||||
255,
|
||||
(int)(255 * (1.0 - exerciseProgress.get()/1000.0f)),
|
||||
(int)(255 * exerciseProgress.get()/1000.0f),
|
||||
0
|
||||
)
|
||||
);*/
|
||||
|
||||
this.invalidate();
|
||||
|
||||
timePassed = (System.nanoTime() - startingTime) / 1E9D;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package com.example.fitbot;
|
||||
//usage: PlayAnimation(animationfile, Qicontext);
|
||||
// https://qisdk.softbankrobotics.com/sdk/doc/pepper-sdk/ch4_api/movement/reference/animation.html
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
package com.example.fitbot.util;
|
||||
|
||||
import com.aldebaran.qi.sdk.QiContext;
|
||||
import com.aldebaran.qi.sdk.builder.AnimateBuilder;
|
||||
@@ -8,15 +9,9 @@ import com.aldebaran.qi.sdk.builder.AnimationBuilder;
|
||||
import com.aldebaran.qi.sdk.object.actuation.Animate;
|
||||
import com.aldebaran.qi.sdk.object.actuation.Animation;
|
||||
|
||||
public class Animations extends AppCompatActivity {
|
||||
|
||||
public class Animations {
|
||||
|
||||
public static void Animate(String AnimationFile, QiContext ctx)
|
||||
{
|
||||
PlayAnimation(AnimationFile, ctx);
|
||||
}
|
||||
|
||||
public static void PlayAnimation(String AnimationFile, QiContext ctx)
|
||||
{
|
||||
int resId = ctx.getResources().getIdentifier(AnimationFile, "raw", ctx.getPackageName());
|
||||
|
||||
@@ -30,5 +25,4 @@ public class Animations extends AppCompatActivity {
|
||||
|
||||
animate.async().run();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package com.example.fitbot.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class ButtonNavigation {
|
||||
|
||||
/**
|
||||
* Sets up a button to navigate to a different activity when clicked.
|
||||
*
|
||||
* @param currentActivity The activity that contains the button
|
||||
* @param buttonId The ID of the button
|
||||
* @param targetActivity The activity to navigate to
|
||||
*/
|
||||
public static void setupButtonNavigation(Activity currentActivity, int buttonId, Class<? extends Activity> targetActivity) {
|
||||
Button button = currentActivity.findViewById(buttonId);
|
||||
button.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(currentActivity, targetActivity);
|
||||
currentActivity.startActivity(intent);
|
||||
currentActivity.finish();
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
package com.example.fitbot.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.aldebaran.qi.sdk.builder.SayBuilder;
|
||||
import com.aldebaran.qi.sdk.object.locale.Language;
|
||||
import com.aldebaran.qi.sdk.object.locale.Locale;
|
||||
import com.aldebaran.qi.sdk.object.locale.Region;
|
||||
import com.example.fitbot.R;
|
||||
import com.aldebaran.qi.sdk.QiContext;
|
||||
import com.aldebaran.qi.sdk.builder.AnimateBuilder;
|
||||
import com.aldebaran.qi.sdk.builder.AnimationBuilder;
|
||||
import com.aldebaran.qi.sdk.object.actuation.Animate;
|
||||
import com.aldebaran.qi.sdk.object.actuation.Animation;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class FitnessCycle extends AppCompatActivity {
|
||||
|
||||
private static final Locale DUTCH_LOCALE = new Locale(Language.DUTCH, Region.NETHERLANDS);
|
||||
|
||||
|
||||
/**
|
||||
* Function for executing a movement animation a certain number of times
|
||||
* on the robot
|
||||
*
|
||||
* @param Exercise The name of the exercise to perform
|
||||
* @param Reps The number of repetitions to perform
|
||||
* @param qiContext The QiContext to use
|
||||
*/
|
||||
public static void executeMovement(String Exercise, int Reps, QiContext qiContext) {
|
||||
AtomicInteger repCount = new AtomicInteger(0);
|
||||
|
||||
Animation animation = AnimationBuilder.with(qiContext)
|
||||
.withResources(qiContext.getResources().getIdentifier(Exercise, "raw", qiContext.getPackageName()))
|
||||
.build();
|
||||
|
||||
Animate animate = AnimateBuilder.with(qiContext)
|
||||
.withAnimation(animation)
|
||||
.build();
|
||||
|
||||
// Add a listener for when a label is reached
|
||||
animate.addOnLabelReachedListener((label, time) -> {
|
||||
// Increment repCount when the end of a repetition is reached
|
||||
if ("end".equals(label)) {
|
||||
repCount.incrementAndGet();
|
||||
}
|
||||
});
|
||||
|
||||
// Run the animation the desired number of times
|
||||
for (int i = 0; i < Reps; i++) {
|
||||
animate.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for making the robot say something with DUTCH_LOCALE as locale
|
||||
* @param phrase The phrase to make the robot say
|
||||
* @param ctx The QiContext to use
|
||||
*/
|
||||
public static void say(String phrase, QiContext ctx)
|
||||
{
|
||||
say(phrase, ctx, DUTCH_LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for making the robot say something with a specific locale
|
||||
* @param phrase The phrase to make the robot say
|
||||
* @param ctx The QiContext to use
|
||||
* @param locale The locale to use
|
||||
*/
|
||||
public static void say(String phrase, QiContext ctx, Locale locale)
|
||||
{
|
||||
SayBuilder
|
||||
.with(ctx)
|
||||
.withLocale(locale)
|
||||
.withText(phrase)
|
||||
.build()
|
||||
.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for playing a video in a VideoView
|
||||
*
|
||||
* @param videoView The VideoView to play the video in
|
||||
* @param context The context to use
|
||||
*/
|
||||
public static void playVideo(VideoView videoView, Context context) {
|
||||
// Set up the video player
|
||||
if (videoView != null) {
|
||||
Uri videoUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.bicepvideo);
|
||||
videoView.setVideoURI(videoUri);
|
||||
|
||||
videoView.setOnCompletionListener(mp -> {
|
||||
// Repeat the video when it finishes playing
|
||||
videoView.start();
|
||||
});
|
||||
|
||||
videoView.start();
|
||||
} else {
|
||||
Log.e("FitnessActivity", "VideoView is null. Check your layout XML.");
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,24 +10,17 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new gesture path with a given set of vectors and curvature.
|
||||
*
|
||||
* @param vectors The vectors that make up the path.
|
||||
* @param curvature The curvature of the path.
|
||||
*/
|
||||
public GesturePath(Vector3f[] vectors, double curvature)
|
||||
public GesturePath(Vector3f[] vectors)
|
||||
{
|
||||
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 +32,6 @@ public class GesturePath {
|
||||
*/
|
||||
public GesturePath(PathSegment... segments) {
|
||||
this.segments = segments;
|
||||
this.curvature = 0.0d;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,9 +54,11 @@ public class GesturePath {
|
||||
if ( segments.length == 1)
|
||||
return segments[0];
|
||||
|
||||
return Arrays
|
||||
.stream(segments)
|
||||
.reduce(segments[0], (a, b) -> PathSegment.closer(a, b, reference));
|
||||
PathSegment closest = segments[0];
|
||||
for ( int i = 1; i < segments.length; i++)
|
||||
closest = PathSegment.closer(closest, segments[i], reference);
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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)));
|
||||
}
|
||||
|
@@ -11,6 +11,6 @@ public interface IMotionDataConsumer {
|
||||
* @param sampleIndex The index of the current sample
|
||||
* @param sampleRate The sample rate.
|
||||
*/
|
||||
void accept(Vector3f transformedVector, MotionData motionData, int sampleIndex, double sampleRate);
|
||||
void accept(Vector3f transformedVector, MotionData motionData, int sampleIndex, double sampleRate, int sensorId);
|
||||
|
||||
}
|
@@ -8,6 +8,7 @@ public class MotionData {
|
||||
|
||||
// Data of the motion sensor
|
||||
public Vector3f acceleration, rotation;
|
||||
public int sensorId;
|
||||
|
||||
// Delimiter for the data received from the motion sensor
|
||||
private static final String DATA_DELIMITER = ";";
|
||||
@@ -21,10 +22,10 @@ public class MotionData {
|
||||
* @param rotationX The rotation in the X axis in degrees.
|
||||
* @param rotationY The rotation in the Y axis in degrees.
|
||||
* @param rotationZ The rotation in the Z axis in degrees.
|
||||
* @param sensorId The sensor id.
|
||||
*/
|
||||
public MotionData(float accelerationX, float accelerationY, float accelerationZ, float rotationX, float rotationY, float rotationZ) {
|
||||
this.acceleration = new Vector3f(accelerationX, accelerationY, accelerationZ);
|
||||
this.rotation = new Vector3f(rotationX, rotationY, rotationZ);
|
||||
public MotionData(float accelerationX, float accelerationY, float accelerationZ, float rotationX, float rotationY, float rotationZ, int sensorId) {
|
||||
this(new Vector3f(accelerationX, accelerationY, accelerationZ), new Vector3f(rotationX, rotationY, rotationZ), sensorId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,9 +34,10 @@ public class MotionData {
|
||||
* @param acceleration The acceleration vector in m/s^2.
|
||||
* @param rotation The rotation vector in degrees.
|
||||
*/
|
||||
public MotionData(Vector3f acceleration, Vector3f rotation) {
|
||||
public MotionData(Vector3f acceleration, Vector3f rotation, int sensorId) {
|
||||
this.acceleration = acceleration;
|
||||
this.rotation = rotation;
|
||||
this.sensorId = sensorId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +52,7 @@ public class MotionData {
|
||||
Objects.requireNonNull(data); // Ensure data is not null
|
||||
|
||||
String[] parts = data.split(DATA_DELIMITER);
|
||||
if (parts.length != 6)
|
||||
if (parts.length != 7)
|
||||
return null;
|
||||
|
||||
return new MotionData(
|
||||
@@ -59,7 +61,8 @@ public class MotionData {
|
||||
Float.parseFloat(parts[2]),
|
||||
Float.parseFloat(parts[3]),
|
||||
Float.parseFloat(parts[4]),
|
||||
Float.parseFloat(parts[5])
|
||||
Float.parseFloat(parts[5]),
|
||||
Integer.parseInt(parts[6])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -3,10 +3,14 @@ package com.example.fitbot.util.processing;
|
||||
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 com.example.fitbot.util.server.WebServer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Matrix3d;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -17,14 +21,16 @@ public class MotionProcessor {
|
||||
|
||||
public static final String DELIMITER = ";";
|
||||
|
||||
private final List<MotionData> preprocessedData = new ArrayList<>(); // Preprocessed motion data
|
||||
private final List<Vector3f> relativePath = new ArrayList<>(); // Relative path of the motion data
|
||||
private final List<Vector3f> relativeLeftPath = new ArrayList<>(); // Relative path of the left motion data
|
||||
private final List<Vector3f> relativeRightPath = new ArrayList<>(); // Relative path of the motion data
|
||||
|
||||
private Vector3f ZERO = new Vector3f(0, 0, 0);
|
||||
|
||||
private float sampleRate = 1.0F; // samples/second
|
||||
private IMotionDataConsumer motionDataConsumer = (p1, p2, p3, p4) -> {};
|
||||
private GesturePath path;
|
||||
private WebSocket socket;
|
||||
private final float sampleRate = 1.0f / 10.0F; // samples/second
|
||||
|
||||
private IMotionDataConsumer motionDataConsumer = (p1, p2, p3, p4, p5) -> { };
|
||||
private WebServer server;
|
||||
|
||||
|
||||
public MotionProcessor() {}
|
||||
|
||||
@@ -37,20 +43,14 @@ public class MotionProcessor {
|
||||
*/
|
||||
public void startListening() {
|
||||
// Create socket server
|
||||
this.socket = WebSocket.createServer();
|
||||
this.server = WebServer.createServer();
|
||||
|
||||
Log.i("MotionProcessor", "Listening for incoming connections.");
|
||||
|
||||
// Check if the socket
|
||||
if (socket != null) {
|
||||
if (server != null) {
|
||||
// Update event handler to match our functionality.
|
||||
socket.setEventHandler(new IWebSocketHandler() {
|
||||
@Override
|
||||
public void onMessageReceived(WebSocket.Message message, WebSocket.MessageReply replier) {
|
||||
parsePacket(message.message);
|
||||
}
|
||||
});
|
||||
socket.startListening();
|
||||
server.setEventHandler(this::parsePacket);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,44 +60,58 @@ public class MotionProcessor {
|
||||
* the WebSocket server.
|
||||
*/
|
||||
public void stopListening() {
|
||||
if (socket != null) {
|
||||
socket.stop();
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for parsing arbitrary packet data.
|
||||
*
|
||||
* @param data The data to parse.
|
||||
*/
|
||||
public void parsePacket(@NotNull String data) {
|
||||
// If the message starts with 'data', it's a data packet.
|
||||
if ( data.startsWith("data")) {
|
||||
Log.i("MotionProcessor", "Received data packet: " + data.split(" ")[1]);
|
||||
MotionData parsedData = MotionData.decode(data.split(" ")[1]);
|
||||
if (parsedData != null) {
|
||||
addMotionData(parsedData);
|
||||
}
|
||||
// Otherwise check if it starts with 'calibrate', this is the ZERO point.
|
||||
} else if ( data.startsWith("zero")) { // message to calibrate device
|
||||
String[] vectorData = data.split(" ")[1].split(DELIMITER);
|
||||
ZERO = new Vector3f(
|
||||
Float.parseFloat(vectorData[0]),
|
||||
Float.parseFloat(vectorData[1]),
|
||||
Float.parseFloat(vectorData[2])
|
||||
);
|
||||
Log.i("MotionProcessor", "Device calibrated at " + ZERO.toString());
|
||||
} else if ( data.startsWith("sampleRate")) {
|
||||
this.sampleRate = Float.parseFloat(data.split(" ")[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for setting the gesture path of the processor.
|
||||
*
|
||||
* @param path The path to set.
|
||||
*/
|
||||
public void setGesturePath(GesturePath path) {
|
||||
this.path = path;
|
||||
try {
|
||||
|
||||
Log.i("MotionProcessor", "Received packet data: " + data);
|
||||
|
||||
JsonElement json = JsonParser.parseString(data);
|
||||
|
||||
if (!json.isJsonObject())
|
||||
return;
|
||||
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
|
||||
String[] required = {
|
||||
"rotationX", "rotationY", "rotationZ",
|
||||
"accelerationX", "accelerationY", "accelerationZ",
|
||||
"type",
|
||||
"deviceId"
|
||||
};
|
||||
|
||||
// Ensure all properties are present in the received JSON object
|
||||
for (String s : required) {
|
||||
if (!object.has(s))
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the data
|
||||
Vector3f rotation = new Vector3f(object.get("rotationX").getAsFloat(), object.get("rotationY").getAsFloat(), object.get("rotationZ").getAsFloat());
|
||||
Vector3f acceleration = new Vector3f(object.get("accelerationX").getAsFloat(), object.get("accelerationY").getAsFloat(), object.get("accelerationZ").getAsFloat());
|
||||
int deviceId = object.get("deviceId").getAsInt();
|
||||
String type = object.get("type").getAsString();
|
||||
MotionData motionData = new MotionData(rotation, acceleration, deviceId);
|
||||
|
||||
if (type.equals("calibrate")) {
|
||||
ZERO = getRelativeVector(motionData);
|
||||
return;
|
||||
}
|
||||
|
||||
addMotionData(motionData);
|
||||
} catch (Exception e) {
|
||||
Log.i("MotionProcessor", "Failed to parse packet data.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,29 +120,35 @@ public class MotionProcessor {
|
||||
* @param data The motion data to add.
|
||||
*/
|
||||
public void addMotionData(MotionData data) {
|
||||
preprocessedData.add(data);
|
||||
Vector3f previous = this.relativePath.isEmpty() ? ZERO : this.relativePath.get(this.relativePath.size() - 1);
|
||||
List<Vector3f> target;
|
||||
if (data.sensorId == 0)
|
||||
target = relativeLeftPath;
|
||||
else target = relativeRightPath;
|
||||
Vector3f previous = target.isEmpty() ? ZERO : target.get(target.size() - 1);
|
||||
Vector3f relativeVector = getRelativeVector(data).add(previous);
|
||||
this.relativePath.add(relativeVector);
|
||||
motionDataConsumer.accept(relativeVector, data, this.relativePath.size(), this.sampleRate);
|
||||
target.add(relativeVector);
|
||||
motionDataConsumer.accept(relativeVector, data, target.size(), this.sampleRate, data.sensorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for updating the relative path.
|
||||
*
|
||||
* @param relativePath The new relative path.
|
||||
* @param relativeRightPath The new relative path.
|
||||
*/
|
||||
public void setRelativePath(List<Vector3f> relativePath) {
|
||||
this.relativePath.clear();
|
||||
this.relativePath.addAll(relativePath);
|
||||
public void setRelativePaths(List<Vector3f> relativeLeftPath, List<Vector3f> relativeRightPath) {
|
||||
this.relativeRightPath.clear();
|
||||
this.relativeLeftPath.clear();
|
||||
this.relativeLeftPath.addAll(relativeLeftPath);
|
||||
this.relativeRightPath.addAll(relativeRightPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for setting the motion data receiver.
|
||||
*
|
||||
* @param consumer The consumer to set.
|
||||
*/
|
||||
public void setMotionDataEventHandler(IMotionDataConsumer consumer) {
|
||||
if ( consumer != null)
|
||||
if (consumer != null)
|
||||
this.motionDataConsumer = consumer;
|
||||
}
|
||||
|
||||
@@ -146,12 +166,16 @@ public class MotionProcessor {
|
||||
// Rotate the acceleration vector back by the rotation vector to make it
|
||||
// perpendicular to the gravity vector, then apply double integration to get the relative position.
|
||||
// s = 1/2 * a * t^2
|
||||
return motionData.acceleration
|
||||
.rotateX(-motionData.rotation.x)
|
||||
.rotateY(-motionData.rotation.y)
|
||||
// Step 2: Create rotation matrices for each axis
|
||||
// Step 4: Rotate the acceleration vector
|
||||
|
||||
return motionData.rotation
|
||||
.mul(5);
|
||||
/*return motionData.acceleration
|
||||
.rotateZ(-motionData.rotation.z)
|
||||
.div(2)
|
||||
.mul(sampleRate * sampleRate);
|
||||
.rotateY(-motionData.rotation.y)
|
||||
.rotateX(-motionData.rotation.x)
|
||||
.mul(sampleRate * sampleRate / 2);*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,48 +187,21 @@ public class MotionProcessor {
|
||||
*/
|
||||
public List<Double> getErrors(GesturePath referencePath) {
|
||||
|
||||
// Return the errors of the relative path compared to the reference path.
|
||||
return relativePath
|
||||
.stream()
|
||||
.map(referencePath::getError)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for getting the error offsets of the motion data compared to the
|
||||
* reference path.
|
||||
*
|
||||
* @return A list of error offsets of the motion data compared to the reference path.
|
||||
* If no path is set, an empty list will be returned.
|
||||
*/
|
||||
public List<Double> getErrors() {
|
||||
if ( path == null)
|
||||
return new ArrayList<>();
|
||||
return getErrors(path);
|
||||
List<Double> errors = new ArrayList<>();
|
||||
for (Vector3f vector : relativeRightPath) {
|
||||
errors.add(referencePath.getError(vector));
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for getting the error of the motion data compared to the reference path.
|
||||
*
|
||||
* @param path The path to compare the motion data to.
|
||||
* @param path The path to compare the motion data to.
|
||||
* @param referencePoint The reference point to compare the motion data to.
|
||||
* @return The error of the motion data compared to the reference path.
|
||||
*/
|
||||
public double getError(GesturePath path, Vector3f referencePoint)
|
||||
{
|
||||
return path.getError(referencePoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for getting the error of the provided vector and the set path.
|
||||
* If no path is set, the error will be 0.
|
||||
*
|
||||
* @param referencePoint The reference point to compare the path data to.
|
||||
* @return The error of the motion data compared to the reference path.
|
||||
*/
|
||||
public double getError(Vector3f referencePoint) {
|
||||
if ( path == null)
|
||||
return 0;
|
||||
public double getError(GesturePath path, Vector3f referencePoint) {
|
||||
return path.getError(referencePoint);
|
||||
}
|
||||
|
||||
@@ -215,24 +212,12 @@ public class MotionProcessor {
|
||||
* @param referencePath The reference path to compare the motion data to.
|
||||
* @return The average error of the motion data compared to the reference path.
|
||||
*/
|
||||
public double getAverageError(GesturePath referencePath) {
|
||||
return getErrors(referencePath)
|
||||
.stream()
|
||||
.mapToDouble(Double::doubleValue)
|
||||
.average()
|
||||
.orElse(0.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for calculating the average error of the motion data
|
||||
* compared to the reference path.
|
||||
*
|
||||
* @return The average error of the motion data compared to the reference path.
|
||||
*/
|
||||
public double getAverageError() {
|
||||
if ( path == null)
|
||||
return 0;
|
||||
return getAverageError(path);
|
||||
public double getAverageError(GesturePath referencePath, int sensorId) {
|
||||
double error = 0;
|
||||
for (Double e : getErrors(referencePath)) {
|
||||
error += e;
|
||||
}
|
||||
return error / Math.max(1, (sensorId == 0 ? relativeLeftPath : relativeRightPath).size());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,8 +226,7 @@ public class MotionProcessor {
|
||||
* @param referencePath The reference path to compare the motion data to.
|
||||
*/
|
||||
public void logStatistics(GesturePath referencePath) {
|
||||
Log.i("MotionProcessor", "Average path error: " + getAverageError(referencePath));
|
||||
Log.i("MotionProcessor", "Path length: " + relativePath.size());
|
||||
Log.i("MotionProcessor", "Path length: " + relativeRightPath.size());
|
||||
Log.i("MotionProcessor", "Sample rate: " + sampleRate);
|
||||
Log.i("MotionProcessor", "Calibration point: " + ZERO.toString());
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* Interface for handling WebSocket events.
|
||||
*/
|
||||
public interface IWebServerHandler {
|
||||
|
||||
void onReceive(String body);
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* Interface for handling WebSocket events.
|
||||
*/
|
||||
public interface IWebSocketHandler {
|
||||
|
||||
// Function for handling the connection of the WebSocket.
|
||||
default void onConnected(Socket socket) {}
|
||||
|
||||
default void onDisconnected(Socket socket) {}
|
||||
|
||||
default void onMessageReceived(WebSocket.Message message, WebSocket.MessageReply replier) {}
|
||||
|
||||
default void onError(Socket socket, String error) {}
|
||||
}
|
@@ -0,0 +1,143 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
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;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class WebServer implements Runnable {
|
||||
|
||||
private ServerSocket serverSocket;
|
||||
protected IWebServerHandler eventHandler = (input) -> {}; // No-op.
|
||||
|
||||
private Thread thread;
|
||||
private AtomicBoolean forceClose = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* Constructor for creating a new WebSocket server.
|
||||
*/
|
||||
private WebServer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for creating a new WebSocket server given the provided port.
|
||||
*
|
||||
* @return A WebSocket connection, or null if something went wrong.
|
||||
*/
|
||||
public static WebServer createServer() {
|
||||
try {
|
||||
WebServer server = new WebServer();
|
||||
server.serverSocket = new ServerSocket();
|
||||
server.serverSocket.bind(new InetSocketAddress(3445));
|
||||
server.serverSocket.setSoTimeout(0);
|
||||
|
||||
Log.i("WebServer", "Server created: " + server.serverSocket.getLocalSocketAddress() + ", " + server.serverSocket.getLocalPort());
|
||||
|
||||
server.thread = new Thread(server);
|
||||
server.thread.start();
|
||||
|
||||
return server;
|
||||
} catch (IOException error) {
|
||||
String cause = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebServer", cause);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Listen for new connections until the socket closes.
|
||||
while (this.isConnected() && !this.forceClose.get()) {
|
||||
try {
|
||||
// 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));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
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");
|
||||
|
||||
if ( data.length > 1) { // Check if the data is valid.
|
||||
this.eventHandler.onReceive(data[1]);
|
||||
}
|
||||
|
||||
} catch (IOException error) {
|
||||
String reason = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebServerConnectionHandler", "Error listening to Socket connections: " + reason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for stopping the WebSocket server.
|
||||
*/
|
||||
public void stop() {
|
||||
try {
|
||||
this.serverSocket.close();
|
||||
this.forceClose.set(true);
|
||||
} catch (IOException error) {
|
||||
String cause = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebServer", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for setting the event handler for this WebSocket server.
|
||||
*
|
||||
* @param handler The handler to use. This handler will parse all events
|
||||
* that occur in this WebSocket connection. The events are the followed:
|
||||
* - onMessageReceived(Socket, String)
|
||||
* - onConnected(Socket)
|
||||
* - onDisconnected(Socket)
|
||||
* - onError(Socket, String)
|
||||
*/
|
||||
public void setEventHandler(IWebServerHandler handler) {
|
||||
this.eventHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for getting the ServerSocket connection
|
||||
*
|
||||
* @return The ServerSocket connection.
|
||||
*/
|
||||
public ServerSocket getSocket() {
|
||||
return this.serverSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for checking whether this WebSocket connection is connected.
|
||||
*
|
||||
* @return The connection status of the WebSocket.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return !this.serverSocket.isClosed();
|
||||
}
|
||||
}
|
@@ -1,150 +0,0 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class WebSocket {
|
||||
|
||||
private ServerSocket serverSocket;
|
||||
private WebSocketConnectionHandler connectionHandler;
|
||||
private final Set<Socket> clients = Collections.synchronizedSet(new HashSet<>());
|
||||
protected IWebSocketHandler eventHandler = new IWebSocketHandler() {}; // NO-OP event handler.
|
||||
|
||||
/**
|
||||
* Constructor for creating a new WebSocket server.
|
||||
*/
|
||||
private WebSocket() {}
|
||||
|
||||
/**
|
||||
* Function for creating a new WebSocket server given the provided port.
|
||||
* @return A WebSocket connection, or null if something went wrong.
|
||||
*/
|
||||
public static @Nullable WebSocket createServer() {
|
||||
try {
|
||||
WebSocket webSocket = new WebSocket();
|
||||
webSocket.serverSocket = new ServerSocket();
|
||||
webSocket.serverSocket.bind(webSocket.serverSocket.getLocalSocketAddress());
|
||||
Log.i("WebSocket -- Creating new WebSocket server", "Server created: " + webSocket.serverSocket.getLocalSocketAddress() + ", " + webSocket.serverSocket.getLocalPort());
|
||||
return webSocket;
|
||||
} catch (IOException error)
|
||||
{
|
||||
String cause = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebSocket -- Creating new WebSocket server", cause);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for listening for incoming connections.
|
||||
*/
|
||||
public void startListening() {
|
||||
this.connectionHandler = new WebSocketConnectionHandler(this);
|
||||
this.connectionHandler.listen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for stopping the WebSocket server.
|
||||
*/
|
||||
public void stop() {
|
||||
try {
|
||||
this.serverSocket.close();
|
||||
this.connectionHandler.stop();
|
||||
} catch (IOException error) {
|
||||
String cause = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebSocket -- Closing server connection", cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for setting the event handler for this WebSocket server.
|
||||
* @param handler The handler to use. This handler will parse all events
|
||||
* that occur in this WebSocket connection. The events are the followed:
|
||||
* - onMessageReceived(Socket, String)
|
||||
* - onConnected(Socket)
|
||||
* - onDisconnected(Socket)
|
||||
* - onError(Socket, String)
|
||||
*/
|
||||
public void setEventHandler(IWebSocketHandler handler) {
|
||||
this.eventHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for getting the ServerSocket connection
|
||||
* @return The ServerSocket connection.
|
||||
*/
|
||||
public ServerSocket getSocket() {
|
||||
return this.serverSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for checking whether this WebSocket connection is connected.
|
||||
* @return The connection status of the WebSocket.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return !this.serverSocket.isClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing a message received from a WebSocket connection.
|
||||
*/
|
||||
public static class Message {
|
||||
|
||||
// Enumerable representing message type (opcode).
|
||||
public enum Opcode {
|
||||
|
||||
CONTINUING((byte) 0x0),
|
||||
TEXT((byte) 0x1),
|
||||
BINARY((byte) 0x2),
|
||||
RES0((byte) 0x3), RES1((byte) 0x4), RES2((byte) 0x5), RES3((byte) 0x6), RES4((byte) 0x7),
|
||||
CLOSE_CONNECTION((byte) 0x8),
|
||||
PING((byte) 0x9),
|
||||
PONG((byte) 0xA),
|
||||
RES5((byte) 0xB), RES6((byte) 0xC), RES7((byte) 0xD), RES8((byte) 0xE), RES9((byte) 0xF);
|
||||
|
||||
byte opcode;
|
||||
Opcode(final byte opcode) {
|
||||
this.opcode = opcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for decoding the opcode of a message.
|
||||
* @param opcode The opcode to decode.
|
||||
* @return The message type.
|
||||
*/
|
||||
public static Opcode decode(byte opcode) {
|
||||
return Opcode.values()[opcode & 0xF];
|
||||
}
|
||||
// Returns the opcode of this message type.
|
||||
public byte getOpcode() { return this.opcode; }
|
||||
}
|
||||
|
||||
public String message;
|
||||
public WebSocketConnection connection;
|
||||
|
||||
/**
|
||||
* Constructor for a WebSocket message.
|
||||
* @param message The message that was sent
|
||||
* @param connection The connection where the message came from.
|
||||
*/
|
||||
public Message(WebSocketConnection connection, String message) {
|
||||
this.message = message;
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for a message reply.
|
||||
* This can be used for when a message has been received from a client
|
||||
* to reply back to the client.
|
||||
*/
|
||||
public interface MessageReply {
|
||||
void reply(String message);
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
public class WebSocketConnection {
|
||||
|
||||
private final WebSocket origin;
|
||||
private final Socket socket;
|
||||
|
||||
/**
|
||||
* Constructor for creating an arbitrary WebSocket connection (Client)
|
||||
* @param connection The server connection
|
||||
* @param socket The client socket
|
||||
*/
|
||||
public WebSocketConnection(WebSocket connection, Socket socket) {
|
||||
this.origin = connection;
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for retrieving the WebSocket connection
|
||||
* @return The WebSocket instance.
|
||||
*/
|
||||
public WebSocket getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for retrieving the Client Socket connection.
|
||||
* @return The Socket connection.
|
||||
*/
|
||||
public Socket getSocket() {
|
||||
return socket;
|
||||
}
|
||||
}
|
@@ -1,217 +0,0 @@
|
||||
package com.example.fitbot.util.server;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class WebSocketConnectionHandler implements Runnable {
|
||||
|
||||
private final WebSocket theSocket;
|
||||
private List<Socket> clients = Collections.synchronizedList(new ArrayList<>());
|
||||
private Thread thread;
|
||||
private boolean forceClose = false;
|
||||
|
||||
/**
|
||||
* Constructor for WebSocketConnectionHandler.
|
||||
* This class handles all new incoming Socket connections.
|
||||
*
|
||||
* @param webSocket The socket to check for new connections.
|
||||
*/
|
||||
protected WebSocketConnectionHandler(WebSocket webSocket) {
|
||||
this.theSocket = webSocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Listen for new connections until the socket closes.
|
||||
while (theSocket.isConnected()) {
|
||||
try {
|
||||
// Find a new connection
|
||||
Socket newSocket = this.theSocket.getSocket().accept();
|
||||
this.theSocket.eventHandler.onConnected(newSocket);
|
||||
clients.add(newSocket);
|
||||
|
||||
InputStream streamIn = newSocket.getInputStream();
|
||||
OutputStream streamOut = newSocket.getOutputStream();
|
||||
|
||||
// Check if the connection was successfully upgraded to WebSocket
|
||||
if (upgradeConnection(streamIn, streamOut)) {
|
||||
applyMessageDecoder(streamIn);
|
||||
}
|
||||
} catch (IOException error) {
|
||||
String reason = error.getMessage() == null ? "Unknown reason" : error.getMessage();
|
||||
Log.e("WebSocketConnectionHandler", "Error listening to Socket connections: " + reason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for upgrading a HTTP connection to a WebSocket connection.
|
||||
* This checks whether the client sent a GET header and sends back
|
||||
* the required headers to upgrade the connection.
|
||||
* @param streamIn The InputStream of the client socket connection.
|
||||
* @param streamOut The OutputStream of the client socket connection.
|
||||
* @return Whether or not the connection was successfully upgraded.
|
||||
*/
|
||||
private boolean upgradeConnection(InputStream streamIn, OutputStream streamOut) {
|
||||
Scanner scanner = new Scanner(streamIn, "UTF-8");
|
||||
String data = scanner.useDelimiter("\\r\\n\\r\\n").next();
|
||||
Matcher header = Pattern.compile("^GET").matcher(data);
|
||||
|
||||
// Check if the header contains the GET keyword
|
||||
// If this is the case, upgrade the HTTP connection to WebSocket.
|
||||
if (!header.find())
|
||||
return false;
|
||||
|
||||
Matcher match = Pattern.compile("Sec-WebSocket-Key: (.*)").matcher(data);
|
||||
match.find(); // Get next match
|
||||
|
||||
try {
|
||||
String SECAccept = Base64.getEncoder().encodeToString(
|
||||
MessageDigest.getInstance("SHA-1").digest((match.group(1) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes(StandardCharsets.UTF_8)));
|
||||
|
||||
byte[] response = (
|
||||
"HTTP/1.1 101 Switching Protocols\r\n" +
|
||||
"Connection: Upgrade\r\n" +
|
||||
"Upgrade: websocket\r\n" +
|
||||
"Sec-WebSocket-Accept: " +
|
||||
SECAccept + "\r\n\r\n").getBytes(StandardCharsets.UTF_8);
|
||||
streamOut.write(response, 0, response.length);
|
||||
|
||||
} catch (IOException | NoSuchAlgorithmException error) {
|
||||
Log.e("WebSocketConnectionHandler", "Failed upgrading HTTP to WebSocket connection" + error.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for applying a message decoder for whenever a socket receives data.
|
||||
* This method attemps to decode a message received from a WebSocket connection.
|
||||
* This message is in the
|
||||
* @param streamIn The message stream to decode.
|
||||
*/
|
||||
private void applyMessageDecoder(InputStream streamIn) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for decoding an encoded WebSocket message
|
||||
* @param bytes The message to decode, in UTF-8 format.
|
||||
* @return The decoded message.
|
||||
* @throws IllegalArgumentException When the `frame` content is in an incorrect format.
|
||||
*/
|
||||
public static String decodeWebSocketMessage(byte[] bytes) {
|
||||
// Check if the packet isn't corrupted
|
||||
if (bytes.length <= 2 || (bytes[0] & 0b1110) != 0)
|
||||
throw new IllegalArgumentException("Attempted to decode corrupted WebSocket frame data");
|
||||
|
||||
WebSocket.Message.Opcode opcode = WebSocket.Message.Opcode.decode((byte) (bytes[0] & 0b11110000));
|
||||
byte payloadLength = (byte) (bytes[1] & 0b01111111); // Payload size (7 bits)
|
||||
boolean fin = (bytes[0] & 0b1) != 0; // Whether this is the whole message
|
||||
boolean masked = (bytes[1] & 0b10000000) != 0; // Whether the 9th bit is masked
|
||||
|
||||
long extendedPayloadLength = 0;
|
||||
int byteOffset = 2;
|
||||
|
||||
// Check whether the payload length is 16-bit
|
||||
if (payloadLength == 126) {
|
||||
// 16-bit extended payload length (byte 2 and 3)
|
||||
extendedPayloadLength = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
|
||||
byteOffset += 2;
|
||||
|
||||
// Check whether payload length is 64-bit
|
||||
} else if (payloadLength == 127) {
|
||||
// 64-bit extended payload length
|
||||
for (int i = 0; i < 8; i++)
|
||||
extendedPayloadLength |= (long) (bytes[2 + i] & 0xFF) << ((7 - i) * 8);
|
||||
byteOffset += 8;
|
||||
|
||||
} else {
|
||||
extendedPayloadLength = payloadLength;
|
||||
}
|
||||
|
||||
byte[] maskingKey = null;
|
||||
byte[] payloadData = new byte[(int) extendedPayloadLength];
|
||||
|
||||
|
||||
// Check if the MASK bit was set, if so, copy the key to the `maskingKey` array.
|
||||
if (masked) {
|
||||
maskingKey = new byte[4];
|
||||
System.arraycopy(bytes, byteOffset, maskingKey, 0, 4); // move mask bytes
|
||||
byteOffset += 4;
|
||||
}
|
||||
|
||||
// Copy payload bytes into `payloadData` array.
|
||||
System.arraycopy(bytes, byteOffset, payloadData, 0, payloadData.length);
|
||||
|
||||
// If mask is present, decode the payload data with the mask.
|
||||
if (masked)
|
||||
for (int i = 0; i < payloadData.length; i++)
|
||||
payloadData[i] ^= maskingKey[i % 4];
|
||||
|
||||
// Convert payload data to string
|
||||
return new String(payloadData, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for checking whether the connection handler is actively listening.
|
||||
* @return Whether it's listening.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return this.thread.isAlive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for listening to all new incoming socket connections.
|
||||
*/
|
||||
public void listen() {
|
||||
this.thread = new Thread(this);
|
||||
this.thread.start();
|
||||
Log.i("WebSocketConnectionHandler", "Listening started.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for stopping the connection handler.
|
||||
*/
|
||||
public void stop() {
|
||||
// Close the socket connection if not already closed
|
||||
if (!this.theSocket.getSocket().isClosed()) {
|
||||
try {
|
||||
this.theSocket.getSocket().close();
|
||||
} catch (IOException error) {
|
||||
Log.e("WebSocketConnectionHandler", "Failed to close the socket connection: " + error.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt the thread
|
||||
this.thread.interrupt();
|
||||
|
||||
// Close all connections
|
||||
this.clients.forEach(client -> {
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException error) {
|
||||
Log.e("WebSocketConnectionHandler", "Failed to close client: " + error.getMessage());
|
||||
}
|
||||
});
|
||||
this.clients.clear();
|
||||
|
||||
|
||||
Log.i("WebSocketConnectionHandler", "Listening stopped.");
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/darkBlue" />
|
||||
<stroke android:width="4dp" android:color="@color/white" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
@@ -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>
|
@@ -2,11 +2,11 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<corners
|
||||
android:radius="20dp"
|
||||
android:radius="15dp"
|
||||
/>
|
||||
|
||||
<gradient
|
||||
android:startColor="#660000"
|
||||
android:endColor="#990000"
|
||||
android:startColor="#990000"
|
||||
android:endColor="#FF0000"
|
||||
android:angle="90"/>
|
||||
</shape>
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/midBlue" />
|
||||
<stroke android:width="2dp" android:color="#FF0000" />
|
||||
<corners android:radius="10dp" />
|
||||
</shape>
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/lightBlue" />
|
||||
<stroke android:width="2dp" android:color="#FF0000" />
|
||||
<corners android:radius="20dp" />
|
||||
</shape>
|
@@ -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="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||
</vector>
|
@@ -9,4 +9,5 @@
|
||||
android:startColor="#990000"
|
||||
android:endColor="#FF0000"
|
||||
android:angle="90"/>
|
||||
|
||||
</shape>
|
108
code/src/Fitbot/app/src/main/res/layout/activity_end_screen.xml
Normal file
@@ -0,0 +1,108 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/darkBlue"
|
||||
tools:context=".ui.activities.HelpActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="800dp"
|
||||
android:layout_height="450dp"
|
||||
android:layout_marginStart="80dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:background="@drawable/help2_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewTitleEndScreen"
|
||||
style="@style/TextStyleTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/klaar" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="700dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewDescriptionEndScreen"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/voltooid" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="700dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewScoreEndScreen"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/score"
|
||||
android:textAlignment="center"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/homeButtonEndScreen"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_marginEnd="280dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:drawableTop="@drawable/ic_baseline_home_48"
|
||||
android:drawableTint="@color/white"
|
||||
android:padding="15dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/startButtonEndScreen"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_marginStart="280dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:text="@string/start"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:padding="15dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@@ -1,10 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
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="@color/darkBlue"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.activities.FitnessActivity"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<com.example.fitbot.ui.components.PersonalMotionPreviewElement
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
<LinearLayout
|
||||
android:layout_width="900dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:padding="15dp"
|
||||
android:background="@drawable/help2_background"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/videoView"
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="400dp"
|
||||
android:layout_marginStart="20dp"
|
||||
/>
|
||||
|
||||
<com.example.fitbot.ui.components.PersonalMotionPreviewElement
|
||||
android:id="@+id/personalMotionPreviewElement"
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="400dp"
|
||||
android:layout_marginStart="20dp"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/homeButtonFitness"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_marginStart="404dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:drawableTop="@drawable/ic_baseline_home_48"
|
||||
android:drawableTint="@color/white"
|
||||
android:padding="15dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
94
code/src/Fitbot/app/src/main/res/layout/activity_help.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/darkBlue"
|
||||
tools:context=".ui.activities.HelpActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/homeButtonHelp"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_marginStart="404dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:drawableTop="@drawable/ic_baseline_home_48"
|
||||
android:drawableTint="@color/white"
|
||||
android:padding="15dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="800dp"
|
||||
android:layout_height="450dp"
|
||||
android:layout_marginStart="80dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:background="@drawable/help2_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewTitleHelp"
|
||||
style="@style/TextStyleTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/help" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="700dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewStartHelp"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/uitlegStart" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="700dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/help_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewHomeHelp"
|
||||
style="@style/TextStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/uitlegHome" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@@ -4,91 +4,110 @@
|
||||
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.MainActivity"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<LinearLayout
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/linearLayout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar" />
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="524dp"
|
||||
android:layout_height="77dp"
|
||||
android:layout_marginStart="378dp"
|
||||
android:layout_marginTop="80dp"
|
||||
android:text="@string/welkom_bij_fitbot"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="64sp" />
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="208dp"
|
||||
android:layout_marginTop="120dp"
|
||||
android:background="@drawable/box_background"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView3"
|
||||
android:layout_width="510dp"
|
||||
android:layout_height="39dp"
|
||||
android:layout_marginStart="385dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@string/robot_helpt"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp" />
|
||||
<TextView
|
||||
android:id="@+id/textViewWelkom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/welkom_bij_fitbot"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="64sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewFit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/robot_helpt"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp"
|
||||
android:translationX="8dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startButton"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="490dp"
|
||||
android:layout_marginTop="100dp"
|
||||
android:id="@+id/startButtonMain"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_marginStart="368dp"
|
||||
android:layout_marginTop="312dp"
|
||||
android:background="@drawable/red_button_gradient"
|
||||
android:text="@string/start"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="80sp"
|
||||
android:textAllCaps="false"
|
||||
android:background="@drawable/red_button_gradient"/>
|
||||
android:gravity="center"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/helpButton"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="560dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:id="@+id/helpButtonMain"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="420dp"
|
||||
android:layout_marginTop="424dp"
|
||||
android:background="@drawable/darkred_button_gradient"
|
||||
android:text="@string/help"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="40sp"
|
||||
android:textAllCaps="false"
|
||||
android:background="@drawable/darkred_button_gradient"/>
|
||||
android:gravity="center"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView2"
|
||||
android:layout_width="375dp"
|
||||
android:layout_height="375dp"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginTop="-180dp"
|
||||
app:srcCompat="@drawable/robot_logo_inverted"
|
||||
android:contentDescription="@string/todo" />
|
||||
android:id="@+id/imageViewRobotLogo"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="340dp"
|
||||
android:contentDescription="@string/robot_logo"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/robot_logo_inverted" />
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/menu_switch_btn"-->
|
||||
<!-- android:layout_width="200dp"-->
|
||||
<!-- android:layout_height="50dp"-->
|
||||
<!-- android:clickable="true"-->
|
||||
<!-- android:text="Go to Sport Menu"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
|
||||
<!-- android:focusable="true" />-->
|
||||
|
||||
</LinearLayout>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.design.widget.NavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:background="@color/darkBlue"
|
||||
app:headerLayout="@layout/header"
|
||||
app:itemIconTint="@color/white"
|
||||
app:itemTextColor="@color/white"
|
||||
|
||||
app:menu="@menu/main_menu" />
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
@@ -1,10 +1,9 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:orientation="vertical"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/ic_launcher_background"
|
||||
android:layout_gravity="top"
|
||||
android:padding="10dp">
|
||||
@@ -25,6 +24,7 @@
|
||||
android:layout_marginTop="60dp"
|
||||
android:text="FitBot"
|
||||
android:textSize="48sp"
|
||||
android:textColor="@color/darkBlue"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
@@ -4,6 +4,5 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#00000000"
|
||||
android:elevation="8dp"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
|
||||
|
||||
android:theme="@style/ToolbarNav">
|
||||
</android.support.v7.widget.Toolbar>
|
@@ -12,20 +12,14 @@
|
||||
|
||||
<group android:checkableBehavior="single">
|
||||
|
||||
<item android:title="Options">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_48"
|
||||
android:title="Settings" />
|
||||
<item
|
||||
android:id="@+id/nav_rate"
|
||||
android:icon="@drawable/ic_baseline_star_rate_48"
|
||||
android:title="Rate" />
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_48"
|
||||
android:title="Settings" />
|
||||
<item
|
||||
android:id="@+id/nav_rate"
|
||||
android:icon="@drawable/ic_baseline_star_rate_48"
|
||||
android:title="Rate" />
|
||||
|
||||
</group>
|
||||
|
||||
|
@@ -2,7 +2,11 @@
|
||||
<Animation xmlns:editor="http://www.ald.softbankrobotics.com/animation/editor" typeVersion="2.0" editor:fps="25">
|
||||
<editor:clip editor:fps="25" editor:startFrame="24" editor:endFrame="79"/>
|
||||
<ActuatorCurve fps="25" actuator="LShoulderPitch" mute="false" unit="degree">
|
||||
<Key value="90.5273514" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="90.5273514" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="90.5273514" frame="10">
|
||||
@@ -14,7 +18,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="LShoulderRoll" mute="false" unit="degree">
|
||||
<Key value="6.67969275" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="89.5" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="6.67969275" frame="10">
|
||||
@@ -26,7 +34,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="LElbowYaw" mute="false" unit="degree">
|
||||
<Key value="-69.7851486" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-69.7851486" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-69.7851486" frame="10">
|
||||
@@ -38,7 +50,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="LElbowRoll" mute="false" unit="degree">
|
||||
<Key value="-29.7070332" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-29.7070332" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-29.7070332" frame="10">
|
||||
@@ -50,7 +66,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="LWristYaw" mute="false" unit="degree">
|
||||
<Key value="-1.76023543" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-1.76023543" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-1.76023543" frame="10">
|
||||
@@ -62,7 +82,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="LHand" mute="false" unit="dimensionless">
|
||||
<Key value="0.589630966" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="0.589630966" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="0.589630966" frame="10">
|
||||
@@ -74,7 +98,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RShoulderPitch" mute="false" unit="degree">
|
||||
<Key value="90.5273438" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="90.5273438" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="90.5273438" frame="10">
|
||||
@@ -86,7 +114,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RShoulderRoll" mute="false" unit="degree">
|
||||
<Key value="-6.59180212" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-89.5" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="-6.59180212" frame="10">
|
||||
@@ -98,7 +130,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RElbowYaw" mute="false" unit="degree">
|
||||
<Key value="70.2246094" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="70.2246094" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="70.2246094" frame="10">
|
||||
@@ -110,7 +146,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RElbowRoll" mute="false" unit="degree">
|
||||
<Key value="29.7070332" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="29.7070332" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="29.7070332" frame="10">
|
||||
@@ -122,7 +162,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RWristYaw" mute="false" unit="degree">
|
||||
<Key value="1.57964516" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="1.57964516" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="1.57964516" frame="10">
|
||||
@@ -134,7 +178,11 @@
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="RHand" mute="false" unit="dimensionless">
|
||||
<Key value="0.588752136" frame="0">
|
||||
<Tangent side="right" abscissaParam="2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="0.588752136" frame="7">
|
||||
<Tangent side="left" abscissaParam="-2.33333333" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
<Tangent side="right" abscissaParam="1" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
<Key value="0.588752136" frame="10">
|
||||
@@ -145,4 +193,19 @@
|
||||
<Tangent side="left" abscissaParam="-20" ordinateParam="0" editor:interpType="bezier_auto"/>
|
||||
</Key>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="HeadYaw" mute="false" unit="degree">
|
||||
<Key value="-0.439454377" frame="0"/>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="HeadPitch" mute="false" unit="degree">
|
||||
<Key value="-12.1289139" frame="0"/>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="HipRoll" mute="false" unit="degree">
|
||||
<Key value="-0.26367262" frame="0"/>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="HipPitch" mute="false" unit="degree">
|
||||
<Key value="-1.49414492" frame="0"/>
|
||||
</ActuatorCurve>
|
||||
<ActuatorCurve fps="25" actuator="KneePitch" mute="false" unit="degree">
|
||||
<Key value="0" frame="0"/>
|
||||
</ActuatorCurve>
|
||||
</Animation>
|
||||
|
6
code/src/Fitbot/app/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="PersonalMotionPreviewElement">
|
||||
|
||||
</declare-styleable>
|
||||
</resources>
|
@@ -7,4 +7,11 @@
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
<color name="darkBlue">#1C1C27</color>
|
||||
<color name="midBlue">#24242F</color>
|
||||
<color name="lightBlue">#2C2C37</color>
|
||||
<color name="invertedBackground">#FFFFFF</color>
|
||||
<color name="invertedTextColor">#000000</color>
|
||||
<color name="invertedIconTint">#000000</color>
|
||||
</resources>
|
||||
|
||||
|
@@ -4,9 +4,23 @@
|
||||
|
||||
<string name="navigation_drawer_open">Open navigation drawer</string>
|
||||
<string name="navigation_drawer_close">Open navigation close</string>
|
||||
|
||||
<string name="welkom_bij_fitbot">Welkom bij FitBot</string>
|
||||
<string name="robot_helpt">de robot die helpt om fit te blijven</string>
|
||||
|
||||
<string name="start">Start</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="todo">TODO</string>
|
||||
<string name="robot_logo" />
|
||||
<string name="home">Home</string>
|
||||
<string name="skip">Skip</string>
|
||||
<string name="complete">Complete</string>
|
||||
|
||||
<string name="uitlegStart">Druk op Start om de oefening te beginnen</string>
|
||||
<string name="uitlegHome">Ga terug naar het begin scherm door op het huisje te klikken</string>
|
||||
|
||||
<string name="klaar">Klaar!</string>
|
||||
<string name="voltooid">U heeft de oefeningen voltooid, druk op start om nog een sessie te beginnen</string>
|
||||
<string name="score">Score:</string>
|
||||
|
||||
</resources>
|
@@ -2,8 +2,33 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:statusBarColor">#00000000</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:colorBackground">@color/darkBlue</item>
|
||||
</style>
|
||||
|
||||
<style name="ToolbarNav" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:textColorSecondary">@color/white</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">25sp</item>
|
||||
<item name="android:textColor">#FFFFFF</item>
|
||||
<item name= "android:textStyle">bold</item>
|
||||
<item name="android:padding">6dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextStyleTitle">
|
||||
<item name="android:textSize">50sp</item>
|
||||
<item name="android:textColor">#D3D3D3</item>
|
||||
<item name= "android:textStyle">bold</item>
|
||||
<item name="android:padding">6dp</item>
|
||||
</style>
|
||||
</resources>
|
@@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Fitbot" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
@@ -7,4 +8,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));
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package com.example.fitbot;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.example.fitbot.util.server.WebSocketConnectionHandler;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Created on 07/05/2024 at 18:27
|
||||
* by Luca Warmenhoven.
|
||||
*/
|
||||
public class WebSocketMessageParsingTest {
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void parseWebSocketMessage() {
|
||||
|
||||
String reference = "abcdef";
|
||||
final byte[] encoded = {
|
||||
(byte) 129, (byte) 134, (byte) 167,
|
||||
(byte) 225, (byte) 225, (byte) 210,
|
||||
(byte) 198, (byte) 131, (byte) 130,
|
||||
(byte) 182, (byte) 194, (byte) 135
|
||||
};
|
||||
String decoded = "";
|
||||
try {
|
||||
decoded = WebSocketConnectionHandler.decodeWebSocketMessage(encoded);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error occurred whilst attempting to parse input" + e.getMessage());
|
||||
}
|
||||
assertEquals(reference, decoded);
|
||||
}
|
||||
}
|
@@ -1,11 +1,71 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Request} request The incoming request
|
||||
* @param {Response} response The response to send back
|
||||
* @param {Express} app Express app instance
|
||||
* @param {Pool} pool MariaDB pool instance
|
||||
*/
|
||||
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';
|
||||
} else parameters.push(request.uid);
|
||||
|
||||
// Acquire database connection
|
||||
pool.getConnection()
|
||||
.then(conn => {
|
||||
conn.query(query, parameters)
|
||||
.then(rows => {
|
||||
if (rows.length === 0)
|
||||
{
|
||||
response
|
||||
.status(404)
|
||||
.send(JSON.stringify({error: 'Exercise not found'}));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send back the data in the right format
|
||||
let converted = rows.map(row => {
|
||||
return {
|
||||
name: row.Name,
|
||||
description: row.Description,
|
||||
muscleGroup: row.MuscleGroup,
|
||||
imageUrl: row.ImageURL,
|
||||
videoUrl: row.VideoURL
|
||||
};
|
||||
});
|
||||
|
||||
response
|
||||
.status(200)
|
||||
.send(JSON.stringify(converted));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
response
|
||||
.status(500)
|
||||
.send(JSON.stringify({error: 'Internal server error (Querying)'}));
|
||||
})
|
||||
.finally(() => {
|
||||
conn.end();
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
response
|
||||
.status(500)
|
||||
.send(JSON.stringify({error: 'Internal server error (Connection)'}));
|
||||
});
|
||||
|
||||
// Om iets met de database te doen, is het handig om een functie te maken
|
||||
// die een `app` parameter en een `pool` parameter accepteert.
|
||||
// Deze moet dan geëxporteerd worden om deze te kunnen gebruiken in `server.js`.
|
||||
// Dit is een voorbeeld van hoe je dat zou kunnen doen:
|
||||
// module.exports = function(app, pool) { ... }
|
||||
}
|
||||
|
||||
// Export the function that registers the incoming request handlers
|
||||
module.exports = function(app, pool) {
|
||||
app.post('/', (req, res) => handleIncoming(req, res, app, pool));
|
||||
};
|
24
code/web/pepper_data_test.js
Normal file
@@ -0,0 +1,24 @@
|
||||
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++)
|
||||
{
|
||||
setTimeout(() => {
|
||||
console.log("Sending data");
|
||||
fetch(address, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
}, i * 1000);
|
||||
}
|
@@ -1,25 +1,27 @@
|
||||
const mariadb = require('mariadb');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
app.use(bodyParser.json());
|
||||
const serverPort = 3000;
|
||||
|
||||
const databaseCredentials = {
|
||||
host: 'localhost',
|
||||
host: '127.0.0.1',
|
||||
user: 'fitbot',
|
||||
password: 'fitbot123',
|
||||
database: 'fitbot',
|
||||
connectionLimit: 5,
|
||||
allowUnauthorized: true
|
||||
}
|
||||
};
|
||||
|
||||
// Create connection pool
|
||||
const pool = mariadb.createPool(databaseCredentials);
|
||||
|
||||
// Register incoming HTTP request handlers
|
||||
require('incoming_request_handlers')(app, pool);
|
||||
require('./incoming_request_handlers')(app, pool);
|
||||
|
||||
// Start server
|
||||
app.listen(port, () => {
|
||||
app.listen(serverPort, () => {
|
||||
console.log(`Server running on port ${serverPort}`);
|
||||
})
|
||||
});
|
16
docs/.pages
@@ -18,14 +18,21 @@ nav:
|
||||
- Android Studio: documentation/android/androidStudio
|
||||
- app setup: documentation/android/appSetup
|
||||
- video view: documentation/android/Videoview
|
||||
- 🧠 Brianstorm:
|
||||
- java classes: documentation/android/javaClasses
|
||||
- robot motion tracking: documentation/android/robot_motion_tracking_system
|
||||
- 🧠 Research:
|
||||
- Ideas: documentation/brainstorm/ideas
|
||||
- Motion tracking system analysis: documentation/research-questions/motion-tracking-system-analysis
|
||||
- position tracking : documentation/research-questions/position-tracking-research
|
||||
- robot comparison : documentation/robots/Comparisons
|
||||
- Colors research : documentation/brainstorm/colorsforlayout
|
||||
- 🗄️ Database:
|
||||
- EERD: documentation/database/EERD
|
||||
- ERD: documentation/database/ERD
|
||||
- Infrastructure: documentation/database/infrastructure
|
||||
- 📦 Hardware:
|
||||
- Hardware: documentation/hardware/sensors
|
||||
- Sensors: documentation/hardware/sensors
|
||||
- Pcb : documentation/hardware/pcb
|
||||
- 🤖 Pepper:
|
||||
- Pepper Setup: documentation/pepper/pepperSetup
|
||||
- Pepper movement: documentation/android/robotmovement
|
||||
@@ -43,5 +50,8 @@ nav:
|
||||
- phpMyAdmin:
|
||||
- phpMyAdmin: documentation/raspberryPi/phpMyAdmin/phpMyAdmin
|
||||
- phpMyAdmin Setup: documentation/raspberryPi/phpMyAdmin/phpMyAdminSetup
|
||||
|
||||
- 💻 Code documentation:
|
||||
- Vector3 : documentation/android/code_documentation/Vector3
|
||||
- Websocket : documentation/android/code_documentation/WebSocket
|
||||
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
We wanted to show the various exercises in a video that everyone could replicate. We did not want to implement a YouTube function because we wanted to have our own videos rather than relying on YouTube. To begin, we need an empty activity file, which you can create using the Android Studio IDE. Then, navigate to the XML file you just created and the go-to widgets, and add the VideoView element.
|
||||
|
||||

|
||||

|
||||
|
||||
If you drag that into your activity, you can change the layout, but it will not function directly. To make it play videos, we need to write some Java code first.
|
||||
```java
|
||||
|
@@ -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
|
@@ -15,8 +15,9 @@ public class MyClass {
|
||||
Then in a class you can have Methods or Atributes where the actual code is.
|
||||
|
||||
```mermaid
|
||||
flowchart
|
||||
a[Access Modifiers] --> b[class] --> c[Class name]
|
||||
flowchart LR
|
||||
0[~] --> a([Access Modifiers]) --> b([class]) --> c([Class name])
|
||||
0 --> b
|
||||
```
|
||||
|
||||
## Constructor
|
||||
@@ -29,8 +30,11 @@ A method is a block of code which only runs when it is called. You can pass data
|
||||
|
||||
Methods are build like this
|
||||
```mermaid
|
||||
flowchart
|
||||
A[Access Modifiers] --> B[Method Modifier] --> C[Return Type] --> D[Method Name] --> E[Parameters] --> F[Method Body]
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
@@ -106,4 +110,5 @@ public class MyClass {
|
||||
|
||||
## Sources
|
||||
|
||||
* https://www.w3schools.com/java/java_modifiers.asp
|
||||
* https://www.w3schools.com/java/java_modifiers.asp explanation of modifiers
|
||||
* https://en.wikipedia.org/wiki/Syntax_diagram For syntax diagram
|
@@ -46,4 +46,8 @@ animate.async().run();
|
||||
```
|
||||
|
||||
|
||||
If you run this on the robot the animation should play.
|
||||
If you run this on the robot the animation should play.
|
||||
|
||||
## Additional stuff
|
||||
every 25 is 1 second so 100 is 4 seconds.
|
||||

|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
docs/documentation/assets/robotanimationtimer.png
Normal file
After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -2,7 +2,7 @@
|
||||
|
||||
### Vision changes
|
||||
As we become older, our vision worsens. We need to keep this in mind because our target audience includes elderly people. Beginning around the age of 40 we are already seeing some issues with our sight. It might become harder to focus on text, hence the need for reading glasses. This is an issue to keep in mind when designing our app, we want to resolve this by using images or bigger text so that it becomes easier to read. We are planing to avoid redundant text. We also see issues with light. With aging our pupils will shrink, this will result in lower light sensitivity and the increased sensitivity to glare. We need to use warmer colors to reduce the brightness on the eye and make our app able to be used when the brightness of the screen is low to resolve this issue. However, one of the biggest issues is with contrast. The older we get, the less able we are able to make out of low contrast patterns. This is really important to keep in mind, some combinations can be really hard to see for elderly people. I'll show you how by providing an example.
|
||||

|
||||

|
||||
This image shows what elderly people may experience while reading or using an app. We must keep this in mind as we design our app.
|
||||
### color psychology
|
||||
Colors can be an effective way to influence emotions and feelings. They may influence you without your knowledge. We can use this to influence those who use our app. Colors have a powerful ability to influence emotions. Every color has a unique effect on our minds. For example, blue has a calming and trustworthy effect on our minds. While blue may not be appropriate for our project, it may prove useful when using a more serious app. We can see PayPal using this trend because it is a banking app that must be trusted. Because blue influences those who use PayPal, it will have a positive impact on their customers. We also want to positively influence our people.
|
||||
@@ -15,14 +15,14 @@ Colors can be an effective way to influence emotions and feelings. They may infl
|
||||
|
||||
Red is an interesting color because it increases excitement, activity, aggression, bravery, and youthfulness. People associate the color red with boldness, fire, competition, love, energy, speed, power, youth, and so much more. These emotions are useful when developing a fitness app, but even a different shade of red affects emotions and effectiveness. Lighter shades highlight the energetic qualities of red. Darker shades emphasize power. This makes red a powerful color and for us and an interesting option because Strava, a fitness app focused on running, uses the same colors.
|
||||
|
||||

|
||||

|
||||
|
||||
<span style="color:ORANGE">
|
||||
<strong> ORANGE: </strong>
|
||||
</span>
|
||||
|
||||
Orange is a warm color that is a combination of red and yellow, making it a good middle ground between the two. Orange is an interesting color for our project because it promotes emotions like playful, warm, friendly, social, gregarious, cheerful, vibrant, confident, and successful. As we can see, there is a good balance of red and yellow emotions. People associate the color orange with extroversion, adventure, celebration, courage, confidence, good health, friendship, and success. This makes it a suitable choice for our project because it triggers most of the emotions we wanted. It is not as aggressive as red, but it basically has the same effect. Deeper oranges are warmer, while lighter tints make it feel more like yellow. We should consider orange for our app because it stimulates the desired emotions.
|
||||

|
||||

|
||||
|
||||
<span style="color:yellow">
|
||||
<strong> YELLOW: </strong>
|
||||
@@ -30,7 +30,7 @@ Orange is a warm color that is a combination of red and yellow, making it a good
|
||||
|
||||
Yellow belongs in the same park as red because they are both warm colors. Yellow boosts emotions such as warmth, cheerfulness, happiness, energy, clarity, and attention, making it a good choice for us to look at. People associate the color or yellow with. Sunshine, creativity, imagination, hope, joy, the future, and spirituality. The various shades affect yellow in different ways, and bright sharp yellows can be tiring and cause headaches. Lighter shades appeal to the happiness aspect, reminding users of summer and the sun. Darker shades, such as gold, add weight. This makes yellow an interesting color option for our app.
|
||||
|
||||

|
||||

|
||||
|
||||
<span style="color:green">
|
||||
<strong> GREEN: </strong>
|
||||
@@ -39,28 +39,28 @@ Yellow belongs in the same park as red because they are both warm colors. Yellow
|
||||
Green is on the opposite side of the spectrum from red and yellow. Green is a colder color, which gives it a different effect. Green enhances emotions such as restful, natural, stable, healthy, and prosperity. This can make it a viable option, especially because it gives people a sense of good health. People associate color green with. Freshness, ecology, nature, health, balance, fertility, growth, renewal, healing, money, and good luck. This is interesting because it not only provides people with the feeling of being healthy, but also of being outside in nature, which may help elderly people feel less isolated. However, the shades of green also make people feel different. Pale greens are soothing. Dark greens can improve concentration. However, because we do not rely on concetration, it will have little impact on our project.
|
||||
|
||||
|
||||

|
||||

|
||||
<span style="color:BLUE">
|
||||
<strong> BLUE: </strong>
|
||||
</span>
|
||||
|
||||
Blue is also a colder color, so it takes the same path as green, giving it a more calming effect. However, it is not comparable to green because they influnce other emotions. Blue enhances emotions like calm, security, peace, patience, loyalty, trust, and sadness. It has the same soothing effect as green, but it does not give people the feeling of being healthy. It gives people trust and peace, which are interesting emotions, but they are not beneficial to us. People associate the color blue with stability, protection, trust, loyalty, patience, perseverance, security, peace, loyalty, sadness and depression, and masculinity. This further confirms that blue gives people a sense of security, which is not important for us because we want people to start exercising. Pale blue is cooling and relaxing, but it should not be used inappropriately because it can make people feel sad and depressed. Indigo is useful in situations where fear prevents activity. Indigo may be useful for a cool-down exercise or if someone is afraid of exercising.
|
||||
|
||||

|
||||

|
||||
|
||||
<span style="color:Black">
|
||||
<strong> BLACK: </strong>
|
||||
</span>
|
||||
Black is not a color but we can use this as the main tone for our app. However since old people tend to have issues when there isnt much light and black is the absence of light we are not very likely to sue it. Black boost emotions like Mysterious, elegant, sophisticated, worldly, powerful, strength, and intelligence. This makes black not that interesting for us since we want to make a simple app that everyone can understand. People associate the color black with Authority, sophistication, simplicity, protection, formality, elegance, night, power, and mystery. This is very intersting but not for our project since we do not desire people to associate our project with these emotions. If we tone the color black we get gray and white of which i will discuss the color white seperatly. Too much black can be frightening. Depressing unless used with other colors.
|
||||
|
||||

|
||||

|
||||
|
||||
<span style="color:White">
|
||||
<strong> WHITE: </strong>
|
||||
</span>
|
||||
White is not a color so it has the same purpose as black being a main tone to our app. White is a light tone which may cause it to glare. This means that you do not what to use the brightest types of screen with white. We do not have this issue so we can use white as much as wel like. White gives people the emotions of: fresh, pure, clear, easy, receptive, modern, neat, and precise. Since we are designing a simple app white is a nice main tone for our app. People associate white with Goodness, innocence, purity, cleanliness, calmness, freshness, healthiness, and precision. This further confirms that white is a good option for our app. However as i said Too bright white can produce eyestrain and headaches. Escpecially elderdly people are extra sensetive for this. So if we use white we need to be a little bit carefull whit it
|
||||
|
||||

|
||||

|
||||
### Conclusion
|
||||
We decided to go for
|
||||
|
||||
|
@@ -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.
|
||||
|
||||

|
100
docs/documentation/diagrams/.$appDiagram.drawio.bkp
Normal file
@@ -0,0 +1,100 @@
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="JqL7afyQoL-OOYxCKZbi-23" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
<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">
|
||||
<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>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
Before Width: | Height: | Size: 99 KiB |
BIN
docs/documentation/diagrams/assets/.$appDiagramV4.png.bkp
Normal file
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 99 KiB |
BIN
docs/documentation/diagrams/assets/appDiagramV2.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
docs/documentation/diagrams/assets/appDiagramV3.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/documentation/diagrams/assets/appDiagramV4.png
Normal file
After Width: | Height: | Size: 27 KiB |
4
docs/documentation/hardware/Issues.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Issues with hardware
|
||||
|
||||
## Issues with libraries
|
||||
The websocket library doesnt work well on the esp8266 d1 mini. It lags out the entire esp and makes it unresponsive.
|
@@ -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,23 +3,25 @@
|
||||
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?
|
||||
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 methods are there to measure this?
|
||||
There are a lot of different ways to measure movement. You can use cameras, gyroscopes, accelerometers or a combination of these. Each of these methods have their own pros and cons. For example cameras are good at measuring movement but they require a lot of processing power and if the user turns the other way the camera cant measure the movement anymore. Accelerometers are good at measuring the movement of the body but they are not good at measuring the speed of the movement. Gyroscopes are good at everything because they can calculate how fast the body is moving and in which rotation.
|
||||
|
||||
### Which gyroscopes are there?
|
||||
There are a lot of different gyroscopes with a lot of different specifications.
|
||||
### What type of sensor are we going to use?
|
||||
To measure these movements we are gonna use IMU's. They are a combination of accelerometers and gyroscopes. This way we can measure the movement of the body and the speed of the movement.
|
||||
|
||||
* ADXL345
|
||||
### Which IMU's are there?
|
||||
There are a lot of different IMU's with a lot of different specifications.
|
||||
|
||||
* ADXL345
|
||||
* BNO085
|
||||
* Bmi160
|
||||
|
||||
### Which one are we gonna use?
|
||||
We haven't decided on which gyroscope we are gonna use yet.
|
||||
|
||||
We are going to use the BNO085 because it has the least amount of drift and its very versatile. We can get almost any type of rotational and acceleration data from it.
|
||||
---
|
||||
<br>
|
||||
<br>
|
||||
|
@@ -6,8 +6,8 @@ For this project we want to design an embedded system that can track a users pos
|
||||
|
||||
## 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 Wii Fit Board and determine the user's position.
|
||||
|
||||
## Research and Analysis
|
||||
|
||||
@@ -80,10 +80,8 @@ To be added
|
||||
## References
|
||||
|
||||
[Wiiboard lib](https://code.google.com/archive/p/wiiboard-simple/wikis/Documentation.wiki)
|
||||
https://advanti-lab.sb.dfki.de/?page_id=64
|
||||
https://github.com/paulburton/fitscales
|
||||
https://github.com/micromu/WiiRemoteJ
|
||||
|
||||
## Appendices
|
||||
|
||||
To be added
|
||||
[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)
|
||||
|