Closed BaptisteLucas closed 3 years ago
Hi @BaptisteLucas , We are still gaining experience with the DMP and sadly we do not have all the answers... I do not know if it is possible to tell the DMP to subtract gravity from the accelerometer data. I think probably not? Please remember that an accelerometer can only measure acceleration. Once you are moving at a constant velocity, the acceleration is zero. I'm going to close this issue as I do not think I can give you any more help. Sorry! Best wishes, Paul
@PaulZC, @BaptisteLucas,
I was playing around with the DMP sketch for a project that I've been trying to get working. It's not the most elegant solution but I'm using the SENSOR_LINEAR_ACCELERATION to push data out at around 40 Hz at the moment.
I've managed to apply the Quat6 to the acceleration data to rotate it into a constant orientation. When the sensor starts up, it comes up with an intial value for the gravity vector, which gets slowly updated using an exponential moving average filter when the sensor isn't moving about too much (this could do with a bit of work).
I then apply another rotation to map "z" onto the gravity vector, with the result that I am getting acceleration readings where z is always down no matter how much you turn over the sensor, left is left etc.
I've tried to create a new example file that does what's required to make all of this work and put in a pull request for it (this is my first attempt, so no idea if it will work) - hopefully it can be of some use to someone.
Thanks, Jon
Hi Jon (@higherstateofawkwardness ),
Yes, please, I'd be very happy to include your example. But can you please do a few things for me? The examples in this library are not board-specific, so it is not really the right place for a OpenLog Artemis example. I would be grateful if you could:
Contribution guidelines are here. If you need a bit more advice, there is an oldie-but-goodie GitHub tutorial here.
Thanks again - we really appreciate the help, Paul
@PaulZC ,
Ah yes - I didn't notice that I was pasting the OLA specific one into the generic library. I'll see if I can make some time over the next short while.
Is there any way to have a quick chat about various development options outside of this particular "Linear acceleration" issue post? There are a few mods that I made to the code over the weekend that may improve the stability and functionality (using Quat9 instead of Quat6, which might remove the need to have a slowly updating gravity vector; upping the datarate to around 120 Hz, although this can introduce a few stability issues that I'm troubleshooting; dropping it into the OLA logging code). The last one of these is a bit of a bodge and probably needs a bit of wider discussion to enable continuous DMP logging as an option, rather than just hacking it in as the main data-collection function.
Contribution guidelines... yeah, that would make sense!
Cheers, Jon
Hi Jon (@higherstateofawkwardness ),
If the development options are specific to logging DMP data with OLA, then please feel free to open an issue in the OLA repo and we can continue the discussion there. For a more general discussion about the DMP, then please feel free to open an issue or issues in this repo if there is more than one thing to talk about. It is best to keep each issue focused on a single thing as far as possible.
If you want to experiment with the latest DMP logging code on OLA, you will find that in the OLA DMP branch. This commit contains the changes I made to log DMP data.
Sincere thanks, Paul
@PaulZC,
That should all be device-independent now. Looking at the various docs, I think that only the ICM-20648 can use the DMP to determine gravity; I've tried to read gravity using the Quat6 of the ICM-20948 but can't get it to work. I've put a manual gravity initialisation in. There is a drift in the Quat6 orientation if you shake it around a lot so this gravity vector is slowly updated in the code. If I can get the Quat9 to be stable and give sensible results, then this may give a lot better results.
Jon
HI Jon (@higherstateofawkwardness ),
Sincere thanks for this. Do you want to send me a Pull Request so I can merge it? Contribution guidelines are here. If you need a bit more advice, there is an oldie-but-goodie GitHub tutorial here. I can add your example manually but then you lose credit for having written it.
Very best wishes, Paul
Hi Jon (@higherstateofawkwardness ),
Please try version 1.2.6 of the library. I have made a small but important change to allow the DMP to work correctly. Please see issue #59 for more details.
I hope this corrects the behavior of the DMP for you and - in the nicest possible way - I hope makes your drift-correction code unnecessary?! ;-)
Best wishes, Paul
@PaulZC,
The code is showing a Pull request for the release candidate branch - not sure if I need to add you as a reviewer of not to make this work (https://github.com/higherstateofawkwardness/SparkFun_ICM-20948_ArduinoLibrary/pull/2) To be honest, I'm not too concerned about attribution, if the code works and can be used then it's better to get it out there.
With respect to the sensor drift, I'd love it we could make the correction uneccesary :). I still see the problem using the 1.2.6 library but I think perhaps "drift" is the wrong word for it (and maybe this is the point where we move this to a new Issue).
Using the Quat6, the quaternion and the accelerometer axes are pretty well aligned when I gently move the sensor around. However, when I shake it around and then let it stabilise in a new orientation, the quat6 orientation versus the accelerometer axes are off. You can see this in attached trend which is the quat6 corrected accelerometer values and has the gravity update algorithm turned off. They should be zero at rest, but i can change their values by beating the sensor around. The magnitude of the x/y/z vector at rest is still 1000 (1g), but in a different orientation.
I figured that this is probably because that I'm exceeding the maximum acceleration/rotation rates that the chip can handle and the DMP has a quaternion drift because it's trying to integrate a value which is over-range on the sensor. I get the same issues with the Quat9. So I did a test looking at just the Quat6 raw output (you can test yourself to confirm). I start with the sensor in a known position and gently move it around, the q1, q2 and q3 values (orientation vector) return to zero when I place the sensor in the original position (zero is the initial orientation by default). But when I shake it around and then put it back in the original orientation, the q1-q3 orientation vector is non-zero, and I can adjust which axis the error is in by shaking it in different orientations.
So this part of the issue seems to be an accumulation of orientation errors in the Quat6 and Quat9 vectors based on exceeding the sensor maximums. The only way that I can see to fix this is with reference to a known signal on the sensor - gravity or magnetic field vectors. Probably the rigorous way is to do it with reference to both; if we correct the gravity vector to point down, we can't be perfectly sure that our Quat6 isn't still rotated in the horizontal plane around the Z axis. Same with the magnetic field - only by using both can we properly reorient back to an external reference vector.
In your look through the documentation, did you find whether the ICM-20948 DMP calculates the gravity vector? I tried enabling "INV_ICM20948_SENSOR_GRAVITY" and reading it from the Quat6 register but this doesn't work. As far as I can tell, it's not actually implemented in the 20948, only the 20648.
Cheers, Jon
Hi Jon (@higherstateofawkwardness ),
Thank you again for digging into this!
I'm not quite sure what has happened with your Pull Request. You seem to have created a Pull Request for the release_candidate branch of your own fork? It is not appearing as a PR on this (the SparkFun "Master") repo...
By default, the DMP uses +/- 4g for the accel and 2000dps for the gyro:
It really doesn't take much to exceed 4g. Any kind of shock or impact will exceed that. So I fear you may be expecting too much from the sensor and DMP. It may be possible to use the 16g setting, but you will need to adjust the scale settings to match:
Re. INV_ICM20948_SENSOR_GRAVITY: I'm afraid you're heading into unchartered territory there. There is nothing in the documentation that defines what the different sensor configurations actually measure, or what their frames of reference are. The weird thing is that the control bit setting for Gravity and GRV are the same:
So I really don't understand how the DMP distinguishes between the two. Maybe I've missed something there. If I find time, I'll try enabling Gravity instead of GRV in ZaneL's wrapper for the InvenSense code and will see if it changes anything in the SPI bus traffic. That's the only concrete way to find the difference - if there is one.
All the best, Paul
Yup. I did a quick check of the SPI traffic from Zane's wrapper and there is no difference when I select INV_SENSOR_TYPE_GRAVITY
instead of INV_SENSOR_TYPE_GAME_ROTATION_VECTOR
... Make of that what you will! ;-)
Best wishes, Paul
@PaulZC,
Who knows, one day I'll get this right. It might even be today - I think that I've managed to create the right pull request from the release candidate branch in the proper library.
I think you have confirmed what I suspected, the gravity sensor is in the ICM-20648 chip but not the 20948.
I think that I've properly rescaled the sensor to 16g, changing the following lines: myFSS.a = gpm16;
// In order to align internal accel raw data 2^25 = 1g write 0x04000000 when FSR is 4g, 0x08000000 for 16g const unsigned char accScale[4] = {0x08, 0x00, 0x00, 0x00};
// In order to output hardware unit data as configured FSR write 0x00040000 when FSR is 4g, 0x08000000 for 16g const unsigned char accScale2[4] = {0x00, 0x08, 0x00, 0x00};
I found this output 1000 (1g) when the sensor is stationary, and makes it much less sensitive to shocks. I've disabled the gravity update routine by default, but it can be enabled by the user. I also put a longer wait time on the initial gravity routine as the sensor was taking a few seconds to settle down etc etc.
Seems to be a workable solution - won't be perfect for everyone but then what is?
I also tried using the Quat9 again and it gave some weird behaviour. C'est la vie.
Cheers, Jon
@PaulZC is this problem been solved? or the behaivior is expected . im using the latests version [Version 1.2.12] and im experiencing the same problem where the linear_accelarion is equal to the raw_accelarometer data. Shouldn't the linear acceleration remove the gravity components?
Hi @FilipeGlooma ,
There are still many things about the DMP that we do not understand...
If you have time to investigate this and share a solution, please do!
Best wishes, Paul
Hi, I'm trying to use the ICM20948 for both orientation and acceleration sensors. With your Example7_DMP_Quat6_EulerAngles file it's easy to get the corrected orientation data.
But for the acceleration it seems more difficule. I tryed to add the sensor linear acceleration mode for the DMP:
The result is that the DMP data contains now raw acceleration : data.Raw_Accel.Data
these accelerations are not corrected by the orientation of the IMU, then I can't use it directly (and I don't know how to use it !)
it seems that this configuration provide the same result as
success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_ACCELEROMETER) == ICM_20948_Stat_Ok);
Is there a way to have the x, y, z acceleration (without the 1g gravity and calibrated ) to be able to know if my sensor is moving left, right, up or down ?
thanks.