Combining Quaternion Rotations

Started by
12 comments, last by Neoalex 14 years ago
Hi I have a problem combining quaternion rotations.I am implementing an inverse kinematics system. If I have an original unit quaternion rotation q and then I want to combine another rotation q1 obtained from the inverse kinematics methods the results i get are not always correct. I have read the article that talks about Quaternion Powers(http://www.gamedev.net/reference/articles/article1095.asp) and it mentions not to combine rotations from different coordinates axes. I think this is what I am doing here but I dont understand why this is wrong and why it gives the wrong results. Furthermore I have no clue on how to fix this. Can somebody help?
Advertisement
Quote:Original post by Neoalex
... I have read the article that talks about Quaternion Powers(http://www.gamedev.net/reference/articles/article1095.asp)

and it mentions not to combine rotations from different coordinates axes. I think this is what I am doing here but I dont understand why this is wrong and why it gives the wrong results. ...

What does "different coordinates axes" mean exactly? For sure, you cannot combine any transformations that are given w.r.t. different co-ordinate frames. On the other hand, combining 2 transformations given in the same space is principally legal, also if that are 2 unit-quaternions representing rotations about the x axis and the y axis, resp. Or do you mean especially that unwanted rolling is introduced due to the multiplication?
Remember quaternion rotation is not commutative. A * B is not equal to B * A so its probably a matter of rotation and see if it works.
Quote:Original post by cgrant
Remember quaternion rotation is not commutative. A * B is not equal to B * A so its probably a matter of rotation and see if it works.


The order that I am doing the quaternion rotation is correct. What does different co-ordinate frames mean exactly? And why can I not combine two rotations from different co-ordinate frames?

Quote:Original post by Neoalex
What does different co-ordinate frames mean exactly? And why can I not combine two rotations from different co-ordinate frames?
A co-ordinate frame is the combination of a frame-of-reference and an attached co-ordinate system. See it as definition of an origin and orientation in space, so that e.g. the x, y, and z co-ordinates of a point can be given. It is sometimes simply called an "axis" or "co-ordinate axis", so I had asked for whether you mean that.

You're speaking of IK. An application of IK is solving for bones in a skeletal driven animation. There a bone (better: its joint) is given as position and orientation w.r.t. to its parental bone. That is in fact a co-ordinate frame.

Now, the position and orientation of a frame is given w.r.t. its parental frame. Assume that the child frame is rotated by 90 degrees about the y axis. If you rotate locally, i.e. in the child frame, by 90 degree about the x axis, and on the other hand about 90 degrees about the x axis of the parental frame, then the results will be different, simply because the orientations of the both frames differ. Hence you must perform the additional rotation w.r.t. the frame! If the both rotations are not given in the same frame, you need to transform at least one of them to get the equivalent rotation in a common frame (e.g. those where the other rotation is given) before you can combine them.

Hmm. Hopefully this is understandable...
Perhaps I should explain a bit more what I am trying to do here. I am making animation system where I load a motion capture file (BVH) and then I modify selected frames using IK and then I save the changes. The problem is that BVH do not provide any joint orientation. The angle changes are stored w.t.r to the original position.

So when I select a frame to modify I have to update the joints' coordinates based on the angles given at that frame and find what is the quaternion rotation that is applied to the original position to get those values. So when I apply the IK I find the rotation needed based on the updated values of the coordinates. So then I have to combine those two rotations in order get the new rotation that is needed.

The problem is that the new rotation doesn't always produce the right results. If I don't update the skeleton and I start from the original position of the skeleton and then I apply IK it works all the time.

So I need a way of combining those two rotations correctly. I am not sure if they are from different co-ordinate frames but it doesn't seem so. Please help.
I've read the format description of BVH just now. AFAIS the BVH data is given in different co-ordinate frames. I.e. for each joint you would compute the local transformation from the offset typically stored in the hierarchy description, and the local orientation typically stored in the motion channels. You have to multiply all local transforms that lie on the path from a current joint up to the root. Then you finally have the global transformation for each joint (where global means w.r.t. the motion capturing device). You do so for each motion frame individually, without considering the motion data of any other frame than the current one. Is that correct so far?

Now you apply some IK to the skeleton. The IK process gives you delta rotations as unit-quaternions instead of the new pose's orientations. So you need to apply the delta rotations to the currently computed pose to get the corrected pose. What exactly gave you into the IK solver? Probably (but not necessarily) the local positions and orientations. So the delta rotations will probably be given in local co-ordinates, too. In such a case I don't see why simple multiplication shouldn't be okay. Here correct order is probably on the global side, so that the new local transformation would be
Ti * Di * Ri
expressed with column matrices, where Di denotes the delta rotation. (Feel free to use the equivalent quaternion math instead, but at the end you have to convert it to matrices anyway.)

The delta rotations may also be given in global space. In such a case you have to do a space-transformation first, because presumably the center of rotation will still be the joint. But if so, then the bones of the skeleton will usually be segregated in a conspicuous manner, assuming that IK usually actually does a correction. However, from your description, it seems me that this isn't happening.

So please verify first what exactly the result of the IK process is.
Quote:Original post by haegarr
I've read the format description of BVH just now. AFAIS the BVH data is given in different co-ordinate frames. I.e. for each joint you would compute the local transformation from the offset typically stored in the hierarchy description, and the local orientation typically stored in the motion channels. You have to multiply all local transforms that lie on the path from a current joint up to the root. Then you finally have the global transformation for each joint (where global means w.r.t. the motion capturing device). You do so for each motion frame individually, without considering the motion data of any other frame than the current one. Is that correct so far?


Correct so far, but I only find the global transformation for the frame I am interested in.

What my IK produces is a local rotation delta in unit quaternion for each joint that needs to be added to the rotation found for the specific frame. It finds the solution based on the global coordinates found before.

so I have something like

LocalRotation= Delta*LocalRotation

So for example if the LocalRotation is an IDENTITY quaternion the IK works fine.

Futhermore the IK also produces the new global coordinates of each joint which I have verified that are correct.

And when I draw the skeleton I transform the quaternion to angle axis.

Quote:Original post by Neoalex
Futhermore the IK also produces the new global coordinates of each joint which I have verified that are correct.
Just for curiosity: For what purpose do you need to multiply the previous rotations and the delta rotations then? Drawing the skeleton itself as well as skinning is best done in model co-ordinates anyway (just a simple subtraction of the "gobal" position gives the model co-ordinates).
Quote:Original post by haegarr
Quote:Original post by Neoalex
Futhermore the IK also produces the new global coordinates of each joint which I have verified that are correct.
Just for curiosity: For what purpose do you need to multiply the previous rotations and the delta rotations then? Drawing the skeleton itself as well as skinning is best done in model co-ordinates anyway (just a simple subtraction of the "gobal" position gives the model co-ordinates).



Well I wish I could do that but you see I need to be able to modify the joint angles in Euler angles for the selected frame so then I can save them back to the BVH file. So I first transform the Euler angles of that frame to a quaternion for each joint. Then I calculate the global coordinates with the procedure as mentioned before. I do they IK which gives me a delta rotation. I combine the two rotations. Then I transform the quaternion back to Euler angles and then save the changes. And I know that all my transformations are correct since I have tested them on simple chain that I have created. The difference is the simple chain doesn't have an initial rotation other than the IDENTITY Quaternion so it works.

This topic is closed to new replies.

Advertisement