## Motion Tracking System

---

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.

```java
// create the motion processor
MotionProcessor motionProcessor = new MotionProcessor();
```

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:

```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));
}

// 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.
```