Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide functions to write numerically stable code and avoid pitfalls #304

Merged
merged 35 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f64adcb
Check if rotation matrix needs normalization
AlexanderFabisch Oct 19, 2024
8d93016
Test function
AlexanderFabisch Oct 19, 2024
547f226
Add function to API docs
AlexanderFabisch Oct 19, 2024
cd8c2b2
Sort functions in API docs
AlexanderFabisch Oct 19, 2024
f8657ad
Euler angle normalization
AlexanderFabisch Oct 19, 2024
5335154
Link in user guide
AlexanderFabisch Oct 19, 2024
9820ef5
Fix test and function
AlexanderFabisch Oct 19, 2024
223f482
Add pr.euler_near_gimbal_lock
AlexanderFabisch Oct 19, 2024
240f40b
Add assert_euler_equal
AlexanderFabisch Oct 20, 2024
f1c6961
Test euler angle equality
AlexanderFabisch Oct 20, 2024
7c1009e
Add compact_axis_angle_near_pi
AlexanderFabisch Oct 20, 2024
4eb8c6d
Correct docstring
AlexanderFabisch Oct 20, 2024
d2876c1
Correct docstring
AlexanderFabisch Oct 20, 2024
f55007f
Add quaternion_double
AlexanderFabisch Oct 20, 2024
5e84155
Add quaternion_requires_renormalization
AlexanderFabisch Oct 20, 2024
e3ef048
Add mrp_near_singularity
AlexanderFabisch Oct 21, 2024
b0cdcd9
Add conversions between axis-angle and mrp
AlexanderFabisch Oct 21, 2024
5b9bc36
Reorganize API docs for rotations
AlexanderFabisch Oct 21, 2024
0023c9c
Sort transformations API
AlexanderFabisch Oct 21, 2024
a2e2f7b
Full branch coverage
AlexanderFabisch Oct 21, 2024
c57a727
Add norm_mrp
AlexanderFabisch Oct 22, 2024
5f69606
Add mrp_double
AlexanderFabisch Oct 22, 2024
47dd896
Add assert_mrp_equal
AlexanderFabisch Oct 22, 2024
13194f5
Add transform_requires_renormalization
AlexanderFabisch Oct 23, 2024
6d84b5f
Add assert_exponential_coordinates_equal
AlexanderFabisch Oct 23, 2024
a980fe9
Fix "see also"
AlexanderFabisch Oct 23, 2024
2190a43
Add dual_quaternion_requires_renormalization
AlexanderFabisch Oct 25, 2024
e31a1ea
Abbreviate dual quaternion symbol
AlexanderFabisch Oct 25, 2024
a928889
Add dual_quaternion_double
AlexanderFabisch Oct 25, 2024
48774bf
More detailed explanation of dq double cover
AlexanderFabisch Oct 25, 2024
9cfe62d
Rename private quaternion submodule
AlexanderFabisch Oct 25, 2024
6a806d0
Fix import
AlexanderFabisch Oct 25, 2024
f539a2f
Structure API docs
AlexanderFabisch Oct 25, 2024
2333786
Reorganize batch API
AlexanderFabisch Oct 25, 2024
96f5592
Update feature list
AlexanderFabisch Oct 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
474 changes: 253 additions & 221 deletions doc/source/api.rst

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pytransform3d offers...
translation / position
* conversions between those representations
* clear documentation of conventions
* functions to check for common pitfalls (e.g., singularities, ambiguities,
discontinuities)
* tight coupling with matplotlib to quickly visualize (or animate)
transformations
* the TransformManager which organizes complex chains of transformations
Expand Down
79 changes: 4 additions & 75 deletions doc/source/user_guide/euler_angles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ and Cardan angles are usually restricted to

-\pi \leq \alpha < \pi, \qquad -\frac{\pi}{2} \leq \beta \leq \frac{\pi}{2}, \qquad -\pi \leq \gamma < \pi

to make these representations unique.
to make these representations unique (using
:func:`~pytransform3d.rotations.norm_euler`).

An alternative convention limits the range of :math:`\alpha` and :math:`\gamma`
to :math:`\left[0, 2 \pi\right)`.
Expand All @@ -89,7 +90,8 @@ to an interval of length :math:`2\pi`: either all pairs of angles that
satisfy :math:`\alpha + \gamma = constant` or all pairs of angles
that satisfy :math:`\alpha - \gamma = constant`. When we reconstruct
Euler angles from a rotation matrix, we set one of these angles to 0 to
determine the other.
determine the other. We can check if Euler angles are close to gimbal lock
with :func:`~pytransform3d.rotations.euler_near_gimbal_lock`.

-----------
Other Names
Expand All @@ -100,79 +102,6 @@ xyz Cardan angles can also be called roll, pitch, and yaw (or sometimes
the intrinsic convention is used here as well). Roll is a rotation about
x, pitch is a rotation about y and yaw is a rotation about z.

---------------------------------------------------
API: Rotation Matrix / Quaternion from Euler Angles
---------------------------------------------------

.. currentmodule:: pytransform3d.rotations

