rod 0.2.1.dev33__tar.gz → 0.2.1.dev45__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.2.1.dev33 → rod-0.2.1.dev45}/.github/workflows/ci_cd.yml +18 -17
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/PKG-INFO +53 -24
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/README.md +50 -20
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/setup.cfg +2 -3
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/__init__.py +35 -6
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/PKG-INFO +53 -24
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/tests/test_meshbuilder.py +35 -20
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/.github/workflows/style.yml +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/.gitignore +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/LICENSE +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/pyproject.toml +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/setup.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/builder/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/builder/primitive_builder.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/builder/primitives.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/kinematics/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/kinematics/kinematic_tree.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/kinematics/tree_transforms.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/logging.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/pretty_printer.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/collision.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/common.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/element.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/geometry.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/joint.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/link.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/material.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/model.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/physics.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/scene.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/sdf.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/visual.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/sdf/world.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/tree/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/tree/directed_tree.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/tree/tree_elements.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/urdf/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/urdf/exporter.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/utils/__init__.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/utils/frame_convention.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/utils/gazebo.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/utils/resolve_frames.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod/utils/resolve_uris.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/SOURCES.txt +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/dependency_links.txt +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/not-zip-safe +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/requires.txt +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/src/rod.egg-info/top_level.txt +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/tests/test_urdf_exporter.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/tests/test_urdf_parsing.py +0 -0
- {rod-0.2.1.dev33 → rod-0.2.1.dev45}/tests/utils_models.py +0 -0
|
@@ -20,12 +20,12 @@ jobs:
|
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
22
|
|
|
23
|
-
- uses: actions/checkout@
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
24
|
with:
|
|
25
25
|
fetch-depth: 0
|
|
26
26
|
|
|
27
27
|
- name: Set up Python
|
|
28
|
-
uses: actions/setup-python@
|
|
28
|
+
uses: actions/setup-python@v5
|
|
29
29
|
with:
|
|
30
30
|
python-version: "3.*"
|
|
31
31
|
|
|
@@ -50,7 +50,7 @@ jobs:
|
|
|
50
50
|
python -c "import packaging.version as v; v.Version(\"$(python -m setuptools_scm)\")"
|
|
51
51
|
|
|
52
52
|
- name: Upload artifacts
|
|
53
|
-
uses: actions/upload-artifact@
|
|
53
|
+
uses: actions/upload-artifact@v4
|
|
54
54
|
with:
|
|
55
55
|
path: dist/*
|
|
56
56
|
name: dist
|
|
@@ -73,10 +73,9 @@ jobs:
|
|
|
73
73
|
- apt
|
|
74
74
|
- conda
|
|
75
75
|
python:
|
|
76
|
-
- "3.8"
|
|
77
|
-
- "3.9"
|
|
78
76
|
- "3.10"
|
|
79
77
|
- "3.11"
|
|
78
|
+
- "3.12"
|
|
80
79
|
exclude:
|
|
81
80
|
- os: macos-latest
|
|
82
81
|
type: apt
|
|
@@ -87,15 +86,14 @@ jobs:
|
|
|
87
86
|
|
|
88
87
|
- name: Set up Python
|
|
89
88
|
if: matrix.type == 'apt'
|
|
90
|
-
uses: actions/setup-python@
|
|
89
|
+
uses: actions/setup-python@v5
|
|
91
90
|
with:
|
|
92
91
|
python-version: ${{ matrix.python }}
|
|
93
92
|
|
|
94
|
-
- uses: conda-incubator/setup-miniconda@
|
|
93
|
+
- uses: conda-incubator/setup-miniconda@v3
|
|
95
94
|
if: matrix.type == 'conda'
|
|
96
95
|
with:
|
|
97
96
|
python-version: ${{ matrix.python }}
|
|
98
|
-
miniforge-variant: Mambaforge
|
|
99
97
|
miniforge-version: latest
|
|
100
98
|
channels: conda-forge
|
|
101
99
|
channel-priority: true
|
|
@@ -112,14 +110,16 @@ jobs:
|
|
|
112
110
|
|
|
113
111
|
- name: Install conda dependencies
|
|
114
112
|
if: matrix.type == 'conda'
|
|
113
|
+
# Note: pytest-icdiff creates problems on macOS.
|
|
115
114
|
run: |
|
|
116
|
-
|
|
115
|
+
conda install -y \
|
|
117
116
|
coloredlogs \
|
|
118
117
|
mashumaro \
|
|
119
118
|
numpy \
|
|
120
119
|
packaging \
|
|
121
120
|
resolve-robotics-uri-py \
|
|
122
121
|
scipy \
|
|
122
|
+
trimesh \
|
|
123
123
|
xmltodict \
|
|
124
124
|
black \
|
|
125
125
|
isort \
|
|
@@ -127,12 +127,11 @@ jobs:
|
|
|
127
127
|
idyntree \
|
|
128
128
|
pytest \
|
|
129
129
|
robot_descriptions \
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
mamba install -y gz-sim7 idyntree
|
|
130
|
+
libgz-tools2 \
|
|
131
|
+
libsdformat13
|
|
133
132
|
|
|
134
133
|
- name: Download Python packages
|
|
135
|
-
uses: actions/download-artifact@
|
|
134
|
+
uses: actions/download-artifact@v4
|
|
136
135
|
with:
|
|
137
136
|
path: dist
|
|
138
137
|
name: dist
|
|
@@ -150,13 +149,15 @@ jobs:
|
|
|
150
149
|
|
|
151
150
|
- name: Import the package
|
|
152
151
|
run: python -c "import rod"
|
|
152
|
+
env:
|
|
153
|
+
ROD_LOGGING_LEVEL: DEBUG
|
|
153
154
|
|
|
154
|
-
- uses: actions/checkout@
|
|
155
|
-
if: matrix.os != 'windows-latest'
|
|
155
|
+
- uses: actions/checkout@v4
|
|
156
156
|
|
|
157
157
|
- name: Run tests
|
|
158
|
-
if: matrix.os != 'windows-latest'
|
|
159
158
|
run: pytest
|
|
159
|
+
env:
|
|
160
|
+
ROD_LOGGING_LEVEL: DEBUG
|
|
160
161
|
|
|
161
162
|
publish:
|
|
162
163
|
name: Publish to PyPI
|
|
@@ -166,7 +167,7 @@ jobs:
|
|
|
166
167
|
steps:
|
|
167
168
|
|
|
168
169
|
- name: Download Python packages
|
|
169
|
-
uses: actions/download-artifact@
|
|
170
|
+
uses: actions/download-artifact@v4
|
|
170
171
|
with:
|
|
171
172
|
path: dist
|
|
172
173
|
name: dist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rod
|
|
3
|
-
Version: 0.2.1.
|
|
3
|
+
Version: 0.2.1.dev45
|
|
4
4
|
Summary: The ultimate Python tool for RObot Descriptions processing.
|
|
5
5
|
Home-page: https://github.com/ami-iit/rod
|
|
6
6
|
Author: Diego Ferigo
|
|
@@ -22,14 +22,13 @@ Classifier: Operating System :: POSIX :: Linux
|
|
|
22
22
|
Classifier: Operating System :: MacOS
|
|
23
23
|
Classifier: Operating System :: Microsoft :: Windows
|
|
24
24
|
Classifier: Programming Language :: Python :: 3
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
27
25
|
Classifier: Programming Language :: Python :: 3.10
|
|
28
26
|
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
28
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
30
29
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
31
30
|
Classifier: Topic :: Games/Entertainment :: Simulation
|
|
32
|
-
Requires-Python: >=3.
|
|
31
|
+
Requires-Python: >=3.10
|
|
33
32
|
Description-Content-Type: text/markdown
|
|
34
33
|
License-File: LICENSE
|
|
35
34
|
Requires-Dist: coloredlogs
|
|
@@ -82,39 +81,71 @@ Last but not least, the pose semantics also makes SDF aware of the concept of _f
|
|
|
82
81
|
|
|
83
82
|
## Features
|
|
84
83
|
|
|
85
|
-
- Out-of-the-box support
|
|
86
|
-
- Serialization and deserialization support
|
|
87
|
-
- In-memory layout based on `dataclasses
|
|
88
|
-
- Syntax highlighting and auto-completion
|
|
89
|
-
-
|
|
90
|
-
- Transitive support
|
|
91
|
-
- Type validation of elements and attributes
|
|
92
|
-
- Automatic check of missing required elements
|
|
93
|
-
-
|
|
94
|
-
-
|
|
84
|
+
- Out-of-the-box support for SDFormat specifications [≥ 1.10][sdformat_spec_110].
|
|
85
|
+
- Serialization and deserialization support for SDF files.
|
|
86
|
+
- In-memory layout based on `dataclasses`.
|
|
87
|
+
- Syntax highlighting and auto-completion.
|
|
88
|
+
- Programmatic creation of SDF files from Python APIs.
|
|
89
|
+
- Transitive support for URDF through conversion to SDF.
|
|
90
|
+
- Type validation of elements and attributes.
|
|
91
|
+
- Automatic check of missing required elements.
|
|
92
|
+
- High-performance serialization and deserialization using [`Fatal1ty/mashumaro`][mashumaro].
|
|
93
|
+
- Export in-memory model description to URDF.
|
|
95
94
|
|
|
96
95
|
[mashumaro]: https://github.com/Fatal1ty/mashumaro
|
|
97
96
|
[open_robotics]: https://www.openrobotics.org/
|
|
98
97
|
[pose_semantics]: http://sdformat.org/tutorials?tut=pose_frame_semantics_proposal&cat=pose_semantics_docs&
|
|
99
98
|
[sdformat]: http://sdformat.org/
|
|
100
99
|
[sdformat_python]: http://sdformat.org/tutorials?tut=python_bindings&cat=developers&
|
|
101
|
-
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
102
100
|
[sdformat_spec]: http://sdformat.org/spec
|
|
103
|
-
[
|
|
101
|
+
[sdformat_spec_110]: http://sdformat.org/spec?elem=sdf&ver=1.10
|
|
104
102
|
[urdf]: http://wiki.ros.org/urdf
|
|
105
103
|
|
|
106
|
-
[^urdf_to_sdf]: Conversion can be done
|
|
104
|
+
[^urdf_to_sdf]: Conversion can be done using the `gz sdf` command included in Gazebo Sim starting from Garden.
|
|
107
105
|
|
|
108
106
|
## Installation
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
> [!TIP]
|
|
109
|
+
> ROD does not support out-of-the-box URDF files.
|
|
110
|
+
> URDF support is obtained by converting URDF files to SDF using the `gz sdf` command provided by [sdformat][sdformat_repo] and [gz-tools][gz-tools_repo].
|
|
111
|
+
> Ensure these tools are installed on your system if URDF support is needed (more information below).
|
|
112
|
+
|
|
113
|
+
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
114
|
+
[gz-tools_repo]: https://github.com/gazebosim/gz-tools
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary>Using conda (recommended)</summary>
|
|
118
|
+
|
|
119
|
+
Installing ROD using `conda` is the recommended way to obtain a complete installation with out-of-the-box support for both URDF and SDF descriptions:
|
|
111
120
|
|
|
112
121
|
```bash
|
|
113
|
-
|
|
122
|
+
conda install rod -c conda-forge
|
|
114
123
|
```
|
|
115
124
|
|
|
125
|
+
This will automatically install `sdformat` and `gz-tools`.
|
|
126
|
+
|
|
127
|
+
</details>
|
|
128
|
+
|
|
129
|
+
<details>
|
|
130
|
+
<summary>Using pip</summary>
|
|
131
|
+
|
|
132
|
+
You can install ROD from PyPI with [`pypa/pip`][pip], preferably in a [virtual environment][venv]:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pip install rod[all]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
If you need URDF support, follow the [official instructions][gazebo_sim_docs] to install Gazebo Sim on your operating system,
|
|
139
|
+
making sure to obtain `sdformat ≥ 13.0` and `gz-tools ≥ 2.0`.
|
|
140
|
+
|
|
141
|
+
You don't need to install the entire Gazebo Sim suite.
|
|
142
|
+
For example, on Ubuntu, you can only install the `libsdformat13 gz-tools2` packages.
|
|
143
|
+
|
|
116
144
|
[pip]: https://github.com/pypa/pip/
|
|
117
|
-
[venv]: https://docs.python.org/3.
|
|
145
|
+
[venv]: https://docs.python.org/3.10/tutorial/venv.html
|
|
146
|
+
[gazebo_sim_docs]: https://gazebosim.org/docs
|
|
147
|
+
|
|
148
|
+
</details>
|
|
118
149
|
|
|
119
150
|
## Examples
|
|
120
151
|
|
|
@@ -225,10 +256,8 @@ print(sdf.serialize(pretty=True))
|
|
|
225
256
|
|
|
226
257
|
from rod.urdf.exporter import UrdfExporter
|
|
227
258
|
|
|
228
|
-
urdf_string = UrdfExporter.
|
|
229
|
-
sdf=sdf
|
|
230
|
-
pretty=True,
|
|
231
|
-
gazebo_preserve_fixed_joints=True,
|
|
259
|
+
urdf_string = UrdfExporter(pretty=True, gazebo_preserve_fixed_joints=True).to_urdf_string(
|
|
260
|
+
sdf=sdf
|
|
232
261
|
)
|
|
233
262
|
|
|
234
263
|
print(urdf_string)
|
|
@@ -21,39 +21,71 @@ Last but not least, the pose semantics also makes SDF aware of the concept of _f
|
|
|
21
21
|
|
|
22
22
|
## Features
|
|
23
23
|
|
|
24
|
-
- Out-of-the-box support
|
|
25
|
-
- Serialization and deserialization support
|
|
26
|
-
- In-memory layout based on `dataclasses
|
|
27
|
-
- Syntax highlighting and auto-completion
|
|
28
|
-
-
|
|
29
|
-
- Transitive support
|
|
30
|
-
- Type validation of elements and attributes
|
|
31
|
-
- Automatic check of missing required elements
|
|
32
|
-
-
|
|
33
|
-
-
|
|
24
|
+
- Out-of-the-box support for SDFormat specifications [≥ 1.10][sdformat_spec_110].
|
|
25
|
+
- Serialization and deserialization support for SDF files.
|
|
26
|
+
- In-memory layout based on `dataclasses`.
|
|
27
|
+
- Syntax highlighting and auto-completion.
|
|
28
|
+
- Programmatic creation of SDF files from Python APIs.
|
|
29
|
+
- Transitive support for URDF through conversion to SDF.
|
|
30
|
+
- Type validation of elements and attributes.
|
|
31
|
+
- Automatic check of missing required elements.
|
|
32
|
+
- High-performance serialization and deserialization using [`Fatal1ty/mashumaro`][mashumaro].
|
|
33
|
+
- Export in-memory model description to URDF.
|
|
34
34
|
|
|
35
35
|
[mashumaro]: https://github.com/Fatal1ty/mashumaro
|
|
36
36
|
[open_robotics]: https://www.openrobotics.org/
|
|
37
37
|
[pose_semantics]: http://sdformat.org/tutorials?tut=pose_frame_semantics_proposal&cat=pose_semantics_docs&
|
|
38
38
|
[sdformat]: http://sdformat.org/
|
|
39
39
|
[sdformat_python]: http://sdformat.org/tutorials?tut=python_bindings&cat=developers&
|
|
40
|
-
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
41
40
|
[sdformat_spec]: http://sdformat.org/spec
|
|
42
|
-
[
|
|
41
|
+
[sdformat_spec_110]: http://sdformat.org/spec?elem=sdf&ver=1.10
|
|
43
42
|
[urdf]: http://wiki.ros.org/urdf
|
|
44
43
|
|
|
45
|
-
[^urdf_to_sdf]: Conversion can be done
|
|
44
|
+
[^urdf_to_sdf]: Conversion can be done using the `gz sdf` command included in Gazebo Sim starting from Garden.
|
|
46
45
|
|
|
47
46
|
## Installation
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
> [!TIP]
|
|
49
|
+
> ROD does not support out-of-the-box URDF files.
|
|
50
|
+
> URDF support is obtained by converting URDF files to SDF using the `gz sdf` command provided by [sdformat][sdformat_repo] and [gz-tools][gz-tools_repo].
|
|
51
|
+
> Ensure these tools are installed on your system if URDF support is needed (more information below).
|
|
52
|
+
|
|
53
|
+
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
54
|
+
[gz-tools_repo]: https://github.com/gazebosim/gz-tools
|
|
55
|
+
|
|
56
|
+
<details>
|
|
57
|
+
<summary>Using conda (recommended)</summary>
|
|
58
|
+
|
|
59
|
+
Installing ROD using `conda` is the recommended way to obtain a complete installation with out-of-the-box support for both URDF and SDF descriptions:
|
|
50
60
|
|
|
51
61
|
```bash
|
|
52
|
-
|
|
62
|
+
conda install rod -c conda-forge
|
|
53
63
|
```
|
|
54
64
|
|
|
65
|
+
This will automatically install `sdformat` and `gz-tools`.
|
|
66
|
+
|
|
67
|
+
</details>
|
|
68
|
+
|
|
69
|
+
<details>
|
|
70
|
+
<summary>Using pip</summary>
|
|
71
|
+
|
|
72
|
+
You can install ROD from PyPI with [`pypa/pip`][pip], preferably in a [virtual environment][venv]:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install rod[all]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If you need URDF support, follow the [official instructions][gazebo_sim_docs] to install Gazebo Sim on your operating system,
|
|
79
|
+
making sure to obtain `sdformat ≥ 13.0` and `gz-tools ≥ 2.0`.
|
|
80
|
+
|
|
81
|
+
You don't need to install the entire Gazebo Sim suite.
|
|
82
|
+
For example, on Ubuntu, you can only install the `libsdformat13 gz-tools2` packages.
|
|
83
|
+
|
|
55
84
|
[pip]: https://github.com/pypa/pip/
|
|
56
|
-
[venv]: https://docs.python.org/3.
|
|
85
|
+
[venv]: https://docs.python.org/3.10/tutorial/venv.html
|
|
86
|
+
[gazebo_sim_docs]: https://gazebosim.org/docs
|
|
87
|
+
|
|
88
|
+
</details>
|
|
57
89
|
|
|
58
90
|
## Examples
|
|
59
91
|
|
|
@@ -164,10 +196,8 @@ print(sdf.serialize(pretty=True))
|
|
|
164
196
|
|
|
165
197
|
from rod.urdf.exporter import UrdfExporter
|
|
166
198
|
|
|
167
|
-
urdf_string = UrdfExporter.
|
|
168
|
-
sdf=sdf
|
|
169
|
-
pretty=True,
|
|
170
|
-
gazebo_preserve_fixed_joints=True,
|
|
199
|
+
urdf_string = UrdfExporter(pretty=True, gazebo_preserve_fixed_joints=True).to_urdf_string(
|
|
200
|
+
sdf=sdf
|
|
171
201
|
)
|
|
172
202
|
|
|
173
203
|
print(urdf_string)
|
|
@@ -37,10 +37,9 @@ classifiers =
|
|
|
37
37
|
Operating System :: MacOS
|
|
38
38
|
Operating System :: Microsoft :: Windows
|
|
39
39
|
Programming Language :: Python :: 3
|
|
40
|
-
Programming Language :: Python :: 3.8
|
|
41
|
-
Programming Language :: Python :: 3.9
|
|
42
40
|
Programming Language :: Python :: 3.10
|
|
43
41
|
Programming Language :: Python :: 3.11
|
|
42
|
+
Programming Language :: Python :: 3.12
|
|
44
43
|
Programming Language :: Python :: 3 :: Only
|
|
45
44
|
Programming Language :: Python :: Implementation :: CPython
|
|
46
45
|
Topic :: Games/Entertainment :: Simulation
|
|
@@ -50,7 +49,7 @@ zip_safe = False
|
|
|
50
49
|
packages = find:
|
|
51
50
|
package_dir =
|
|
52
51
|
=src
|
|
53
|
-
python_requires = >=3.
|
|
52
|
+
python_requires = >=3.10
|
|
54
53
|
install_requires =
|
|
55
54
|
coloredlogs
|
|
56
55
|
mashumaro
|
|
@@ -28,7 +28,7 @@ from .utils.frame_convention import FrameConvention
|
|
|
28
28
|
# ===============================
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def
|
|
31
|
+
def installation_is_editable():
|
|
32
32
|
"""
|
|
33
33
|
Check if the rod package is installed in editable mode.
|
|
34
34
|
"""
|
|
@@ -51,12 +51,41 @@ def _is_editable():
|
|
|
51
51
|
return rod_package_dir not in site.getsitepackages()
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
def get_default_logging_level(env_var: str) -> logging.LoggingLevel:
|
|
55
|
+
"""
|
|
56
|
+
Get the default logging level.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
env_var: The environment variable to check.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
The logging level to set.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
import os
|
|
66
|
+
|
|
67
|
+
# Define the default logging level depending on the installation mode.
|
|
68
|
+
default_logging_level = (
|
|
69
|
+
logging.LoggingLevel.DEBUG
|
|
70
|
+
if installation_is_editable()
|
|
71
|
+
else logging.LoggingLevel.WARNING
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Allow to override the default logging level with an environment variable.
|
|
75
|
+
try:
|
|
76
|
+
return logging.LoggingLevel[
|
|
77
|
+
os.environ.get(env_var, default_logging_level.name).upper()
|
|
78
|
+
]
|
|
79
|
+
except KeyError as exc:
|
|
80
|
+
msg = f"Invalid logging level defined in {env_var}='{os.environ[env_var]}'"
|
|
81
|
+
raise RuntimeError(msg) from exc
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Configure the logger with the default logging level.
|
|
85
|
+
logging.configure(level=get_default_logging_level(env_var="ROD_LOGGING_LEVEL"))
|
|
58
86
|
|
|
59
|
-
del
|
|
87
|
+
del installation_is_editable
|
|
88
|
+
del get_default_logging_level
|
|
60
89
|
|
|
61
90
|
# =====================================
|
|
62
91
|
# Check for compatible sdformat version
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rod
|
|
3
|
-
Version: 0.2.1.
|
|
3
|
+
Version: 0.2.1.dev45
|
|
4
4
|
Summary: The ultimate Python tool for RObot Descriptions processing.
|
|
5
5
|
Home-page: https://github.com/ami-iit/rod
|
|
6
6
|
Author: Diego Ferigo
|
|
@@ -22,14 +22,13 @@ Classifier: Operating System :: POSIX :: Linux
|
|
|
22
22
|
Classifier: Operating System :: MacOS
|
|
23
23
|
Classifier: Operating System :: Microsoft :: Windows
|
|
24
24
|
Classifier: Programming Language :: Python :: 3
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
27
25
|
Classifier: Programming Language :: Python :: 3.10
|
|
28
26
|
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
28
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
30
29
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
31
30
|
Classifier: Topic :: Games/Entertainment :: Simulation
|
|
32
|
-
Requires-Python: >=3.
|
|
31
|
+
Requires-Python: >=3.10
|
|
33
32
|
Description-Content-Type: text/markdown
|
|
34
33
|
License-File: LICENSE
|
|
35
34
|
Requires-Dist: coloredlogs
|
|
@@ -82,39 +81,71 @@ Last but not least, the pose semantics also makes SDF aware of the concept of _f
|
|
|
82
81
|
|
|
83
82
|
## Features
|
|
84
83
|
|
|
85
|
-
- Out-of-the-box support
|
|
86
|
-
- Serialization and deserialization support
|
|
87
|
-
- In-memory layout based on `dataclasses
|
|
88
|
-
- Syntax highlighting and auto-completion
|
|
89
|
-
-
|
|
90
|
-
- Transitive support
|
|
91
|
-
- Type validation of elements and attributes
|
|
92
|
-
- Automatic check of missing required elements
|
|
93
|
-
-
|
|
94
|
-
-
|
|
84
|
+
- Out-of-the-box support for SDFormat specifications [≥ 1.10][sdformat_spec_110].
|
|
85
|
+
- Serialization and deserialization support for SDF files.
|
|
86
|
+
- In-memory layout based on `dataclasses`.
|
|
87
|
+
- Syntax highlighting and auto-completion.
|
|
88
|
+
- Programmatic creation of SDF files from Python APIs.
|
|
89
|
+
- Transitive support for URDF through conversion to SDF.
|
|
90
|
+
- Type validation of elements and attributes.
|
|
91
|
+
- Automatic check of missing required elements.
|
|
92
|
+
- High-performance serialization and deserialization using [`Fatal1ty/mashumaro`][mashumaro].
|
|
93
|
+
- Export in-memory model description to URDF.
|
|
95
94
|
|
|
96
95
|
[mashumaro]: https://github.com/Fatal1ty/mashumaro
|
|
97
96
|
[open_robotics]: https://www.openrobotics.org/
|
|
98
97
|
[pose_semantics]: http://sdformat.org/tutorials?tut=pose_frame_semantics_proposal&cat=pose_semantics_docs&
|
|
99
98
|
[sdformat]: http://sdformat.org/
|
|
100
99
|
[sdformat_python]: http://sdformat.org/tutorials?tut=python_bindings&cat=developers&
|
|
101
|
-
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
102
100
|
[sdformat_spec]: http://sdformat.org/spec
|
|
103
|
-
[
|
|
101
|
+
[sdformat_spec_110]: http://sdformat.org/spec?elem=sdf&ver=1.10
|
|
104
102
|
[urdf]: http://wiki.ros.org/urdf
|
|
105
103
|
|
|
106
|
-
[^urdf_to_sdf]: Conversion can be done
|
|
104
|
+
[^urdf_to_sdf]: Conversion can be done using the `gz sdf` command included in Gazebo Sim starting from Garden.
|
|
107
105
|
|
|
108
106
|
## Installation
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
> [!TIP]
|
|
109
|
+
> ROD does not support out-of-the-box URDF files.
|
|
110
|
+
> URDF support is obtained by converting URDF files to SDF using the `gz sdf` command provided by [sdformat][sdformat_repo] and [gz-tools][gz-tools_repo].
|
|
111
|
+
> Ensure these tools are installed on your system if URDF support is needed (more information below).
|
|
112
|
+
|
|
113
|
+
[sdformat_repo]: https://github.com/gazebosim/sdformat
|
|
114
|
+
[gz-tools_repo]: https://github.com/gazebosim/gz-tools
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary>Using conda (recommended)</summary>
|
|
118
|
+
|
|
119
|
+
Installing ROD using `conda` is the recommended way to obtain a complete installation with out-of-the-box support for both URDF and SDF descriptions:
|
|
111
120
|
|
|
112
121
|
```bash
|
|
113
|
-
|
|
122
|
+
conda install rod -c conda-forge
|
|
114
123
|
```
|
|
115
124
|
|
|
125
|
+
This will automatically install `sdformat` and `gz-tools`.
|
|
126
|
+
|
|
127
|
+
</details>
|
|
128
|
+
|
|
129
|
+
<details>
|
|
130
|
+
<summary>Using pip</summary>
|
|
131
|
+
|
|
132
|
+
You can install ROD from PyPI with [`pypa/pip`][pip], preferably in a [virtual environment][venv]:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pip install rod[all]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
If you need URDF support, follow the [official instructions][gazebo_sim_docs] to install Gazebo Sim on your operating system,
|
|
139
|
+
making sure to obtain `sdformat ≥ 13.0` and `gz-tools ≥ 2.0`.
|
|
140
|
+
|
|
141
|
+
You don't need to install the entire Gazebo Sim suite.
|
|
142
|
+
For example, on Ubuntu, you can only install the `libsdformat13 gz-tools2` packages.
|
|
143
|
+
|
|
116
144
|
[pip]: https://github.com/pypa/pip/
|
|
117
|
-
[venv]: https://docs.python.org/3.
|
|
145
|
+
[venv]: https://docs.python.org/3.10/tutorial/venv.html
|
|
146
|
+
[gazebo_sim_docs]: https://gazebosim.org/docs
|
|
147
|
+
|
|
148
|
+
</details>
|
|
118
149
|
|
|
119
150
|
## Examples
|
|
120
151
|
|
|
@@ -225,10 +256,8 @@ print(sdf.serialize(pretty=True))
|
|
|
225
256
|
|
|
226
257
|
from rod.urdf.exporter import UrdfExporter
|
|
227
258
|
|
|
228
|
-
urdf_string = UrdfExporter.
|
|
229
|
-
sdf=sdf
|
|
230
|
-
pretty=True,
|
|
231
|
-
gazebo_preserve_fixed_joints=True,
|
|
259
|
+
urdf_string = UrdfExporter(pretty=True, gazebo_preserve_fixed_joints=True).to_urdf_string(
|
|
260
|
+
sdf=sdf
|
|
232
261
|
)
|
|
233
262
|
|
|
234
263
|
print(urdf_string)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import pathlib
|
|
3
1
|
import tempfile
|
|
4
2
|
|
|
5
3
|
import numpy as np
|
|
@@ -9,53 +7,70 @@ from rod.builder.primitives import MeshBuilder
|
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
def test_builder_creation():
|
|
10
|
+
|
|
11
|
+
# Create a mesh of a box primitive.
|
|
12
12
|
mesh = trimesh.creation.box([1, 1, 1])
|
|
13
13
|
|
|
14
|
-
# Temporary write to file because rod Mesh works with uri
|
|
15
|
-
with tempfile.
|
|
16
|
-
|
|
14
|
+
# Temporary write to file because rod Mesh works with uri.
|
|
15
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
16
|
+
with tempfile.NamedTemporaryFile(suffix=".stl", dir=tmp, delete=False) as fp:
|
|
17
|
+
|
|
18
|
+
mesh.export(fp.name, file_type="stl")
|
|
19
|
+
fp.close()
|
|
20
|
+
|
|
21
|
+
builder = MeshBuilder(
|
|
22
|
+
name="test_mesh",
|
|
23
|
+
mesh_path=fp.name,
|
|
24
|
+
mass=1.0,
|
|
25
|
+
scale=np.array([1.0, 1.0, 1.0]),
|
|
26
|
+
)
|
|
17
27
|
|
|
18
|
-
builder = MeshBuilder(
|
|
19
|
-
name="test_mesh",
|
|
20
|
-
mesh_path=fp.name,
|
|
21
|
-
mass=1.0,
|
|
22
|
-
scale=np.array([1.0, 1.0, 1.0]),
|
|
23
|
-
)
|
|
24
28
|
assert (
|
|
25
29
|
builder.mesh.vertices.shape == mesh.vertices.shape
|
|
26
30
|
), f"{builder.mesh.vertices.shape} != {mesh.vertices.shape}"
|
|
31
|
+
|
|
27
32
|
assert (
|
|
28
33
|
builder.mesh.faces.shape == mesh.faces.shape
|
|
29
34
|
), f"{builder.mesh.faces.shape} != {mesh.faces.shape}"
|
|
35
|
+
|
|
30
36
|
assert (
|
|
31
37
|
builder.mesh.moment_inertia.all() == mesh.moment_inertia.all()
|
|
32
38
|
), f"{builder.mesh.moment_inertia} != {mesh.moment_inertia}"
|
|
39
|
+
|
|
33
40
|
assert builder.mesh.volume == mesh.volume, f"{builder.mesh.volume} != {mesh.volume}"
|
|
34
41
|
|
|
35
42
|
|
|
36
43
|
def test_builder_creation_custom_mesh():
|
|
44
|
+
|
|
37
45
|
# Create a custom mesh
|
|
38
46
|
vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
|
|
39
47
|
faces = np.array([[0, 1, 2], [0, 2, 3]])
|
|
40
48
|
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
|
|
41
49
|
|
|
42
|
-
# Temporary write to file because rod Mesh works with uri
|
|
43
|
-
with tempfile.
|
|
44
|
-
|
|
50
|
+
# Temporary write to file because rod Mesh works with uri.
|
|
51
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
52
|
+
with tempfile.NamedTemporaryFile(suffix=".stl", dir=tmp, delete=False) as fp:
|
|
53
|
+
|
|
54
|
+
mesh.export(fp.name, file_type="stl")
|
|
55
|
+
fp.close()
|
|
56
|
+
|
|
57
|
+
builder = MeshBuilder(
|
|
58
|
+
name="test_mesh",
|
|
59
|
+
mesh_path=fp.name,
|
|
60
|
+
mass=1.0,
|
|
61
|
+
scale=np.array([1.0, 1.0, 1.0]),
|
|
62
|
+
)
|
|
45
63
|
|
|
46
|
-
builder = MeshBuilder(
|
|
47
|
-
name="test_mesh",
|
|
48
|
-
mesh_path=fp.name,
|
|
49
|
-
mass=1.0,
|
|
50
|
-
scale=np.array([1.0, 1.0, 1.0]),
|
|
51
|
-
)
|
|
52
64
|
assert (
|
|
53
65
|
builder.mesh.vertices.shape == mesh.vertices.shape
|
|
54
66
|
), f"{builder.mesh.vertices.shape} != {mesh.vertices.shape}"
|
|
67
|
+
|
|
55
68
|
assert (
|
|
56
69
|
builder.mesh.faces.shape == mesh.faces.shape
|
|
57
70
|
), f"{builder.mesh.faces.shape} != {mesh.faces.shape}"
|
|
71
|
+
|
|
58
72
|
assert (
|
|
59
73
|
builder.mesh.moment_inertia.all() == mesh.moment_inertia.all()
|
|
60
74
|
), f"{builder.mesh.moment_inertia} != {mesh.moment_inertia}"
|
|
75
|
+
|
|
61
76
|
assert builder.mesh.volume == mesh.volume, f"{builder.mesh.volume} != {mesh.volume}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|