Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

caliberateAccelerometer() results in an error! #2

Open
PatrickPB opened this issue Jul 7, 2020 · 4 comments
Open

caliberateAccelerometer() results in an error! #2

PatrickPB opened this issue Jul 7, 2020 · 4 comments

Comments

@PatrickPB
Copy link

Whenever I activate calibrateAccelerometer() and after the 6 obligate positions, I get IndexError: list index out of range
see below

"..
Put the IMU in 6 position
[-3.65328894 9.16576421 3.43421432]
[9.416180537422752, -10.05599768734264]
[8.000009931792171, 9.165764213321125]
[-7.225422289768825]
Traceback (most recent call last):
File "kalman.py", line 29, in
imu.caliberateAccelerometer()
File "/home/pi/.local/lib/python3.7/site-packages/imusensor/MPU9250/MPU9250.py", line 307, in caliberateAccelerometer
self.AccelBias[2] = -1*(zscale[0] + zscale[1])/(abs(zscale[0]) + abs(zscale[1]))
IndexError: list index out of range
"
Can you help?
I need calibration, the values are going too much up and down. Trying to use the 9250 for a 2 wheel balancing robot.
Kp me informed

@niru-5
Copy link
Owner

niru-5 commented Jul 8, 2020

Hi Patrick,
In the above error, the last three lines showcase the mean acceleration across various axes ->
[9.416180537422752, -10.05599768734264] -> +- x-axis
[8.000009931792171, 9.165764213321125] -> +- y-axis
[-7.225422289768825] -> +- z-axis
Every time you put in a specific position, it calculates the mean acceleration value. However, if the mean value is below 7, it is not considered as the lowest g on earth does not go below 9, so I assumed 7 is a safe cutoff. If it is below 7, then I believe it has some other force acting on it while calibrating.
I also see a lot of change in the values for mean values across the other axes. I would suggest the following steps ->
The default imu.Accels and imu.AccelBias are [1,1,1] and [0,0,0] respectively.
Use the below code to see how well they are working.

import os
import sys
import time
import smbus

from imusensor.MPU9250 import MPU9250

address = 0x68
bus = smbus.SMBus(1)
imu = MPU9250.MPU9250(bus, address)
imu.begin()
# imu.caliberateGyro()
# imu.caliberateAccelerometer()
# or load your own caliberation file
#imu.loadCalibDataFromFile("/home/pi/calib_real_bolder.json")

while True:
	imu.readSensor()
	imu.computeOrientation()

	print ("Accel x: {0} ; Accel y : {1} ; Accel z : {2}".format(imu.AccelVals[0], imu.AccelVals[1], imu.AccelVals[2]))
	time.sleep(0.1)

Use the above code to see the acceleration value in all directions. If you get roughly equal to 9.8 or close to it, that tells that the accelerometer has been properly calibrated at the factory itself, you might not need any change.
However, in the case that you don't see proper values or values not so close to 9.8 or close to the gravity at your place
Placing the sensor in 6 different positions can be a pain and doing this every time is not feasible. I would suggest you do this once properly and save the calibration values using the below code.

import smbus
import numpy as np
import sys
import os
import time

from imusensor.MPU9250 import MPU9250


address = 0x68
bus = smbus.SMBus(1)
imu = MPU9250.MPU9250(bus, address)
imu.begin()
print ("Gyro caliberation starting")
imu.caliberateGyro()
print ("Gyro caliberation finished")
print ("Accel caliberation starting")
imu.caliberateAccelerometer()
print ("Accel caliberation Finisehd")
print (imu.AccelBias)
print (imu.Accels)
imu.saveCalibDataToFile("/your_path/calib.json")

Make sure to give your path and also make sure it has .json at the end for the function imu.saveCalibDataToFile()
Note: Make sure not to move the sensor when the gyro is being calibrated.

Once you have all the calibration saved, you can directly call the calibration file using imu.loadCalibDataFromFile and check the accelerometer values again.

import time
import smbus

from imusensor.MPU9250 import MPU9250

