cartesian-tree 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/Cargo.lock +129 -1
  2. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/Cargo.toml +16 -1
  3. cartesian_tree-0.3.0/PKG-INFO +89 -0
  4. cartesian_tree-0.3.0/README.md +65 -0
  5. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/pyproject.toml +2 -2
  6. cartesian_tree-0.3.0/python/cartesian_tree/__init__.py +9 -0
  7. cartesian_tree-0.3.0/python/cartesian_tree/angles.py +70 -0
  8. cartesian_tree-0.3.0/python/cartesian_tree/base_types.py +269 -0
  9. cartesian_tree-0.3.0/python/cartesian_tree/lazy_access.py +107 -0
  10. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/python/cartesian_tree/lib.py +117 -36
  11. cartesian_tree-0.3.0/python/cartesian_tree/quaternion.py +86 -0
  12. cartesian_tree-0.3.0/src/bindings/frame.rs +182 -0
  13. cartesian_tree-0.3.0/src/bindings/lazy_access.rs +69 -0
  14. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/bindings/mod.rs +1 -0
  15. cartesian_tree-0.3.0/src/bindings/pose.rs +110 -0
  16. cartesian_tree-0.3.0/src/bindings/utils.rs +208 -0
  17. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/frame.rs +560 -65
  18. cartesian_tree-0.3.0/src/lazy_access.rs +71 -0
  19. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/lib.rs +13 -4
  20. cartesian_tree-0.3.0/src/pose.rs +228 -0
  21. cartesian_tree-0.3.0/src/rotation.rs +57 -0
  22. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/tree/traits.rs +1 -0
  23. cartesian_tree-0.2.0/.github/CODEOWNERS +0 -1
  24. cartesian_tree-0.2.0/.github/workflows/ci.yaml +0 -91
  25. cartesian_tree-0.2.0/.github/workflows/publish.yaml +0 -61
  26. cartesian_tree-0.2.0/.github/workflows/release.yaml +0 -20
  27. cartesian_tree-0.2.0/.gitignore +0 -25
  28. cartesian_tree-0.2.0/PKG-INFO +0 -29
  29. cartesian_tree-0.2.0/README.md +0 -5
  30. cartesian_tree-0.2.0/license-apache +0 -176
  31. cartesian_tree-0.2.0/python/cartesian_tree/__init__.py +0 -12
  32. cartesian_tree-0.2.0/python/cartesian_tree/helper.py +0 -194
  33. cartesian_tree-0.2.0/python/tests/__init__.py +0 -1
  34. cartesian_tree-0.2.0/python/tests/test_lib.py +0 -147
  35. cartesian_tree-0.2.0/src/bindings/frame.rs +0 -138
  36. cartesian_tree-0.2.0/src/bindings/pose.rs +0 -84
  37. cartesian_tree-0.2.0/src/bindings/utils.rs +0 -187
  38. cartesian_tree-0.2.0/src/orientation.rs +0 -17
  39. cartesian_tree-0.2.0/src/pose.rs +0 -133
  40. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/license-mit +0 -0
  41. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/python/cartesian_tree/py.typed +0 -0
  42. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/errors.rs +0 -0
  43. {cartesian_tree-0.2.0 → cartesian_tree-0.3.0}/src/tree/mod.rs +0 -0
@@ -4,13 +4,15 @@ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "CartesianTree"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  dependencies = [
9
+ "approx",
9
10
  "nalgebra",
10
11
  "pyo3",
11
12
  "serde",
12
13
  "serde_json",
13
14
  "thiserror",
15
+ "uuid",
14
16
  ]
15
17
 
16
18
  [[package]]
@@ -28,12 +30,36 @@ version = "1.4.0"
28
30
  source = "registry+https://github.com/rust-lang/crates.io-index"
29
31
  checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
30
32
 
33
+ [[package]]
34
+ name = "bumpalo"
35
+ version = "3.19.0"
36
+ source = "registry+https://github.com/rust-lang/crates.io-index"
37
+ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
38
+
31
39
  [[package]]
32
40
  name = "bytemuck"
33
41
  version = "1.23.0"
34
42
  source = "registry+https://github.com/rust-lang/crates.io-index"
35
43
  checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
36
44
 