.. autosummary::
:toctree: _apidoc/
:template: function.rst

~quaternion_from_euler
~matrix_from_euler
~active_matrix_from_intrinsic_euler_xzx
~active_matrix_from_extrinsic_euler_xzx
~active_matrix_from_intrinsic_euler_xyx
~active_matrix_from_extrinsic_euler_xyx
~active_matrix_from_intrinsic_euler_yxy
~active_matrix_from_extrinsic_euler_yxy
~active_matrix_from_intrinsic_euler_yzy
~active_matrix_from_extrinsic_euler_yzy
~active_matrix_from_intrinsic_euler_zyz
~active_matrix_from_extrinsic_euler_zyz
~active_matrix_from_intrinsic_euler_zxz
~active_matrix_from_extrinsic_euler_zxz
~active_matrix_from_intrinsic_euler_xzy
~active_matrix_from_extrinsic_euler_xzy
~active_matrix_from_intrinsic_euler_xyz
~active_matrix_from_extrinsic_euler_xyz
~active_matrix_from_intrinsic_euler_yxz
~active_matrix_from_extrinsic_euler_yxz
~active_matrix_from_intrinsic_euler_yzx
~active_matrix_from_extrinsic_euler_yzx
~active_matrix_from_intrinsic_euler_zyx
~active_matrix_from_extrinsic_euler_zyx
~active_matrix_from_intrinsic_euler_zxy
~active_matrix_from_extrinsic_euler_zxy
~active_matrix_from_extrinsic_roll_pitch_yaw

---------------------------------------------------
API: Euler Angles from Rotation Matrix / Quaternion
---------------------------------------------------

.. autosummary::
:toctree: _apidoc/
:template: function.rst

~euler_from_quaternion
~euler_from_matrix
~intrinsic_euler_xzx_from_active_matrix
~extrinsic_euler_xzx_from_active_matrix
~intrinsic_euler_xyx_from_active_matrix
~extrinsic_euler_xyx_from_active_matrix
~intrinsic_euler_yxy_from_active_matrix
~extrinsic_euler_yxy_from_active_matrix
~intrinsic_euler_yzy_from_active_matrix
~extrinsic_euler_yzy_from_active_matrix
~intrinsic_euler_zyz_from_active_matrix
~extrinsic_euler_zyz_from_active_matrix
~intrinsic_euler_zxz_from_active_matrix
~extrinsic_euler_zxz_from_active_matrix
~intrinsic_euler_xzy_from_active_matrix
~extrinsic_euler_xzy_from_active_matrix
~intrinsic_euler_xyz_from_active_matrix
~extrinsic_euler_xyz_from_active_matrix
~intrinsic_euler_yxz_from_active_matrix
~extrinsic_euler_yxz_from_active_matrix
~intrinsic_euler_yzx_from_active_matrix
~extrinsic_euler_yzx_from_active_matrix
~intrinsic_euler_zyx_from_active_matrix
~extrinsic_euler_zyx_from_active_matrix
~intrinsic_euler_zxy_from_active_matrix
~extrinsic_euler_zxy_from_active_matrix

----------
References
----------
Expand Down
2 changes: 1 addition & 1 deletion doc/source/user_guide/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ representations on the following pages.
| :math:`(\pmb{p}, \pmb{q})` | | | |
+----------------------------------------+---------------------+------------------+---------------+
| Dual quaternion | (8,) | X | X |
| :math:`\pmb{p} + \epsilon\pmb{q}` | | | |
| :math:`\boldsymbol{\sigma}` | | | |
+----------------------------------------+---------------------+------------------+---------------+

----------
Expand Down
11 changes: 6 additions & 5 deletions doc/source/user_guide/transformations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ another representation. The following table is an overview.
| :math:`(\pmb{p}, \pmb{q})` | | | | | |
+----------------------------------------+------------+--------------------------+---------------+---------------+-----------------+
| Dual quaternion | Quaternion | Yes | Yes | ScLERP | Required |
| :math:`\pmb{p} + \epsilon \pmb{q}` | Conjugate | | | | |
| :math:`\boldsymbol{\sigma}` | Conjugate | | | | |
+----------------------------------------+------------+--------------------------+---------------+---------------+-----------------+

---------------------
Expand Down Expand Up @@ -323,7 +323,8 @@ A dual quaternion consists of a real quaternion and a dual quaternion:

.. math::

\boldsymbol{p} + \epsilon \boldsymbol{q} = p_w + p_x i + p_y j + p_z k + \epsilon (q_w + q_x i + q_y j + q_z k),
\boldsymbol{\sigma} = \boldsymbol{p} + \epsilon \boldsymbol{q}
= p_w + p_x i + p_y j + p_z k + \epsilon (q_w + q_x i + q_y j + q_z k),

where :math:`\epsilon^2 = 0` and :math:`\epsilon \neq 0`.
We use unit dual quaternions to represent
Expand All @@ -345,9 +346,9 @@ interpolation between two dual quaternions is possible (with

.. warning::

The unit dual quaternions :math:`\boldsymbol{p} + \epsilon \boldsymbol{q}`
and :math:`-\boldsymbol{p} - \epsilon \boldsymbol{q}` represent exactly
the same transformation.
The unit dual quaternions
:math:`\boldsymbol{\sigma} = \boldsymbol{p} + \epsilon \boldsymbol{q}` and
:math:`-\boldsymbol{\sigma}` represent exactly the same transformation.

The reason for this ambiguity is that the real quaternion
:math:`\boldsymbol{p}` represents the orientation component, the dual
Expand Down
37 changes: 28 additions & 9 deletions pytransform3d/rotations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from ._utils import (
norm_angle, norm_vector, angle_between_vectors, perpendicular_to_vector,
vector_projection, perpendicular_to_vectors,
norm_axis_angle, norm_compact_axis_angle, norm_matrix,
norm_axis_angle, compact_axis_angle_near_pi, norm_compact_axis_angle,
matrix_requires_renormalization, norm_matrix,
quaternion_requires_renormalization,
plane_basis_from_normal,
check_skew_symmetric_matrix, check_matrix, check_quaternion,
check_quaternions, check_axis_angle, check_compact_axis_angle,
Expand All @@ -27,7 +29,8 @@
compact_axis_angle_from_matrix,
matrix_from_quaternion, matrix_from_compact_axis_angle,
matrix_from_axis_angle, matrix_from_two_vectors,
active_matrix_from_angle, matrix_from_euler,
active_matrix_from_angle, norm_euler, euler_near_gimbal_lock,
matrix_from_euler,
active_matrix_from_extrinsic_euler_xyx,
active_matrix_from_intrinsic_euler_xyx,
active_matrix_from_extrinsic_euler_xyz,
Expand Down Expand Up @@ -83,16 +86,19 @@
quaternion_from_angle,
cross_product_matrix,
mrp_from_quaternion,
quaternion_from_mrp)
from ._quaternion_operations import (
quaternion_integrate, quaternion_gradient, concatenate_quaternions, q_conj,
q_prod_vector, quaternion_diff, quaternion_dist, quaternion_from_euler)
from ._mrp import concatenate_mrp
quaternion_from_mrp,
mrp_from_axis_angle,
axis_angle_from_mrp)
from ._quaternions import (
quaternion_double, quaternion_integrate, quaternion_gradient,
concatenate_quaternions, q_conj, q_prod_vector, quaternion_diff,
quaternion_dist, quaternion_from_euler)
from ._mrp import mrp_near_singularity, norm_mrp, mrp_double, concatenate_mrp
from ._slerp import (slerp_weights, pick_closest_quaternion, quaternion_slerp,
axis_angle_slerp, rotor_slerp)
from ._testing import (
assert_quaternion_equal, assert_axis_angle_equal,
assert_compact_axis_angle_equal, assert_rotation_matrix)
assert_euler_equal, assert_quaternion_equal, assert_axis_angle_equal,
assert_compact_axis_angle_equal, assert_rotation_matrix, assert_mrp_equal)
from ._plot import plot_basis, plot_axis_angle, plot_bivector
from ._rotors import (
wedge, geometric_product, rotor_apply, rotor_reverse, concatenate_rotors,
Expand Down Expand Up @@ -121,8 +127,11 @@
"vector_projection",
"perpendicular_to_vectors",
"norm_axis_angle",
"compact_axis_angle_near_pi",
"norm_compact_axis_angle",
"matrix_requires_renormalization",
"norm_matrix",
"quaternion_requires_renormalization",
"random_vector",
"random_axis_angle",
"random_compact_axis_angle",
Expand Down Expand Up @@ -153,6 +162,8 @@
"matrix_from_axis_angle",
"matrix_from_two_vectors",
"active_matrix_from_angle",
"norm_euler",
"euler_near_gimbal_lock",
"matrix_from_euler",
"active_matrix_from_extrinsic_euler_xyx",
"active_matrix_from_intrinsic_euler_xyx",
Expand Down Expand Up @@ -208,10 +219,16 @@
"euler_from_quaternion",
"quaternion_from_angle",
"quaternion_from_euler",
"mrp_near_singularity",
"norm_mrp",
"mrp_double",
"concatenate_mrp",
"cross_product_matrix",
"mrp_from_quaternion",
"quaternion_from_mrp",
"mrp_from_axis_angle",
"axis_angle_from_mrp",
"quaternion_double",
"quaternion_integrate",
"quaternion_gradient",
"concatenate_quaternions",
Expand All @@ -223,10 +240,12 @@
"pick_closest_quaternion",
"quaternion_slerp",
"axis_angle_slerp",
"assert_euler_equal",
"assert_quaternion_equal",
"assert_axis_angle_equal",
"assert_compact_axis_angle_equal",
"assert_rotation_matrix",
"assert_mrp_equal",
"plot_basis",
"plot_axis_angle",
"wedge",
Expand Down
2 changes: 1 addition & 1 deletion pytransform3d/rotations/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
eps = 1e-7

two_pi = 2.0 * np.pi

half_pi = 0.5 * np.pi
Loading
Loading