- Home /
Why is my Quaternion rotation going crazy?
I am working on a simulation project that renders various machine components based on imported data.
One of the moving pieces is what can best be describes as an arm that rotates from 0-180 degrees around the X axis. For almost all inputs, my implementation of this rotation works correctly, however in some edge cases the rotation goes crazy and begins to rotate around all sorts of axes.
Here is a picture of the machine to give you a better idea: Not Rotated
Rotated
Here is the code that I use for rotation:
{
var rotationValue = MethodThatGetsRotationValue();
var degree = Mathf.Lerp(0.0f, 180.0f, rotationValue / 100.0f);
var endRot = Quaternion.AngleAxis(-degree, objectToRotate.transform.right);
var trans = objectToRotate.transform;
StartCoroutine(RotateOverTime(trans, endRot, 2.0f));
}
public IEnumerator RotateOverTime(Transform pivotPoint, Quaternion endRot, float totalTime)
{
var startRot = pivotPoint.rotation;
var startTime = Time.time;
var t = 0.0f;
while (t <= 1.0f)
{
yield return new WaitForEndOfFrame();
t = (Time.time - startTime) / totalTime;
pivotPoint.rotation = Quaternion.Slerp(startRot, endRot, t);
}
}
Something to note is that this error only started occuring when I increased the rotation from 0-90 degrees to 0-180 degrees.
Also, I am aware that the reason behind it going really crazy is that I am using the right value from the object being rotated, meaning that it gets wild when each subsequent rotation is using the wrong direction. A partial fix for this is to just use parent.transform.right instead, but I would like to actually understand the issue.
Answer by Bunny83 · Dec 06, 2019 at 12:18 PM
I don't think the issue is your usage of transform.right. You only read it once at the beginning where it is still unrotated / not messed up. However the issue is that Quaternions can only represent rotations <180° As soon as you have a rotation that is 180° there is no proper rotation axis that slerp can calculate. Keep in mind that a quaternion essentially an axis of rotation and an angle around that axis. To determine the rotation from one quaternion to the other you get the rotation axis through the cross product between the two quaternion axes. Though if your two rotations are 180° apart from each other you can't calculate a rotation axis.
An analogy would be to calculate the direction you have to go towards when you want to go from one place on the earth to another. This is equal to great circle navigation. So determine the shortest path between the two points. There is always only one path except for the case when the two points are exactly opposite from each other. If you are on the north pole and you want to go to the south pole. You can go any direction (of course on an idealized sphere ^^). So when you want to animate that travel from north to south by just specifying the start and end point, which path would you pick?
Quaternions are really great for animation since it avoids all gimbal issues. However it comes with the above mentioned limitation. Though If you have a robot you actually have a gimbal system since each axis of the robot can only rotate around that one axis. So you usually want to rotate just a single local angle for each joint. Setting the absolute worldspace rotation for a robot joint doesn't make much sense anyways.
We don't know what your exact setup looks like and what your requirements are. However when you want to animate a robot you usually just want to animate the joint parameters (see forward kinematics). So when you just setup an empty gameobject at each joint to act as the parent of the following parts you only have to use a single local euler angle to rotate that joint.
Thank you very much for your response.
I take your point on setting the worldspace rotation for a robot.
Your analogy about quaternion paths across 180 degrees makes sense and I think has helped me understand them a little better. I am slightly vexed still as testing this system and limiting the rotation to 170 degrees still gives me the same error.
Another confusing element is that the object in question that is causing errors only seems to be moving between 48-52%.
I think that it is likely that this system was not set up correctly and it may be more apt to use a hinge joint or similar to control this. Thank you again for your time.
Your answer
Follow this Question
Related Questions
Check if rotation (only on Y axis) of some object toward another is finshed? 0 Answers
How to use quaternions to apply an offset to a rotation to calibrate a controller 1 Answer
Get real compass direction 1 Answer
How do i make my Mouselook behave when changing the z rotation? 0 Answers
How can I instantiate a gameobject facing another gameobject 2D? 0 Answers