45
+ [[package]]
46
+ name = "cfg-if"
47
+ version = "1.0.4"
48
+ source = "registry+https://github.com/rust-lang/crates.io-index"
49
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
50
+
51
+ [[package]]
52
+ name = "getrandom"
53
+ version = "0.3.3"
54
+ source = "registry+https://github.com/rust-lang/crates.io-index"
55
+ checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
56
+ dependencies = [
57
+ "cfg-if",
58
+ "libc",
59
+ "r-efi",
60
+ "wasi",
61
+ ]
62
+
37
63
  [[package]]
38
64
  name = "heck"
39
65
  version = "0.5.0"
@@ -52,6 +78,16 @@ version = "1.0.15"
52
78
  source = "registry+https://github.com/rust-lang/crates.io-index"
53
79
  checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
54
80
 
81
+ [[package]]
82
+ name = "js-sys"
83
+ version = "0.3.83"
84
+ source = "registry+https://github.com/rust-lang/crates.io-index"
85
+ checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
86
+ dependencies = [
87
+ "once_cell",
88
+ "wasm-bindgen",
89
+ ]
90
+
55
91
  [[package]]
56
92
  name = "libc"
57
93
  version = "0.2.172"
@@ -258,12 +294,24 @@ dependencies = [
258
294
  "proc-macro2",
259
295
  ]
260
296
 
297
+ [[package]]
298
+ name = "r-efi"
299
+ version = "5.3.0"
300
+ source = "registry+https://github.com/rust-lang/crates.io-index"
301
+ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
302
+
261
303
  [[package]]
262
304
  name = "rawpointer"
263
305
  version = "0.2.1"
264
306
  source = "registry+https://github.com/rust-lang/crates.io-index"
265
307
  checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
266
308
 
309
+ [[package]]
310
+ name = "rustversion"
311
+ version = "1.0.22"
312
+ source = "registry+https://github.com/rust-lang/crates.io-index"
313
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
314
+
267
315
  [[package]]
268
316
  name = "ryu"
269
317
  version = "1.0.20"
@@ -390,6 +438,80 @@ version = "0.2.4"
390
438
  source = "registry+https://github.com/rust-lang/crates.io-index"
391
439
  checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
392
440
 
441
+ [[package]]
442
+ name = "uuid"
443
+ version = "1.18.1"
444
+ source = "registry+https://github.com/rust-lang/crates.io-index"
445
+ checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
446
+ dependencies = [
447
+ "getrandom",
448
+ "js-sys",
449
+ "wasm-bindgen",
450
+ ]
451
+
452
+ [[package]]
453
+ name = "wasi"
454
+ version = "0.14.7+wasi-0.2.4"
455
+ source = "registry+https://github.com/rust-lang/crates.io-index"
456
+ checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
457
+ dependencies = [
458
+ "wasip2",
459
+ ]
460
+
461
+ [[package]]
462
+ name = "wasip2"
463
+ version = "1.0.1+wasi-0.2.4"
464
+ source = "registry+https://github.com/rust-lang/crates.io-index"
465
+ checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
466
+ dependencies = [
467
+ "wit-bindgen",
468
+ ]
469
+
470
+ [[package]]
471
+ name = "wasm-bindgen"
472
+ version = "0.2.106"
473
+ source = "registry+https://github.com/rust-lang/crates.io-index"
474
+ checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
475
+ dependencies = [
476
+ "cfg-if",
477
+ "once_cell",
478
+ "rustversion",
479
+ "wasm-bindgen-macro",
480
+ "wasm-bindgen-shared",
481
+ ]
482
+
483
+ [[package]]
484
+ name = "wasm-bindgen-macro"
485
+ version = "0.2.106"
486
+ source = "registry+https://github.com/rust-lang/crates.io-index"
487
+ checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
488
+ dependencies = [
489
+ "quote",
490
+ "wasm-bindgen-macro-support",
491
+ ]
492
+
493
+ [[package]]
494
+ name = "wasm-bindgen-macro-support"
495
+ version = "0.2.106"
496
+ source = "registry+https://github.com/rust-lang/crates.io-index"
497
+ checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
498
+ dependencies = [
499
+ "bumpalo",
500
+ "proc-macro2",
501
+ "quote",
502
+ "syn",
503
+ "wasm-bindgen-shared",
504
+ ]
505
+
506
+ [[package]]
507
+ name = "wasm-bindgen-shared"
508
+ version = "0.2.106"
509
+ source = "registry+https://github.com/rust-lang/crates.io-index"
510
+ checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
511
+ dependencies = [
512
+ "unicode-ident",
513
+ ]
514
+
393
515
  [[package]]
394
516
  name = "wide"
395
517
  version = "0.7.32"
@@ -399,3 +521,9 @@ dependencies = [
399
521
  "bytemuck",
400
522
  "safe_arch",
401
523
  ]
524
+
525
+ [[package]]
526
+ name = "wit-bindgen"
527
+ version = "0.46.0"
528
+ source = "registry+https://github.com/rust-lang/crates.io-index"
529
+ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
@@ -1,22 +1,37 @@
1
1
  [package]
2
2
  authors = ["Kn0g"]
3
3
  name = "CartesianTree"
4
- version = "0.2.0"
4
+ version = "0.3.0"
5
5
  edition = "2024"
6
6
  description = "Build hierarchical Cartesian coordinate systems to easily transform poses."
7
7
  homepage = "https://github.com/Kn0g/cartesian-tree"
8
8
  readme = "README.md"
9
9
  repository = "https://github.com/Kn0g/cartesian-tree"
10
10
  license = "MIT"
11
+ include = ["/src"]
11
12
  keywords = ["Cartesian", "coordinate-systems", "transform", "poses"]
12
13
  categories = ["mathematics", "data-structures"]
13
14
 
15
+ [lints.clippy]
16
+ all = "warn"
17
+ style = "warn"
18
+ pedantic = "warn"
19
+ cargo = "warn"
20
+ nursery = "warn"
21
+ missing_panics_doc = "warn"
22
+ missing_errors_doc = "warn"
23
+ missing_safety_doc = "warn"
24
+ empty_line_after_outer_attr = "warn"
25
+ empty_line_after_doc_comments = "warn"
26
+
14
27
  [dependencies]
15
28
  nalgebra = { version = "0.33.2", features = ["serde-serialize"] }
16
29
  pyo3 = { version = "0.25.0", features = ["extension-module"] , optional = true}
17
30
  thiserror = "2.0.12"
18
31
  serde = { version = "1.0", features = ["derive"] }
19
32
  serde_json = "1.0"
33
+ approx = "0.5.1"
34
+ uuid = { version = "1", features = ["v4"] }
20
35
 
21
36
  [features]
