Angular velocity from two quaternions

1,436 views
Skip to first unread message

jcooper

unread,
Nov 23, 2010, 3:10:23 PM11/23/10
to ode-users
We want to find the angular velocity, w(t) (in world coordinates),
that will move a body from orientation q(t) to orientation q(t+dt) in
one timestep, dt. Using the time derivative dq(t)/dt = .5*w(t)*q(t),
it’s apparent that we can get what we want from: w(t) = 2*dq(t)*q’(t)/
dt where q’(t) is the quaternion conjugate. So, we need to compute
dq(t). The easiest thing to do is pretend it’s linear:
dq(t) = q(t+dt) - q(t)
I’ve done this and it seems to work fairly well for small changes, but
less well for larger changes (I have already ensured that dq(t) is
always going the short way around the circle).
If we take the time derivative of the Slerp function and evaluate it
at the starting time, we get:
dq(t) = (theta/sin(theta))*(q(t+dt) - cos(theta)*q(t)) where theta =
acos(dot(q(t),q(t+dt)).
This seems right. As theta approaches zero, it’s identical to the
linear method. We should be able to use the same approximation of
sinc(x) already implemented in util.cpp. I haven’t tried this yet,
though. I wondered how it compared to the Fixed joint.
The fixed joint, when all is said and done, seems to use this formula:
dq(t) = q(t)*[q’(t)*q(t+dt)]{real->0}
where the ‘real’ (w) component of the product inside the brackets is
set to zero. It seems like this must be related somehow to the other
equation used for Slerp: q(t)*(q’(t)*q(t+dt))^(x/dt), but I’m not sure
how. I haven't tried, but it seems like this method will also not
step the full distance if the change is large (even if ERP is set to
1).
Does anyone know the advantages of the different methods? Is there a
better way to do this?

Tom A

unread,
Nov 25, 2010, 8:22:52 AM11/25/10
to ode-users


On Nov 24, 7:10 am, jcooper <josephcoo...@gmail.com> wrote:
> I’ve done this and it seems to work fairly well for small changes, but
> less well for larger changes (I have already ensured that dq(t) is
> always going the short way around the circle).

Do you have any specific examples where it doesn't work very well?
Message has been deleted

jcooper

unread,
Nov 29, 2010, 12:06:30 PM11/29/10
to ode-users
It's easiest to see if we take the extreme example of going from the
default orientation q1 = [1,0,0,0] to a rotation of pi radians around
the x axis: q2 = [0,1,0,0]. If you use the linear method, you get w_s
= [2,0,0]/dt. If you use the slerp method, you get w_s = [pi,0,0]/
dt. Clearly the second one is correct. We want to rotate pi radians
around the x axis in dt time. If you then use the FiniteRotation flag
on the body, w_s will produce the desired result. w_l will not.
Using infinitesimal rotation, w_l results in a final orientation q_l=[.
707,.707,0,0] which is half of the desired change; w_s produces a
final orientation of q_s=[.537,.844,0,0]. I suppose that under the
infinitesimal method, we would need infinite velocity to makes such a
drastic change in a single time step. It looks like the slerp method
with FiniteRotation is the one to use if you need a kinematic body to
get to the right orientation at each time step while still pushing
dynamic things out of the way. This seems a bit intensive, but
shouldn't be a big problem for a small number of bodies. It's not
ideal, but I hope it'll do.

jc



Reply all
Reply to author
Forward
0 new messages