sscbirrt-assets 1.0.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.
- sscbirrt_assets-1.0.0/.gitignore +1 -0
- sscbirrt_assets-1.0.0/LICENSE +21 -0
- sscbirrt_assets-1.0.0/PKG-INFO +42 -0
- sscbirrt_assets-1.0.0/README.md +25 -0
- sscbirrt_assets-1.0.0/fetch.py +112 -0
- sscbirrt_assets-1.0.0/hatch_build.py +23 -0
- sscbirrt_assets-1.0.0/manifest.json +37 -0
- sscbirrt_assets-1.0.0/pyproject.toml +45 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/__init__.py +44 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/2f85.xml +191 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/LICENSE +23 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/base.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/base_mount.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/coupler.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/driver.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/follower.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/pad.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/silicone_pad.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/robotiq_2f85/assets/spring_link.stl +0 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/LICENSE +26 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/base_0.obj +15306 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/base_1.obj +17646 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/forearm_0.obj +45520 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/forearm_1.obj +2159 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/forearm_2.obj +25602 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/forearm_3.obj +29961 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/shoulder_0.obj +79709 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/shoulder_1.obj +15676 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/shoulder_2.obj +65873 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/upperarm_0.obj +4342 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/upperarm_1.obj +29711 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/upperarm_2.obj +99001 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/upperarm_3.obj +144582 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist1_0.obj +7761 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist1_1.obj +66213 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist1_2.obj +44960 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist2_0.obj +23375 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist2_1.obj +57886 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist2_2.obj +57883 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/assets/wrist3.obj +5893 -0
- sscbirrt_assets-1.0.0/src/sscbirrt_assets/menagerie/universal_robots_ur5e/ur5e.xml +136 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
src/sscbirrt_assets/menagerie/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Siddhartha Srinivasa <siddhartha.srinivasa@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sscbirrt-assets
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: The MuJoCo Menagerie UR5e and Robotiq 2F-85 models, packaged for the sscbirrt demos
|
|
5
|
+
Project-URL: Homepage, https://github.com/personalrobotics/sscbirrt
|
|
6
|
+
Project-URL: Source, https://github.com/personalrobotics/sscbirrt/tree/main/assets
|
|
7
|
+
Project-URL: Upstream, https://github.com/google-deepmind/mujoco_menagerie
|
|
8
|
+
Author-email: Siddhartha Srinivasa <siddhartha.srinivasa@gmail.com>
|
|
9
|
+
License-Expression: MIT AND BSD-3-Clause AND BSD-2-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: mujoco,robot-models,robotiq,sscbirrt,ur5e
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# sscbirrt-assets
|
|
19
|
+
|
|
20
|
+
The [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie) UR5e and Robotiq 2F-85 models, packaged so that `pip install "sscbirrt[demo]"` can run the [sscbirrt](https://github.com/personalrobotics/sscbirrt) demos without cloning the Menagerie.
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
import sscbirrt_assets
|
|
24
|
+
|
|
25
|
+
sscbirrt_assets.ur5e_xml() # .../menagerie/universal_robots_ur5e/ur5e.xml
|
|
26
|
+
sscbirrt_assets.robotiq_2f85_xml() # .../menagerie/robotiq_2f85/2f85.xml
|
|
27
|
+
sscbirrt_assets.menagerie_path() # a directory laid out like a Menagerie clone
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The functions return real file paths, since MJCF loaders resolve meshes relative to the XML.
|
|
31
|
+
|
|
32
|
+
## Provenance and licenses
|
|
33
|
+
|
|
34
|
+
Each file is copied unmodified from Menagerie at the commit in `sscbirrt_assets.MENAGERIE_COMMIT` and checked against the SHA-256 in `manifest.json`. Only the MJCF, the meshes and the LICENSE of each model ship.
|
|
35
|
+
|
|
36
|
+
- UR5e: BSD-3-Clause, Copyright 2018 ROS Industrial Consortium
|
|
37
|
+
- Robotiq 2F-85: BSD-2-Clause, Copyright (c) 2013, ROS-Industrial
|
|
38
|
+
- The Python code in this package: MIT
|
|
39
|
+
|
|
40
|
+
## Building
|
|
41
|
+
|
|
42
|
+
`fetch.py` places the files. The build hook calls it, so `uv build assets` works on its own. Pass `python assets/fetch.py --from <clone>` to copy from a local Menagerie clone instead of downloading. Either way the hashes are checked. After moving the pin, regenerate the manifest with `--write-manifest --from <clone>`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# sscbirrt-assets
|
|
2
|
+
|
|
3
|
+
The [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie) UR5e and Robotiq 2F-85 models, packaged so that `pip install "sscbirrt[demo]"` can run the [sscbirrt](https://github.com/personalrobotics/sscbirrt) demos without cloning the Menagerie.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import sscbirrt_assets
|
|
7
|
+
|
|
8
|
+
sscbirrt_assets.ur5e_xml() # .../menagerie/universal_robots_ur5e/ur5e.xml
|
|
9
|
+
sscbirrt_assets.robotiq_2f85_xml() # .../menagerie/robotiq_2f85/2f85.xml
|
|
10
|
+
sscbirrt_assets.menagerie_path() # a directory laid out like a Menagerie clone
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The functions return real file paths, since MJCF loaders resolve meshes relative to the XML.
|
|
14
|
+
|
|
15
|
+
## Provenance and licenses
|
|
16
|
+
|
|
17
|
+
Each file is copied unmodified from Menagerie at the commit in `sscbirrt_assets.MENAGERIE_COMMIT` and checked against the SHA-256 in `manifest.json`. Only the MJCF, the meshes and the LICENSE of each model ship.
|
|
18
|
+
|
|
19
|
+
- UR5e: BSD-3-Clause, Copyright 2018 ROS Industrial Consortium
|
|
20
|
+
- Robotiq 2F-85: BSD-2-Clause, Copyright (c) 2013, ROS-Industrial
|
|
21
|
+
- The Python code in this package: MIT
|
|
22
|
+
|
|
23
|
+
## Building
|
|
24
|
+
|
|
25
|
+
`fetch.py` places the files. The build hook calls it, so `uv build assets` works on its own. Pass `python assets/fetch.py --from <clone>` to copy from a local Menagerie clone instead of downloading. Either way the hashes are checked. After moving the pin, regenerate the manifest with `--write-manifest --from <clone>`.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 Siddhartha Srinivasa
|
|
3
|
+
|
|
4
|
+
"""Fetch the menagerie files sscbirrt-assets ships, pinned by commit and checked by SHA-256.
|
|
5
|
+
|
|
6
|
+
The files are not committed; they are copied into ``src/sscbirrt_assets/menagerie/`` at build time
|
|
7
|
+
(``hatch_build.py`` calls :func:`fetch`). ``manifest.json`` is the contract: the upstream commit and
|
|
8
|
+
the SHA-256 of every file. Any mismatch aborts the build.
|
|
9
|
+
|
|
10
|
+
python assets/fetch.py # download from GitHub at the pinned commit
|
|
11
|
+
python assets/fetch.py --from ~/mujoco_menagerie # copy from a local clone (hashes still checked)
|
|
12
|
+
python assets/fetch.py --write-manifest --from ~/mujoco_menagerie # regenerate the manifest
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import hashlib
|
|
19
|
+
import json
|
|
20
|
+
import shutil
|
|
21
|
+
import subprocess
|
|
22
|
+
import sys
|
|
23
|
+
import urllib.request
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
HERE = Path(__file__).resolve().parent
|
|
27
|
+
MANIFEST = HERE / "manifest.json"
|
|
28
|
+
DEST = HERE / "src" / "sscbirrt_assets" / "menagerie"
|
|
29
|
+
RAW_URL = "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/{commit}/{path}"
|
|
30
|
+
|
|
31
|
+
# What the manifest covers: each model's MJCF, its meshes, and its LICENSE. Not the preview .png,
|
|
32
|
+
# the scene.xml, or the README/CHANGELOG.
|
|
33
|
+
MODELS = {
|
|
34
|
+
"universal_robots_ur5e": ["ur5e.xml", "LICENSE", "assets/*.obj"],
|
|
35
|
+
"robotiq_2f85": ["2f85.xml", "LICENSE", "assets/*.stl"],
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _sha256(data: bytes) -> str:
|
|
40
|
+
return hashlib.sha256(data).hexdigest()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _read_source(path: str, commit: str, local: Path | None) -> bytes:
|
|
44
|
+
if local is not None:
|
|
45
|
+
return (local / path).read_bytes()
|
|
46
|
+
with urllib.request.urlopen(RAW_URL.format(commit=commit, path=path), timeout=60) as response:
|
|
47
|
+
return response.read()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def fetch(local: Path | None = None) -> Path:
|
|
51
|
+
"""Place every manifest file under DEST, verified; skip files already present with the right hash."""
|
|
52
|
+
manifest = json.loads(MANIFEST.read_text())
|
|
53
|
+
commit = manifest["commit"]
|
|
54
|
+
for path, digest in manifest["files"].items():
|
|
55
|
+
target = DEST / path
|
|
56
|
+
if target.is_file() and _sha256(target.read_bytes()) == digest:
|
|
57
|
+
continue
|
|
58
|
+
data = _read_source(path, commit, local)
|
|
59
|
+
if _sha256(data) != digest:
|
|
60
|
+
raise RuntimeError(f"{path}: SHA-256 mismatch against manifest (menagerie commit {commit})")
|
|
61
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
target.write_bytes(data)
|
|
63
|
+
# Nothing outside the manifest ships: remove stale files from an earlier manifest.
|
|
64
|
+
wanted = {DEST / p for p in manifest["files"]}
|
|
65
|
+
for existing in DEST.rglob("*"):
|
|
66
|
+
if existing.is_file() and existing not in wanted:
|
|
67
|
+
existing.unlink()
|
|
68
|
+
return DEST
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def write_manifest(local: Path) -> None:
|
|
72
|
+
"""Regenerate manifest.json from a local clone at the commit it is checked out at."""
|
|
73
|
+
status = subprocess.run(
|
|
74
|
+
["git", "-C", str(local), "status", "--porcelain", "--", *MODELS], capture_output=True, text=True, check=True
|
|
75
|
+
).stdout
|
|
76
|
+
tracked_changes = [line for line in status.splitlines() if not line.startswith("??")]
|
|
77
|
+
if tracked_changes:
|
|
78
|
+
raise RuntimeError(f"{local} has local changes to the shipped models:\n" + "\n".join(tracked_changes))
|
|
79
|
+
commit = subprocess.run(
|
|
80
|
+
["git", "-C", str(local), "rev-parse", "HEAD"], capture_output=True, text=True, check=True
|
|
81
|
+
).stdout.strip()
|
|
82
|
+
files = {}
|
|
83
|
+
for model, patterns in MODELS.items():
|
|
84
|
+
for pattern in patterns:
|
|
85
|
+
for f in sorted((local / model).glob(pattern)):
|
|
86
|
+
rel = f.relative_to(local).as_posix()
|
|
87
|
+
files[rel] = _sha256(f.read_bytes())
|
|
88
|
+
MANIFEST.write_text(json.dumps({"commit": commit, "files": files}, indent=2) + "\n")
|
|
89
|
+
print(f"wrote {MANIFEST} ({len(files)} files, commit {commit})")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def main() -> int:
|
|
93
|
+
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
94
|
+
parser.add_argument("--from", dest="local", type=Path, help="copy from a local menagerie clone")
|
|
95
|
+
parser.add_argument("--write-manifest", action="store_true", help="regenerate manifest.json from --from")
|
|
96
|
+
parser.add_argument("--clean", action="store_true", help="delete the fetched files")
|
|
97
|
+
args = parser.parse_args()
|
|
98
|
+
if args.clean:
|
|
99
|
+
shutil.rmtree(DEST, ignore_errors=True)
|
|
100
|
+
return 0
|
|
101
|
+
if args.write_manifest:
|
|
102
|
+
if args.local is None:
|
|
103
|
+
parser.error("--write-manifest needs --from")
|
|
104
|
+
write_manifest(args.local.expanduser())
|
|
105
|
+
return 0
|
|
106
|
+
dest = fetch(args.local.expanduser() if args.local else None)
|
|
107
|
+
print(f"assets ready in {dest}")
|
|
108
|
+
return 0
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
sys.exit(main())
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 Siddhartha Srinivasa
|
|
3
|
+
|
|
4
|
+
"""Build hook: place and verify the menagerie files before hatchling packs them."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FetchMenagerie(BuildHookInterface):
|
|
15
|
+
PLUGIN_NAME = "fetch-menagerie"
|
|
16
|
+
|
|
17
|
+
def initialize(self, version, build_data):
|
|
18
|
+
sys.path.insert(0, str(Path(self.root)))
|
|
19
|
+
try:
|
|
20
|
+
from fetch import fetch
|
|
21
|
+
finally:
|
|
22
|
+
sys.path.pop(0)
|
|
23
|
+
fetch()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commit": "feadf76d42f8a2162426f7d226a3b539556b3bf5",
|
|
3
|
+
"files": {
|
|
4
|
+
"universal_robots_ur5e/ur5e.xml": "ffd0a7b336d3c2d27c35a15cc0d4aaa95196769aca190ac8d6522d3318c345a0",
|
|
5
|
+
"universal_robots_ur5e/LICENSE": "5ec71ccf66c8d03261448f2441a586765b97f2248c860a1ae19689fb1c45cee6",
|
|
6
|
+
"universal_robots_ur5e/assets/base_0.obj": "9a3b21f1524baef6af8a52d7af90b6e94b79f7e3c2b04a0f6581f74d22291b0b",
|
|
7
|
+
"universal_robots_ur5e/assets/base_1.obj": "cf7d54691a2c1eeda280955ebd6bd83c2dbecfc46fb53c10198f05d107511b50",
|
|
8
|
+
"universal_robots_ur5e/assets/forearm_0.obj": "64c049a55149c2ab355594d52302b53d3e34da3677ceaa1917c427cde7743146",
|
|
9
|
+
"universal_robots_ur5e/assets/forearm_1.obj": "a96fe203015cf532b193f414cd01268c7c36795e51a837dd33afd122334f81f2",
|
|
10
|
+
"universal_robots_ur5e/assets/forearm_2.obj": "05b436505fc595aeab26675590c2b56b88a65b2d52d6352096fed9f07cb4c4ca",
|
|
11
|
+
"universal_robots_ur5e/assets/forearm_3.obj": "fa31af19cfad7a765b62e8a2d5931cb014b88de84195a7850b4e5ee902112e9a",
|
|
12
|
+
"universal_robots_ur5e/assets/shoulder_0.obj": "477387a7e7312782a6040484a3c2c2fcee33f40109f419076e31b6f6e1692c68",
|
|
13
|
+
"universal_robots_ur5e/assets/shoulder_1.obj": "8537bba02804640ddf6e260f79fe66e895b3229ed3d44298a95e8e027eb5d435",
|
|
14
|
+
"universal_robots_ur5e/assets/shoulder_2.obj": "291714518416bb8f0bafbf123867db011ecbf5146a05245ca5893ee8c57d4e21",
|
|
15
|
+
"universal_robots_ur5e/assets/upperarm_0.obj": "14143d4f1175a7dbacc8e2f2f98f1cac5a2b2e238cd46cd03654d31f2610eb53",
|
|
16
|
+
"universal_robots_ur5e/assets/upperarm_1.obj": "272899e927f4a32b7c25e34560ec70654c0346cc8ed1c616c0555f3f53b32d14",
|
|
17
|
+
"universal_robots_ur5e/assets/upperarm_2.obj": "86c05350d60eb0e7e28a81b544267478b7db997baba41cef19088ebbeffecfa1",
|
|
18
|
+
"universal_robots_ur5e/assets/upperarm_3.obj": "b257dab441e6fab64ea03b4b87029d8a96554ad1a513cce944d56acba0ad948a",
|
|
19
|
+
"universal_robots_ur5e/assets/wrist1_0.obj": "7ef0c59b5c5d56a9902435c9a058b27d2a38c85fe2bae02d00a9284dd1f4d519",
|
|
20
|
+
"universal_robots_ur5e/assets/wrist1_1.obj": "ee6d5c562e6becef94109b0543329080d285d1aef521a01ed98e18a5bf1e8684",
|
|
21
|
+
"universal_robots_ur5e/assets/wrist1_2.obj": "88c66dc64f15391287147d50add37729a3f41dadd80b1f859cf2cb6d45daf32a",
|
|
22
|
+
"universal_robots_ur5e/assets/wrist2_0.obj": "2ac2e2e39d8f7005bc3b3ab26cd61634be2e14930074615da5318b9ee7c569a8",
|
|
23
|
+
"universal_robots_ur5e/assets/wrist2_1.obj": "a721d06dc61d3b3a8ec58c035c9e3358ed30d6991a72e077d8abf3c3c203b633",
|
|
24
|
+
"universal_robots_ur5e/assets/wrist2_2.obj": "6df4335c8bd5e881fda2c224f770115ffe9ddd0cd321ebe3c0a4a310796f0987",
|
|
25
|
+
"universal_robots_ur5e/assets/wrist3.obj": "0e51748f9c93bd66604360a5cf7e2e8a6e754550be64076333ff4fc19ec90c61",
|
|
26
|
+
"robotiq_2f85/2f85.xml": "e07bba81975002dbae8b1e9984b0a2088ecca55f52cf395d099650d15db2bc9d",
|
|
27
|
+
"robotiq_2f85/LICENSE": "3d5edd18d1e22a17666e9bb84270171ed5ac90b192d24e0177fd171708ea2316",
|
|
28
|
+
"robotiq_2f85/assets/base.stl": "1c7b9f2bd92d705fc4e897c94e905973a3c05f406845e942229433deb7041453",
|
|
29
|
+
"robotiq_2f85/assets/base_mount.stl": "87971dfdd6e5311b5a723e7b73c4701ebf5c2364df671500f30dfc1c53c8e61a",
|
|
30
|
+
"robotiq_2f85/assets/coupler.stl": "d5ee95e62f8415bf5b6e503c831a958f5fc1990bf9b2865329ec38a28932727c",
|
|
31
|
+
"robotiq_2f85/assets/driver.stl": "bbd6e868b1778bead60d2516c7ede581d7ad4e431744b1828757d6ea5129c112",
|
|
32
|
+
"robotiq_2f85/assets/follower.stl": "633793332c081641ce200df27a40643cc293b29956e3cb5cb29cb811c33ef1c7",
|
|
33
|
+
"robotiq_2f85/assets/pad.stl": "4af1fa8d9bb285abecbf5dfc88e74cb30f059a7a074c2030dc35e9ee4316019d",
|
|
34
|
+
"robotiq_2f85/assets/silicone_pad.stl": "ca20c0fa61e6d3ce7b04bed25360e048e31dfd88ace04187aa6d9e8f4ca3fd0f",
|
|
35
|
+
"robotiq_2f85/assets/spring_link.stl": "4fb74a8a0d76c0e471cf19fd48bc676fd5b19123798e7a39eb6aa56869354283"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sscbirrt-assets"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "The MuJoCo Menagerie UR5e and Robotiq 2F-85 models, packaged for the sscbirrt demos"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
# The Python code is MIT; the model files keep their upstream licenses.
|
|
8
|
+
license = "MIT AND BSD-3-Clause AND BSD-2-Clause"
|
|
9
|
+
license-files = [
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"src/sscbirrt_assets/menagerie/universal_robots_ur5e/LICENSE",
|
|
12
|
+
"src/sscbirrt_assets/menagerie/robotiq_2f85/LICENSE",
|
|
13
|
+
]
|
|
14
|
+
keywords = ["mujoco", "ur5e", "robotiq", "robot-models", "sscbirrt"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Intended Audience :: Science/Research",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Topic :: Scientific/Engineering",
|
|
19
|
+
]
|
|
20
|
+
authors = [
|
|
21
|
+
{name = "Siddhartha Srinivasa", email = "siddhartha.srinivasa@gmail.com"},
|
|
22
|
+
]
|
|
23
|
+
dependencies = []
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/personalrobotics/sscbirrt"
|
|
27
|
+
Source = "https://github.com/personalrobotics/sscbirrt/tree/main/assets"
|
|
28
|
+
Upstream = "https://github.com/google-deepmind/mujoco_menagerie"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["hatchling>=1.27"]
|
|
32
|
+
build-backend = "hatchling.build"
|
|
33
|
+
|
|
34
|
+
# The menagerie files are fetched at build time (hatch_build.py -> fetch.py, pinned and hash-checked) and
|
|
35
|
+
# gitignored, so they are declared as artifacts: hatchling otherwise drops VCS-ignored files.
|
|
36
|
+
[tool.hatch.build.hooks.custom]
|
|
37
|
+
path = "hatch_build.py"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.wheel]
|
|
40
|
+
packages = ["src/sscbirrt_assets"]
|
|
41
|
+
artifacts = ["src/sscbirrt_assets/menagerie/**"]
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.sdist]
|
|
44
|
+
include = ["src/", "fetch.py", "hatch_build.py", "manifest.json", "README.md", "LICENSE"]
|
|
45
|
+
artifacts = ["src/sscbirrt_assets/menagerie/**"]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 Siddhartha Srinivasa
|
|
3
|
+
|
|
4
|
+
"""Robot models for the sscbirrt demos: the MuJoCo Menagerie UR5e and Robotiq 2F-85.
|
|
5
|
+
|
|
6
|
+
The files are copied unmodified from google-deepmind/mujoco_menagerie at the commit in
|
|
7
|
+
:data:`MENAGERIE_COMMIT`, each under its own LICENSE (UR5e: BSD-3-Clause; 2F-85: BSD-2-Clause).
|
|
8
|
+
The functions return real file paths because loaders such as ``ssik.Manipulator.from_mjcf`` and
|
|
9
|
+
``mujoco.MjSpec.from_file`` resolve the meshes relative to the MJCF.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
__all__ = ["MENAGERIE_COMMIT", "menagerie_path", "robotiq_2f85_xml", "ur5e_xml"]
|
|
17
|
+
|
|
18
|
+
MENAGERIE_COMMIT = "feadf76d42f8a2162426f7d226a3b539556b3bf5"
|
|
19
|
+
|
|
20
|
+
_ROOT = Path(__file__).resolve().parent / "menagerie"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def menagerie_path() -> Path:
|
|
24
|
+
"""A directory laid out like a menagerie clone, holding only the shipped models."""
|
|
25
|
+
return _ROOT
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _existing(relative: str) -> Path:
|
|
29
|
+
path = _ROOT / relative
|
|
30
|
+
if not path.is_file():
|
|
31
|
+
raise FileNotFoundError(
|
|
32
|
+
f"{path} is missing. In a source checkout, run `python assets/fetch.py` to place the models."
|
|
33
|
+
)
|
|
34
|
+
return path
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def ur5e_xml() -> Path:
|
|
38
|
+
"""The Menagerie UR5e MJCF (``universal_robots_ur5e/ur5e.xml``)."""
|
|
39
|
+
return _existing("universal_robots_ur5e/ur5e.xml")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def robotiq_2f85_xml() -> Path:
|
|
43
|
+
"""The Menagerie Robotiq 2F-85 MJCF (``robotiq_2f85/2f85.xml``)."""
|
|
44
|
+
return _existing("robotiq_2f85/2f85.xml")
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
<mujoco model="robotiq_2f85">
|
|
2
|
+
<compiler angle="radian" meshdir="assets" autolimits="true"/>
|
|
3
|
+
|
|
4
|
+
<option cone="elliptic" impratio="10"/>
|
|
5
|
+
|
|
6
|
+
<asset>
|
|
7
|
+
<material name="metal" rgba="0.58 0.58 0.58 1"/>
|
|
8
|
+
<material name="silicone" rgba="0.1882 0.1882 0.1882 1"/>
|
|
9
|
+
<material name="gray" rgba="0.4627 0.4627 0.4627 1"/>
|
|
10
|
+
<material name="black" rgba="0.149 0.149 0.149 1"/>
|
|
11
|
+
|
|
12
|
+
<mesh class="2f85" file="base_mount.stl"/>
|
|
13
|
+
<mesh class="2f85" file="base.stl"/>
|
|
14
|
+
<mesh class="2f85" file="driver.stl"/>
|
|
15
|
+
<mesh class="2f85" file="coupler.stl"/>
|
|
16
|
+
<mesh class="2f85" file="follower.stl"/>
|
|
17
|
+
<mesh class="2f85" file="pad.stl"/>
|
|
18
|
+
<mesh class="2f85" file="silicone_pad.stl"/>
|
|
19
|
+
<mesh class="2f85" file="spring_link.stl"/>
|
|
20
|
+
</asset>
|
|
21
|
+
|
|
22
|
+
<default>
|
|
23
|
+
<default class="2f85">
|
|
24
|
+
<mesh scale="0.001 0.001 0.001"/>
|
|
25
|
+
<general biastype="affine"/>
|
|
26
|
+
|
|
27
|
+
<joint axis="1 0 0"/>
|
|
28
|
+
<default class="driver">
|
|
29
|
+
<joint range="0 0.8" armature="0.005" damping="0.1" solimplimit="0.95 0.99 0.001" solreflimit="0.005 1"/>
|
|
30
|
+
</default>
|
|
31
|
+
<default class="follower">
|
|
32
|
+
<joint range="-0.872664 0.872664" armature="0.001" pos="0 -0.018 0.0065" solimplimit="0.95 0.99 0.001" solreflimit="0.005 1"/>
|
|
33
|
+
</default>
|
|
34
|
+
<default class="spring_link">
|
|
35
|
+
<joint range="-0.29670597283 0.8" armature="0.001" stiffness="0.05" springref="2.62" damping="0.00125"/>
|
|
36
|
+
</default>
|
|
37
|
+
<default class="coupler">
|
|
38
|
+
<joint range="-1.57 0" armature="0.001" solimplimit="0.95 0.99 0.001" solreflimit="0.005 1"/>
|
|
39
|
+
</default>
|
|
40
|
+
|
|
41
|
+
<default class="visual">
|
|
42
|
+
<geom type="mesh" contype="0" conaffinity="0" group="2"/>
|
|
43
|
+
</default>
|
|
44
|
+
<default class="collision">
|
|
45
|
+
<geom type="mesh" group="3"/>
|
|
46
|
+
<default class="pad_box1">
|
|
47
|
+
<geom mass="0" type="box" pos="0 -0.0026 0.028125" size="0.011 0.004 0.009375" friction="0.7"
|
|
48
|
+
solimp="0.95 0.99 0.001" solref="0.004 1" priority="1" rgba="0.55 0.55 0.55 1"/>
|
|
49
|
+
</default>
|
|
50
|
+
<default class="pad_box2">
|
|
51
|
+
<geom mass="0" type="box" pos="0 -0.0026 0.009375" size="0.011 0.004 0.009375" friction="0.6"
|
|
52
|
+
solimp="0.95 0.99 0.001" solref="0.004 1" priority="1" rgba="0.45 0.45 0.45 1"/>
|
|
53
|
+
</default>
|
|
54
|
+
</default>
|
|
55
|
+
</default>
|
|
56
|
+
</default>
|
|
57
|
+
|
|
58
|
+
<worldbody>
|
|
59
|
+
<body name="base_mount" pos="0 0 0.007" childclass="2f85">
|
|
60
|
+
<geom class="visual" mesh="base_mount" material="black"/>
|
|
61
|
+
<geom class="collision" mesh="base_mount"/>
|
|
62
|
+
<body name="base" pos="0 0 0.0038" quat="1 0 0 -1">
|
|
63
|
+
<inertial mass="0.777441" pos="0 -2.70394e-05 0.0354675" quat="1 -0.00152849 0 0"
|
|
64
|
+
diaginertia="0.000260285 0.000225381 0.000152708"/>
|
|
65
|
+
<geom class="visual" mesh="base" material="black"/>
|
|
66
|
+
<geom class="collision" mesh="base"/>
|
|
67
|
+
<site name="pinch" pos="0 0 0.145" type="sphere" group="5" rgba="0.9 0.9 0.9 1" size="0.005"/>
|
|
68
|
+
<!-- Right-hand side 4-bar linkage -->
|
|
69
|
+
<body name="right_driver" pos="0 0.0306011 0.054904">
|
|
70
|
+
<inertial mass="0.00899563" pos="2.96931e-12 0.0177547 0.00107314" quat="0.681301 0.732003 0 0"
|
|
71
|
+
diaginertia="1.72352e-06 1.60906e-06 3.22006e-07"/>
|
|
72
|
+
<joint name="right_driver_joint" class="driver"/>
|
|
73
|
+
<geom class="visual" mesh="driver" material="gray"/>
|
|
74
|
+
<geom class="collision" mesh="driver"/>
|
|
75
|
+
<body name="right_coupler" pos="0 0.0315 -0.0041">
|
|
76
|
+
<inertial mass="0.0140974" pos="0 0.00301209 0.0232175" quat="0.705636 -0.0455904 0.0455904 0.705636"
|
|
77
|
+
diaginertia="4.16206e-06 3.52216e-06 8.88131e-07"/>
|
|
78
|
+
<joint name="right_coupler_joint" class="coupler"/>
|
|
79
|
+
<geom class="visual" mesh="coupler" material="black"/>
|
|
80
|
+
<geom class="collision" mesh="coupler"/>
|
|
81
|
+
</body>
|
|
82
|
+
</body>
|
|
83
|
+
<body name="right_spring_link" pos="0 0.0132 0.0609">
|
|
84
|
+
<inertial mass="0.0221642" pos="-8.65005e-09 0.0181624 0.0212658" quat="0.663403 -0.244737 0.244737 0.663403"
|
|
85
|
+
diaginertia="8.96853e-06 6.71733e-06 2.63931e-06"/>
|
|
86
|
+
<joint name="right_spring_link_joint" class="spring_link"/>
|
|
87
|
+
<geom class="visual" mesh="spring_link" material="black"/>
|
|
88
|
+
<geom class="collision" mesh="spring_link"/>
|
|
89
|
+
<body name="right_follower" pos="0 0.055 0.0375">
|
|
90
|
+
<inertial mass="0.0125222" pos="0 -0.011046 0.0124786" quat="1 0.1664 0 0"
|
|
91
|
+
diaginertia="2.67415e-06 2.4559e-06 6.02031e-07"/>
|
|
92
|
+
<joint name="right_follower_joint" class="follower"/>
|
|
93
|
+
<geom class="visual" mesh="follower" material="black"/>
|
|
94
|
+
<geom class="collision" mesh="follower"/>
|
|
95
|
+
<body name="right_pad" pos="0 -0.0189 0.01352">
|
|
96
|
+
<geom class="pad_box1" name="right_pad1"/>
|
|
97
|
+
<geom class="pad_box2" name="right_pad2"/>
|
|
98
|
+
<inertial mass="0.0035" pos="0 -0.0025 0.0185" quat="0.707107 0 0 0.707107"
|
|
99
|
+
diaginertia="4.73958e-07 3.64583e-07 1.23958e-07"/>
|
|
100
|
+
<geom class="visual" mesh="pad"/>
|
|
101
|
+
<body name="right_silicone_pad">
|
|
102
|
+
<geom class="visual" mesh="silicone_pad" material="black"/>
|
|
103
|
+
</body>
|
|
104
|
+
</body>
|
|
105
|
+
</body>
|
|
106
|
+
</body>
|
|
107
|
+
<!-- Left-hand side 4-bar linkage -->
|
|
108
|
+
<body name="left_driver" pos="0 -0.0306011 0.054904" quat="0 0 0 1">
|
|
109
|
+
<inertial mass="0.00899563" pos="0 0.0177547 0.00107314" quat="0.681301 0.732003 0 0"
|
|
110
|
+
diaginertia="1.72352e-06 1.60906e-06 3.22006e-07"/>
|
|
111
|
+
<joint name="left_driver_joint" class="driver"/>
|
|
112
|
+
<geom class="visual" mesh="driver" material="gray"/>
|
|
113
|
+
<geom class="collision" mesh="driver"/>
|
|
114
|
+
<body name="left_coupler" pos="0 0.0315 -0.0041">
|
|
115
|
+
<inertial mass="0.0140974" pos="0 0.00301209 0.0232175" quat="0.705636 -0.0455904 0.0455904 0.705636"
|
|
116
|
+
diaginertia="4.16206e-06 3.52216e-06 8.88131e-07"/>
|
|
117
|
+
<joint name="left_coupler_joint" class="coupler"/>
|
|
118
|
+
<geom class="visual" mesh="coupler" material="black"/>
|
|
119
|
+
<geom class="collision" mesh="coupler"/>
|
|
120
|
+
</body>
|
|
121
|
+
</body>
|
|
122
|
+
<body name="left_spring_link" pos="0 -0.0132 0.0609" quat="0 0 0 1">
|
|
123
|
+
<inertial mass="0.0221642" pos="-8.65005e-09 0.0181624 0.0212658" quat="0.663403 -0.244737 0.244737 0.663403"
|
|
124
|
+
diaginertia="8.96853e-06 6.71733e-06 2.63931e-06"/>
|
|
125
|
+
<joint name="left_spring_link_joint" class="spring_link"/>
|
|
126
|
+
<geom class="visual" mesh="spring_link" material="black"/>
|
|
127
|
+
<geom class="collision" mesh="spring_link"/>
|
|
128
|
+
<body name="left_follower" pos="0 0.055 0.0375">
|
|
129
|
+
<inertial mass="0.0125222" pos="0 -0.011046 0.0124786" quat="1 0.1664 0 0"
|
|
130
|
+
diaginertia="2.67415e-06 2.4559e-06 6.02031e-07"/>
|
|
131
|
+
<joint name="left_follower_joint" class="follower"/>
|
|
132
|
+
<geom class="visual" mesh="follower" material="black"/>
|
|
133
|
+
<geom class="collision" mesh="follower"/>
|
|
134
|
+
<body name="left_pad" pos="0 -0.0189 0.01352">
|
|
135
|
+
<geom class="pad_box1" name="left_pad1"/>
|
|
136
|
+
<geom class="pad_box2" name="left_pad2"/>
|
|
137
|
+
<inertial mass="0.0035" pos="0 -0.0025 0.0185" quat="1 0 0 1"
|
|
138
|
+
diaginertia="4.73958e-07 3.64583e-07 1.23958e-07"/>
|
|
139
|
+
<geom class="visual" mesh="pad"/>
|
|
140
|
+
<body name="left_silicone_pad">
|
|
141
|
+
<geom class="visual" mesh="silicone_pad" material="black"/>
|
|
142
|
+
</body>
|
|
143
|
+
</body>
|
|
144
|
+
</body>
|
|
145
|
+
</body>
|
|
146
|
+
</body>
|
|
147
|
+
</body>
|
|
148
|
+
</worldbody>
|
|
149
|
+
|
|
150
|
+
<contact>
|
|
151
|
+
<exclude body1="base" body2="left_driver"/>
|
|
152
|
+
<exclude body1="base" body2="right_driver"/>
|
|
153
|
+
<exclude body1="base" body2="left_spring_link"/>
|
|
154
|
+
<exclude body1="base" body2="right_spring_link"/>
|
|
155
|
+
<exclude body1="right_coupler" body2="right_follower"/>
|
|
156
|
+
<exclude body1="left_coupler" body2="left_follower"/>
|
|
157
|
+
</contact>
|
|
158
|
+
|
|
159
|
+
<!--
|
|
160
|
+
This adds stability to the model by having a tendon that distributes the forces between both
|
|
161
|
+
joints, such that the equality constraint doesn't have to do that much work in order to equalize
|
|
162
|
+
both joints. Since both joints share the same sign, we split the force between both equally by
|
|
163
|
+
setting coef=0.5
|
|
164
|
+
-->
|
|
165
|
+
<tendon>
|
|
166
|
+
<fixed name="split">
|
|
167
|
+
<joint joint="right_driver_joint" coef="0.5"/>
|
|
168
|
+
<joint joint="left_driver_joint" coef="0.5"/>
|
|
169
|
+
</fixed>
|
|
170
|
+
</tendon>
|
|
171
|
+
|
|
172
|
+
<equality>
|
|
173
|
+
<connect anchor="0 0 0" body1="right_follower" body2="right_coupler" solimp="0.95 0.99 0.001" solref="0.005 1"/>
|
|
174
|
+
<connect anchor="0 0 0" body1="left_follower" body2="left_coupler" solimp="0.95 0.99 0.001" solref="0.005 1"/>
|
|
175
|
+
<joint joint1="right_driver_joint" joint2="left_driver_joint" polycoef="0 1 0 0 0" solimp="0.95 0.99 0.001"
|
|
176
|
+
solref="0.005 1"/>
|
|
177
|
+
</equality>
|
|
178
|
+
|
|
179
|
+
<!--
|
|
180
|
+
The general actuator below is a customized position actuator (with some damping) where
|
|
181
|
+
gainprm[0] != kp (see http://mujoco.org/book/modeling.html#position).
|
|
182
|
+
The reason why gainprm[0] != kp is because the control input range has to be re-scaled to
|
|
183
|
+
[0, 255]. The joint range is currently set at [0, 0.8], the control range is [0, 255] and
|
|
184
|
+
kp = 100. Tau = Kp * scale * control_input - Kp * error, max(Kp * scale * control_input) = 0.8,
|
|
185
|
+
hence scale = 0.8 * 100 / 255
|
|
186
|
+
-->
|
|
187
|
+
<actuator>
|
|
188
|
+
<general class="2f85" name="fingers_actuator" tendon="split" forcerange="-5 5" ctrlrange="0 255"
|
|
189
|
+
gainprm="0.3137255 0 0" biasprm="0 -100 -10"/>
|
|
190
|
+
</actuator>
|
|
191
|
+
</mujoco>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2013, ROS-Industrial
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
5
|
+
are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
Redistributions in binary form must reproduce the above copyright notice, this
|
|
11
|
+
list of conditions and the following disclaimer in the documentation and/or
|
|
12
|
+
other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
15
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
16
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
18
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
19
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
20
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
21
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
22
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
23
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright 2018 ROS Industrial Consortium
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
4
|
+
are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
7
|
+
list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation and/or
|
|
11
|
+
other materials provided with the distribution.
|
|
12
|
+
|
|
13
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
may be used to endorse or promote products derived from this software without
|
|
15
|
+
specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
21
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
24
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|