22
37
  bindings = ["dep:pyo3"]
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: cartesian-tree
3
+ Version: 0.3.0
4
+ Classifier: Programming Language :: Python
5
+ Requires-Dist: cartesian-tree[lint] ; extra == 'dev'
6
+ Requires-Dist: cartesian-tree[test] ; extra == 'dev'
7
+ Requires-Dist: cartesian-tree[build] ; extra == 'dev'
8
+ Requires-Dist: ruff==0.12.4 ; extra == 'lint'
9
+ Requires-Dist: mypy==1.17.0 ; extra == 'lint'
10
+ Requires-Dist: pytest==8.4.1 ; extra == 'test'
11
+ Requires-Dist: maturin==1.8.6 ; extra == 'build'
12
+ Provides-Extra: dev
13
+ Provides-Extra: lint
14
+ Provides-Extra: test
15
+ Provides-Extra: build
16
+ License-File: license-mit
17
+ Summary: Build hierarchical Cartesian coordinate systems to easily transform poses.
18
+ Keywords: Cartesian,coordinate systems,transform,poses
19
+ Home-Page: https://github.com/Kn0g/cartesian-tree
20
+ Author: Kn0g
21
+ Maintainer: Kn0g
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
24
+
25
+ # cartesian-tree
26
+
27
+ cartesian-tree is a library for managing and transforming poses in a tree-structured hierarchy of 3D coordinate frames in rust as well as python.
28
+
29
+ ## Key ideas
30
+ - Tree Structure: Frames form a tree where each frame defines its position and orientation relative to a parent frame.
31
+ - Poses and Transformations: A Pose represents a position + orientation in a frame. Easily transform poses between frames of the same tree.
32
+ - Unified Rotations: Supports quaternions and roll-pitch-yaw (RPY) interchangeably.
33
+ - Lazy Operations: Quick adjustments like translations (`+ x(1.0)`) or rotations (`* rz(PI/4)`).
34
+
35
+ ## Installation
36
+ The project can be found on [crates.io](https://crates.io/crates/cartesiantree) and [pypi.org](https://pypi.org/project/cartesian-tree/#description)
37
+
38
+
39
+ ## Usage
40
+ Rust:
41
+
42
+ ```rust
43
+ use cartesian_tree::{Frame, Pose};
44
+ use nalgebra::{Vector3, UnitQuaternion};
45
+
46
+ fn main() {
47
+ // Create root frame
48
+ let world = Frame::new_origin("world");
49
+
50
+ // Add a child frame
51
+ let child = world.add_child(
52
+ "child",
53
+ Vector3::new(1.0, 0.0, 0.0),
54
+ UnitQuaternion::from_euler_angles(0.0, 0.0, std::f64::consts::FRAC_PI_2),
55
+ ).unwrap();
56
+
57
+ // Create a pose in the world frame
58
+ let pose = world.add_pose(Vector3::new(0.0, 1.0, 0.0), UnitQuaternion::identity());
59
+
60
+ // Transform the pose to the child frame
61
+ let pose_in_child = pose.in_frame(&child).unwrap();
62
+
63
+ println!("Pose in child: {:?}", pose_in_base.transformation());
64
+ ```
65
+ Python:
66
+
67
+ ```python
68
+ from cartesian_tree import Frame, Rotation, Vector3
69
+
70
+ # Create root frame
71
+ world = Frame("world")
72
+
73
+ # Add a child frame
74
+ child = world.add_child(
75
+ "child",
76
+ Vector3(1.0, 0.0, 0.0),
77
+ Rotation.identity()
78
+ )
79
+
80
+ # Create a pose in the world frame
81
+ pose = world.add_pose(
82
+ Vector3(0.0, 1.0, 0.0), Rotation.identity()
83
+ )
84
+
85
+ # Transform the pose to the child frame
86
+ pose_in_child = pose.in_frame(child)
87
+
88
+ print(f"Pose in child: {pose_in_child}")
89
+ ```
@@ -0,0 +1,65 @@
1
+ # cartesian-tree
2
+
3
+ cartesian-tree is a library for managing and transforming poses in a tree-structured hierarchy of 3D coordinate frames in rust as well as python.
4
+
5
+ ## Key ideas
6
+ - Tree Structure: Frames form a tree where each frame defines its position and orientation relative to a parent frame.
7
+ - Poses and Transformations: A Pose represents a position + orientation in a frame. Easily transform poses between frames of the same tree.
8
+ - Unified Rotations: Supports quaternions and roll-pitch-yaw (RPY) interchangeably.
9
+ - Lazy Operations: Quick adjustments like translations (`+ x(1.0)`) or rotations (`* rz(PI/4)`).
10
+
11
+ ## Installation
12
+ The project can be found on [crates.io](https://crates.io/crates/cartesiantree) and [pypi.org](https://pypi.org/project/cartesian-tree/#description)
13
+
14
+
15
+ ## Usage
16
+ Rust:
17
+
18
+ ```rust
19
+ use cartesian_tree::{Frame, Pose};
20
+ use nalgebra::{Vector3, UnitQuaternion};
21
+
22
+ fn main() {
23
+ // Create root frame
24
+ let world = Frame::new_origin("world");
25
+
26
+ // Add a child frame
27
+ let child = world.add_child(
28
+ "child",
29
+ Vector3::new(1.0, 0.0, 0.0),
30
+ UnitQuaternion::from_euler_angles(0.0, 0.0, std::f64::consts::FRAC_PI_2),
31
+ ).unwrap();
32
+
33
+ // Create a pose in the world frame
34
+ let pose = world.add_pose(Vector3::new(0.0, 1.0, 0.0), UnitQuaternion::identity());
35
+
36
+ // Transform the pose to the child frame
37
+ let pose_in_child = pose.in_frame(&child).unwrap();
38
+
39
+ println!("Pose in child: {:?}", pose_in_base.transformation());
40
+ ```
41
+ Python:
42
+
43
+ ```python
44
+ from cartesian_tree import Frame, Rotation, Vector3
45
+
46
+ # Create root frame
47
+ world = Frame("world")
48
+
49
+ # Add a child frame
50
+ child = world.add_child(
51
+ "child",
52
+ Vector3(1.0, 0.0, 0.0),
53
+ Rotation.identity()
54
+ )
55
+
56
+ # Create a pose in the world frame
57
+ pose = world.add_pose(
58
+ Vector3(0.0, 1.0, 0.0), Rotation.identity()
59
+ )
60
+
61
+ # Transform the pose to the child frame
62
+ pose_in_child = pose.in_frame(child)
63
+
64
+ print(f"Pose in child: {pose_in_child}")
65
+ ```
@@ -9,7 +9,7 @@ maintainers = [{name = "Kn0g"}]
9
9
  description = "Build hierarchical Cartesian coordinate systems to easily transform poses."
10
10
  readme = "README.md"
11
11
  keywords = ["Cartesian", "coordinate systems", "transform", "poses"]
12
- license = "MIT"
12
+ license = { file = "license-mit" }
13
13
  classifiers = [
14
14
  "Programming Language :: Python"
15
15
  ]
@@ -62,7 +62,7 @@ skip-magic-trailing-comma = false
62
62
  docstring-code-format = true
63
63
 
64
64
  [tool.ruff.lint.per-file-ignores]
65
- "python/tests/*" = ["D103", "S101"]
65
+ "python/tests/*" = ["D103", "S101", "PLR2004"]
66
66
 
67
67
  [tool.mypy]
68
68
  disallow_untyped_defs = true
@@ -0,0 +1,9 @@
1
+ """A library for calculating Cartesian poses in different coordinate systems."""
2
+
3
+ from .angles import RPY
4
+ from .base_types import Isometry, Rotation, Vector3
5
+ from .lazy_access import rx, ry, rz, x, y, z
6
+ from .lib import Frame, Pose
7
+ from .quaternion import Quaternion
8
+
9
+ __all__ = ["RPY", "Frame", "Isometry", "Pose", "Quaternion", "Rotation", "Vector3", "rx", "ry", "rz", "x", "y", "z"]
@@ -0,0 +1,70 @@
1
+ """Contains angle representations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from cartesian_tree import _cartesian_tree as _core # type: ignore[attr-defined]
6
+
7
+
8
+ class RPY:
9
+ """Defines a roll-pitch-yaw angle representation."""
10
+
11
+ def __init__(self, roll: float, pitch: float, yaw: float) -> None:
12
+ """Initializes the roll-pitch-yaw angles.
13
+
14
+ Args:
15
+ roll: The roll angle in radians.
16
+ pitch: The pitch angle in radians.
17
+ yaw: The yaw angle in radians
18
+ """
19
+ self._core_rotation = _core.Rotation.from_rpy(roll, pitch, yaw)
20
+
21
+ @classmethod
22
+ def identity(cls) -> RPY:
23
+ """Initializes the identity RPY angles."""
24
+ instance = cls.__new__(cls)
25
+ instance._core_rotation = _core.Rotation.from_rpy(0.0, 0.0, 0.0)
26
+ return instance
27
+
28
+ @property
29
+ def roll(self) -> float:
30
+ """The roll angle in radians."""
31
+ return self._core_rotation.as_rpy()[0]
32
+
33
+ @property
34
+ def pitch(self) -> float:
35
+ """The pitch angle in radians."""
36
+ return self._core_rotation.as_rpy()[1]
37
+
38
+ @property
39
+ def yaw(self) -> float:
40
+ """The yaw angle in radians."""
41
+ return self._core_rotation.as_rpy()[2]
42
+
43
+ def as_list(self) -> list[float]:
44
+ """Returns the angles as list.
45
+
46
+ Returns:
47
+ The angle as list.
48
+ """
49
+ return list(self._core_rotation.as_rpy())
50
+
51
+ def as_tuple(self) -> tuple[float, float, float]:
52
+ """Returns the angles as tuple.
53
+
54
+ Returns:
55
+ The angles as tuple.
56
+ """
57
+ return self._core_rotation.as_rpy()
58
+
59
+ @classmethod
60
+ def _from_rust(cls, rust_rotation: _core.Rotation) -> RPY:
61
+ instance = cls.__new__(cls)
62
+ instance._core_rotation = rust_rotation
63
+ return instance
64
+
65
+ def __str__(self) -> str:
66
+ roll, pitch, yaw = self._core_rotation.as_rpy()
67
+ return f"({roll}, {pitch}, {yaw})"
68
+
69
+ def __repr__(self) -> str:
70
+ return self.__str__()