|
| 1 | +/* This example shows how to calculate rotation |
| 2 | + * from LSM6DS3 data. |
| 3 | + * |
| 4 | + * Created 27/06/2024 |
| 5 | + * By Augmented Robotics |
| 6 | + * |
| 7 | + * Check out https://roboheart.de/en_gb/ for more information about RoboHeart. |
| 8 | + */ |
| 9 | + |
| 10 | +#include <RoboHeart.h> |
| 11 | +#include <Wire.h> |
| 12 | +#include <math.h> |
| 13 | +#define TRESHOLD 0.1 //treshold in rad/s |
| 14 | + |
| 15 | +float drift_x = 0; |
| 16 | +float drift_y = 0; |
| 17 | +float drift_z = 0; |
| 18 | + |
| 19 | +unsigned long prevSamplingTime = 0; |
| 20 | +unsigned long prevPrintTime = 0; |
| 21 | + |
| 22 | +RoboHeart heart = RoboHeart(Serial); |
| 23 | + |
| 24 | +void calculateDrifts(int timeout_ms = 500) { |
| 25 | + unsigned long time = millis(); |
| 26 | + for (int i = 0; i < timeout_ms; i++) { |
| 27 | + drift_x += heart.imu.readFloatGyroX() / timeout_ms; |
| 28 | + drift_y += heart.imu.readFloatGyroY() / timeout_ms; |
| 29 | + drift_z += heart.imu.readFloatGyroZ() / timeout_ms; |
| 30 | + delay(1); |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +bool isCalibrated(int timeout_ms = 1000) { |
| 35 | + unsigned long time = millis(); |
| 36 | + long counter = 0; |
| 37 | + while ((millis() - time) < timeout_ms) { |
| 38 | + if (abs(heart.imu.readFloatGyroX() - drift_x) > TRESHOLD || abs(heart.imu.readFloatGyroY() - drift_y) > TRESHOLD || abs(heart.imu.readFloatGyroZ() - drift_z) > TRESHOLD) { |
| 39 | + counter++; |
| 40 | + } |
| 41 | + delay(1); |
| 42 | + } |
| 43 | + return (counter < (timeout_ms / 5)); |
| 44 | +} |
| 45 | + |
| 46 | +float rotation[3] = { 0, 0, 0 }; |
| 47 | +void setup() { |
| 48 | + Serial.begin(115200); |
| 49 | + |
| 50 | + // Set up the RoboHeart |
| 51 | + heart.begin(); |
| 52 | + |
| 53 | + Serial.println("RoboHeart LSM6DS3 rotation demo"); |
| 54 | + |
| 55 | + Serial.println(drift_x, 4); |
| 56 | + Serial.println(drift_y, 4); |
| 57 | + Serial.println(drift_z, 4); |
| 58 | + calculateDrifts(); |
| 59 | + Serial.println(drift_x, 4); |
| 60 | + Serial.println(drift_y, 4); |
| 61 | + Serial.println(drift_z, 4); |
| 62 | + while (isCalibrated() == 0) {} |
| 63 | + |
| 64 | + Serial.println("RoboHeart calibrated"); |
| 65 | +} |
| 66 | + |
| 67 | +void loop() { |
| 68 | + unsigned long actualTime = millis(); |
| 69 | + if (actualTime - prevSamplingTime > 10) { |
| 70 | + float a_v_x = heart.imu.readFloatGyroX() - drift_x; |
| 71 | + float a_v_y = heart.imu.readFloatGyroY() - drift_y; |
| 72 | + float a_v_z = heart.imu.readFloatGyroZ() - drift_z; |
| 73 | + rotation[0] += a_v_x * (actualTime - prevSamplingTime) * 0.001; |
| 74 | + rotation[1] += a_v_y * (actualTime - prevSamplingTime) * 0.001; |
| 75 | + rotation[2] += a_v_z * (actualTime - prevSamplingTime) * 0.001; |
| 76 | + |
| 77 | + if (rotation[0] > 360) { |
| 78 | + rotation[0] -= 360; |
| 79 | + } else if (rotation[0] < 0) { |
| 80 | + rotation[0] += 360; |
| 81 | + } |
| 82 | + if (rotation[1] > 360) { |
| 83 | + rotation[1] -= 360; |
| 84 | + } else if (rotation[1] < 0) { |
| 85 | + rotation[1] += 360; |
| 86 | + } |
| 87 | + if (rotation[2] > 360) { |
| 88 | + rotation[2] -= 360; |
| 89 | + } else if (rotation[2] < 0) { |
| 90 | + rotation[2] += 360; |
| 91 | + } |
| 92 | + |
| 93 | + prevSamplingTime = millis(); |
| 94 | + } |
| 95 | + if (actualTime - prevPrintTime > 1000) { |
| 96 | + Serial.print("\nRotation:\n"); |
| 97 | + Serial.print(" X = "); |
| 98 | + Serial.println(rotation[0], 4); |
| 99 | + Serial.print(" Y = "); |
| 100 | + Serial.println(rotation[1], 4); |
| 101 | + Serial.print(" Z = "); |
| 102 | + Serial.println(rotation[2], 4); |
| 103 | + |
| 104 | + prevPrintTime = millis(); |
| 105 | + } |
| 106 | +} |
0 commit comments