Giter Club home page Giter Club logo

lsm9ds1's Introduction

LSM9DS1

ST's new smaller, lower-power 9-axis motion sensor

The LSM9DS1 is a high-resolution (16-bit) 9-axis motion sensor (accelerometer, gyroscope, and magnetometer) in a 3 mm x 3.5 mm LGA 28 pin package. Coupled with the fine 24-bit Measurement Specialties MS5611 altimeter, the Teensy 3.1 add-on/breakout board offers 10 degrees of freedom in a compact size for many motion control applications.

Breakout boards are for sale at Tindie.com.

This is a basic Arduino (Teensiduino) sketch that parametrizes the registers, initializes the sensor configurations, performs the accel and gyro self-tests, calibrates the sensors, and uses the scaled output to obtain yaw, pitch, roll, and quaternions with open-source Madgwick and Mahony sensor fusion filters.

lsm9ds1's People

Contributors

davidrojas avatar j-mcc1993 avatar kriswiner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lsm9ds1's Issues

Not completely working for me

Hi Kris, I have been trying to make my LSM9DS1 with your code. I just have a few questions.

I am using madwick filter on an arduino uno.
MadgwickQuaternionUpdate(ax, ay, az, gx * PI / 180.0f, gy * PI / 180.0f, gz * PI / 180.0f, -mx, my, mz);

`if (readByte(LSM9DS1M_ADDRESS, LSM9DS1M_STATUS_REG_M) & 0x08) { // check if new mag data is ready
readMagData(magCount); // Read the x/y/z adc values

// Calculate the magnetometer values in milliGauss
// Include factory calibration per data sheet and user environmental corrections
mx = (float)magCount[0]*mRes; // - magBias[0];  // get actual magnetometer value, this depends on scale being set
my = (float)magCount[1]*mRes; // - magBias[1];  
mz = (float)magCount[2]*mRes; // - magBias[2];   

}`

In the above code why do you comment our the bias on magnetometre?

Secondly with my yaw has a lot of problems. I place the board on a breadboard and leave it on a place surface. i then rotate it by the z axis. but i can not see any changes.

below pic shows me moving in an eight shape and then putting the sensor to rest.
screenshot from 2017-08-16 15-17-13

the format is ax,ay,az,gx,gy,gz,mx,my,mz, roll,pitch, yaw. The sensor is flat on a breadboard on a tale and i am rotating it about the z axis.

Is there something i am doing wrong or some registers not outputting something? is there a way to factory reset the sensor?

finally i am using this sketch to visualise my imu.
https://github.com/PaulStoffregen/NXPMotionSense/blob/master/OrientationVisualiser/OrientationVisualiser.pde

it just doesnt seem to be doing anything.I rotate it then put it to rest and it reacts so slow. when i move it, it gets confused, goes the wrong way then back to the the other way.

Hope you can help fix this.

Kind Regards

Magnetometer data coherence

Hi,

I am using a LSM9DS1 on a custom PCB, with your code (thanks a lot btw), for a dead reckoning algorithm. For now I am outputing calculated quaternions for a Python script (https://github.com/thecountoftuscany/PyTeapot-Quaternion-Euler-cube-rotation), that calculates Euler angles and allow a visualization of the board position in 3D. Everything seems to be working fine when I try to manually move the board, yaw, pitch and roll angles values seem correct.

But when I try to put my device in a car and I take a 90° or 180° turn (with a few meters radius), mag values doesn't seem to change: on the visualizer, I can see the board trying to turn, because of the gyroscope input, but it is dampened by magnetometer data that doesn't change, and so it will then slowly go back to magnetometer calculated heading, that is still the same from before the turn... I also tried to calculate the heading by simply using magnetometer data (atan2(my,mx)), and have the same result. Plus, if I use a version of Madgwick algo without mag data, only accel and gyro, the turn is detected. So I know this error is coming from the magnetometer.

I'm sorry I know this issue might not be directly correlated to your code, but I just wanted to ask if you knew about such an issue and its origin.

Thank you in advance for any help !

LSM9DS1 Heading and Calibration

Hi Kris,

First, Thank you for your forums and support.
We are building a new product using the LSM9DS1 IMU unit.
We try to use it on a slow flight drone and currently we are at a preliminary stage of sensitivity and reliability tests.
I'm guessing it's an easy solution for you :-), but currently all we are trying to achieve is stable direction when holding the drone at a static phases and turning it (by hand) every 30-40 degrees.
For the code we use the madgwick filter.
Every 30 seconds after start up we implement a 'hand movement' calibration (moving it at all 3 dimensions).
We also perform a gyro bypass correction for the first 100 measurements to correct the drift.
At this point we struggle with several issues:

  • Updating time - when we move it to an heading, we see the heading updating very very slowly and it takes several seconds to reach to required one.
  • Unstable heading: Sometimes it a constant drift and sometimes its +-40 degrees

Any help will be appreciated.
Thank you!
Asher.

LSM9DS1 Gyro lsb value

According to the datasheet, lsb of gyro is 8.75 mdps/lsb for +-245 dps. 245/32768 gives 7.4768 mdps. Its also different for +-500 and +-2000 dps. Which one we should use?

Arduino Nano 33 BLE with LSM9DS1 sensor -> problem with implementation Madgwick libary

Hey Kris,

I am writing to You becouse I have big problem with my Arduino board and I can't resolve this from week.

I want to implement Madgwick filter and quaternions into my Arduino Nano 33 BLE board. After that i receive a lot of really crazy numbers without any sense.

I configured My board with ArduinoLSM9DS1 libary (https://www.arduino.cc/en/Reference/ArduinoLSM9DS1) it's really simply part of code in comparison into yours. For me is perfect beacouse I am beginner.

In my first use of this board I used data from sensors and I calculated Eulers angles to receive pitch,roll and yaw. I received preety good numbers.

Nextly I want to implement madgwick from here(https://x-io.co.uk/open-source-imu-and-ahrs-algorithms/)

Maybe You know with Your experience why I still cant use Madgwick on my board ? Maybe You done someting before on this board ?

Magnetometer calibration

Hi,

This is not an issue, it's more of a question, I spent a few good days on this.

I'm trying to calibrate the magnetometer inside LSM9DS1 and I'm not sure if my sensor is broken or if I get something wrong.

After I get the offset values and I apply them in the Madgwick filter, my yaw still drifts.

My guess is that the problem is related to the fact that no matter how slow or 'in a sphere' I move the sensor, the xy line never forms a circle, it's always a shaky line. Does anyone know why this happens?

Here's a video with the calibration attempt:
https://youtu.be/C8gwi17Sdag
(xy - blue; xz - pink; yz - yellow)

(No highlitht on the xy axis)
https://youtu.be/bjhdq8AKYg4

Gabriel

Have you ever run this code?

The question says it all. I'm looking at

// Function which accumulates gyro and accelerometer data after device initialization. It calculates the average
// of the at-rest readings and then loads the resulting offsets into accelerometer and gyro bias registers.
void accelgyrocalLSM9DS1(float * dest1, float * dest2)
{  
  uint8_t data[6] = {0, 0, 0, 0, 0, 0};
  int32_t gyro_bias[3] = {0, 0, 0}, accel_bias[3] = {0, 0, 0};
  uint16_t samples, ii;

   // enable the 3-axes of the gyroscope
   writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG4, 0x38);
   // configure the gyroscope
   writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG1_G, Godr << 5 | Gscale << 3 | Gbw);
   delay(200);
   // enable the three axes of the accelerometer 
   writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG5_XL, 0x38);
   // configure the accelerometer-specify bandwidth selection with Abw
   writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG6_XL, Aodr << 5 | Ascale << 3 | 0x04 |Abw);
   delay(200);
   // enable block data update, allow auto-increment during multiple byte read
   writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG8, 0x44);

  // First get gyro bias
  byte c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c | 0x02);     // Enable gyro FIFO  
  delay(50);                                                       // Wait for change to take effect
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_CTRL, 0x20 | 0x1F);  // Enable gyro FIFO stream mode and set watermark at 32 samples
  delay(1000);  // delay 1000 milliseconds to collect FIFO samples

  samples = (readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_SRC) & 0x2F); // Read number of stored samples

  for(ii = 0; ii < samples ; ii++) {            // Read the gyro data stored in the FIFO
    int16_t gyro_temp[3] = {0, 0, 0};
    readBytes(LSM9DS1XG_ADDRESS, LSM9DS1XG_OUT_X_L_G, 6, &data[0]);
    gyro_temp[0] = (int16_t) (((int16_t)data[1] << 8) | data[0]); // Form signed 16-bit integer for each sample in FIFO
    gyro_temp[1] = (int16_t) (((int16_t)data[3] << 8) | data[2]);
    gyro_temp[2] = (int16_t) (((int16_t)data[5] << 8) | data[4]);

    gyro_bias[0] += (int32_t) gyro_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases
    gyro_bias[1] += (int32_t) gyro_temp[1]; 
    gyro_bias[2] += (int32_t) gyro_temp[2]; 
  }  

  gyro_bias[0] /= samples; // average the data
  gyro_bias[1] /= samples; 
  gyro_bias[2] /= samples; 

  dest1[0] = (float)gyro_bias[0]*gRes;  // Properly scale the data to get deg/s
  dest1[1] = (float)gyro_bias[1]*gRes;
  dest1[2] = (float)gyro_bias[2]*gRes;

  c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c & ~0x02);   //Disable gyro FIFO  
  delay(50);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_CTRL, 0x00);  // Enable gyro bypass mode

  // now get the accelerometer bias
  c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c | 0x02);     // Enable accel FIFO  
  delay(50);                                                       // Wait for change to take effect
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_CTRL, 0x20 | 0x1F);  // Enable accel FIFO stream mode and set watermark at 32 samples
  delay(1000);  // delay 1000 milliseconds to collect FIFO samples

  samples = (readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_SRC) & 0x2F); // Read number of stored samples

  for(ii = 0; ii < samples ; ii++) {            // Read the accel data stored in the FIFO
    int16_t accel_temp[3] = {0, 0, 0};
    readBytes(LSM9DS1XG_ADDRESS, LSM9DS1XG_OUT_X_L_XL, 6, &data[0]);
    accel_temp[0] = (int16_t) (((int16_t)data[1] << 8) | data[0]); // Form signed 16-bit integer for each sample in FIFO
    accel_temp[1] = (int16_t) (((int16_t)data[3] << 8) | data[2]);
    accel_temp[2] = (int16_t) (((int16_t)data[5] << 8) | data[4]);

    accel_bias[0] += (int32_t) accel_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases
    accel_bias[1] += (int32_t) accel_temp[1]; 
    accel_bias[2] += (int32_t) accel_temp[2]; 
  }  

  accel_bias[0] /= samples; // average the data
  accel_bias[1] /= samples; 
  accel_bias[2] /= samples; 

  if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) (1.0/aRes);}  // Remove gravity from the z-axis accelerometer bias calculation
  else {accel_bias[2] += (int32_t) (1.0/aRes);}

  dest2[0] = (float)accel_bias[0]*aRes;  // Properly scale the data to get g
  dest2[1] = (float)accel_bias[1]*aRes;
  dest2[2] = (float)accel_bias[2]*aRes;

  c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c & ~0x02);   //Disable accel FIFO  
  delay(50);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_CTRL, 0x00);  // Enable accel bypass mode
} 

and have many questions...
Just one, for example:

  // First get gyro bias
  byte c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c | 0x02);     // Enable gyro FIFO   

I can see that you're indeed, enabling the fifo, but why is it gyro? You just enabled above all axes for both G and XL
Then you do:

  c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c & ~0x02);   //Disable gyro FIFO  
  delay(50);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_FIFO_CTRL, 0x00);  // Enable gyro bypass mode

  // now get the accelerometer bias
  c = readByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9);
  writeByte(LSM9DS1XG_ADDRESS, LSM9DS1XG_CTRL_REG9, c | 0x02);     // Enable accel FIFO  
  delay(50);                                                       // Wait for change to take effect 

Sorry, I don't see where the difference is and how is it now XL and not G? What am I missing?

Thanks.

Adafruit NXP Library for LSM9DS1

Hi to all.

First of all, I want to appreciate @kriswiner for making this code, that's a huge one, it makes using the sensor so easy and understandable for me. Thanks again.
Currently I'm trying to use the adafruit NXP Library for LSM9DS1, but unfortunately it's not working correctly.
I'm having some yaw drift problem with it.

I'm gonna be grateful for any help.

Regards,
Mason

Calibration question

Hi.
I am having trouble getting consistent readings from the lsm9ds1, and I think the issue is with my calibrations.

