Updated documentation

This commit is contained in:
Luca Warmenhoven
2024-06-04 14:42:30 +02:00
parent c084443799
commit 3f560d9f47
4 changed files with 134 additions and 112 deletions

View File

@@ -0,0 +1,37 @@
## Pepper Handling
---
To make the handling of the Pepper robot easier, we've made some classes
that can be used to interact with the robot.
The classes associated with the Pepper robot interaction are located in the
`com.example.fitbot.pepper` package. To start interacting with the Pepper robot,
one must assign a `QiContext` first. This can be done by calling `Pepper.provideQiContext(QiContext context)`
method. This method takes a `QiContext` object as a parameter. This object is used to interact with the robot.
To make the robot talk, one can call the following method:
```java
Pepper.say(String text);
```
To make the robot execute an animation, one can call the following method:
```java
Pepper.animate(String animationName);
```
To make the robot do more sophisticated things, one can call the
```java
Pepper.addToEventQueue(AbstractPepperActionEvent event);
```
This adds the provided event to the event queue. The event will be executed in the order it was added.
Whenever there's no valid QiContext available to use, the event will maintain in the queue until one is
provided.
*Note* All Pepper action events are added to a queue, and executed synchronously. This means
that if the robot is still busy with a task, adding a new event to the queue will not do anything until
the robot is done with the current task.
Currently, the only supported actions are:
- `PepperSpeechEvent` - This event makes the robot say something.
- `PepperAnimationEvent` - This event makes the robot execute an animation.

View File

@@ -1,108 +1,60 @@
## Motion Tracking System
## Motion Tracking System -- Pepper
---
To capture the user's motion with the sensing devices, we'll need to use a tracking system that calculates the
path the user makes to be able to determine the user's position and orientation, and therefore whether the movement
that was made correlates to the provided path.
This is done by some calculations in the `MotionProcessor` class. To get started, create an instance of the `MotionProcessor` class and call the `processMotion` method with the `MotionData` object as a parameter. This will return a `MotionResult` object that contains the calculated path.
### Introduction
The robot motion tracking system is a system that allows the robot to track the user's motion and provide feedback
based on the user's motion. The system consists of a Web Server, which actively listens for incoming data from the
two ESP8266 modules. The ESP8266 modules are connected to the robot and are responsible for tracking the user's motion.
These sensors send rotation data to the Web Server, which can then be parsed and used to provide feedback to the user.
### System Architecture
The system consists of three main components: the Web Server, the ESP8266 modules, and the Pepper robot. The Web Server
is responsible for receiving data from the ESP8266 modules and processing it. The ESP8266 modules are responsible for
sending rotation data to the web server, which is then parsed.
### Parsing Data
To parse the data received by the web server, one must utilize the class `InputProcessor`. This class is responsible for
both starting the server and processing data received by the server. To start parsing data, one can do the following:
```java
// create the motion processor
MotionProcessor motionProcessor = new MotionProcessor();
InputProcessor processor = new InputProcessor();
processor.startListening(); // This starts the web server.
```
To start listening for input, one must call the following method:
```java
// start listening for input
motionProcessor.startListening();
```
Calling this function creates a WebSocket server, which the sensing devices can connect to.
The `MotionProcessor` class will then start listening for a set of messages that start with specified kind of keywords.
The messages always start with the keyword, separated by a space, and then the data is sent.
The default data separator is `;`.
An example of the message format is shown below:
```java
// Sending data
"data accelerationX;accelerationY;accelerationZ;rotationX;rotationY;rotationZ" // all values are floats
// Changing the sample rate
"sampleRate rate" // rate is an integer
// Calibrating the zero point
"zero x;y;z" // x, y, z are floats
```
To add a custom message received handler, one can simply call the following method:
```java
// Add a custom message handler
motionProcessor.setMotionDataEventHandler((Vector3 vector) -> { ... });
```
*Note: The message handler provides a vector as a parameter; this vector is already converted from relative acceleration and rotation.*
### Error checking
To check whether the made movements correlate with a given path, one must check for their differences.
This can be done by a few implemented methods:
***Get the error of a vector compared to a path***
```java
GesturePath path = new GesturePath.Builder()
.addVector(...)
.build();
Vector3 referencePoint = new Vector3(...);
double error = motionProcessor.getError(path, referencePoint);
```
***Get the average error of a computed path to a `GesturePath`***
```java
GesturePath path = new GesturePath.Builder()
.addVector(...)
.build();
double error = motionProcessor.getAverageError(path);
```
***Get a list of error values from a computed path to a `GesturePath`***
```java
GesturePath path = new GesturePath.Builder()
.addVector(...)
.build();
List<Double> errorList = motionProcessor.getErrors(path);
```
### Example
An example of how to use a motion tracking system is shown below:
To parse data received by the server, one can register an event listener with the `InputProcessor` class. This event listener
will be called whenever new data is received by the server. To register an event listener, one can do the following:
```java
// create the motion processor
MotionProcessor motionProcessor = new MotionProcessor();
// Create a gesture path
GesturePath.Builder pathBuilder = new GesturePath.Builder();
for ( int i = 0; i < 100; i++ )
pathBuilder.addVector(new Vector3(i, i, i));
GesturePath path = pathBuilder.build();
// Set the path
for ( int i = 0; i < 100; i++ ) {
motionProcessor.addMotionData(new MotionData(i, i, i, i, i, i));
processor.setInputHandler(new IInputHandler() {
@Override
public void accept(Vector3f rotationVector, int sensorId) {
// Do something with the input.
}
});
```
### Providing Feedback
If one wants to provide feedback to the user, one must first provide an exercise to the `InputProcessor` object.
This can be done by calling the `setExercise(Exercise exercise)` method. This method takes an `Exercise` object as a parameter.
This object contains information about the exercise, such as the name of the exercise, the muscle group it targets, and the
video associated with the exercise. One can then check the status of the current exercise by calling one of the following
methods:
```java
processor.getCurrentProgress(); // Returns the current progress of the exercise as a scalar (0 - 1)
processor.getError(int sensorId, float time); // Get the error offset for a given sensor at a given time
processor.getAverageError(int sensorId); // Get the average error for a given sensor
processor.secondsPassed(); // Get the number of seconds that have passed since the exercise started
processor.hasFinished(); // Check if the exercise has finished
// Get error values
List<Double> errorList = motionProcessor.getErrors(path);
// Get average error
double averageError = motionProcessor.getAverageError(path);
// Now you can do whatever you want with these results.
```

View File

@@ -3,59 +3,56 @@
``` mermaid
classDiagram
Raspberry pi --> NodeJS
Raspberry pi --> Database
NodeJS --> Androidapp : getExerciseData (Wifi, Rest API)
Raspberry Pi --> NodeJS
Raspberry Pi --> Database
NodeJS <--> Android Application : Request exercise data from database
Database <--> NodeJS : Database queries
ESP8266 --> Androidapp : getRotationalData (Wifi)
ESP8266 --> Android Application : Send rotation data via WiFi to\n Pepper Web Server
namespace Server {
class Raspberry pi {
class Raspberry Pi {
+MariaDB
+Apache2
+NodeJS
Database()
Webserver()
Database
Webserver
}
class Database {
+ExerciseID
+ExerciseName
+ExerciseShortDesc
+ExerciseDescription
+ExerciseVideo
+GyroCoordinates
+ExerciseImage
+GyroVectors
+MuscleGroup
}
class NodeJS {
+MariaDB
GetRandomExercise()
+Handle requests
}
}
namespace Pepper {
class Androidapp {
class Android Application {
+Java
+Android SDK
+QiSDK
motionProcessing()
robotMovement()
showVideo()
fitnessCycle()
+WebServer
+Acquire rotation data from sensors
}
}
namespace Hardware {
class ESP8266{
+RotationalX
+RotationalY
+RotationalZ
Gyroscope()
+RotationX
+RotationY
+RotationZ
Send rotation data to Web Server
}
}
```

View File

@@ -0,0 +1,36 @@
K1 - Object-Oriented Programming
---
In alle classen gerelateerd aan de Pepper besturingen wordt er gebruik gemaakt
van abstractie en encapsulatie.
Zie:
- `PepperAnimationEvent`
- `PepperSpeechEvent`
Deze classes inheriten `AbstractPepperActionEvent`.
K2: Gebruikers Test
---
Wij hebben gezamenlijk gecommuniceerd over het plan, echter is alleen
Niels heengegaan om te communiceren met de gebruikers.
We hebben om ons heen mede studenten gevraagd om feedback te geven over onze
applicatie, gezien we helaas te weinig informatie hebben verkregen van de
actuele gebruiker.
---
K3 - Infrastructure UML
---
Zie bestand 'infrastructure.md'
---
K4 - Ontwerp embedded system
---