Page 1 of 1

slerp Bug

Posted: Wed Feb 19, 2014 1:20 am
by porcus
Hi,

I noticed that quaternion::slerp may calculate a not normalized quaternion (because of rounding errors and epecially in the lerp case). In my case the slerp result was sometimes up to 10° off. After I added the normalization the problem disappeared:

Please change:

Code: Select all

 
     if (angle <= (1-threshold)) // spherical interpolation
     {
         const f32 theta = acosf(angle);
         const f32 invsintheta = reciprocal(sinf(theta));
         const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
         const f32 invscale = sinf(theta * time) * invsintheta;
         return (*this = (q1*scale) + (q2*invscale));
     }
     else // linear interploation
         return lerp(q1,q2,time);
 
to

Code: Select all

 
     if (angle <= (1-threshold)) // spherical interpolation
     {
         const f32 theta = acosf(angle);
         const f32 invsintheta = reciprocal(sinf(theta));
         const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
         const f32 invscale = sinf(theta * time) * invsintheta;
         *this = (q1*scale) + (q2*invscale);
     }
     else // linear interploation
         lerp(q1,q2,time);
     normalize();
     return *this;
 

Re: slerp Bug

Posted: Wed Feb 19, 2014 9:23 am
by CuteAlien
Thanks for the info. But it would be really nice if you could add a test-case to reproduce the bug so we can see the problem in action.

Re: slerp Bug

Posted: Wed Feb 19, 2014 12:18 pm
by porcus
I used slerp for sensor fusion to interpolate between a slow changing reference rotation and a fast changing gyroscope rotation (which has an accumulating error) to eliminate the error. For testing purposes I used a predefined rotation in exchange for the gyrosope output which converges then to the reference rotation over time. Without normalization the rotation converges sometimes to a slightly different rotation which is about 10° off.
Unfortunately I think it would take a lot of time to create an independent test case.

Re: slerp Bug

Posted: Wed Feb 19, 2014 12:41 pm
by CuteAlien
Yeah, I know creating test-cases takes time. That's why I had hoped you already have one to start with. Because we have to start from scratch without even having a case were it goes wrong now to reproduce it which takes even more time.

But how do you know this really was your bug if you don't have a test-case? Adding a normalize at some point without having a good test-case might just hide the real problem if you're unlucky...

edit: Note, some ways I create such test-cases is for example - I copy the function once and run some code twice - once with original and once with changed function. Then I compare the results and set a breakpoint if they are different. Then I can just step back in the debugger and copy the values which go inside the function. Bingo - testcase. But that certainly only works if you already have somthing to start with - that's why it would be so much faster for you to do that than for us.

Re: slerp Bug

Posted: Wed Feb 19, 2014 4:58 pm
by porcus
That's a good idea, but unfortunately I wasn't able to get ndk-gdb running. I'm using the internal sensors of my Nexus 7 for both rotations, so I can't test it on my pc.