Hi everyone.
I am working on a project where i have to determine position and rotation of an IoT object with accelerometer, gyroscope and magnetometer. The goal is to show this object in a Unity3D virtual world.
To do this, i have an Arduino Nano 33 BLE that include a LSM9DS1 as inertial module.
So, i started to determine the rotation of my object. This link was very usefull : accéléromètre et gyroscope MPU6050 - /dev/tbo
That's the line for get the Y axis :
angle=0.98*(angle+float(gy)0.01/131) + 0.02atan2((double)ax,(double)az)*180/PI;
With this one, i can get X, Y and Z angles. When i try one by one axis orientation, all axis rotation are fine. The problem is when i use 2 axis or more at same time. For example, i use only X and Y axis. When i turn only X axis of 90°, Y axis turn of 90° too. This video will explain more accurately than words : Problem Orientation Arduino Nano 33 BLE to Unity - YouTube
I searched lot of things to fix it but now, i have no more idea. Can anyone guide me?
Read about how to post on the forum, then post code, schematics etc. Use code tags.
Thanks, and sorry. I havn't read this post before ask my question ...
This is my complete code :
#include <Arduino_LSM9DS1.h>
#include "math.h"
float ax, ay, az;
float gx, gy, gz;
float anglex=0, angley=0, anglez=0;
unsigned long timer = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Started");
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
}
void loop() {
timer = millis();
if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
IMU.readAcceleration(ax, ay, az);
IMU.readGyroscope(gx, gy, gz);
//Read accelerometer and gyroscope as degree
float atanx = atan2((double)ay,(double)az)*180/PI;
float gyrox = fmod(double(anglex+float(gx)*0.03/0.762), 360.0);
float atany = atan2((double)ax,(double)az)*180/PI;
float gyroy = fmod(double(angley+float(gy)*0.03/0.762), 360.0);
float atanz = atan2((double)ay,(double)ax)*180/PI;
float gyroz = fmod(double(angley+float(gy)*0.03/0.762), 360.0);
//Change value to get a value from 0 to 360°
if (atanx < 0) {
atanx = atanx + 360;
}
if (gyrox < 0) {
gyrox = gyrox + 360;
}
if (atany < 0) {
atany = atany + 360;
}
if (gyroy < 0) {
gyroy = gyroy + 360;
}
if (atanz < 0) {
atanz = atanz + 360;
}
if (gyroz < 0) {
gyroz = gyroz + 360;
}
/*
* Get angle smmoth from gyro and accel.
* Tried different way to change coef before gyro and accel.
* All time coef gyro + coef accel = 1
*/
anglex=0.6*gyrox + 0.4*atanx;
angley=0.6*gyroy + 0.4*atany;
anglez=0.6*gyroz + 0.4*atanz;
//print values
Serial.print(anglex);
Serial.print("/");
Serial.print(angley);
Serial.print("/");
Serial.println(anglez);
}
delay((0.03*1000) - (millis() - timer));
}
In Unity3D, i just get this values and asign them to an object.
Your video looks like “gimbal lock”, I wonder if your equations and processes have a fundamental difficulty with certain orientations? Perhaps there is some kind of discontinuity that makes passing through that straight up position mathematically fraught.
Only thinging out loud, so to speak.
a7