address = 0x68
bus = smbus.SMBus(1)
imu = MPU9250.MPU9250(bus, address)
imu.begin()
# imu.caliberateGyro()
# imu.caliberateAccelerometer()
# or load your own caliberation file
imu.loadCalibDataFromFile("/your_path/calib.json")

while True:
	imu.readSensor()
	imu.computeOrientation()

	print ("Accel x: {0} ; Accel y : {1} ; Accel z : {2}".format(imu.AccelVals[0], imu.AccelVals[1], imu.AccelVals[2]))
        print ("roll: {0} ; pitch : {1} ; yaw : {2}".format(imu.roll, imu.pitch, imu.yaw))
	time.sleep(0.1)

You can also have a look at the orientation computed as well. However, yaw might not be accurate until the magnetometer calibration is not done.

I have tested the above code once and I get the following axes values
Put the IMU in 6 position
[ 0.40221046 9.76319585 -0.40129463]
[-9.5352143373769742, 9.8833130803387483]
[-9.6117189636072311, 9.7631958489356823]
[-10.336259255664912, 9.1167883231860838]

I felt most variations are around 8 to 11, but below 7, I felt it could be due to other external forces as well and hence put a check for it. I hope if the sensor properly placed should be able to calibrate. If you still face a problem or the above error, let me know.

I hope the above steps help.
Mag calibration a different thing altogether and you can have a look at my example for that.

If your curious understand the calibration process for accelerometer, it is as follows ->
Let's take one axis for example. The sensor comes with its own set of bias and scale internally which is normally set in the factory itself.
raw_sensor_val = N(sensor_val*scale_factory + bias_factory)
Here N is the sensitivity factor that maps volts to m/sec_square. It normally comes from the range we set to the accelerometer.

In ideal conditions, the raw_sensor_val should read +-g when its axis is parallel to Earth's g. This is isn't always the case and hence we get two more parameters scale and bias.

sensor_val = (scale)*raw_sensor_val + bias
Using the above equation we get two equations when the sensor axis is aligned with Earth's g.
g = (scale)*raw_sensor_val_1 + bias
-g = (scale)*raw_sensor_val_2 + bias

From the above two equations we can find scale and bias
scale = 2g/(raw_sensor_val_1 - raw_sensor_val_2)
bias = -1
(raw_sensor_val_1 + raw_sensor_val_2)/(raw_sensor_val_1 - raw_sensor_val_2)

In the code, I find raw_sensor_val_1 and raw_sensor_val_2 by averaging over 100 values in that respective position.
Note: This method of calibration should be good for finding the orientation of the sensor as that would deal with ratios.

@niru-5
Copy link
Owner

niru-5 commented Jul 8, 2020

Hi,

I have updated the package with a small change in the calibration of accelerometer.
You can get it by the following command
pip install --upgrade imusensor or in your case pip3 install --upgrade imusensor

Note:
In the above comment the equation for bias is as follows
bias = -g*(raw_sensor_val_1 + raw_sensor_val_2)/(raw_sensor_val_1 - raw_sensor_val_2)

@PatrickPB
Copy link
Author

Thx, after updating ; error solved
But looking into the accelero values, I will need good calibration - the values go up to 15,9 and -15,9 on one axe when the others are around 0 to 1; strange to have such deviation from 9.8 knowing its calibrated in prod; anyway i will dive into the details when more time avail and feed back.
I have another question:
Did you write code to get the dmp quaternion values directly?
Did you make a comparison of performance of the internal dmp output with the Kalman output?
Regards

@niru-5
Copy link
Owner

niru-5 commented Jul 11, 2020

It is strange to see such drastic changes. Were the values any better after calibration?

About accessing DMP and a lot of its features, I will be working on it and update you when we release it. However, It could take a while, in the mean time, you can use the code of underlying commands like _write_register and _read_registers to your advantage. These functions are undocumented but you can get an idea when you see the code. They are present in imusensor/MPU9250/MPU9250.py

Thanks
Niru

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants