Sensor Fusion yaw drift after fast movements

Using sensor fusion streaming mode with three MetaWear-R under iOS at the same time (iPhone 7 and bluetooth 4.2), I have noticed that after initial initialization, particularly with very fast movements that I had in time and even quite quickly a drift between sensors regarding attitude (yaw euler angle) 
I have tried with different sensorfusion options ; NDoF, M4G even IMUplus without magnetometer, but with the same results with my 3 sensors...
Would you have any advice to learn to manage this drift in time ; particularly with multi sensors which need to get the same attitude (yaw angle).
What about an NDof option with magnetometer at 50Hz or 100Hz ?

Am I alone to get this ?


  • Can you provide some data from the 3 devices showing the discrepency?
  • @patrice

    Re: NDoF 50/100 Hz Mag, the sensorfusion algorithms in NDoF only support magnetometer input at 25Hz.  However, changing the settings (which primarily involve oversampling) on the magnetometer can produce a more responsive or more averaged measurement.  Those settings may help to stabilize the output behavior you are seeing.
  • edited April 12
    Thanks Eric and Matt for your answers.

    Before sending you some significant samples I have to make some new tests after some code review in my app. Particularly compare objective c and swift implementation with several sensors.

    Nevertheless, using MetaWearApi Test app, it is quite easy to see the drift and attitude accuracy issues with fast successive movements.
    I just add on the storyboard 3 new labels under the sensor fusion graph to show Euler values from (obj.p), (obj.y) et (obj.r) and survey particularly obj.y (yaw) after really fast successive movements... 
    My method is :
    - start the streaming, 
    - read the values with the sensors motionless,
    - then move the sensor during 15 seconds (mainly the yaw rotation), alternating fast and slow rotations in one sens and another.
    - and finaly read the new values with the sensor motionless (and paying attention to get the same values for obj.p and obj.r).

    I also notice that I had better result using sensor in horizontal (landscape) mode that in vertical mode (portrait).
    Indeed, regarding a rotation from LandscapeLeft to LandscapeRight  when sensor is horizontal, obj.r (roll) is moving but obj.p and obj.y do not change (which is normal) ; yaw movement looks really independent...
    But if you do the same thing with the sensor "vertical", when you roll (obj.r changing) it affects yaw (with obj.y which changes also...) which shouldn't I think... Normal according to you ?

    Many thanks for your attention

  • What mode and data ranges are you using for sensor fusion?  Another user had mentioned discrepancies with vertical usage but was able to correct the data.

  • Thanks Eric,
    NDoF mainly but I tried with each mode and it is the same problem.
    I even tried with quaternions but as mentioned by ivancap in his post, all is about the reference frame.
    I m going to ask him if he could be a little more explicit regarding the quaterniomultiplication as I guess he needs to calculate behind all euler angles ; which is really not easy.
  • @patrice 
    I was wondering if you had any progress/solution to the reference frame issue as I am using the sensor in a vertical position.  Really appreciate any additional information you may have.  Thanks.
  • Hello Winston,

    Yes I succeed to get a better result in vertical mode thanks to ivancap and using :
    1. first a quaternion multiplication ,
    2. and then euler calculation from quaternion.
    But I unfortunately still have the yaw drift in time while moving fast ; and impossible until now to synchronize the yaw (at least 1 or even 2 degrees) of two metawear in time...

    Here is my code regarding quaternion multiplication, I do hope it will help !

    let init_q = GLKQuaternionMake(Float(obj.x), Float(obj.y), Float(obj.z), Float(obj.w))

    let rotation_q = GLKQuaternionMakeWithAngleAndAxis(Float.pi/2100)

    let q = GLKQuaternionMultiply(rotation_q, init_q)

Sign In or Register to comment.