cartesian-tree 0.2.1__tar.gz → 0.4.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.
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/Cargo.lock +145 -1
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/Cargo.toml +14 -6
- cartesian_tree-0.4.0/PKG-INFO +90 -0
- cartesian_tree-0.4.0/README.md +66 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/pyproject.toml +2 -2
- cartesian_tree-0.4.0/python/cartesian_tree/__init__.py +9 -0
- cartesian_tree-0.4.0/python/cartesian_tree/_cartesian_tree.pyi +95 -0
- cartesian_tree-0.4.0/python/cartesian_tree/angles.py +79 -0
- cartesian_tree-0.4.0/python/cartesian_tree/base_types.py +326 -0
- cartesian_tree-0.4.0/python/cartesian_tree/lazy_access.py +125 -0
- cartesian_tree-0.4.0/python/cartesian_tree/lib.py +381 -0
- cartesian_tree-0.4.0/python/cartesian_tree/quaternion.py +106 -0
- cartesian_tree-0.4.0/src/bindings/frame.rs +188 -0
- cartesian_tree-0.4.0/src/bindings/lazy_access.rs +69 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/src/bindings/mod.rs +1 -0
- cartesian_tree-0.4.0/src/bindings/pose.rs +110 -0
- cartesian_tree-0.4.0/src/bindings/utils.rs +208 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/src/errors.rs +10 -4
- cartesian_tree-0.4.0/src/frame.rs +1956 -0
- cartesian_tree-0.4.0/src/lazy_access.rs +71 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/src/lib.rs +13 -4
- cartesian_tree-0.4.0/src/pose.rs +253 -0
- cartesian_tree-0.4.0/src/rotation.rs +90 -0
- cartesian_tree-0.4.0/src/tree/mod.rs +5 -0
- cartesian_tree-0.2.1/PKG-INFO +0 -29
- cartesian_tree-0.2.1/README.md +0 -5
- cartesian_tree-0.2.1/python/cartesian_tree/__init__.py +0 -12
- cartesian_tree-0.2.1/python/cartesian_tree/helper.py +0 -194
- cartesian_tree-0.2.1/python/cartesian_tree/lib.py +0 -258
- cartesian_tree-0.2.1/src/bindings/frame.rs +0 -136
- cartesian_tree-0.2.1/src/bindings/pose.rs +0 -83
- cartesian_tree-0.2.1/src/bindings/utils.rs +0 -187
- cartesian_tree-0.2.1/src/frame.rs +0 -770
- cartesian_tree-0.2.1/src/orientation.rs +0 -17
- cartesian_tree-0.2.1/src/pose.rs +0 -136
- cartesian_tree-0.2.1/src/tree/mod.rs +0 -5
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/license-mit +0 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/python/cartesian_tree/py.typed +0 -0
- {cartesian_tree-0.2.1 → cartesian_tree-0.4.0}/src/tree/traits.rs +0 -0
|
@@ -4,13 +4,16 @@ version = 4
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "CartesianTree"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
dependencies = [
|
|
9
|
+
"approx",
|
|
9
10
|
"nalgebra",
|
|
10
11
|
"pyo3",
|
|
11
12
|
"serde",
|
|
12
13
|
"serde_json",
|
|
14
|
+
"slotmap",
|
|
13
15
|
"thiserror",
|
|
16
|
+
"uuid",
|
|
14
17
|
]
|
|
15
18
|
|
|
16
19
|
[[package]]
|
|
@@ -28,12 +31,36 @@ version = "1.4.0"
|
|
|
28
31
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
29
32
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
|
30
33
|
|
|
34
|
+
[[package]]
|
|
35
|
+
name = "bumpalo"
|
|
36
|
+
version = "3.19.0"
|
|
37
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
38
|
+
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
|
39
|
+
|
|
31
40
|
[[package]]
|
|
32
41
|
name = "bytemuck"
|
|
33
42
|
version = "1.23.0"
|
|
34
43
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
35
44
|
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
|
|
36
45
|
|
|
46
|
+
[[package]]
|
|
47
|
+
name = "cfg-if"
|
|
48
|
+
version = "1.0.4"
|
|
49
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
50
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
51
|
+
|
|
52
|
+
[[package]]
|
|
53
|
+
name = "getrandom"
|
|
54
|
+
version = "0.3.3"
|
|
55
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
56
|
+
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
|
57
|
+
dependencies = [
|
|
58
|
+
"cfg-if",
|
|
59
|
+
"libc",
|
|
60
|
+
"r-efi",
|
|
61
|
+
"wasi",
|
|
62
|
+
]
|
|
63
|
+
|
|
37
64
|
[[package]]
|
|
38
65
|
name = "heck"
|
|
39
66
|
version = "0.5.0"
|
|
@@ -52,6 +79,16 @@ version = "1.0.15"
|
|
|
52
79
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
53
80
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|
54
81
|
|
|
82
|
+
[[package]]
|
|
83
|
+
name = "js-sys"
|
|
84
|
+
version = "0.3.83"
|
|
85
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
86
|
+
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
|
|
87
|
+
dependencies = [
|
|
88
|
+
"once_cell",
|
|
89
|
+
"wasm-bindgen",
|
|
90
|
+
]
|
|
91
|
+
|
|
55
92
|
[[package]]
|
|
56
93
|
name = "libc"
|
|
57
94
|
version = "0.2.172"
|
|
@@ -258,12 +295,24 @@ dependencies = [
|
|
|
258
295
|
"proc-macro2",
|
|
259
296
|
]
|
|
260
297
|
|
|
298
|
+
[[package]]
|
|
299
|
+
name = "r-efi"
|
|
300
|
+
version = "5.3.0"
|
|
301
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
302
|
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
|
303
|
+
|
|
261
304
|
[[package]]
|
|
262
305
|
name = "rawpointer"
|
|
263
306
|
version = "0.2.1"
|
|
264
307
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
265
308
|
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
|
266
309
|
|
|
310
|
+
[[package]]
|
|
311
|
+
name = "rustversion"
|
|
312
|
+
version = "1.0.22"
|
|
313
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
314
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
315
|
+
|
|
267
316
|
[[package]]
|
|
268
317
|
name = "ryu"
|
|
269
318
|
version = "1.0.20"
|
|
@@ -335,6 +384,15 @@ dependencies = [
|
|
|
335
384
|
"wide",
|
|
336
385
|
]
|
|
337
386
|
|
|
387
|
+
[[package]]
|
|
388
|
+
name = "slotmap"
|
|
389
|
+
version = "1.1.1"
|
|
390
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
391
|
+
checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038"
|
|
392
|
+
dependencies = [
|
|
393
|
+
"version_check",
|
|
394
|
+
]
|
|
395
|
+
|
|
338
396
|
[[package]]
|
|
339
397
|
name = "syn"
|
|
340
398
|
version = "2.0.101"
|
|
@@ -390,6 +448,86 @@ version = "0.2.4"
|
|
|
390
448
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
391
449
|
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
392
450
|
|
|
451
|
+
[[package]]
|
|
452
|
+
name = "uuid"
|
|
453
|
+
version = "1.18.1"
|
|
454
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
455
|
+
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
|
|
456
|
+
dependencies = [
|
|
457
|
+
"getrandom",
|
|
458
|
+
"js-sys",
|
|
459
|
+
"wasm-bindgen",
|
|
460
|
+
]
|
|
461
|
+
|
|
462
|
+
[[package]]
|
|
463
|
+
name = "version_check"
|
|
464
|
+
version = "0.9.5"
|
|
465
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
466
|
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
467
|
+
|
|
468
|
+
[[package]]
|
|
469
|
+
name = "wasi"
|
|
470
|
+
version = "0.14.7+wasi-0.2.4"
|
|
471
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
472
|
+
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
|
|
473
|
+
dependencies = [
|
|
474
|
+
"wasip2",
|
|
475
|
+
]
|
|
476
|
+
|
|
477
|
+
[[package]]
|
|
478
|
+
name = "wasip2"
|
|
479
|
+
version = "1.0.1+wasi-0.2.4"
|
|
480
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
481
|
+
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
|
482
|
+
dependencies = [
|
|
483
|
+
"wit-bindgen",
|
|
484
|
+
]
|
|
485
|
+
|
|
486
|
+
[[package]]
|
|
487
|
+
name = "wasm-bindgen"
|
|
488
|
+
version = "0.2.106"
|
|
489
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
490
|
+
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
|
491
|
+
dependencies = [
|
|
492
|
+
"cfg-if",
|
|
493
|
+
"once_cell",
|
|
494
|
+
"rustversion",
|
|
495
|
+
"wasm-bindgen-macro",
|
|
496
|
+
"wasm-bindgen-shared",
|
|
497
|
+
]
|
|
498
|
+
|
|
499
|
+
[[package]]
|
|
500
|
+
name = "wasm-bindgen-macro"
|
|
501
|
+
version = "0.2.106"
|
|
502
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
503
|
+
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
|
|
504
|
+
dependencies = [
|
|
505
|
+
"quote",
|
|
506
|
+
"wasm-bindgen-macro-support",
|
|
507
|
+
]
|
|
508
|
+
|
|
509
|
+
[[package]]
|
|
510
|
+
name = "wasm-bindgen-macro-support"
|
|
511
|
+
version = "0.2.106"
|
|
512
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
513
|
+
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
|
|
514
|
+
dependencies = [
|
|
515
|
+
"bumpalo",
|
|
516
|
+
"proc-macro2",
|
|
517
|
+
"quote",
|
|
518
|
+
"syn",
|
|
519
|
+
"wasm-bindgen-shared",
|
|
520
|
+
]
|
|
521
|
+
|
|
522
|
+
[[package]]
|
|
523
|
+
name = "wasm-bindgen-shared"
|
|
524
|
+
version = "0.2.106"
|
|
525
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
526
|
+
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
|
|
527
|
+
dependencies = [
|
|
528
|
+
"unicode-ident",
|
|
529
|
+
]
|
|
530
|
+
|
|
393
531
|
[[package]]
|
|
394
532
|
name = "wide"
|
|
395
533
|
version = "0.7.32"
|
|
@@ -399,3 +537,9 @@ dependencies = [
|
|
|
399
537
|
"bytemuck",
|
|
400
538
|
"safe_arch",
|
|
401
539
|
]
|
|
540
|
+
|
|
541
|
+
[[package]]
|
|
542
|
+
name = "wit-bindgen"
|
|
543
|
+
version = "0.46.0"
|
|
544
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
545
|
+
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
authors = ["Kn0g"]
|
|
3
3
|
name = "CartesianTree"
|
|
4
|
-
version = "0.
|
|
4
|
+
version = "0.4.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"
|
|
@@ -13,16 +13,19 @@ keywords = ["Cartesian", "coordinate-systems", "transform", "poses"]
|
|
|
13
13
|
categories = ["mathematics", "data-structures"]
|
|
14
14
|
|
|
15
15
|
[lints.clippy]
|
|
16
|
-
all = "warn"
|
|
17
|
-
style = "warn"
|
|
18
|
-
pedantic = "warn"
|
|
19
|
-
cargo = "warn"
|
|
20
|
-
nursery = "warn"
|
|
16
|
+
all = { level = "warn", priority = -1 }
|
|
17
|
+
style = { level = "warn", priority = -1 }
|
|
18
|
+
pedantic = { level = "warn", priority = -1 }
|
|
19
|
+
cargo = { level = "warn", priority = -1 }
|
|
20
|
+
nursery = { level = "warn", priority = -1 }
|
|
21
21
|
missing_panics_doc = "warn"
|
|
22
22
|
missing_errors_doc = "warn"
|
|
23
23
|
missing_safety_doc = "warn"
|
|
24
24
|
empty_line_after_outer_attr = "warn"
|
|
25
25
|
empty_line_after_doc_comments = "warn"
|
|
26
|
+
# Guards in this crate are already scoped as tightly as the borrow checker allows;
|
|
27
|
+
# this nursery lint's suggestions frequently do not compile here.
|
|
28
|
+
significant_drop_tightening = "allow"
|
|
26
29
|
|
|
27
30
|
[dependencies]
|
|
28
31
|
nalgebra = { version = "0.33.2", features = ["serde-serialize"] }
|
|
@@ -30,6 +33,11 @@ pyo3 = { version = "0.25.0", features = ["extension-module"] , optional = true}
|
|
|
30
33
|
thiserror = "2.0.12"
|
|
31
34
|
serde = { version = "1.0", features = ["derive"] }
|
|
32
35
|
serde_json = "1.0"
|
|
36
|
+
slotmap = "1"
|
|
37
|
+
uuid = { version = "1", features = ["v4"] }
|
|
38
|
+
|
|
39
|
+
[dev-dependencies]
|
|
40
|
+
approx = "0.5.1"
|
|
33
41
|
|
|
34
42
|
[features]
|
|
35
43
|
bindings = ["dep:pyo3"]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cartesian-tree
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Classifier: Programming Language :: Python
|
|
5
|
+
Requires-Dist: maturin==1.8.6 ; extra == 'build'
|
|
6
|
+
Requires-Dist: cartesian-tree[lint] ; extra == 'dev'
|
|
7
|
+
Requires-Dist: cartesian-tree[test] ; extra == 'dev'
|
|
8
|
+
Requires-Dist: cartesian-tree[build] ; extra == 'dev'
|
|
9
|
+
Requires-Dist: ruff==0.12.4 ; extra == 'lint'
|
|
10
|
+
Requires-Dist: mypy==1.17.0 ; extra == 'lint'
|
|
11
|
+
Requires-Dist: pytest==8.4.1 ; extra == 'test'
|
|
12
|
+
Provides-Extra: build
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Provides-Extra: lint
|
|
15
|
+
Provides-Extra: test
|
|
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
|
+
- Thread Safety: Frames and poses can be shared across threads; every operation sees a consistent snapshot of the tree.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
The project can be found on [crates.io](https://crates.io/crates/cartesiantree) and [pypi.org](https://pypi.org/project/cartesian-tree/#description)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
Rust:
|
|
42
|
+
|
|
43
|
+
```rust
|
|
44
|
+
use cartesian_tree::{Frame, Pose};
|
|
45
|
+
use nalgebra::{Vector3, UnitQuaternion};
|
|
46
|
+
|
|
47
|
+
fn main() {
|
|
48
|
+
// Create root frame
|
|
49
|
+
let world = Frame::new_origin("world");
|
|
50
|
+
|
|
51
|
+
// Add a child frame
|
|
52
|
+
let child = world.add_child(
|
|
53
|
+
"child",
|
|
54
|
+
Vector3::new(1.0, 0.0, 0.0),
|
|
55
|
+
UnitQuaternion::from_euler_angles(0.0, 0.0, std::f64::consts::FRAC_PI_2),
|
|
56
|
+
).unwrap();
|
|
57
|
+
|
|
58
|
+
// Create a pose in the world frame
|
|
59
|
+
let pose = world.add_pose(Vector3::new(0.0, 1.0, 0.0), UnitQuaternion::identity());
|
|
60
|
+
|
|
61
|
+
// Transform the pose to the child frame
|
|
62
|
+
let pose_in_child = pose.in_frame(&child).unwrap();
|
|
63
|
+
|
|
64
|
+
println!("Pose in child: {:?}", pose_in_child.transformation());
|
|
65
|
+
```
|
|
66
|
+
Python:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from cartesian_tree import Frame, Rotation, Vector3
|
|
70
|
+
|
|
71
|
+
# Create root frame
|
|
72
|
+
world = Frame("world")
|
|
73
|
+
|
|
74
|
+
# Add a child frame
|
|
75
|
+
child = world.add_child(
|
|
76
|
+
"child",
|
|
77
|
+
Vector3(1.0, 0.0, 0.0),
|
|
78
|
+
Rotation.identity()
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Create a pose in the world frame
|
|
82
|
+
pose = world.add_pose(
|
|
83
|
+
Vector3(0.0, 1.0, 0.0), Rotation.identity()
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Transform the pose to the child frame
|
|
87
|
+
pose_in_child = pose.in_frame(child)
|
|
88
|
+
|
|
89
|
+
print(f"Pose in child: {pose_in_child}")
|
|
90
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
- Thread Safety: Frames and poses can be shared across threads; every operation sees a consistent snapshot of the tree.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
The project can be found on [crates.io](https://crates.io/crates/cartesiantree) and [pypi.org](https://pypi.org/project/cartesian-tree/#description)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
Rust:
|
|
18
|
+
|
|
19
|
+
```rust
|
|
20
|
+
use cartesian_tree::{Frame, Pose};
|
|
21
|
+
use nalgebra::{Vector3, UnitQuaternion};
|
|
22
|
+
|
|
23
|
+
fn main() {
|
|
24
|
+
// Create root frame
|
|
25
|
+
let world = Frame::new_origin("world");
|
|
26
|
+
|
|
27
|
+
// Add a child frame
|
|
28
|
+
let child = world.add_child(
|
|
29
|
+
"child",
|
|
30
|
+
Vector3::new(1.0, 0.0, 0.0),
|
|
31
|
+
UnitQuaternion::from_euler_angles(0.0, 0.0, std::f64::consts::FRAC_PI_2),
|
|
32
|
+
).unwrap();
|
|
33
|
+
|
|
34
|
+
// Create a pose in the world frame
|
|
35
|
+
let pose = world.add_pose(Vector3::new(0.0, 1.0, 0.0), UnitQuaternion::identity());
|
|
36
|
+
|
|
37
|
+
// Transform the pose to the child frame
|
|
38
|
+
let pose_in_child = pose.in_frame(&child).unwrap();
|
|
39
|
+
|
|
40
|
+
println!("Pose in child: {:?}", pose_in_child.transformation());
|
|
41
|
+
```
|
|
42
|
+
Python:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from cartesian_tree import Frame, Rotation, Vector3
|
|
46
|
+
|
|
47
|
+
# Create root frame
|
|
48
|
+
world = Frame("world")
|
|
49
|
+
|
|
50
|
+
# Add a child frame
|
|
51
|
+
child = world.add_child(
|
|
52
|
+
"child",
|
|
53
|
+
Vector3(1.0, 0.0, 0.0),
|
|
54
|
+
Rotation.identity()
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Create a pose in the world frame
|
|
58
|
+
pose = world.add_pose(
|
|
59
|
+
Vector3(0.0, 1.0, 0.0), Rotation.identity()
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Transform the pose to the child frame
|
|
63
|
+
pose_in_child = pose.in_frame(child)
|
|
64
|
+
|
|
65
|
+
print(f"Pose in child: {pose_in_child}")
|
|
66
|
+
```
|
|
@@ -62,13 +62,13 @@ 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
|
|
69
69
|
warn_unused_ignores = true
|
|
70
70
|
exclude = [
|
|
71
|
-
"
|
|
71
|
+
"src/",
|
|
72
72
|
"venv.*/",
|
|
73
73
|
"log/",
|
|
74
74
|
"target/",
|
|
@@ -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,95 @@
|
|
|
1
|
+
# Type stubs for the Rust extension module `cartesian_tree._cartesian_tree`.
|
|
2
|
+
# Keep in sync with the pymethods in src/bindings/.
|
|
3
|
+
|
|
4
|
+
class Vector3:
|
|
5
|
+
def __init__(self, x: float, y: float, z: float) -> None: ...
|
|
6
|
+
@property
|
|
7
|
+
def x(self) -> float: ...
|
|
8
|
+
@property
|
|
9
|
+
def y(self) -> float: ...
|
|
10
|
+
@property
|
|
11
|
+
def z(self) -> float: ...
|
|
12
|
+
def to_tuple(self) -> tuple[float, float, float]: ...
|
|
13
|
+
|
|
14
|
+
class Rotation:
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_quaternion(cls, x: float, y: float, z: float, w: float) -> Rotation: ...
|
|
17
|
+
@classmethod
|
|
18
|
+
def from_rpy(cls, roll: float, pitch: float, yaw: float) -> Rotation: ...
|
|
19
|
+
@classmethod
|
|
20
|
+
def identity(cls) -> Rotation: ...
|
|
21
|
+
def as_quaternion(self) -> tuple[float, float, float, float]: ...
|
|
22
|
+
def as_rpy(self) -> tuple[float, float, float]: ...
|
|
23
|
+
|
|
24
|
+
class Isometry:
|
|
25
|
+
@classmethod
|
|
26
|
+
def identity(cls) -> Isometry: ...
|
|
27
|
+
@classmethod
|
|
28
|
+
def from_translation(cls, translation: Vector3) -> Isometry: ...
|
|
29
|
+
@classmethod
|
|
30
|
+
def from_rotation(cls, rotation: Rotation) -> Isometry: ...
|
|
31
|
+
@classmethod
|
|
32
|
+
def from_parts(cls, translation: Vector3, rotation: Rotation) -> Isometry: ...
|
|
33
|
+
def decompose(self) -> tuple[Vector3, Rotation]: ...
|
|
34
|
+
def translation(self) -> Vector3: ...
|
|
35
|
+
def rotation(self) -> Rotation: ...
|
|
36
|
+
def inverse(self) -> Isometry: ...
|
|
37
|
+
def __mul__(self, other: Isometry) -> Isometry: ...
|
|
38
|
+
|
|
39
|
+
class LazyTranslation: ...
|
|
40
|
+
class LazyRotation: ...
|
|
41
|
+
|
|
42
|
+
class Frame:
|
|
43
|
+
def __init__(self, name: str) -> None: ...
|
|
44
|
+
@property
|
|
45
|
+
def name(self) -> str: ...
|
|
46
|
+
@property
|
|
47
|
+
def depth(self) -> int: ...
|
|
48
|
+
@property
|
|
49
|
+
def position(self) -> Vector3: ...
|
|
50
|
+
@property
|
|
51
|
+
def orientation(self) -> Rotation: ...
|
|
52
|
+
def add_child(self, name: str, position: Vector3, orientation: Rotation) -> Frame: ...
|
|
53
|
+
def remove_child(self, name: str) -> None: ...
|
|
54
|
+
def calibrate_child(
|
|
55
|
+
self,
|
|
56
|
+
name: str,
|
|
57
|
+
desired_position: Vector3,
|
|
58
|
+
desired_orientation: Rotation,
|
|
59
|
+
reference_pose: Pose,
|
|
60
|
+
) -> Frame: ...
|
|
61
|
+
def add_pose(self, position: Vector3, orientation: Rotation) -> Pose: ...
|
|
62
|
+
def transformation(self) -> tuple[Vector3, Rotation]: ...
|
|
63
|
+
def set(self, position: Vector3, orientation: Rotation) -> None: ...
|
|
64
|
+
def apply_in_parent_frame(self, isometry: Isometry) -> None: ...
|
|
65
|
+
def apply_in_local_frame(self, isometry: Isometry) -> None: ...
|
|
66
|
+
def to_json(self) -> str: ...
|
|
67
|
+
def apply_config(self, json: str) -> None: ...
|
|
68
|
+
def root(self) -> Frame: ...
|
|
69
|
+
def parent(self) -> Frame | None: ...
|
|
70
|
+
def children(self) -> list[Frame]: ...
|
|
71
|
+
def __add__(self, other: LazyTranslation) -> Frame: ...
|
|
72
|
+
def __sub__(self, other: LazyTranslation) -> Frame: ...
|
|
73
|
+
def __mul__(self, other: LazyRotation) -> Frame: ...
|
|
74
|
+
|
|
75
|
+
class Pose:
|
|
76
|
+
def frame(self) -> Frame | None: ...
|
|
77
|
+
@property
|
|
78
|
+
def position(self) -> Vector3: ...
|
|
79
|
+
@property
|
|
80
|
+
def orientation(self) -> Rotation: ...
|
|
81
|
+
def transformation(self) -> tuple[Vector3, Rotation]: ...
|
|
82
|
+
def set(self, position: Vector3, orientation: Rotation) -> None: ...
|
|
83
|
+
def apply_in_parent_frame(self, isometry: Isometry) -> None: ...
|
|
84
|
+
def apply_in_local_frame(self, isometry: Isometry) -> None: ...
|
|
85
|
+
def in_frame(self, target_frame: Frame) -> Pose: ...
|
|
86
|
+
def __add__(self, other: LazyTranslation) -> Pose: ...
|
|
87
|
+
def __sub__(self, other: LazyTranslation) -> Pose: ...
|
|
88
|
+
def __mul__(self, other: LazyRotation) -> Pose: ...
|
|
89
|
+
|
|
90
|
+
def x(value: float) -> LazyTranslation: ...
|
|
91
|
+
def y(value: float) -> LazyTranslation: ...
|
|
92
|
+
def z(value: float) -> LazyTranslation: ...
|
|
93
|
+
def rx(value: float) -> LazyRotation: ...
|
|
94
|
+
def ry(value: float) -> LazyRotation: ...
|
|
95
|
+
def rz(value: float) -> LazyRotation: ...
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Contains angle representations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from cartesian_tree import _cartesian_tree as _core
|
|
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
|
+
def __eq__(self, other: object) -> bool:
|
|
60
|
+
"""Exact component-wise equality of the angle values (no angle wrapping)."""
|
|
61
|
+
if not isinstance(other, RPY):
|
|
62
|
+
return NotImplemented
|
|
63
|
+
return self.as_tuple() == other.as_tuple()
|
|
64
|
+
|
|
65
|
+
def __hash__(self) -> int:
|
|
66
|
+
return hash(self.as_tuple())
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def _from_rust(cls, rust_rotation: _core.Rotation) -> RPY:
|
|
70
|
+
instance = cls.__new__(cls)
|
|
71
|
+
instance._core_rotation = rust_rotation
|
|
72
|
+
return instance
|
|
73
|
+
|
|
74
|
+
def __str__(self) -> str:
|
|
75
|
+
roll, pitch, yaw = self._core_rotation.as_rpy()
|
|
76
|
+
return f"({roll}, {pitch}, {yaw})"
|
|
77
|
+
|
|
78
|
+
def __repr__(self) -> str:
|
|
79
|
+
return self.__str__()
|