SU Decomposition
This repository contains a Python implementation of the SU-decomposition, which can be used to compute a coordinate-invariant local representation for rigid-body motion trajectories and force trajectories. This representation is referred to as the Dual-Upper-Triangular Invariant Representation (DUTIR). The accompanying Python package is called the SU-decomposition library, or sulib.
The implementation is intended for trajectory analysis, identification, and generalization across coordinate systems. A detailed description of the method is provided in the corresponding paper:
A Coordinate-Invariant Local Representation of Motion and Force Trajectories for Identification and Generalization Across Coordinate Systems
A preprint is available on arXiv.
Highlights and conceptual overview figure
A key feature of the provided code is that it enables the direct computation of the DUTIR from either a screw trajectory or a rigid-body pose trajectory. The main steps of the implementation when starting from a rigid-body pose trajectory are summarized conceptually in the figure below:
More specifically, the main functionalities of the provided code are:
sulib.SU(): Compute the SU-decomposition of a 6 x 3 matrix.sulib.screw_trajectory_to_dutir(): Compute the DUTIR from a 6 x N screw trajectory, where N represents the number of trajectory samples. The DUTIR is computed by applying the SU-decomposition to successive and overlapping windows of screw triplets.sulib.pose_trajectory_to_dutir(): Compute the DUTIR from a 4 x 4 x N rigid-body pose trajectory, where N represents the number of trajectory samples. The pose trajectory is first converted into a screw trajectory, after whichsulib.screw_trajectory_to_dutir()is applied.
Duality between motion and force
The function sulib.screw_trajectory_to_dutir() takes screw trajectories as input. For motion, these screw trajectories correspond to twist trajectories. For force/torque data, they correspond to wrench trajectories.
Conceptually:
Rigid-body pose trajectory
│
▼
Twist trajectory Wrench trajectory
│ │
▼ ▼
SU-decomposition SU-decomposition
│ │
▼ ▼
DUTIR of rigid-body motion DUTIR of force/torque data
Hence, the functions sulib.screw_trajectory_to_dutir() and sulib.SU() can be applied directly to either twist or wrench data:
Installation (public user)
Install the latest published version from PyPI:
pip install sulib
Public functions (exposed via __init__)
sulib.RU, sulib.SU, sulib.pose_trajectory_to_dutir, sulib.screw_trajectory_to_dutir, and sulib.generate_synthetic_pose_trajectory.
Example: computation of the DUTIR
import numpy as np
import sulib
# Generate pose trajectory data of a precession motion
T, dt = sulib.generate_synthetic_pose_trajectory(trajectory_type="rotation_3D")
# Calculate the DUTIR of this pose trajectory
dutir, twist_trajectory = sulib.pose_trajectory_to_dutir(T, dt, L=0.3, twist_type="body")
# Print the first three samples of the twist_trajectory as an intermediate result
print("Three twist samples:")
print(np.round(twist_trajectory[:, :3], 5))
print(" ")
# Print the first DUTIR sample
print("First DUTIR sample:")
print(np.round(dutir[:, :, 0], 5))
Output:
Three twist samples:
[[ 2.35575 2.35575 2.35575]
[ 0.05608 0.1681 0.27975]
[ 2.35575 2.35041 2.33975]
[ 0. -0. -0. ]
[ 0.23557 0.23504 0.23398]
[-0.00561 -0.01681 -0.02798]]
First DUTIR sample:
[[ 3.332 3.33012 3.32446]
[-0. 0.11214 0.22409]
[ 0. 0. -0.00377]
[ 0. -0. -0. ]
[ 0. 0. -0. ]
[ 0. -0. -0. ]]
Installation (developer)
Clone the repository and install the required dependencies and sulib package:
git clone https://github.com/arnoverduyn/SU_decomposition.git
cd SU_decomposition
pip install -r requirements.txt
pip install -e .
The core implementation is located in src/sulib.
Repository structure
SU_decomposition/
├── data/
│ └── demos/
│ ├── contour_following/
│ ├── peg_on_hole_alignment/
│ ├── pouring/
│ └── pouring_objects/
│
├── figures/
│
├── notebooks/
│ ├── notebook.ipynb
│
├── scripts/
│ ├── example_public.py
│ ├── example_developer_dutir_force.py
│ └── example_developer_dutir_motion.py
│
├── src/
│ └── sulib/
│ ├── _data_handling.py
│ ├── _plotting.py
│ ├── _preprocessing.py
│ ├── _robotics.py
│ └── _core.py
│
├── tests/
│ └── test_core.py
│
├── pyproject.toml
├── requirements.txt
├── LICENSE
├── CHANGELOG.md
└── README.md
Package modules (internal)
sulib._robotics— robotics-related operations for rigid-body trajectories.sulib._preprocessing— trajectory preprocessing utilities.sulib._data_handling— loading and handling trajectory data.sulib._plotting— visualization utilities.sulib._core— core functionalities of thesulibpackage
Extra examples
The notebooks/ directory contains numerical examples and demonstrations.
Additional example scripts are provided in scripts/:
Reference
If you use this implementation in academic work, please cite the associated paper:
A Coordinate-Invariant Local Representation of Motion and Force Trajectories for Identification and Generalization Across Coordinate Systems
Preprint: arXiv:2604.10241
License
This project is distributed under the license specified in LICENSE.
Metadata
Release files for sulib 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sulib-1.0.3.tar.gz | 1.5 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sulib-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.5 MB
Release files / sulib-1.0.3.tar.gz
| Download URL | sulib-1.0.3.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9f9eded164b4c9a1aec7430a98cc50a980ecc74f3530303e75a85f204d042a57
|
|
BLAKE2b-256 checksum How to use checksums |
2392b87506de629a27e23b7c6339754efcaee83f7fbbfaff1c163ca6b10dad3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.
Transparency logRelease files / sulib-1.0.3-py3-none-any.whl
| Download URL | sulib-1.0.3-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
06a895923c3a43aae3ccce2dcf5bfb085a5f4d9c5b563dac60a9a7c56f1231e0
|
|
BLAKE2b-256 checksum How to use checksums |
6f5927926c5fc336cb7e010b7f3535afa6b2fbbed13deacad4703566562cfeb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.
Transparency log