rod 0.3.1.dev7__tar.gz → 0.3.2.dev4__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.
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/PKG-INFO +1 -1
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/builder/primitive_builder.py +6 -7
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/kinematics/kinematic_tree.py +13 -13
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/pretty_printer.py +3 -3
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/collision.py +1 -2
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/common.py +16 -14
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/element.py +6 -6
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/geometry.py +43 -16
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/joint.py +8 -5
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/link.py +13 -14
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/material.py +6 -7
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/model.py +15 -16
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/physics.py +2 -2
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/scene.py +4 -5
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/sdf.py +10 -11
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/visual.py +1 -1
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/world.py +6 -7
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/tree/directed_tree.py +5 -5
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/tree/tree_elements.py +15 -17
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/urdf/exporter.py +36 -55
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/utils/frame_convention.py +0 -2
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/utils/gazebo.py +1 -1
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/utils/resolve_frames.py +1 -2
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/utils/resolve_uris.py +1 -2
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/PKG-INFO +1 -1
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/.github/workflows/ci_cd.yml +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/.github/workflows/style.yml +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/.gitignore +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/LICENSE +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/README.md +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/pyproject.toml +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/setup.cfg +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/setup.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/builder/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/builder/primitives.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/kinematics/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/kinematics/tree_transforms.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/logging.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/sdf/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/tree/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/urdf/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod/utils/__init__.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/SOURCES.txt +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/dependency_links.txt +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/not-zip-safe +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/requires.txt +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/src/rod.egg-info/top_level.txt +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/tests/test_meshbuilder.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/tests/test_urdf_exporter.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/tests/test_urdf_parsing.py +0 -0
- {rod-0.3.1.dev7 → rod-0.3.2.dev4}/tests/utils_models.py +0 -0
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
4
|
import dataclasses
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import numpy as np
|
|
8
7
|
import numpy.typing as npt
|
|
@@ -272,7 +271,7 @@ class PrimitiveBuilder(abc.ABC):
|
|
|
272
271
|
|
|
273
272
|
def _collision(
|
|
274
273
|
self,
|
|
275
|
-
name:
|
|
274
|
+
name: str | None,
|
|
276
275
|
pose: rod.Pose | None = None,
|
|
277
276
|
) -> rod.Collision:
|
|
278
277
|
name = name if name is not None else f"{self.name}_collision"
|
|
@@ -294,11 +293,11 @@ class PrimitiveBuilder(abc.ABC):
|
|
|
294
293
|
|
|
295
294
|
@staticmethod
|
|
296
295
|
def build_pose(
|
|
297
|
-
pos: npt.NDArray = None,
|
|
298
|
-
rpy: npt.NDArray = None,
|
|
299
|
-
relative_to: str = None,
|
|
300
|
-
degrees: bool = None,
|
|
301
|
-
rotation_format: str = None,
|
|
296
|
+
pos: npt.NDArray | None = None,
|
|
297
|
+
rpy: npt.NDArray | None = None,
|
|
298
|
+
relative_to: str | None = None,
|
|
299
|
+
degrees: bool | None = None,
|
|
300
|
+
rotation_format: str | None = None,
|
|
302
301
|
) -> rod.Pose | None:
|
|
303
302
|
if pos is None and rpy is None:
|
|
304
303
|
return rod.Pose.from_transform(transform=np.eye(4), relative_to=relative_to)
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import copy
|
|
4
4
|
import dataclasses
|
|
5
5
|
import functools
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import Sequence
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
|
|
@@ -16,8 +16,8 @@ from rod.tree import DirectedTree, DirectedTreeNode, TreeEdge, TreeFrame
|
|
|
16
16
|
class KinematicTree(DirectedTree):
|
|
17
17
|
model: rod.Model
|
|
18
18
|
|
|
19
|
-
joints:
|
|
20
|
-
frames:
|
|
19
|
+
joints: list[TreeEdge] = dataclasses.field(default_factory=list)
|
|
20
|
+
frames: list[TreeFrame] = dataclasses.field(default_factory=list)
|
|
21
21
|
|
|
22
22
|
def __post_init__(self):
|
|
23
23
|
# Initialize base class
|
|
@@ -38,13 +38,13 @@ class KinematicTree(DirectedTree):
|
|
|
38
38
|
self.joints.sort(key=lambda j: j.index)
|
|
39
39
|
self.frames.sort(key=lambda f: f.index)
|
|
40
40
|
|
|
41
|
-
def link_names(self) ->
|
|
41
|
+
def link_names(self) -> list[str]:
|
|
42
42
|
return [node.name() for node in self]
|
|
43
43
|
|
|
44
|
-
def frame_names(self) ->
|
|
44
|
+
def frame_names(self) -> list[str]:
|
|
45
45
|
return [frame.name() for frame in self.frames]
|
|
46
46
|
|
|
47
|
-
def joint_names(self) ->
|
|
47
|
+
def joint_names(self) -> list[str]:
|
|
48
48
|
return [joint.name() for joint in self.joints]
|
|
49
49
|
|
|
50
50
|
@staticmethod
|
|
@@ -73,7 +73,7 @@ class KinematicTree(DirectedTree):
|
|
|
73
73
|
|
|
74
74
|
# In our tree, links are the nodes and joints the edges.
|
|
75
75
|
# Create a dict mapping link names to tree nodes, for easy retrieval.
|
|
76
|
-
nodes_links_dict:
|
|
76
|
+
nodes_links_dict: dict[str, DirectedTreeNode] = {
|
|
77
77
|
# Add one node for each link of the model
|
|
78
78
|
**{link.name: DirectedTreeNode(_source=link) for link in model.links()},
|
|
79
79
|
# Add special world node, that will become a frame later
|
|
@@ -101,7 +101,7 @@ class KinematicTree(DirectedTree):
|
|
|
101
101
|
# Furthermore, existing frames are extra elements that could be optionally
|
|
102
102
|
# attached to the kinematic tree (but by default they're not part of it).
|
|
103
103
|
# Create a dict mapping frame names to frame nodes, for easy retrieval.
|
|
104
|
-
nodes_frames_dict:
|
|
104
|
+
nodes_frames_dict: dict[str, TreeFrame] = {
|
|
105
105
|
# Add a frame node for each frame in the model
|
|
106
106
|
**{frame.name: TreeFrame(_source=frame) for frame in model.frames()},
|
|
107
107
|
# Add implicit frames used in the SDF specification (__model__).
|
|
@@ -249,7 +249,7 @@ class KinematicTree(DirectedTree):
|
|
|
249
249
|
@staticmethod
|
|
250
250
|
def remove_edge(
|
|
251
251
|
edge: TreeEdge, keep_parent: bool = True
|
|
252
|
-
) ->
|
|
252
|
+
) -> tuple[DirectedTreeNode, Sequence[TreeFrame]]:
|
|
253
253
|
# Removed node: the node to remove.
|
|
254
254
|
# Replaced node: the node removed and replaced with the new node.
|
|
255
255
|
# New node: the new node that combines the removed and replaced nodes.
|
|
@@ -306,17 +306,17 @@ class KinematicTree(DirectedTree):
|
|
|
306
306
|
raise NotImplementedError("Inertial parameters lumping")
|
|
307
307
|
|
|
308
308
|
@functools.cached_property
|
|
309
|
-
def links_dict(self) ->
|
|
309
|
+
def links_dict(self) -> dict[str, DirectedTreeNode]:
|
|
310
310
|
return self.nodes_dict
|
|
311
311
|
|
|
312
312
|
@functools.cached_property
|
|
313
|
-
def frames_dict(self) ->
|
|
313
|
+
def frames_dict(self) -> dict[str, TreeFrame]:
|
|
314
314
|
return {frame.name(): frame for frame in self.frames}
|
|
315
315
|
|
|
316
316
|
@functools.cached_property
|
|
317
|
-
def joints_dict(self) ->
|
|
317
|
+
def joints_dict(self) -> dict[str, TreeEdge]:
|
|
318
318
|
return {joint.name(): joint for joint in self.joints}
|
|
319
319
|
|
|
320
320
|
@functools.cached_property
|
|
321
|
-
def joints_connection_dict(self) ->
|
|
321
|
+
def joints_connection_dict(self) -> dict[tuple[str, str], TreeEdge]:
|
|
322
322
|
return {(j.parent.name(), j.child.name()): j for j in self.joints}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import dataclasses
|
|
3
3
|
import numbers
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class DataclassPrettyPrinter(abc.ABC):
|
|
@@ -9,7 +9,7 @@ class DataclassPrettyPrinter(abc.ABC):
|
|
|
9
9
|
return DataclassPrettyPrinter.dataclass_to_str(obj=self, level=1)
|
|
10
10
|
|
|
11
11
|
@staticmethod
|
|
12
|
-
def list_to_string(obj:
|
|
12
|
+
def list_to_string(obj: list[Any], level: int = 1) -> str:
|
|
13
13
|
if not isinstance(obj, list):
|
|
14
14
|
raise TypeError(obj, type(obj))
|
|
15
15
|
|
|
@@ -40,7 +40,7 @@ class DataclassPrettyPrinter(abc.ABC):
|
|
|
40
40
|
if not dataclasses.is_dataclass(obj):
|
|
41
41
|
raise TypeError(obj, type(obj))
|
|
42
42
|
|
|
43
|
-
serialization:
|
|
43
|
+
serialization: list[tuple[str, str]] = []
|
|
44
44
|
|
|
45
45
|
for field in dataclasses.fields(obj):
|
|
46
46
|
attr = getattr(obj, field.name)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
import mashumaro
|
|
5
4
|
|
|
@@ -13,4 +12,4 @@ class Collision(Element):
|
|
|
13
12
|
geometry: Geometry
|
|
14
13
|
name: str = dataclasses.field(metadata=mashumaro.field_options(alias="@name"))
|
|
15
14
|
|
|
16
|
-
pose:
|
|
15
|
+
pose: Pose | None = dataclasses.field(default=None)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import dataclasses
|
|
2
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
3
5
|
|
|
4
6
|
import mashumaro
|
|
5
7
|
import numpy.typing as npt
|
|
@@ -9,7 +11,7 @@ from .element import Element
|
|
|
9
11
|
|
|
10
12
|
@dataclasses.dataclass
|
|
11
13
|
class Xyz(Element):
|
|
12
|
-
xyz:
|
|
14
|
+
xyz: list[float] = dataclasses.field(
|
|
13
15
|
default=None,
|
|
14
16
|
metadata=mashumaro.field_options(
|
|
15
17
|
alias="#text",
|
|
@@ -18,12 +20,12 @@ class Xyz(Element):
|
|
|
18
20
|
),
|
|
19
21
|
)
|
|
20
22
|
|
|
21
|
-
expressed_in:
|
|
23
|
+
expressed_in: str | None = dataclasses.field(
|
|
22
24
|
default=None, metadata=mashumaro.field_options(alias="@expressed_in")
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
@classmethod
|
|
26
|
-
def __pre_deserialize__(cls, d:
|
|
28
|
+
def __pre_deserialize__(cls, d: dict[Any, Any]) -> dict[Any, Any]:
|
|
27
29
|
if isinstance(d, str):
|
|
28
30
|
d = {"#text": d, "@expressed_in": ""}
|
|
29
31
|
|
|
@@ -32,7 +34,7 @@ class Xyz(Element):
|
|
|
32
34
|
|
|
33
35
|
@dataclasses.dataclass
|
|
34
36
|
class Pose(Element):
|
|
35
|
-
pose:
|
|
37
|
+
pose: list[float] = dataclasses.field(
|
|
36
38
|
default=None,
|
|
37
39
|
metadata=mashumaro.field_options(
|
|
38
40
|
alias="#text",
|
|
@@ -41,31 +43,31 @@ class Pose(Element):
|
|
|
41
43
|
),
|
|
42
44
|
)
|
|
43
45
|
|
|
44
|
-
relative_to:
|
|
46
|
+
relative_to: str | None = dataclasses.field(
|
|
45
47
|
default=None, metadata=mashumaro.field_options(alias="@relative_to")
|
|
46
48
|
)
|
|
47
49
|
|
|
48
|
-
degrees:
|
|
50
|
+
degrees: bool | None = dataclasses.field(
|
|
49
51
|
default=None, metadata=mashumaro.field_options(alias="@degrees")
|
|
50
52
|
)
|
|
51
53
|
|
|
52
|
-
rotation_format:
|
|
54
|
+
rotation_format: str | None = dataclasses.field(
|
|
53
55
|
default=None, metadata=mashumaro.field_options(alias="@rotation_format")
|
|
54
56
|
)
|
|
55
57
|
|
|
56
58
|
@classmethod
|
|
57
|
-
def __pre_deserialize__(cls, d:
|
|
59
|
+
def __pre_deserialize__(cls, d: dict[Any, Any]) -> dict[Any, Any]:
|
|
58
60
|
if isinstance(d, str):
|
|
59
61
|
d = {"#text": d, "@relative_to": ""}
|
|
60
62
|
|
|
61
63
|
return d
|
|
62
64
|
|
|
63
65
|
@property
|
|
64
|
-
def xyz(self) ->
|
|
66
|
+
def xyz(self) -> list[float]:
|
|
65
67
|
return self.pose[0:3]
|
|
66
68
|
|
|
67
69
|
@property
|
|
68
|
-
def rpy(self) ->
|
|
70
|
+
def rpy(self) -> list[float]:
|
|
69
71
|
return self.pose[3:6]
|
|
70
72
|
|
|
71
73
|
def transform(self) -> npt.NDArray:
|
|
@@ -89,7 +91,7 @@ class Pose(Element):
|
|
|
89
91
|
)
|
|
90
92
|
|
|
91
93
|
@staticmethod
|
|
92
|
-
def from_transform(transform: npt.NDArray, relative_to: str = None) ->
|
|
94
|
+
def from_transform(transform: npt.NDArray, relative_to: str | None = None) -> Pose:
|
|
93
95
|
if transform.shape != (4, 4):
|
|
94
96
|
raise ValueError(transform.shape)
|
|
95
97
|
|
|
@@ -105,8 +107,8 @@ class Pose(Element):
|
|
|
105
107
|
class Frame(Element):
|
|
106
108
|
name: str = dataclasses.field(metadata=mashumaro.field_options(alias="@name"))
|
|
107
109
|
|
|
108
|
-
attached_to:
|
|
110
|
+
attached_to: str | None = dataclasses.field(
|
|
109
111
|
default=None, metadata=mashumaro.field_options(alias="@attached_to")
|
|
110
112
|
)
|
|
111
113
|
|
|
112
|
-
pose:
|
|
114
|
+
pose: Pose | None = dataclasses.field(default=None)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
import mashumaro.config
|
|
5
5
|
import mashumaro.mixins.dict
|
|
@@ -13,7 +13,7 @@ class Element(mashumaro.mixins.dict.DataClassDictMixin, DataclassPrettyPrinter):
|
|
|
13
13
|
class Config(mashumaro.config.BaseConfig):
|
|
14
14
|
serialize_by_alias = True
|
|
15
15
|
|
|
16
|
-
def __post_serialize__(self, d:
|
|
16
|
+
def __post_serialize__(self, d: dict[Any, Any]) -> dict[Any, Any]:
|
|
17
17
|
out = d.copy()
|
|
18
18
|
|
|
19
19
|
for key, value in d.items():
|
|
@@ -45,16 +45,16 @@ class Element(mashumaro.mixins.dict.DataClassDictMixin, DataclassPrettyPrinter):
|
|
|
45
45
|
return str(data)
|
|
46
46
|
|
|
47
47
|
@staticmethod
|
|
48
|
-
def serialize_list(data:
|
|
48
|
+
def serialize_list(data: list[float]) -> str:
|
|
49
49
|
assert isinstance(data, list)
|
|
50
|
-
return " ".join(
|
|
50
|
+
return " ".join(map(lambda element: str(float(element)), data))
|
|
51
51
|
|
|
52
52
|
@staticmethod
|
|
53
|
-
def deserialize_list(data: str, length: int | None = None) ->
|
|
53
|
+
def deserialize_list(data: str, length: int | None = None) -> list[float]:
|
|
54
54
|
assert isinstance(data, str)
|
|
55
55
|
array = np.atleast_1d(np.array(data.split(sep=" "), dtype=float).squeeze())
|
|
56
56
|
|
|
57
57
|
if length is not None:
|
|
58
58
|
assert array.size == length
|
|
59
59
|
|
|
60
|
-
return
|
|
60
|
+
return array.tolist()
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import dataclasses
|
|
2
|
-
|
|
4
|
+
import types
|
|
5
|
+
from typing import ClassVar, Union
|
|
3
6
|
|
|
4
7
|
import mashumaro
|
|
5
8
|
|
|
@@ -8,7 +11,7 @@ from .element import Element
|
|
|
8
11
|
|
|
9
12
|
@dataclasses.dataclass
|
|
10
13
|
class Box(Element):
|
|
11
|
-
size:
|
|
14
|
+
size: list[float] = dataclasses.field(
|
|
12
15
|
default=None,
|
|
13
16
|
metadata=mashumaro.field_options(
|
|
14
17
|
serialize=Element.serialize_list,
|
|
@@ -41,7 +44,7 @@ class Cylinder(Element):
|
|
|
41
44
|
|
|
42
45
|
@dataclasses.dataclass
|
|
43
46
|
class Ellipsoid(Element):
|
|
44
|
-
radii:
|
|
47
|
+
radii: list[float] = dataclasses.field(
|
|
45
48
|
default=None,
|
|
46
49
|
metadata=mashumaro.field_options(
|
|
47
50
|
serialize=Element.serialize_list,
|
|
@@ -54,7 +57,7 @@ class Ellipsoid(Element):
|
|
|
54
57
|
class Heightmap(Element):
|
|
55
58
|
uri: str
|
|
56
59
|
|
|
57
|
-
size:
|
|
60
|
+
size: list[float] = dataclasses.field(
|
|
58
61
|
default=None,
|
|
59
62
|
metadata=mashumaro.field_options(
|
|
60
63
|
alias="#text",
|
|
@@ -63,7 +66,7 @@ class Heightmap(Element):
|
|
|
63
66
|
),
|
|
64
67
|
)
|
|
65
68
|
|
|
66
|
-
pos:
|
|
69
|
+
pos: list[float] = dataclasses.field(
|
|
67
70
|
default=None,
|
|
68
71
|
metadata=mashumaro.field_options(
|
|
69
72
|
alias="#text",
|
|
@@ -77,7 +80,7 @@ class Heightmap(Element):
|
|
|
77
80
|
class Mesh(Element):
|
|
78
81
|
uri: str
|
|
79
82
|
|
|
80
|
-
scale:
|
|
83
|
+
scale: list[float] | None = dataclasses.field(
|
|
81
84
|
default=None,
|
|
82
85
|
metadata=mashumaro.field_options(
|
|
83
86
|
serialize=Element.serialize_list,
|
|
@@ -88,14 +91,14 @@ class Mesh(Element):
|
|
|
88
91
|
|
|
89
92
|
@dataclasses.dataclass
|
|
90
93
|
class Plane(Element):
|
|
91
|
-
normal:
|
|
94
|
+
normal: list[float] = dataclasses.field(
|
|
92
95
|
metadata=mashumaro.field_options(
|
|
93
96
|
serialize=Element.serialize_list,
|
|
94
97
|
deserialize=lambda l: Element.deserialize_list(data=l, length=3),
|
|
95
98
|
),
|
|
96
99
|
)
|
|
97
100
|
|
|
98
|
-
size:
|
|
101
|
+
size: list[float] | None = dataclasses.field(
|
|
99
102
|
default=None,
|
|
100
103
|
metadata=mashumaro.field_options(
|
|
101
104
|
serialize=Element.serialize_list,
|
|
@@ -113,11 +116,35 @@ class Sphere(Element):
|
|
|
113
116
|
|
|
114
117
|
@dataclasses.dataclass
|
|
115
118
|
class Geometry(Element):
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
|
|
120
|
+
GeometryType: ClassVar[types.UnionType] = (
|
|
121
|
+
Box | Capsule | Cylinder | Ellipsoid | Heightmap | Mesh | Plane | Sphere
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
box: Box | None = dataclasses.field(default=None)
|
|
125
|
+
capsule: Capsule | None = dataclasses.field(default=None)
|
|
126
|
+
cylinder: Cylinder | None = dataclasses.field(default=None)
|
|
127
|
+
ellipsoid: Ellipsoid | None = dataclasses.field(default=None)
|
|
128
|
+
heightmap: Heightmap | None = dataclasses.field(default=None)
|
|
129
|
+
mesh: Mesh | None = dataclasses.field(default=None)
|
|
130
|
+
plane: Plane | None = dataclasses.field(default=None)
|
|
131
|
+
sphere: Sphere | None = dataclasses.field(default=None)
|
|
132
|
+
|
|
133
|
+
def geometries(self) -> list[Geometry.GeometryType]:
|
|
134
|
+
|
|
135
|
+
return [
|
|
136
|
+
self.__getattribute__(field.name)
|
|
137
|
+
for field in dataclasses.fields(self)
|
|
138
|
+
if self.__getattribute__(field.name) is not None
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
def geometry(self) -> Geometry.GeometryType | None:
|
|
142
|
+
"""Return the actual geometry stored in the object"""
|
|
143
|
+
|
|
144
|
+
geometries = self.geometries()
|
|
145
|
+
|
|
146
|
+
if len(geometries) > 1:
|
|
147
|
+
msg = "More than one geometry found, returning the first one"
|
|
148
|
+
logging.warning(msg)
|
|
149
|
+
|
|
150
|
+
return geometries[0] if len(geometries) > 0 else None
|
|
@@ -9,12 +9,15 @@ from .element import Element
|
|
|
9
9
|
|
|
10
10
|
@dataclasses.dataclass
|
|
11
11
|
class Limit(Element):
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
lower: Optional[float] = dataclasses.field(
|
|
14
|
+
default=None,
|
|
15
|
+
metadata=mashumaro.field_options(serialize=Element.serialize_float),
|
|
14
16
|
)
|
|
15
17
|
|
|
16
|
-
upper: float = dataclasses.field(
|
|
17
|
-
|
|
18
|
+
upper: Optional[float] = dataclasses.field(
|
|
19
|
+
default=None,
|
|
20
|
+
metadata=mashumaro.field_options(serialize=Element.serialize_float),
|
|
18
21
|
)
|
|
19
22
|
|
|
20
23
|
effort: Optional[float] = dataclasses.field(
|
|
@@ -74,5 +77,5 @@ class Joint(Element):
|
|
|
74
77
|
parent: str
|
|
75
78
|
child: str
|
|
76
79
|
|
|
77
|
-
pose:
|
|
80
|
+
pose: Pose | None = dataclasses.field(default=None)
|
|
78
81
|
axis: Optional[Axis] = dataclasses.field(default=None)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import List, Optional
|
|
3
2
|
|
|
4
3
|
import mashumaro
|
|
5
4
|
import numpy as np
|
|
@@ -61,58 +60,58 @@ class Inertial(Element):
|
|
|
61
60
|
|
|
62
61
|
inertia: Inertia
|
|
63
62
|
|
|
64
|
-
name:
|
|
65
|
-
pose:
|
|
63
|
+
name: str | None = dataclasses.field(default=None)
|
|
64
|
+
pose: Pose | None = dataclasses.field(default=None)
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
@dataclasses.dataclass
|
|
69
68
|
class Link(Element):
|
|
70
69
|
name: str = dataclasses.field(metadata=mashumaro.field_options(alias="@name"))
|
|
71
70
|
|
|
72
|
-
pose:
|
|
71
|
+
pose: Pose | None = dataclasses.field(default=None)
|
|
73
72
|
|
|
74
|
-
inertial:
|
|
73
|
+
inertial: Inertial | None = dataclasses.field(default=None)
|
|
75
74
|
|
|
76
|
-
visual:
|
|
75
|
+
visual: Visual | list[Visual] | None = dataclasses.field(default=None)
|
|
77
76
|
|
|
78
|
-
collision:
|
|
77
|
+
collision: Collision | list[Collision] | None = dataclasses.field(default=None)
|
|
79
78
|
|
|
80
|
-
gravity:
|
|
79
|
+
gravity: bool | None = dataclasses.field(
|
|
81
80
|
default=None,
|
|
82
81
|
metadata=mashumaro.field_options(
|
|
83
82
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
84
83
|
),
|
|
85
84
|
)
|
|
86
85
|
|
|
87
|
-
enable_wind:
|
|
86
|
+
enable_wind: bool | None = dataclasses.field(
|
|
88
87
|
default=None,
|
|
89
88
|
metadata=mashumaro.field_options(
|
|
90
89
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
91
90
|
),
|
|
92
91
|
)
|
|
93
92
|
|
|
94
|
-
self_collide:
|
|
93
|
+
self_collide: bool | None = dataclasses.field(
|
|
95
94
|
default=None,
|
|
96
95
|
metadata=mashumaro.field_options(
|
|
97
96
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
98
97
|
),
|
|
99
98
|
)
|
|
100
99
|
|
|
101
|
-
kinematic:
|
|
100
|
+
kinematic: bool | None = dataclasses.field(
|
|
102
101
|
default=None,
|
|
103
102
|
metadata=mashumaro.field_options(
|
|
104
103
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
105
104
|
),
|
|
106
105
|
)
|
|
107
106
|
|
|
108
|
-
must_be_base_link:
|
|
107
|
+
must_be_base_link: bool | None = dataclasses.field(
|
|
109
108
|
default=None,
|
|
110
109
|
metadata=mashumaro.field_options(
|
|
111
110
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
112
111
|
),
|
|
113
112
|
)
|
|
114
113
|
|
|
115
|
-
def visuals(self) ->
|
|
114
|
+
def visuals(self) -> list[Visual]:
|
|
116
115
|
if self.visual is None:
|
|
117
116
|
return []
|
|
118
117
|
|
|
@@ -122,7 +121,7 @@ class Link(Element):
|
|
|
122
121
|
assert isinstance(self.visual, list), type(self.visual)
|
|
123
122
|
return self.visual
|
|
124
123
|
|
|
125
|
-
def collisions(self) ->
|
|
124
|
+
def collisions(self) -> list[Collision]:
|
|
126
125
|
if self.collision is None:
|
|
127
126
|
return []
|
|
128
127
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from typing import List, Optional
|
|
3
2
|
|
|
4
3
|
import mashumaro
|
|
5
4
|
|
|
@@ -14,16 +13,16 @@ class Script(Element):
|
|
|
14
13
|
|
|
15
14
|
@dataclasses.dataclass
|
|
16
15
|
class Material(Element):
|
|
17
|
-
script:
|
|
16
|
+
script: Script | None = dataclasses.field(default=None)
|
|
18
17
|
|
|
19
|
-
lightning:
|
|
18
|
+
lightning: bool | None = dataclasses.field(
|
|
20
19
|
default=None,
|
|
21
20
|
metadata=mashumaro.field_options(
|
|
22
21
|
serialize=Element.serialize_bool, deserialize=Element.deserialize_bool
|
|
23
22
|
),
|
|
24
23
|
)
|
|
25
24
|
|
|
26
|
-
ambient:
|
|
25
|
+
ambient: list[float] | None = dataclasses.field(
|
|
27
26
|
default=None,
|
|
28
27
|
metadata=mashumaro.field_options(
|
|
29
28
|
serialize=Element.serialize_list,
|
|
@@ -31,7 +30,7 @@ class Material(Element):
|
|
|
31
30
|
),
|
|
32
31
|
)
|
|
33
32
|
|
|
34
|
-
diffuse:
|
|
33
|
+
diffuse: list[float] | None = dataclasses.field(
|
|
35
34
|
default=None,
|
|
36
35
|
metadata=mashumaro.field_options(
|
|
37
36
|
serialize=Element.serialize_list,
|
|
@@ -39,7 +38,7 @@ class Material(Element):
|
|
|
39
38
|
),
|
|
40
39
|
)
|
|
41
40
|
|
|
42
|
-
specular:
|
|
41
|
+
specular: list[float] | None = dataclasses.field(
|
|
43
42
|
default=None,
|
|
44
43
|
metadata=mashumaro.field_options(
|
|
45
44
|
serialize=Element.serialize_list,
|
|
@@ -47,7 +46,7 @@ class Material(Element):
|
|
|
47
46
|
),
|
|
48
47
|
)
|
|
49
48
|
|
|
50
|
-
emissive:
|
|
49
|
+
emissive: list[float] | None = dataclasses.field(
|
|
51
50
|
default=None,
|
|
52
51
|
metadata=mashumaro.field_options(
|
|
53
52
|
serialize=Element.serialize_list,
|