orangeduck / Motion-Matching

Learned Motion Matching example implementation and source code for the article "Code vs Data Driven Displacement"
MIT License
702 stars 105 forks source link

Potentially a bug in quat.py #32

Open kai-lan opened 1 month ago

kai-lan commented 1 month ago

There seem to be a bug in quaternion to euler conversion. Here is my test:

e = np.array([0.1*np.pi, 0.2*np.pi, 0.5*np.pi])
q = from_euler(e, order='xyz')
e1 = to_euler(q, order='xyz')
q1 = from_euler(e1, order='xyz')
print(q)
print(q1)

print()
from scipy.spatial.transform import Rotation as R
q = R.from_euler('XYZ', e, degrees=False).as_quat(scalar_first=True)
e1 = R.from_quat(q).as_euler('XYZ', degrees=False)
q1 = R.from_euler('XYZ', e1, degrees=False).as_quat()
print(q)
print(q1)

Expected output:

[0.63003676 0.32101976 0.11061587 0.69840112]
[0.63003676 0.32101976 0.11061587 0.69840112]

[0.63003676 0.32101976 0.11061587 0.69840112]
[0.63003676 0.32101976 0.11061587 0.69840112]

Actual output:

[0.63003676 0.32101976 0.11061587 0.69840112]
[ 0.69840112  0.11061587 -0.32101976  0.63003676]

[0.63003676 0.32101976 0.11061587 0.69840112]
[0.63003676 0.32101976 0.11061587 0.69840112]
orangeduck commented 1 month ago

Thanks Kai.

I have a feeling that when I did this I screwed up the to_euler function and it actually takes the order argument the wrong way around compared to from_euler (at least for the xyz case. I'm not sure about the yzx case).

So I believe if you do the following you get the same result (I could be wrong):

e = np.array([0.1*np.pi, 0.2*np.pi, 0.5*np.pi])
q = from_euler(e, order='zyx')
e1 = to_euler(q, order='xyz')
q1 = from_euler(e1, order='zyx')

Perhaps you can check that and if so maybe do a PR that fixes it?