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.
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 .
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.
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!
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With