Values from BNO055 are drifting when measuring for a longer period of time (IMU)

Thread Starter

anziboy

Joined Mar 25, 2019
4
Hello, I am a master thesis student at LTH who is currently working on creating a prototype which can measure the human knee joint angle for 24 hours. I am using two BNO055 sensors which are placed on the shank and thigh.

I get the quaternion values and find the absolute value from both in which i get the angle value. I tried running some measurements on humans and they seem to be really fine, however, when i do the measurements for a longer period of time (for example more than 20 minutes), my readings get drifted. Now my guess is that the drifting is coming from the gyroscope. I tried the different operational modes : IMUPLUS, NDOF in which i can measure the relative angle and absolute angle. Both are giving me the same error. When measure for a short period of time, it does not seem to be any problem.
I will post some screenshots where you can see how my drift values look (x-axis is time in seconds since arduino started, and y-axis the knee joint angle)

Now I am wondering if you can help me with that. What operational mode do you think i should try? I tried IMU and NDOF, but they both seem to be giving me the same error for a longer period of time.

I also tried placing the sensors in a stationary position for 30 minutes and they did not seem to get any drifting problems. I just get that once i start walking around with the sensors.

Any help or tips would be really appreciated! Thank you! I will also post my arduino code.

best wishes,
Anza

Code:
Adafruit_BNO055 bno = Adafruit_BNO055(55, BNO055_ADDRESS_A);
Adafruit_BNO055 bno1 = Adafruit_BNO055(55,BNO055_ADDRESS_B);
SdFat SD;
//SdFile myFile;
File myFile;
unsigned long id = 1;
const int chipSelect = SS;
#define SD_CS_PIN SS
unsigned long time;
long timeInterval = 10000;
long previousTime = 0;
const int buttonPin = 9;
int buttonState = 0;
long previousMillis = 0;
unsigned long StartTime = millis();
int LED = 6;
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) -1;
char fileName[] = FILE_BASE_NAME "00.txt";

void setup(void)
{
  //115200
  Serial.begin(115200);
  Serial.println(F("Relative angle measurement")); Serial.println("");
  Serial.print(F("Initializing SD card..."));
 
  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print(F("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!"));
    while(1);
  }

    if(!bno1.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print(F("Ooops, no BNO055 second detected ... Check your wiring or I2C ADDR!"));
    while(1);
  }

  pinMode(SS, OUTPUT);
//  if (!SD.begin(10)) {
//    Serial.println("initialization failed, program stopped!");
//    exit(0);
//SD.begin(SD_CS_PIN, SPI_FULL_SPEED);
if (!SD.begin(SD_CS_PIN)) {
    Serial.println(F("initialization failed!"));
   exit(0);
 
  }
  Serial.println(F("initialization done."));


//For creating a text file in SD card.
  while(SD.exists(fileName)) {
    if(fileName[BASE_NAME_SIZE +1] != '9'){
      fileName[BASE_NAME_SIZE +1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE +1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      Serial.println(F("Can't create file name"));
      return;
    }
  }
  myFile = SD.open(fileName, O_CREAT | O_WRITE);
  if(!myFile) {
    Serial.println(F("Open failed"));
    return;
  }
  Serial.print(F("Opened: "));
  Serial.println(fileName);

bno.setMode(bno.OPERATION_MODE_NDOF);
bno1.setMode(bno.OPERATION_MODE_NDOF);
  bno.setExtCrystalUse(true);
bno1.setExtCrystalUse(true);


void loop(void)
{
unsigned long CurrentTime = millis();
unsigned long ElapsedTime = CurrentTime - StartTime;
  buttonState = digitalRead(buttonPin);

sensors_event_t event;
  bno.getEvent(&event);
  bno1.getEvent(&event);
 
//Get quaternion values.
imu::Quaternion quat = bno.getQuat();
imu::Quaternion quat2 = bno1.getQuat();

quat.normalize();
quat2.normalize();
//Formula for the absolute angle between two quaternions.
double relDeg = 57.2958*2*acos(abs(quat.w()*quat2.w() + quat.x()*quat2.x() + quat.y()*quat2.y()+quat.z()*quat2.z()));
 

Attachments

Top