Skip to content

Fix cs_quat2euler degrees and duplicate CasADi function names - #152

Open
malikdurmus wants to merge 1 commit into
learnsyslab:mainfrom
malikdurmus:fix-casadi-rotation
Open

malikdurmus wants to merge 1 commit into
learnsyslab:mainfrom
malikdurmus:fix-casadi-rotation

Conversation

@malikdurmus

Copy link
Copy Markdown
Contributor

Split from #151.

cs_quat2euler(degrees=True) converts the wrong way

The degrees branch multiplied by pi / 180 instead of 180 / pi (This is a silent error!). The test i added compares against scipy's as_euler for extrinsic, intrinsic and symmetric sequences, in both radians and degrees.

Duplicate CasADi function names in rotation.py

cs_ang_vel_deriv2rpy_rates_deriv and cs_rpy_rates_deriv2ang_vel_deriv were both created with the name "cs_ang_vel2rpy_rates". I think this doesn't affect simulation results, but it gives misleading names in printouts and error messages.

- Convert radians to degrees in cs_quat2euler(degrees=True) instead of the inverse
- Give the CasADi derivative conversion functions unique names
Comment on lines +262 to +269
fns = [
rotation.cs_ang_vel2rpy_rates,
rotation.cs_rpy_rates2ang_vel,
rotation.cs_ang_vel_deriv2rpy_rates_deriv,
rotation.cs_rpy_rates_deriv2ang_vel_deriv,
rotation.cs_quat2matrix_func,
rotation.cs_rpy2matrix_func,
]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we collect these automatically instead?

@pytest.mark.parametrize("seq", ["xyz", "zyx", "zxz", "XYZ", "ZYX", "ZXZ"])
@pytest.mark.parametrize("degrees", [False, True])
def test_quat2euler_symbolic(seq: str, degrees: bool):
rot = R.random(100)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably never reaches gimbal locks (which have some switching logic), so it would be great to add these as well. E.g.

lock = [0.0, np.pi] if seq[0] == seq[2] else [np.pi / 2, -np.pi / 2]
rot = R.from_euler(seq, [[0.3, angle, 0.4] for angle in lock])
with pytest.warns(UserWarning, match="Gimbal lock"):
    reference = rot.as_euler(seq, degrees=degrees)
for q, euler_scipy in zip(rot.as_quat(), reference):
    euler_cs = np.array(quat2euler(q)).flatten()
    assert np.allclose(euler_cs, euler_scipy, atol=tol), "Symbolic quat->euler differs at lock."

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants