Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i extrapolate a new quaternion rotation from two previous packets?

I'm at my wits end here! I'm working on lag-reduction in my First Person Shooter, and now it's just a case of adding some extrapolation. I can extrapolate position; getting the last two positions and the velocity from them, then adding the velocity to the existing position (* delta time). However, i cannot do the same for rotation. By default, the angles are Euler, but i can (and do) convert them to quaternions as they can suffer gimball lock. How would i extrapolate a new orientation from 2 previous orientations? I have time between packets, 2 packets and current orientation.

like image 633
Angus Hollands Avatar asked Feb 17 '12 02:02

Angus Hollands


People also ask

Can you interpolate quaternions?

Use interpolation to calculate quaternion between two quaternions p=[1.0 0 1.0 0] and q=[-1.0 0 1.0 0] using the SLERP method. This example uses the quatnormalize function to first-normalize the two quaternions to pn and qn .

How does quaternion Slerp work?

Quaternion SlerpWhen Slerp is applied to unit quaternions, the quaternion path maps to a path through 3D rotations in a standard way. The effect is a rotation with uniform angular velocity around a fixed rotation axis.

What are the 4 values of a quaternion?

Four values make up a quaternion, namely x, y, z and w. Three of the values are used to represent the axis in vector format, and the forth value would be the angle of rotation around the axis." So you could think of it as the rotation of the rotation, in simple terms!

How do quaternion rotations work?

Quaternions are an alternate way to describe orientation or rotations in 3D space using an ordered set of four numbers. They have the ability to uniquely describe any three-dimensional rotation about an arbitrary axis and do not suffer from gimbal lock.


2 Answers

I found a good answer here: http://answers.unity3d.com/questions/168779/extrapolating-quaternion-rotation.html

I adapted the code to my needs and it works quite well!

For the two quaternions qa, qb, this will give you interpolation and extrapolation using the same formula. t is the amount of interpolation/extrapolation, t of 0.1 = 0.1 of the way from qa->qb, t = -1 -> extrapolate a whole step from qa->qb back, etc. I used selfwritten functions to allow the use of quaternions/axisAngle with opencv cv::Mat but I would probably choose Eigen for that instead

Quat qc = QuaternionMultiply(qb, QuaternionInverse(qa)); // rot is the rotation from qa to qb     
AxisAngle axisAngleC = QuaternionToAxisAngle(qc); // find axis-angle representation

double ang = axisAngleC.angle; //axis will remain the same, changes apply to the angle

if (ang > M_PI) ang -= 2.0*M_PI; // assume rotation to take the shortest path
ang = fmod(ang * t,2.0*M_PI);   // multiply angle by the interpolation/extrapolation factor and remove multiples of 2PI

axisAngleC.angle = ang;

return QuaternionMultiply(AxisAngleToQuaternion(axisAngleC),qa); // combine with first rotation
like image 108
Oliver Zendel Avatar answered Nov 11 '22 13:11

Oliver Zendel


If you represent the two orientations as vectors, the vector cross product of them will give you the axis of rotation and the vector dot product can be used to find the angle of rotation.

You can then calculate an angular velocity in the same way as you calculated the scalar velocity, and use it to calculate the extrapolated rotation around the axis determined earlier.

like image 1
caf Avatar answered Nov 11 '22 13:11

caf