Open mahdihj opened 9 years ago
I'm also still confuse how to understand the math flow. There's some constant that shown:
dmpGetLinearAccelInWorld
function, is the return unit same as dmpGetLinearAccel
?https://github.com/jrowberg/i2cdevlib/blob/61866067ea283ebfb8e8673eb9a9a8f5e9af5398/Arduino/MPU6050/MPU6050_6Axis_MotionApps20.h#L496+-2g or 1/4 of 32768 OP this should read (+1g = +8192 in standard DMP FIFO packet, sensitivity is +-2g)
0 ~ 16383 is a negative gravity reading for all scales 16384 == 0g always no matter what scale you are using 16385 ~ 32768 is a positive gravity reading for all scales
Hi @ZHomeSlice,
Thanks for the clarification, it helping me understand a little bit better. One more thing, I still don't follow the math on how to get rid of gravity component (val-gravity) by multiplying it with 1g (val*8192)?
It's like just converting a g-unit value (maybe) back to bit-unit, ex:
val=1.5g, 1g=8192bit, val=1.5*(8192bit)=12288bit
Hi @ZHomeSlice,
The acceleration values are 2 bytes. Therefore, shouldn't the values range from -32768 to 32767? In that case, 8192 = 0.5g.
Or am I misunderstanding something here?
Edit:
I've tried running the MPU6050_DMP6_using_DMP_V6.12.ino
example. When the sensor is placed flat on a flat surface, the Z acceleration reads roughly 8192
(should be roughly 0
). If I changed the dmpGetLinearAccel() method to multiply the individual values of gravity by 16384
instead, the respective acceleration values returned from that method returns all 0
when the sensor is flat at rest.
@jrowberg could you comment on this?
When the MPU is set for +-2G
1G is = 16384;
and 2G = 32,767
@lekoook yes you are correct 8192 = 0.5g.
from the Unsigned int: The output of the MPU6050 at 0g is 1/2 of 65,535 or 32,768 The output of the MPU6050 at +2G is 65,535 The output of the MPU6050 at -2G is 0
It looks like your correct...
// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef);
// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet);
uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) {
// get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g)
v -> x = vRaw -> x - gravity -> x*8192;
v -> y = vRaw -> y - gravity -> y*8192;
v -> z = vRaw -> z - gravity -> z*8192;
return 0;
}
should be:
// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef);
// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet);
uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) {
// get rid of the gravity component (+1g = 16384 in standard DMP FIFO packet, sensitivity is +-2g)
v -> x = vRaw -> x - gravity -> x*16384;
v -> y = vRaw -> y - gravity -> y*16384;
v -> z = vRaw -> z - gravity -> z*16384;
return 0;
}
This is always true when using DMP as the DMP Accelerometer scale must be set to +-2g to work properly.
I did not write this code and I have not tested this as I use quaternion mainly for my balancing bots.
Anyone object to this change??? if not, let's suggest this as an update to jeffs code.
Z
Data Sheet: Document: MPU-6000/MPU-6050 Register Map and Descriptions Page 29 4.17 Registers 59 to 64 – Accelerometer Measurements These registers store the most recent accelerometer measurements. Accelerometer measurements are written to these registers at the Sample Rate as defined in Register 25. The accelerometer measurement registers, along with the temperature measurement registers, gyroscope measurement registers, and external sensor data registers, are composed of two sets of registers: an internal register set and a user-facing read register set. The data within the accelerometer sensors’ internal register set is always updated at the Sample Rate. Meanwhile, the user-facing read register set duplicates the internal register set’s data values whenever the serial interface is idle. This guarantees that a burst read of sensor registers will read measurements from the same sampling instant. Note that if burst reads are not used, the user is responsible for ensuring a set of single byte reads correspond to a single sampling instant by checking the Data Ready interrupt. Each 16-bit accelerometer measurement has a full scale defined in ACCEL_FS (Register 28). For each full-scale setting, the accelerometers’ sensitivity per LSB in ACCEL_xOUT is shown in the table below. AFS_SEL Full Scale Range LSB Sensitivity 0 ±2g 16384 LSB/g 1 ±4g 8192 LSB/g 2 ±8g 4096 LSB/g 3 ±16g 2048 LSB/g Parameters: ACCEL_XOUT 16-bit 2’s complement value. Stores the most recent X axis accelerometer measurement. ACCEL_YOUT 16-bit 2’s complement value. Stores the most recent Y axis accelerometer measurement. ACCEL_ZOUT 16-bit 2’s complement value. Stores the most recent Z axis accelerometer measurement.
Once DMP is enabled, the acc range must be +-4g and gyro +-2000 dps, this is required by dmp hardcoded firmware. If you try to modify these values inside dmpInitialize() you will get incorrect data out of dmp fifo. Hence the sensitivity is 8192/1g see: https://github.com/jrowberg/i2cdevlib/issues/391
I just found this same bug today. Was there a PR opened to fix it?
uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 _v, VectorInt16 vRaw, VectorFloat gravity) { // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) v -> x = vRaw -> x - gravity -> x_8192; v -> y = vRaw -> y - gravity -> y_8192; v -> z = vRaw -> z - gravity -> z_8192; return 0; }
I think based on the MPU-6050 specification sheet: 1g should be equal 16384 for sensitivity of 2g.
Sensitivity Scale Factor AFS_SEL=0 16,384 LSB/g