The thing is, I have had a couple of attempts where the readings have been spot on, but other times there is a lot of drift. So I know it works.
I have found that the best calibrations are made when I turn the devise around the yaw, pitch and roll, and then back again. You instruct to wave the device in the figure eight, could you perhaps expand on this technique?

Is there a way I can store the calibrations, or is it nessesary to calibrate it for every use?

Magnetometer Calibration

@kriswiner i have been using your code to make an ecompass and I have had a few problems which I am trying to pin down. Seeing issues on other repos of yours I decided to put some more effort on calibrating the magnetometer before posting.

According to my results, unless I am doing something terribly wrong, the magcal algorithm seems to be inadequate.

First I run it multiple times and found out that the magBias results are completely different. Then I plotted some experiments to make this a bit more concise. In the next screenshots you can see three views of the same experiment (mx, my, mz being printed)

screenshot from 2017-12-20 23-21-00
screenshot from 2017-12-20 23-20-39
screenshot from 2017-12-20 23-20-22

It looks like there is need for both soft and hard iron calibration.

temperature conversion

The line:

temperature = ((float) tempCount/256. + 25.0); // Gyro chip temperature in degrees Centigrade

only gives you (incorrect) temperatures from narrow range +17 to +33 ⁰C (because chip temp output registers are 12-bits only: -2048...+2047)

Where did you get the 256 value? For ThingSee device I'm using a different divisor (when converting to integer in hundredths of ⁰C):

/* 12-bit value, max. range -2048..+2047. Sensitivity according to datasheet
 * is quoted at 16 LSB/⁰C (Typ.), so we use that. 
 * Zero raw value = 25 ⁰C.
 */
     enum { LSM9DS1_TEMPERATURE_PRECISION=100 };

*int_temper = *raw_temper * LSM9DS1_TEMPERATURE_PRECISION / 16 +
    25 * LSM9DS1_TEMPERATURE_PRECISION;

For some other ST parts, the datasheets don't even bother to quote the sensitivity or even the zero point!

raw and pitch change simultaneously

Hi,

I can confirm the following:

a) I have calibrated my magnetometer, accelerometer and gyroscope correctly.

b) The data being passed in the Mahony and the Madgewick filter is in the correct order.
(ax, ay, az, gx, gy, gz, -1 * mx, my, mz)

I seem to be getting correct orientation for raw, but as pitch changes from +PI/2 to -PI/2, I also observe a change in yaw by PI radians, as pitch starts approach PI/2 radians, yaw starts getting distorted. I would be grateful if you could please provide some insight.

Many thanks,

Acc only reading changes

Hi Kris,
I´m setting the sensor to those settings after reset. The accel only changes its values when I move the device. There is no recognition of earth´s G, when I let one of the axes pointing to the ground, what I would expect.. Just a bit fluctation around 0. gyro and magnetometer values seem to be reasonable.

Do you have an hint for me, please?

I2C_SetSlaveAddress(Gyro);
	I2C_WriteRegister(CTRL_REG4, 0x38); //enable all axes
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG1_G, (uint8_t) (G_ODR_238<< 5 | G_SCALE_245DPS << 3 | GBW_med));
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG3_G,HP_enable);
	__delay_cycles(10);
	I2C_WriteRegister(FIFO_CTRL,0x0);//  FIFO off... by default off
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG9,DA_timer_enable);
	__delay_cycles(10);
	return 1;
}


uint8_t configAccel()
{
	I2C_SetSlaveAddress(Accel);
	I2C_WriteRegister(CTRL_REG5_XL, 0x38); //enable all axes
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG6_XL, (uint8_t) (AODR_238Hz << 5 | AFS_2G << 3 | 0x04 |ABW_50Hz) );
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG7_XL,0xA4); //High res Mode on,LP cutofffrequ  ODR/100
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG8, 0x44);// enable block data update, allow auto-increment during multiple byte read
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG9,DA_timer_enable);
	return 1;
}

uint8_t configMagnet()
{
	I2C_SetSlaveAddress(Magneto);
	I2C_WriteRegister(CTRL_REG1_M,0xF4 );  //xy:temp compensated, ultra performance mode, 10 Hz, def +-4gauss
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG2_M, (uint8_t) (MFS_4G << 5) ); // select mag full scal
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG3_M,0x0 ); //continous conversion mode, LPM off
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG4_M, (uint8_t) MMode_UltraHighPerformance <<2);// z Axis ultra perf
	__delay_cycles(10);
	I2C_WriteRegister(CTRL_REG5_M, 0x40);  //Block Update Mode
	__delay_cycles(10);
	return 1;

Reading from FIFO

Hello, I'm trying to program the LSM9DS1 to use FIFO mode, and then dump the FIFO onto my processor when it is full. In your code you say you use the FIFO but I'm unsure exactly how you do it. do you think you could quickly walk me through the procedure to read a full FIFO?

Your help is much appreciated.

Question

Hello, i was wondering how could implement all the code (so no serial code either) in python. I have an LSM9DS1TR chip simular to LSM9DS1. But if i convert the phi, theta and pitch to degrees its really off. There is a big difference, is there anyway u could help?

