sstsr 2.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.
- sstsr-2.0.0/.github/CODEOWNERS +1 -0
- sstsr-2.0.0/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
- sstsr-2.0.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- sstsr-2.0.0/.github/ISSUE_TEMPLATE/improvement.md +13 -0
- sstsr-2.0.0/.github/ISSUE_TEMPLATE/task.md +12 -0
- sstsr-2.0.0/.github/pull_request_template.md +24 -0
- sstsr-2.0.0/.github/workflows/ci.yml +53 -0
- sstsr-2.0.0/.github/workflows/release.yml +110 -0
- sstsr-2.0.0/.gitignore +217 -0
- sstsr-2.0.0/CHANGELOG.md +66 -0
- sstsr-2.0.0/CODE_OF_CONDUCT.md +13 -0
- sstsr-2.0.0/CONTRIBUTING.md +50 -0
- sstsr-2.0.0/CONTRIBUTORS.md +11 -0
- sstsr-2.0.0/LICENSE +24 -0
- sstsr-2.0.0/PKG-INFO +318 -0
- sstsr-2.0.0/README.md +278 -0
- sstsr-2.0.0/SECURITY.md +7 -0
- sstsr-2.0.0/assets/mesh_placements.png +0 -0
- sstsr-2.0.0/assets/stable_placements.png +0 -0
- sstsr-2.0.0/assets/tsr_grasps.png +0 -0
- sstsr-2.0.0/docs/ARCHITECTURE.md +61 -0
- sstsr-2.0.0/docs/REVIEW.md +96 -0
- sstsr-2.0.0/docs/figures/fig1_tsr_concept.png +0 -0
- sstsr-2.0.0/docs/figures/fig2_coordinate_frames.png +0 -0
- sstsr-2.0.0/docs/figures/fig3_bounds_matrix.png +0 -0
- sstsr-2.0.0/docs/figures/fig4_primitives.png +0 -0
- sstsr-2.0.0/docs/figures/fig5_tsr_chain.png +0 -0
- sstsr-2.0.0/docs/figures/fig6_placement_example.png +0 -0
- sstsr-2.0.0/docs/figures/generate_figures.py +743 -0
- sstsr-2.0.0/docs/tutorial.md +657 -0
- sstsr-2.0.0/examples/basic_tsr.py +81 -0
- sstsr-2.0.0/examples/mesh_placements.py +324 -0
- sstsr-2.0.0/examples/parallel_jaw_grasp.py +143 -0
- sstsr-2.0.0/examples/stable_placements.py +165 -0
- sstsr-2.0.0/examples/task_templates.py +85 -0
- sstsr-2.0.0/examples/tsr_chains.py +109 -0
- sstsr-2.0.0/pyproject.toml +110 -0
- sstsr-2.0.0/src/tsr/__init__.py +104 -0
- sstsr-2.0.0/src/tsr/core/__init__.py +35 -0
- sstsr-2.0.0/src/tsr/core/tsr.py +550 -0
- sstsr-2.0.0/src/tsr/core/tsr_chain.py +249 -0
- sstsr-2.0.0/src/tsr/core/utils.py +108 -0
- sstsr-2.0.0/src/tsr/hands/__init__.py +30 -0
- sstsr-2.0.0/src/tsr/hands/base.py +652 -0
- sstsr-2.0.0/src/tsr/hands/parallel_jaw.py +1302 -0
- sstsr-2.0.0/src/tsr/hands/registry.py +92 -0
- sstsr-2.0.0/src/tsr/io.py +99 -0
- sstsr-2.0.0/src/tsr/placement/__init__.py +20 -0
- sstsr-2.0.0/src/tsr/placement/_stable_poses.py +166 -0
- sstsr-2.0.0/src/tsr/placement/stable_placer.py +309 -0
- sstsr-2.0.0/src/tsr/sampling.py +251 -0
- sstsr-2.0.0/src/tsr/template.py +157 -0
- sstsr-2.0.0/src/tsr/templates/README.md +60 -0
- sstsr-2.0.0/src/tsr/templates/grasps/mug_handle_grasp.yaml +54 -0
- sstsr-2.0.0/src/tsr/templates/grasps/screwdriver_grasp.yaml +54 -0
- sstsr-2.0.0/src/tsr/templates/places/mug_on_table.yaml +52 -0
- sstsr-2.0.0/src/tsr/templates/places/toolchest_drop.yaml +55 -0
- sstsr-2.0.0/src/tsr/templates/tasks/drive_screw.yaml +55 -0
- sstsr-2.0.0/src/tsr/templates/tasks/mug_pour_into_sink.yaml +55 -0
- sstsr-2.0.0/src/tsr/templates/tasks/mug_transport_upright.yaml +55 -0
- sstsr-2.0.0/src/tsr/tsr.py +12 -0
- sstsr-2.0.0/src/tsr/tsr_chain.py +12 -0
- sstsr-2.0.0/src/tsr/utils.py +24 -0
- sstsr-2.0.0/src/tsr/viz.py +685 -0
- sstsr-2.0.0/tests/README.md +143 -0
- sstsr-2.0.0/tests/__init__.py +0 -0
- sstsr-2.0.0/tests/benchmarks/__init__.py +4 -0
- sstsr-2.0.0/tests/benchmarks/test_performance.py +179 -0
- sstsr-2.0.0/tests/tsr/__init__.py +0 -0
- sstsr-2.0.0/tests/tsr/_hypothesis_strategies.py +91 -0
- sstsr-2.0.0/tests/tsr/hands/__init__.py +0 -0
- sstsr-2.0.0/tests/tsr/hands/test_box_grasp.py +326 -0
- sstsr-2.0.0/tests/tsr/hands/test_parallel_jaw.py +257 -0
- sstsr-2.0.0/tests/tsr/hands/test_registry.py +63 -0
- sstsr-2.0.0/tests/tsr/hands/test_robotiq.py +48 -0
- sstsr-2.0.0/tests/tsr/hands/test_robotiq_2f85.py +58 -0
- sstsr-2.0.0/tests/tsr/hands/test_sphere_grasp.py +140 -0
- sstsr-2.0.0/tests/tsr/hands/test_torus_grasp.py +260 -0
- sstsr-2.0.0/tests/tsr/placement/__init__.py +0 -0
- sstsr-2.0.0/tests/tsr/placement/test_stable_placer.py +426 -0
- sstsr-2.0.0/tests/tsr/test_architecture.py +54 -0
- sstsr-2.0.0/tests/tsr/test_property_core.py +155 -0
- sstsr-2.0.0/tests/tsr/test_property_factories.py +155 -0
- sstsr-2.0.0/tests/tsr/test_regressions.py +109 -0
- sstsr-2.0.0/tests/tsr/test_sampling.py +338 -0
- sstsr-2.0.0/tests/tsr/test_serialization.py +356 -0
- sstsr-2.0.0/tests/tsr/test_tsr.py +426 -0
- sstsr-2.0.0/tests/tsr/test_tsr_chain.py +439 -0
- sstsr-2.0.0/tests/tsr/test_tsr_template.py +379 -0
- sstsr-2.0.0/tests/tsr/test_utils.py +194 -0
- sstsr-2.0.0/uv.lock +1617 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @siddhss5
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a reproducible bug
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Environment
|
|
8
|
+
- OS:
|
|
9
|
+
- Python version:
|
|
10
|
+
- uv version:
|
|
11
|
+
- Package version or commit:
|
|
12
|
+
|
|
13
|
+
## Reproduction
|
|
14
|
+
<!-- Minimal steps to reproduce the problem. -->
|
|
15
|
+
|
|
16
|
+
## Expected behavior
|
|
17
|
+
|
|
18
|
+
## Actual behavior
|
|
19
|
+
|
|
20
|
+
## Logs / traceback
|
|
21
|
+
```
|
|
22
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Improvement
|
|
3
|
+
about: Propose an enhancement to existing functionality
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Motivation
|
|
8
|
+
<!-- What problem or limitation prompts this improvement? -->
|
|
9
|
+
|
|
10
|
+
## Proposal
|
|
11
|
+
<!-- What should change, concretely? -->
|
|
12
|
+
|
|
13
|
+
## Alternatives considered
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences describing what this PR does and why. -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bulleted list of the concrete changes made. -->
|
|
8
|
+
-
|
|
9
|
+
|
|
10
|
+
## Testing
|
|
11
|
+
|
|
12
|
+
- [ ] `uv run pytest tests/ -v` passes
|
|
13
|
+
- [ ] `uv run ruff check .` passes
|
|
14
|
+
- [ ] `uv run ruff format --check .` passes
|
|
15
|
+
- [ ] Integration tested locally against the robot-code workspace (if cross-repo)
|
|
16
|
+
|
|
17
|
+
## Breaking changes
|
|
18
|
+
|
|
19
|
+
- [ ] None
|
|
20
|
+
- [ ] Yes (describe migration below):
|
|
21
|
+
|
|
22
|
+
## Related issues
|
|
23
|
+
|
|
24
|
+
<!-- e.g. Fixes #123, Part of personalrobotics/robot-code#3 -->
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
python-version: ${{ matrix.python-version }}
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: uv sync --all-extras --dev
|
|
32
|
+
|
|
33
|
+
- name: Ruff lint
|
|
34
|
+
run: uv run ruff check .
|
|
35
|
+
|
|
36
|
+
- name: Ruff format check
|
|
37
|
+
run: uv run ruff format --check .
|
|
38
|
+
|
|
39
|
+
- name: Pytest
|
|
40
|
+
run: uv run pytest tests/ -v
|
|
41
|
+
|
|
42
|
+
notify-robot-code:
|
|
43
|
+
needs: test
|
|
44
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- name: Dispatch integration run
|
|
48
|
+
uses: peter-evans/repository-dispatch@v3
|
|
49
|
+
with:
|
|
50
|
+
token: ${{ secrets.ROBOT_CODE_DISPATCH_TOKEN }}
|
|
51
|
+
repository: personalrobotics/robot-code
|
|
52
|
+
event-type: sibling-updated
|
|
53
|
+
client-payload: '{"repo":"${{ github.event.repository.name }}","sha":"${{ github.sha }}"}'
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Tag-driven release pipeline.
|
|
4
|
+
#
|
|
5
|
+
# Tag patterns:
|
|
6
|
+
# v*rc* -> build sdist + wheel, publish to TestPyPI (dry run)
|
|
7
|
+
# v* -> build sdist + wheel, publish to real PyPI + GitHub Release
|
|
8
|
+
# (manual workflow_dispatch also builds + publishes to TestPyPI)
|
|
9
|
+
#
|
|
10
|
+
# Auth: Trusted Publishing (PyPI / TestPyPI OIDC). No API tokens in CI.
|
|
11
|
+
# The publish jobs run inside named GitHub environments (`release` /
|
|
12
|
+
# `testpypi-release`) so the org's environment-protection rules apply.
|
|
13
|
+
#
|
|
14
|
+
# sstsr is pure Python, so a single `uv build` produces both artifacts.
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
tags: ["v*"]
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
build:
|
|
26
|
+
name: Build sdist + wheel
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 0
|
|
32
|
+
|
|
33
|
+
- name: Set up uv
|
|
34
|
+
uses: astral-sh/setup-uv@v5
|
|
35
|
+
|
|
36
|
+
- name: Build
|
|
37
|
+
run: uv build
|
|
38
|
+
|
|
39
|
+
- name: Check metadata
|
|
40
|
+
run: uvx twine check dist/*
|
|
41
|
+
|
|
42
|
+
- name: Upload artifacts
|
|
43
|
+
uses: actions/upload-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist/*
|
|
47
|
+
|
|
48
|
+
publish_testpypi:
|
|
49
|
+
name: Publish → TestPyPI
|
|
50
|
+
needs: build
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
# RC tags (e.g. v2.0.0rc1) and manual triggers. The real PyPI job runs on
|
|
53
|
+
# non-RC v* tags only.
|
|
54
|
+
if: contains(github.ref, 'rc') || github.event_name == 'workflow_dispatch'
|
|
55
|
+
environment:
|
|
56
|
+
name: testpypi-release
|
|
57
|
+
url: https://test.pypi.org/p/sstsr
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write # Trusted Publishing OIDC
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/download-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
name: dist
|
|
64
|
+
path: dist
|
|
65
|
+
|
|
66
|
+
- name: Publish to TestPyPI
|
|
67
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
68
|
+
with:
|
|
69
|
+
repository-url: https://test.pypi.org/legacy/
|
|
70
|
+
|
|
71
|
+
publish_pypi:
|
|
72
|
+
name: Publish → PyPI
|
|
73
|
+
needs: build
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
# Real PyPI: only on v* tags that DON'T contain 'rc' (e.g. v2.0.0).
|
|
76
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'rc')
|
|
77
|
+
environment:
|
|
78
|
+
name: release
|
|
79
|
+
url: https://pypi.org/p/sstsr
|
|
80
|
+
permissions:
|
|
81
|
+
id-token: write
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/download-artifact@v4
|
|
84
|
+
with:
|
|
85
|
+
name: dist
|
|
86
|
+
path: dist
|
|
87
|
+
|
|
88
|
+
- name: Publish to PyPI
|
|
89
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
90
|
+
|
|
91
|
+
github_release:
|
|
92
|
+
name: Create GitHub Release
|
|
93
|
+
needs: publish_pypi
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'rc')
|
|
96
|
+
permissions:
|
|
97
|
+
contents: write
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@v4
|
|
100
|
+
with:
|
|
101
|
+
fetch-depth: 0
|
|
102
|
+
|
|
103
|
+
- name: Create Release
|
|
104
|
+
uses: softprops/action-gh-release@v2
|
|
105
|
+
with:
|
|
106
|
+
tag_name: ${{ github.ref_name }}
|
|
107
|
+
name: sstsr ${{ github.ref_name }}
|
|
108
|
+
generate_release_notes: true
|
|
109
|
+
draft: false
|
|
110
|
+
prerelease: false
|
sstsr-2.0.0/.gitignore
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be added to the global gitignore or merged into this project gitignore. For a PyCharm
|
|
158
|
+
# project, it is recommended to include the following files in version control:
|
|
159
|
+
# - .idea/modules.xml
|
|
160
|
+
# - .idea/*.iml
|
|
161
|
+
# - .idea/misc.xml
|
|
162
|
+
# - .idea/vcs.xml
|
|
163
|
+
# - .idea/workspace.xml
|
|
164
|
+
# - .idea/tasks.xml
|
|
165
|
+
# - .idea/usage.statistics.xml
|
|
166
|
+
# - .idea/shelf
|
|
167
|
+
# - .idea/dictionaries
|
|
168
|
+
# - .idea/inspectionProfiles
|
|
169
|
+
# - .idea/libraries
|
|
170
|
+
# - .idea/runConfigurations
|
|
171
|
+
# - .idea/scopes
|
|
172
|
+
# - .idea/tools
|
|
173
|
+
# - .idea/uiDesigner.xml
|
|
174
|
+
# - .idea/artifacts
|
|
175
|
+
# - .idea/compiler.xml
|
|
176
|
+
# - .idea/libraries with .xml
|
|
177
|
+
# - .idea/jarRepositories.xml
|
|
178
|
+
# - .idea/encodings.xml
|
|
179
|
+
# - .idea/misc.xml
|
|
180
|
+
# - .idea/modules.xml
|
|
181
|
+
# - .idea/*.iml
|
|
182
|
+
# - .idea/modules
|
|
183
|
+
# - *.iml
|
|
184
|
+
# - *.ipr
|
|
185
|
+
.idea/
|
|
186
|
+
|
|
187
|
+
# VS Code
|
|
188
|
+
.vscode/
|
|
189
|
+
|
|
190
|
+
# macOS
|
|
191
|
+
.DS_Store
|
|
192
|
+
.AppleDouble
|
|
193
|
+
.LSOverride
|
|
194
|
+
|
|
195
|
+
# Windows
|
|
196
|
+
Thumbs.db
|
|
197
|
+
ehthumbs.db
|
|
198
|
+
Desktop.ini
|
|
199
|
+
|
|
200
|
+
# Linux
|
|
201
|
+
*~
|
|
202
|
+
|
|
203
|
+
# ROS specific (if any remnants)
|
|
204
|
+
*.launch
|
|
205
|
+
*.urdf
|
|
206
|
+
*.sdf
|
|
207
|
+
*.world
|
|
208
|
+
|
|
209
|
+
# Temporary files
|
|
210
|
+
*.tmp
|
|
211
|
+
*.temp
|
|
212
|
+
*.swp
|
|
213
|
+
*.swo
|
|
214
|
+
*~
|
|
215
|
+
|
|
216
|
+
# uv specific
|
|
217
|
+
.uv/
|
sstsr-2.0.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [2.0.0] — 2026-09
|
|
8
|
+
|
|
9
|
+
First PyPI release. The distribution is named **`sstsr`** (the name `tsr` was
|
|
10
|
+
already taken); the import name is unchanged — `import tsr`.
|
|
11
|
+
|
|
12
|
+
### Packaging & licensing
|
|
13
|
+
- **Distribution renamed to `sstsr`.** `pip install sstsr`, then `import tsr`.
|
|
14
|
+
- **Relicensed to BSD-2-Clause**, matching the original PrPy/OpenRAVE-derived TSR
|
|
15
|
+
core (resolves the prior README-vs-LICENSE mismatch).
|
|
16
|
+
- Grasp/hand classes (`ParallelJawGripper`, `Robotiq2F85`, `Robotiq2F140`,
|
|
17
|
+
`FrankaHand`) are now exported at the top level alongside `StablePlacer`.
|
|
18
|
+
- `tsr.__version__` is now available.
|
|
19
|
+
- Tested on Python 3.10–3.14 (classifiers and CI matrix extended to 3.13 and 3.14).
|
|
20
|
+
|
|
21
|
+
### Breaking changes
|
|
22
|
+
- **`TablePlacer` removed** — use `tsr.placement.StablePlacer`.
|
|
23
|
+
- **`TSRChain.contains()` uses AND semantics** — a transform must satisfy all
|
|
24
|
+
TSRs in the chain simultaneously (was OR).
|
|
25
|
+
- **Grasp factories return `[]` for infeasible geometry instead of raising.**
|
|
26
|
+
`grasp_cylinder_*` and `grasp_sphere` previously raised `ValueError` when the
|
|
27
|
+
object exceeded the aperture; they now return `[]`, consistent with the box and
|
|
28
|
+
torus factories. Exceptions are reserved for invalid *arguments* (non-positive
|
|
29
|
+
sizes, `k < 1`, reversed `angle_range`). See `docs/ARCHITECTURE.md`.
|
|
30
|
+
- **Gripper geometry corrections** (change sampled poses for existing callers):
|
|
31
|
+
`Robotiq2F140` frame correction and `finger_length`; `FrankaHand.finger_length`
|
|
32
|
+
corrected to 54 mm; clearance is now scaled by graspable depth, not
|
|
33
|
+
`finger_length`.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- **RPY near gimbal lock** (`rot_to_rpy`, `rot_within_rpy_bounds`): the
|
|
37
|
+
singularity threshold was far too wide (`1e-3`), snapping pitch to ±90° up to
|
|
38
|
+
~2.5° early and discarding up to 0.04 rad of rotation. This made `contains()`
|
|
39
|
+
reject poses that `sample()` produced. Tightened to a true-singularity
|
|
40
|
+
threshold; round-trip error dropped from ~0.04 to ~1e-13.
|
|
41
|
+
- **`StablePlacer.place_mesh` seating**: objects whose center of mass is not at
|
|
42
|
+
the object-frame origin floated above or sank through the table. The resting
|
|
43
|
+
face now sits at `z = 0` for any COM.
|
|
44
|
+
- **`wrap_to_interval`** now guarantees a result in `[lower, lower + 2π)` (a
|
|
45
|
+
floating-point modulo artifact could return exactly `lower + 2π`).
|
|
46
|
+
- **`TSRChain.distance`** no longer crashes on outer (wrapping) rotation
|
|
47
|
+
intervals, and a single-TSR chain's `contains()` uses the exact closed-form
|
|
48
|
+
check instead of the optimiser.
|
|
49
|
+
- Degenerate meshes (fewer than 4 points, coplanar) raise a clear `ValueError`
|
|
50
|
+
instead of a raw SciPy `QhullError`.
|
|
51
|
+
- `grasp_*(k=0)` raises `ValueError` instead of `IndexError`; reversed
|
|
52
|
+
`angle_range` raises instead of silently collapsing yaw freedom.
|
|
53
|
+
|
|
54
|
+
### Internal
|
|
55
|
+
- The pure-math core (`TSR`, `TSRChain`, SE(3) helpers) moved to a `tsr.core`
|
|
56
|
+
subpackage; deep imports such as `from tsr.tsr import TSR` still work via
|
|
57
|
+
back-compat shims.
|
|
58
|
+
- Added property-based tests (`hypothesis`) covering the core consistency
|
|
59
|
+
contract, serialization round-trips, and the factory invariants; added an
|
|
60
|
+
architecture-enforcement test (`tsr.core` has no upward imports; `import tsr`
|
|
61
|
+
pulls no heavy viz dependencies).
|
|
62
|
+
- Added `docs/REVIEW.md` (pre-release review) and `docs/ARCHITECTURE.md`.
|
|
63
|
+
- Removed the dead top-level `templates/` duplicate and the vestigial
|
|
64
|
+
`MANIFEST.in` (hatchling bundles the packaged `tsr/templates/` automatically).
|
|
65
|
+
|
|
66
|
+
[2.0.0]: https://github.com/personalrobotics/tsr/releases/tag/v2.0.0
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project adopts the [Contributor Covenant, version 2.1][cc].
|
|
4
|
+
|
|
5
|
+
The full text is available at <https://www.contributor-covenant.org/version/2/1/code_of_conduct/>.
|
|
6
|
+
|
|
7
|
+
## Reporting
|
|
8
|
+
|
|
9
|
+
Instances of unacceptable behavior may be reported privately to the project
|
|
10
|
+
maintainer at **siddhartha.srinivasa@gmail.com**. All reports will be
|
|
11
|
+
reviewed and investigated promptly and fairly.
|
|
12
|
+
|
|
13
|
+
[cc]: https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
This repository is part of the [robot-code workspace](https://github.com/personalrobotics/robot-code).
|
|
4
|
+
All projects in the workspace share a common layout (`src/` + `tests/`), a single
|
|
5
|
+
package manager (`uv`), and a common CI setup.
|
|
6
|
+
|
|
7
|
+
## Development setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/personalrobotics/robot-code
|
|
11
|
+
cd robot-code
|
|
12
|
+
./setup.sh
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This clones every sibling repo (including this one) into a single uv workspace
|
|
16
|
+
and runs `uv sync`. You can then work in any sibling's directory.
|
|
17
|
+
|
|
18
|
+
## Running tests and linters
|
|
19
|
+
|
|
20
|
+
From inside this repo:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv run pytest tests/ -v
|
|
24
|
+
uv run ruff check .
|
|
25
|
+
uv run ruff format --check .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
From the workspace root, you can also run the cross-repo integration suite:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv run pytest tests/integration -v
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Pull requests
|
|
35
|
+
|
|
36
|
+
- Branch from `main`. Open a PR with a clear summary and test plan.
|
|
37
|
+
- Per-repo CI (ruff + pytest) must pass.
|
|
38
|
+
- Cross-repo integration CI in robot-code runs automatically when this repo's
|
|
39
|
+
`main` advances, and on scheduled nightly runs.
|
|
40
|
+
- Review is by [@siddhss5](https://github.com/siddhss5) (enforced via CODEOWNERS).
|
|
41
|
+
|
|
42
|
+
## Package manager: uv only
|
|
43
|
+
|
|
44
|
+
We use [uv](https://docs.astral.sh/uv/) exclusively. **Do not use pip.**
|
|
45
|
+
The workspace layout in robot-code relies on uv's workspace resolution.
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
By contributing, you agree that your contributions will be licensed under the
|
|
50
|
+
MIT License (see [LICENSE](LICENSE)).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Contributors
|
|
2
|
+
|
|
3
|
+
This project builds on earlier work by the robotics community. We acknowledge
|
|
4
|
+
the following original authors and contributors:
|
|
5
|
+
|
|
6
|
+
- **Dmitry Berenson**, **Siddhartha Srinivasa**, **James Kuffner** — original
|
|
7
|
+
TSR formulation, [IJRR 2011](https://www.ri.cmu.edu/pub_files/2011/10/dmitry_ijrr10-1.pdf).
|
|
8
|
+
- **Michael Koval** (Carnegie Mellon University, 2013) — early Python TSR
|
|
9
|
+
implementation that seeded this package.
|
|
10
|
+
|
|
11
|
+
Please submit pull requests to be added to this list.
|
sstsr-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Siddhartha Srinivasa and contributors to TSR
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|