ami-iit / jaxsim

A differentiable physics engine and multibody dynamics library for control and robot learning.
https://jaxsim.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
57 stars 9 forks source link

Possibility to pass euler angles into JaxSimModelData's build #146

Closed lorycontixd closed 2 months ago

lorycontixd commented 2 months ago

Often I find myself with the necessity of building a model's data manually, and to feed an initial rotation to this data. The static JaxSimModelData.build function of JaxSimModelData only accepts quaternions as a rotation parameter, but it would be nice to let it accept euler angles as well, as they are definitely more intuitive. What I suggest is to leverage the different shapes between quaternions and euler angles (quaternions's shape = 4, euler angles shape = 3) to distinguish which type of rotation has been passed to the function and perform an internal conversion.

flferretti commented 2 months ago

Hi @lorycontixd, thanks for your suggestion! I believe that the problem here is that Euler angles are affected by gimbal lock and using quaternions normally ensures a proper handling of this issue.

lorycontixd commented 2 months ago

What about other rotation formalisms which are still more intuitive than quaternions, such as angle-axis or a rotation matrix? As far as I know, these are not subject to gimbal lock. The idea is still to convert it immediately to a quaternion for internal use, but at least it's easier to build the data in the front-end side.

flferretti commented 2 months ago

Rotation matrix are already supported internally by JaxSim, but you have to make sure they actually represent a rotation, e.g. they must be elements of $\mathrm{SO}(3)$. For you objective, you can easily pass from rotation matrix or angle-axis representations to quaternions by using jaxlie

diegoferigo commented 2 months ago

I'm not sure if it's worth complicating the APIs for adding another one among many other representations of $\text{SO}(3)$ elements. You don't need any third-party dependencies to convert in your downstream code your preferred representation to quaternion since JAX provides jax.scipy.spatial.transform.Rotation:

import jax.numpy as jnp
from jax.scipy.spatial.transform import Rotation

r, p, y = 1.0, 2.0, 3.0

Q_xyzw = Rotation.from_euler("xyz", [r, p, y]).as_quat() 
Q_wxyz = Q_xyzw[jnp.array([3, 0, 1, 2])]

Note that, in any case, supporting Euler angles is all but straightforward. There are way too many conventions (intrinsic/extrinsic, countless sequences, etc) and I prefer to expose unambiguous quantities like a quaternion.