-
Notifications
You must be signed in to change notification settings - Fork 1k
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
EKF estimates Yaw incorrectly #870
Comments
In KalmanUSC we always used the full IMU data. We didn't have anything like Re. the first If the attitude estimate is always perfect, and we pretend the body is perfectly rigid and blade flapping does not happen, then it's true that the Re. the second It looks like this block is trying to make the EKF behave more like the complementary filter when the quad is sitting on the ground. This is (IMO) a good goal. However, it is always reverting towards If we want to apply such a correction during flight, It might be more correct to rotate towards the nearest quaternion with roll/pitch of zero but allow the yaw to drift. Technically even this is wrong, since we might hold a fixed nonzero roll/pitch attitude for a long time if we were flying long distances outdoors. |
Thanks for the detailed comments! I commented out the correction ( crazyflie-firmware/src/modules/src/kalman_core/kalman_core.c Lines 553 to 560 in 0787950
quadIsFlying blocks. However, I did reset the kalman filter always prior to takeoff, which might have prevented me from seeing strange drifting in roll/pitch. I also only did the hover test (where there are micro-movements in x/y). I didn't do any test where the Crazyflie is just sitting on the ground. The offline analysis with the Python bindings used a simple circle trajectory.
|
So your test was equivalent to setting |
FYI, the |
So, @whoenig could you explain the state of this like I was a 38-year-old engineer with no control theory background? |
|
Hi, As for the implementation, I have tried both the original code as well as when commenting out the lines suggested by @whoenig. While both work fine for me with respect to yaw, the implemenation with all the accelerations (so not just zacc) makes the crazyflie subjectively more "nervous" in terms of position control (especially with TDoA): crazyflie-firmware/src/modules/src/kalman_core/kalman_core.c Lines 506 to 509 in 7a0ed44
crazyflie-firmware/src/modules/src/kalman_core/kalman_core.c Lines 521 to 524 in 7a0ed44
However, it seems to me this implementation is "more correct". The original (only zacc) uses the z-axis acceleration as an input representing thrust. But this means any other aerodynamic forces (lift and drag of the structure and props) is neglected. Including all the accelerations accounts for all the forces acting on the crazyflie (see equations 9 and 15 of Mueller 2015). Interestingly, the "nervousness" can be to a greater deal removed (again subjectively) by using the "robust" implementation of TWR & TDoA, which seems to improve the performance in general. I am personally interested in including some terms that can capture aerodynamic forces other than thrust, as otherwise the attitude of our Bolt-based flapping-wing drones does not get estimated correctly in forward flight... And so this could be the easiest and most generic way to go... Will try to do some more testing with the Lighthouse and also with the flapping-wing... |
My setup is a motion capture system with a single marker on top (i.e., the EKF fuses position and IMU data). I fly a simple figure 8 and can observe the drift very quickly after a few seconds. The drifting gets worse over time. Lighthouse has some "hacked" yaw-compensation when flying in the crossing-beam method. For the regular EKF fusion, the current filter works OK for me. Tu fully implement Mueller 2015, we need the forward model of the quadrotor (i.e. PWM-> force; easy to obtain for CF2.1, but might be difficult for Bolt or flapping-wing). |
I see, so when simply hovering there is no drift, only with the figure 8 pattern? The implementation of the drag model would "just" need to measure/estimate motor rpm, and then measure the thrust curve and measure/estimate the drag coefficients... Not impossible, even for a flapping wing :) But the accelerometer is in principle measuring all that already, isn't it? |
Hovering also causes a drift, but this is "expected" (since yaw is not observable if x/y are not changing). Yes, the accelerometer captures everything, although with lots of noise and time delays. It might be interesting to fuse the acc-data directly as measurement. Slightly off-topic: the Python bindings are making progress and I have used prototypes of them in the past for tuning the EKF. If we have good datasets, this would be much easier than tuning + flight tests. |
Ok, I see... Well in my tests I was simply hovering and no problem observed after 2 minutes.... But it could be that with LPS the xy oscillations are enough to make yaw observable again... But that wouldn't explain why the figure 8 is problematic in your case... FYI, with a CF2 in a Lighthouse keeping all the accelerometer terms in the position & velocity updates did not seem to have any adverse effect. For a flapping wing in LPS, however, the high accelerometer "noise" (actually real vibrations) makes it perform much much worse than with only accz. So if we make some changes, I would opt for making them optional :) Maybe indeed treating the accelerometer as measurement could help to some extent... |
Perhaps what is suggested in #981 can be a solution to this? |
I think #981 can certainly help for tuning, but is independent of this issue. |
Seems like people are hitting this issue again. Let's check if this is still the case https://github.com/orgs/bitcraze/discussions/1321 |
When flying without external yaw-compensation, the Crazyflie will quickly (about 30seconds) become unstable due to incorrect yaw estimates. Until now, it seems to have assumed to be normal, as there are workaround in the code (e.g., push "virtual" yaw measurement in lighthouse:
crazyflie-firmware/src/modules/src/lighthouse/lighthouse_position_est.c
Line 445 in 0787950
From preliminary Python bindings, I found that the yaw is indeed estimated very badly (off by 20 degrees after 30s), even in cases where the gyro.z data is excellent.
When setting
quadIsFlying
toFalse
(or alternatively deletingcrazyflie-firmware/src/modules/src/kalman_core/kalman_core.c
Lines 480 to 508 in 0787950
crazyflie-firmware/src/modules/src/kalman_core/kalman_core.c
Lines 553 to 560 in 0787950
The main difference between the two modes is the use of the accelerometer. In the
quadIsFlying
mode, acc.z is used to estimate the commanded thrust (as rpm measurements are not readily available as proposed in the paper). In the second, better-working, mode, the accelerometer is used for position and velocity update (using the IMU rather than concrete dynamics models knowledge). I haven't found out yet why this differences causes such dramatic problems with the yaw estimate (and not the other orientation components).@jpreiss: Did we always use acc+gyro for the prediction step in KalmanUSC? Do you have some insights on why the
quadIsFlying
mode might cause issues with the yaw estimate?My proposal is to delete the logic mentioned above and have one unified code path, independent of
quadIsFlying
. Alternatively, we could use a proper model for the commanded thrust (as we can compute with the system ID deck) and use that rather thanacc.z
.The text was updated successfully, but these errors were encountered: