Merge branch 'main' of ssh://gitlab.fdmci.hva.nl/propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-4/muupooviixee66
This commit is contained in:
@@ -24,6 +24,7 @@ const char* getServerURL = "http://145.92.8.132:443/get-ip";
|
||||
String ipAddress = ""; // string that will hold the server's IP address
|
||||
|
||||
const char* Connectivity::fetchIPAddress() {
|
||||
char* ipAddress = NULL; // Declare ipAddress as a char*
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
HTTPClient http;
|
||||
WiFiClient client;
|
||||
@@ -33,7 +34,7 @@ const char* Connectivity::fetchIPAddress() {
|
||||
if (httpCode > 0) {
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
// If successful (code 200), read the response body and store the IP address
|
||||
ipAddress = http.getString();
|
||||
ipAddress = strdup(http.getString().c_str());
|
||||
}
|
||||
} else {
|
||||
Serial.printf("GET request failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
|
@@ -37,7 +37,7 @@ struct acceleration {
|
||||
accelData.z,
|
||||
"data");
|
||||
// %d = int, %f = floatation, %s = string
|
||||
connectivity.httpPost(serverIp, "/", 3445, buffer, strlen(buffer), "application/json");
|
||||
connectivity.httpPost("192.168.137.30", "/", 3445, buffer, strlen(buffer), "application/json");
|
||||
lastTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
@@ -17,14 +17,14 @@ void SensorManager::sensorSetup() {
|
||||
// myIMU.enableStepCounter(500); //Send data update every 500ms
|
||||
}
|
||||
//get sensordata
|
||||
SensorManager::RotationQuintillions SensorManager::getQuintillions() {
|
||||
SensorManager::RotationQuaternions SensorManager::getQuaternions() {
|
||||
if (myIMU.dataAvailable() == true) {
|
||||
float i = myIMU.getQuatI();
|
||||
float j = myIMU.getQuatJ();
|
||||
float k = myIMU.getQuatK();
|
||||
float w = myIMU.getQuatReal();
|
||||
|
||||
RotationQuintillions rotation = { i, j, k, w };
|
||||
RotationQuaternions rotation = { i, j, k, w };
|
||||
return rotation;
|
||||
} else {
|
||||
float i = myIMU.getQuatI();
|
||||
@@ -32,13 +32,13 @@ SensorManager::RotationQuintillions SensorManager::getQuintillions() {
|
||||
float k = myIMU.getQuatK();
|
||||
float w = myIMU.getQuatReal();
|
||||
|
||||
RotationQuintillions rotation = { i, j, k, w };
|
||||
RotationQuaternions rotation = { i, j, k, w };
|
||||
return rotation;
|
||||
}
|
||||
}
|
||||
//calculate Quintillions to Euler angles from -1π to +1π
|
||||
//calculate Quaternions to Euler angles from -1π to +1π
|
||||
SensorManager::eulerAngles SensorManager::getEulerAngles() {
|
||||
SensorManager::RotationQuintillions rotation = getQuintillions();
|
||||
SensorManager::RotationQuaternions rotation = getQuaternions();
|
||||
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));
|
||||
|
@@ -23,13 +23,13 @@ public:
|
||||
acceleration getAcelleration();
|
||||
bool sensorTap();
|
||||
private:
|
||||
struct RotationQuintillions {
|
||||
struct RotationQuaternions {
|
||||
float i;
|
||||
float j;
|
||||
float k;
|
||||
float w;
|
||||
};
|
||||
RotationQuintillions getQuintillions();
|
||||
RotationQuaternions getQuaternions();
|
||||
BNO080 myIMU;
|
||||
};
|
||||
|
||||
|
@@ -39,6 +39,9 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
private TextView exerciseNameTextView;
|
||||
private TextView exerciseShortDescriptionTextView;
|
||||
private TextView exerciseDescriptionTextView;
|
||||
private static String exerciseVideoUrl;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
// Some nice little messages for the user
|
||||
private static final String[] EXERCISE_NOT_FOUND_MESSAGES = new String[]{
|
||||
@@ -58,25 +61,20 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
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);
|
||||
|
||||
// Fill empty objects with exercise data
|
||||
this.exerciseNameTextView = findViewById(R.id.textViewFitnessTitle);
|
||||
this.exerciseDescriptionTextView = findViewById(R.id.textViewDialogDescription);
|
||||
//this.exerciseDescriptionTextView = findViewById(R.id.textViewDialogDescription);
|
||||
this.exerciseShortDescriptionTextView = findViewById(R.id.textViewFitnessShortDescription);
|
||||
|
||||
// Find the VideoView by its ID
|
||||
VideoView videoView = findViewById(R.id.videoView);
|
||||
playVideo(videoView, this);
|
||||
// Navigation Buttons
|
||||
NavigationManager.setupButtonNavigation(this, R.id.homeButtonFitness, MainActivity.class);
|
||||
NavigationManager.setupButtonNavigation(this, R.id.skipButtonFitness, MainActivity.class); //Needs to skip exercises once those are implemented
|
||||
|
||||
// Hide system UI
|
||||
NavigationManager.hideSystemUI(this);
|
||||
setSpeechBarDisplayStrategy(SpeechBarDisplayStrategy.IMMERSIVE);
|
||||
|
||||
// Initiate info button
|
||||
Button infoButtonFitness = findViewById(R.id.infoButtonFitness);
|
||||
@@ -109,8 +107,8 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
exerciseStatusElement.initialize(exercise, motionProcessor, EXERCISE_COUNT);
|
||||
motionProcessor.useExercise(exercise);
|
||||
/* TODO: Remove if not needed */motionProcessor.setRecording(true, 10);
|
||||
motionProcessor.startListening();
|
||||
motionProcessor.setInputHandler(exerciseStatusElement);
|
||||
motionProcessor.startListening();
|
||||
|
||||
}, (n) -> {
|
||||
int randomMessageIndex = (int) Math.floor(Math.random() * EXERCISE_NOT_FOUND_MESSAGES.length);
|
||||
@@ -119,8 +117,9 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
NavigationManager.navigateToActivity(this, EndScreenActivity.class);
|
||||
});
|
||||
});
|
||||
|
||||
// FitnessCycle.playVideo(qiContext, videoView, this);
|
||||
VideoView videoView = findViewById(R.id.videoView);
|
||||
Log.e("exerciseVideoUrl", "videoUrl:" + exerciseVideoUrl);
|
||||
playVideo(videoView, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,10 +135,13 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
if (exercise == null) {
|
||||
onFailedFetch.handle(null);
|
||||
} else {
|
||||
onSuccessfulFetch.handle(exercise);
|
||||
this.runOnUiThread(() -> {
|
||||
exerciseNameTextView.setText(exercise.name);
|
||||
exerciseShortDescriptionTextView.setText(exercise.shortDescription);
|
||||
exerciseDescriptionTextView.setText(exercise.description);
|
||||
onSuccessfulFetch.handle(exercise);
|
||||
// exerciseDescriptionTextView.setText(exercise.description);
|
||||
exerciseVideoUrl = exercise.videoUrl;
|
||||
});
|
||||
}
|
||||
})).start();
|
||||
}
|
||||
@@ -153,14 +155,7 @@ public class FitnessActivity extends RobotActivity implements RobotLifecycleCall
|
||||
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.setVideoPath(exerciseVideoUrl);
|
||||
videoView.start();
|
||||
} else {
|
||||
Log.e("FitnessActivity", "VideoView is null. Check your layout XML.");
|
||||
|
@@ -14,7 +14,11 @@ public class GesturePath {
|
||||
*/
|
||||
public GesturePath(Vector3f[] vectors) {
|
||||
if (vectors.length < 2) {
|
||||
this.segments = new PathSegment[0];
|
||||
this.segments = new PathSegment[1];
|
||||
this.segments[0] = new PathSegment(
|
||||
new Vector3f(0, 0, 0),
|
||||
new Vector3f(0, 0, 0)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -160,6 +160,8 @@ public class InputProcessor {
|
||||
|
||||
try {
|
||||
|
||||
Log.i("MotionProcessor", "Time passed: " + this.secondsPassed + "s");
|
||||
Log.i("MotionProcessor", "Recording: " + this.recordingMovement + ", " + this.secondsPassed + " / " + this.recordingDurationInSeconds);
|
||||
Log.i("MotionProcessor", "Received packet data: " + data);
|
||||
|
||||
JsonElement json = JsonParser.parseString(data);
|
||||
@@ -198,18 +200,12 @@ public class InputProcessor {
|
||||
|
||||
// Re-calculate time for index calculation
|
||||
secondsPassed = (System.currentTimeMillis() - lastTime) / 1000.0d;
|
||||
lastTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
// Supposed index of the current rotation vector in the `rotationVectorPaths` array
|
||||
int selfIndex = (int) (secondsPassed * sampleRate);
|
||||
|
||||
motionDataConsumer.accept(rotation, deviceId);
|
||||
if (selfIndex >= selfRotationVectorPaths[deviceId].length || selfIndex < 0)
|
||||
return;
|
||||
|
||||
selfRotationVectorPaths[deviceId][selfIndex] = rotation;
|
||||
|
||||
if ( this.recordingMovement && this.hasFinished()) {
|
||||
if ( this.recordingMovement && this.secondsPassed >= this.recordingDurationInSeconds) {
|
||||
// Do something with the recorded data.
|
||||
this.recordingMovement = false;
|
||||
// Convert recorded data from `selfRotationVectorPaths` to string, and
|
||||
@@ -221,6 +217,11 @@ public class InputProcessor {
|
||||
Log.i("MotionProcessor", "Converted data: ");
|
||||
Log.i("MotionProcessor", converted);
|
||||
}
|
||||
motionDataConsumer.accept(rotation, deviceId);
|
||||
if (selfIndex >= selfRotationVectorPaths[deviceId].length || selfIndex < 0)
|
||||
return;
|
||||
|
||||
selfRotationVectorPaths[deviceId][selfIndex] = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,10 @@
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="300dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_margin="50dp" />
|
||||
android:layout_marginStart="50dp"
|
||||
android:layout_marginTop="50dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:layout_marginBottom="50dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
Binary file not shown.
34
docs/documentation/brainstorm/Dataprotocols.md
Normal file
34
docs/documentation/brainstorm/Dataprotocols.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Dataprotocols
|
||||
|
||||
|
||||
|
||||
# different types
|
||||
|
||||
### Hypertext Transfer Protocol (HTTP)
|
||||
HTTP is the foundation of web communication, permitting the transport of data across the internet using a request-response architecture. It uses TCP/IP and stands out by its statelessness, with each request being independent, increasing the web's scalability and flexibility. While it does not encrypt data which makes it usable with sensible data it still makes an nice easy to use option.
|
||||
|
||||
We decided to use this for our project because for communicating with the database it is easy to use and we are not usiong sensible data. If we were to use sensible data that we want to encrypt we can use HTTPS. We are only sending small amounts of data to our app and we are not transfering files to our app. This made HTTP it way more attractive option.
|
||||
|
||||
### File Transfer Protocol (FTP)
|
||||
FTP is the classic protocol for transferring files between computers. It establishes a connection between two computers and it has 2 modes. Passive mode for recieving files. This leaves a port open on the computer. You also have an active mode. This is were the client opens a port towards an other computer. If you want to encrypt your data you can use FTPS.
|
||||
|
||||
When we started the project is thought of this as a option however since we are not only transfering videos but also stuff like titles and dicriptions i thought we were not going to enable it to its fullest potattional. On top of that we are also transfering only small amounts of videos and we switched the way we used videos on our project by hosting the videos on a service like youtube. This made FTP not usefull for our project.
|
||||
|
||||
### User Datagram Protocol (UDP)
|
||||
UDP is s connectionless protocol that prioritizes speed over reliability. It sends datagrams to a computer without establishing a connection with the reciever. It is not stable so you need to keep in mind that it will not be 100% accurate. However it is really fast so this makes it a suitible option for applications where a tiny amount of dataloss is not an issue.
|
||||
|
||||
(to be added)
|
||||
|
||||
### Message Queue Telemetry Transport (MQTT)
|
||||
MQTT is s lightweight messaging protocol designed for machine-to-machine communication in Internet of Things applications. It uses a publish subscribe model. This is were one device publishes data on a server and the other devices need to subscribe to that publisher to recieve the data. It is commonly used to transmot sensor data to a server.
|
||||
|
||||
(to be added)
|
||||
|
||||
### Real-time Streaming Protocols (RTSP)
|
||||
RTSP is collection of protocols used for streaming media such as videos over networks. However it requires additional software for it to work properly. RTSP shines in controlling live streams allowing features like pause. It's often used in IPTV's and video conferencing applications.
|
||||
|
||||
|
||||
Due to its limited support we are not uising it in our project. We were already having issues with other things that are not supported on android or mobile apps and we did not want to risk getting more issues while working on our project since we were already using up our limited time. It is a very interesting option though since it will enable more advanced videos. It also is realy complex which makes it a less atractive option since we are already learning a lot of new things and if we were to want to learn more things we would rather learn something with a low learning curve.
|
||||
|
||||
|
||||
# Conclusion
|
Reference in New Issue
Block a user