#Data ophalen vanuit de chip.
            accel_x = data.data['accel_x_mg']
            accel_y = data.data['accel_y_mg']
            accel_z = data.data['accel_z_mg']

            gyro_x = data.data['gyro_x_dps'] 
            gyro_y = data.data['gyro_y_dps']
            gyro_z = data.data['gyro_z_dps']

            magn_x = data.data['magn_x_mG']
            magn_y = data.data['magn_y_mG']
            magn_z = data.data['magn_z_mG']
            
            dt = (millis() - millisOld) / 1000
            millisOld = millis()

            q = [1.0, 0.0, 0.0, 0.0]
            eInt = [0.0, 0.0, 0.0]

            hx = float()
            hy = float()
            bx = float()
            bz = float()

            vx = float()
            vy = float()
            vz = float()

            wx = float()
            wy = float()
            wz = float()

            ex = float()
            ey = float()
            ez = float()

            pa = float()
            pb = float()
            pc = float()
            
            q1 = q[0]
            q2 = q[1]
            q3 = q[2]
            q4 = q[3]

            q1q1 = q[0]*q[0]
            q1q2 = q[0]*q[1]
            q1q3 = q[0]*q[2]
            q1q4 = q[0]*q[3]
            q2q2 = q[0]*q[1]
            q2q3 = q[0]*q[2]
            q2q4 = q[0]*q[3]
            q3q3 = q[0]*q[2]
            q3q4 = q[0]*q[3]
            q4q4 = q[0]*q[3]

            norm = math.sqrt(accel_x*accel_x + accel_y*accel_y + accel_z*accel_z)
            norm = 1.0 / norm #norm berekenen.

            accel_x *= norm 
            accel_y *= norm
            accel_z *= norm

        	#Deze 3 waardes bij elkaar in het kwadraat is ongeveer 1.0, met soms een hele kleine afwijking
            # print(np.round(accel_x, decimals=4), np.round(accel_y, decimals=4), np.round(accel_z, decimals=4))

            norm = math.sqrt(magn_x*magn_x + magn_y*magn_y + magn_z*magn_z)
            norm = 1.0 / norm #norm berekenen.

            magn_x *= norm 
            magn_y *= norm
            magn_z *= norm
            #plus minus 1

            hx = 2.0 * magn_x * (0.5 - q3q3 - q4q4) + 2.0 * magn_y * (q2q2 - q1q4) + 2.0 * magn_z * (q2q4 + q1q3)
            hY = 2.0 * magn_x * (q2q3 + q1q4) + 2.0 * magn_y * (0.5 - q2q2 - q4q4) + 2.0 * magn_z * (q3q4 - q1q2)
            bx = math.sqrt((hx*hx) + (hy*hy))
            bz = 2.0 * bx * (q2q4 - q1q3) + 2.0 * magn_y * (q3q4 + q1q2) + 2.0 * magn_z * (0.5 - q2q2 - q3q3)

            vx = 2.0 * (q2q4 - q1q3)
            vy = 2.0 * (q1q2 + q3q4)
            vz = q1q1 - q2q2  - q3q3 + q4q4
            
            wx = 2.0 * bx * (0.5 - q3q3 - q4q4) + 2.0 * bz * (q2q4 - q1q3)
            wy = 2.0 * bx * (q2q3 - q1q4) + 2.0 * bz * (q1q2 + q3q4)
            wz = 2.0 * bx * (q1q3 + q2q4) + 2.0 * bz * (0.5 - q2q2 - q3q3)

            ex = (accel_y * vz - accel_z * vy) + (magn_y * wz - magn_z * wy)
            ey = (accel_z * vx  - accel_x * vz) + (magn_z * wx  - magn_x * wz)
            ez = (accel_x * vy - accel_y * vx) + (magn_x * wy - magn_y * wx)

            Ki = float()
            if(Ki > 0.0):
                eInt[0] += ex
                eInt[1] += ey
                eInt[2] += ez
            else:
                eInt[0] = 0.0
                eInt[1] = 0.0
                eInt[2] = 0.0
            
            Kp = 2.0 * 5.0
            gyro_x = gyro_x + Kp * ex + Ki * eInt[0]
            gyro_y = gyro_y + Kp * ey + Ki * eInt[1]
            gyro_z = gyro_z + Kp * ez + Ki * eInt[2]

            pa = q2
            pb = q3
            pc = q4
            q1 = q1 + (-q2 * gyro_x - q3 * gyro_y - q4 * gyro_z) * (0.5 * dt)
            q2 = pa + (q1 * gyro_x + pb * gyro_z - pc * gyro_y) * (0.5 * dt)
            q3 = pb + (q1 * gyro_y - pa * gyro_z + pc * gyro_x) * (0.5 * dt)
            q4 = pc + (q1 * gyro_z + pa * gyro_y - pb * gyro_x) * (0.5 * dt)

            # Normalise quaternion
            norm = math.sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4)
            norm = 1.0 / norm
            q[0] = q1 * norm
            q[1] = q2 * norm
            q[2] = q3 * norm
            q[3] = q4 * norm
            #Ongeveer 1.0

            # print(q[0]*q[0]+q[1]*q[1]+q[2]*q[2]+q[3]*q[3])

            yaw   = math.atan2(2.0 * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3])
            pitch = -math.asin(2.0 * (q[1] * q[3] - q[0] * q[2]))
            roll  = math.atan2(2.0 * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3])
            pitch *= 180.0 / np.pi
            yaw   *= 180.0 / np.pi
            # yaw   -= 13.22 # Declination at Los Altos, California is ~13 degrees 13 minutes on 2020-07-19
            roll  *= 180.0 / np.pi
            print(pitch, yaw, roll)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.