Compare commits

...

9 Commits

12 changed files with 205 additions and 56 deletions

View File

@@ -1,6 +1,6 @@
#include "headerFile.h"
SensorManager::Rotation offset;
// SensorManager::Rotation offset;
void setup() {
Serial.begin(9600);
@@ -10,51 +10,49 @@ void setup() {
sensorManager.sensorSetup();
//ws server address, port and URL
webSocket.begin("145.3.245.22", 8001, "");
webSocket.begin("145.28.160.108", 8001, "");
// try every 500 again if connection has failed
webSocket.setReconnectInterval(500);
}
void loop() {
SensorManager::Rotation rotation = sensorManager.readLoop();
SensorManager::eulerAngles eulerRotation = sensorManager.getEulerAngles();
// Subtract offset
rotation.i -= offset.i;
rotation.j -= offset.j;
rotation.k -= offset.k;
rotation.w -= offset.w;
// 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;
// float rollDegrees = roll * 180.0f / PI;
// float pitchDegrees = pitch * 180.0f / PI;
// float yawDegrees = yaw * 180.0f / PI;
Serial.print(roll);
Serial.print(eulerRotation.roll);
Serial.print(" ");
Serial.print(pitch);
Serial.print(eulerRotation.pitch);
Serial.print(" ");
Serial.print(yaw);
sendData(roll, pitch, yaw);
Serial.print(eulerRotation.yaw);
sendData(eulerRotation.roll, eulerRotation.pitch, eulerRotation.yaw);
Serial.println();
webSocket.loop();
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
command.trim(); // remove any trailing whitespace
if (command == "setZeroPoint") {
setZeroPoint();
}
}
}
void setZeroPoint() {
offset = sensorManager.readLoop();
}
// if (Serial.available()) {
// String command = Serial.readStringUntil('\n');
// command.trim(); // remove any trailing whitespace
// if (command == "setZeroPoint") {
// setZeroPoint();
// }
// }
// }
// 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) + "\"}";

View File

@@ -15,12 +15,12 @@ void SensorManager::sensorSetup() {
//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
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");
@@ -29,23 +29,31 @@ void SensorManager::sensorSetup() {
Serial.println(F("magnetometer rotation enabled"));
}
SensorManager::Rotation SensorManager::readLoop() {
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;
}
}
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;
}

View File

@@ -5,18 +5,26 @@
#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;
};
eulerAngles getEulerAngles();
private:
struct RotationQuintillions {
float i;
float j;
float k;
float w;
};
RotationQuintillions getQuintillions();
BNO080 myIMU;
};
#endif

3
code/src/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@@ -7,6 +7,7 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@@ -7,7 +7,7 @@ android {
defaultConfig {
applicationId "com.example.fitbot"
minSdk 29
minSdk 23
targetSdk 29
versionCode 1
versionName "1.0"

View File

@@ -1,4 +1,4 @@
package com.example.fitbot;
package com.example.fitbot.sports;
import android.support.v7.app.AppCompatActivity;
@@ -7,6 +7,7 @@ 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 com.example.fitbot.ui.activities.MainActivity;
public class Animations extends AppCompatActivity {

View File

@@ -1,20 +1,28 @@
package com.example.fitbot.ui.activities;
import static com.example.fitbot.sports.Animations.Animate;
import android.os.Bundle;
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.example.fitbot.sports.Animations;
public class FitnessActivity extends RobotActivity implements RobotLifecycleCallbacks {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
QiSDK.register(this, this);
}
@Override
public void onRobotFocusGained(QiContext qiContext) {
// Implement your logic when the robot focus is gained
Animate("bicepcurl", qiContext);
}
@Override
@@ -26,4 +34,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() {
QiSDK.unregister(this, this);
super.onDestroy();
}
}

View File

@@ -1,5 +1,7 @@
package com.example.fitbot.ui.activities;
import static com.example.fitbot.sports.Animations.Animate;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
@@ -9,6 +11,9 @@ import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import com.aldebaran.qi.sdk.QiContext;
import com.aldebaran.qi.sdk.QiSDK;
import com.aldebaran.qi.sdk.RobotLifecycleCallbacks;
import com.example.fitbot.R;
public class MainActivity extends AppCompatActivity {
@@ -23,6 +28,7 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
QiSDK.register(this, (RobotLifecycleCallbacks) this);
/*---Hooks---*/
drawerLayout = findViewById(R.id.drawer_layout);

View File

@@ -6,4 +6,4 @@ plugins {
task clean(type: Delete) {
delete rootProject.buildDir
}
}

View File

@@ -0,0 +1,109 @@
# Java class modifiers
## How are classes build in java?
There are a lot of classes with a lot of parameters
A class always begins with either the public or default or abstract access modifier. Then comes the class name
Example:
```java
public class MyClass {
//methods and atributes
}
```
Then in a class you can have Methods or Atributes where the actual code is.
```mermaid
flowchart
a[Access Modifiers] --> b[class] --> c[Class name]
```
## Constructor
A constructor in Java is a special method that is used to initialize objects. The constructor is called when an object of a class is created. It can be used to set initial values for object attributes.
The constructor Method is the first method that is called when a class is created. It has the same name as the class and no return type. It is automaticly called when a class is created.
### Methods
A method is a block of code which only runs when it is called. You can pass data, known as parameters, into a method. Methods are used to perform certain actions, and they are also known as functions.
Methods are build like this
```mermaid
flowchart
A[Access Modifiers] --> B[Method Modifier] --> C[Return Type] --> D[Method Name] --> E[Parameters] --> F[Method Body]
```
Example:
```java
public class MyClass {
// Method
static void myMethod() {
// print Hello World!
System.out.println("Hello World!");
}
// Main method
//access modifier, Method Modifier, return type, method name, parameters, method body
public static void main(String[] args) {
// Call the method
myMethod();
}
}
```
### Atributes
Attributes are variables within a class. When an object is created from a class, the object will have these attributes.
Example:
```java
public class MyClass {
int x = 5;
}
```
## Classes
### Class modifiers
#### Non-access modifiers
| Modifier | Description | | | |
|---|---|---|---|---|
| final | The class cannot be inherited by other classes (You will learn more about inheritance in the Inheritance chapter) | | | |
| abstract | The class cannot be used to create objects (To access an abstract class, it must be inherited from another class. You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters) | | | |
||||
#### Access modifiers
| Modifier | Description | | | |
|---|---|---|---|---|
| public | The code is accessible for all classes | | | |
| private | The code is only accessible within the declared class | | | |
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
| | | | | |
## Methods and attributes
#### non access modifiers
| Modifier | Description | | | |
|---|---|---|---|---|
| final | Attributes and methods cannot be overridden/modified | | | |
| static | Attributes and methods belongs to the class, rather than an object. You don't really wanna use this one. | | | |
| abstract | Can only be used in an abstract class, and can only be used on methods. The method does not have a body, for example abstract void run();. The body is provided by the subclass (inherited from). You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters | | | |
| transient | Attributes and methods are skipped when serializing the object containing them | | | |
| synchronized | Methods can only be accessed by one thread at a time | | | |
| volatile | The value of an attribute is not cached thread-locally, and is always read from the "main memory" | | | |
||||
#### Access modifiers
| Modifier | Description | | | |
|---|---|---|---|---|
| public | The code is accessible for all classes | | | |
| private | The code is only accessible within the declared class | | | |
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
| | | | | |
## Sources
* https://www.w3schools.com/java/java_modifiers.asp

View File

@@ -3,11 +3,11 @@
Which sensor are we gonna use for this project and why?
### What do we wanna measure?
### What do we want to measure?
We wanna measure the movement of the people doing our exercises. We want to know how many times they have done the exercise and how many times they have done it correctly.
### What sensor are we gonna use?
### What sensor are we going to use?
To measure these movements we are gonna use gyroscopes. With gyroscopes we can measure the rotation of the body. With some math we can also measure the speed of the rotation. So we know how fast the person is doing the exercise.
### Which gyroscopes are there?