-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add first version of the package (#1)
- Loading branch information
1 parent
0f28d1c
commit 947d31d
Showing
8 changed files
with
278 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
name: CI Workflow | ||
|
||
on: | ||
push: | ||
pull_request: | ||
schedule: | ||
# * is a special character in YAML so you have to quote this string | ||
# Execute a "nightly" build at 2 AM UTC | ||
- cron: '0 2 * * *' | ||
|
||
jobs: | ||
build-with-conda-dependencies: | ||
name: '[conda:${{ matrix.os }}]' | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
build_type: [Release] | ||
os: [ubuntu-22.04, macos-latest, windows-2019] | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Print used environment (no conda) [Conda] | ||
shell: bash | ||
run: | | ||
env | ||
- uses: mamba-org/setup-micromamba@v1 | ||
with: | ||
environment-file: ci_env.yml | ||
|
||
- name: Install the package | ||
shell: bash -l {0} | ||
run: python -m pip install --no-deps . | ||
|
||
- name: Import the package | ||
shell: bash -l {0} | ||
run: python -c "import resolve_robotics_uri_py" | ||
|
||
# This test requires the conda-forge::icub-models, | ||
# robotology::ergocub-software and | ||
# robostack-staging::ros-humble-moveit-resources-panda-description | ||
# conda packages, that are installed in ci_env.yml environment | ||
- name: Check command line helper | ||
shell: bash -l {0} | ||
run: | | ||
resolve-robotics-uri-py package://iCub/robots/iCubGazeboV2_7/model.urdf | ||
resolve-robotics-uri-py package://ergoCub/robots/ergoCubSN000/model.urdf | ||
resolve-robotics-uri-py package://moveit_resources_panda_description/urdf/panda.urdf | ||
! resolve-robotics-uri-py package://this/file/does/not/exist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,53 @@ | ||
# resolve-robotics-uri-py | ||
Resolve a package:// or model:// URI to an absolute filename in Python. | ||
|
||
Pure Python package (that only depends on Python stdlib) to resolve a package:// (ROS-style) or model:// (Gazebo-style) URI to an absolute filename. | ||
|
||
## Installation | ||
|
||
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install resolve-robotics-uri-py. | ||
|
||
```bash | ||
python -m pip install git+https://github.com/ami-iit/resolve-robotics-uri-py | ||
``` | ||
|
||
## Usage in Python | ||
|
||
Add `import resolve_robotics_uri_py` to your Python file, then take inspiration from the following examples. | ||
|
||
If you want to get the location of the `iCubGazeboV2_7` iCub model installed from [`icub-models`](https://github.com/robotology/icub-models): | ||
|
||
~~~python | ||
absolute_path = resolve_robotics_uri_py.resolve_robotics_uri("package://iCub/robots/iCubGazeboV2_7/model.urdf") | ||
~~~ | ||
|
||
If you want to get the location of the `ergoCubSN00` model installed from [`ergocub-software`](https://github.com/icub-tech-iit/ergocub-software): | ||
|
||
~~~python | ||
absolute_path = resolve_robotics_uri_py.resolve_robotics_uri("package://ergoCub/robots/ergoCubSN000/model.urdf") | ||
~~~ | ||
|
||
If you want to get the location of the `panda` model installed by [`moveit_resources_panda_description`](https://index.ros.org/p/moveit_resources_panda_description/): | ||
|
||
~~~python | ||
absolute_path = resolve_robotics_uri_py.resolve_robotics_uri("package://moveit_resources_panda_description/urdf/panda.urdf") | ||
~~~ | ||
|
||
|
||
## Command Line usage | ||
|
||
`resolve_robotics_uri_py` also install a command line tool called `resolve-robotics-uri-py` for use in scripts, that can be used as: | ||
|
||
~~~ | ||
resolve-robotics-uri-py package://iCub/robots/iCubGazeboV2_7/model.urdf | ||
~~~ | ||
|
||
## Contributing | ||
|
||
Pull requests are welcome. For major changes, please open an issue first | ||
to discuss what you would like to change. | ||
|
||
Please make sure to update tests as appropriate. | ||
|
||
## License | ||
|
||
[BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name: testenv | ||
channels: | ||
- conda-forge | ||
- robotology | ||
- robostack-staging | ||
dependencies: | ||
- python | ||
- pip | ||
# packages that ship URDFs used to test | ||
- icub-models | ||
- ergocub-software | ||
- ros-humble-moveit-resources-panda-description |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[build-system] | ||
build-backend = "setuptools.build_meta" | ||
requires = [ | ||
"wheel", | ||
"setuptools>=45", | ||
"setuptools_scm[toml]>=6.2", | ||
] | ||
|
||
[tool.setuptools_scm] | ||
local_scheme = "dirty-tag" | ||
|
||
[tool.black] | ||
line-length = 88 | ||
|
||
[tool.isort] | ||
profile = "black" | ||
multi_line_output = 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
[metadata] | ||
name = resolve-robotics-uri-py | ||
description = Pure python package to solve ROS-style package:// and Gazebo-style model:// URIs in absolute paths. | ||
long_description = file: README.md | ||
long_description_content_type = text/markdown | ||
author = Silvio Traversaro | ||
author_email = [email protected] | ||
license = BSD | ||
license_files = LICENSE | ||
platforms = any | ||
url = https://github.com/ami-iit/resolve-robotics-uri-py | ||
|
||
project_urls = | ||
Changelog = https://github.com/ami-iit/resolve-robotics-uri-py/releases | ||
Source = https://github.com/ami-iit/resolve-robotics-uri-py | ||
Tracker = https://github.com/ami-iit/resolve-robotics-uri-py/issues | ||
|
||
keywords = | ||
|
||
classifiers = | ||
Development Status :: 4 - Beta | ||
Intended Audience :: Developers | ||
License :: OSI Approved :: BSD License | ||
Operating System :: POSIX :: Linux | ||
Operating System :: MacOS | ||
Operating System :: Microsoft | ||
Programming Language :: Python :: 3.8 | ||
Programming Language :: Python :: 3.9 | ||
Programming Language :: Python :: 3.10 | ||
Programming Language :: Python :: 3.11 | ||
Programming Language :: Python :: 3 :: Only | ||
Programming Language :: Python :: Implementation :: CPython | ||
Topic :: Software Development | ||
|
||
[options] | ||
zip_safe = False | ||
packages = find: | ||
package_dir = | ||
=src | ||
python_requires = >=3.8 | ||
install_requires = | ||
|
||
|
||
[options.packages.find] | ||
where = src | ||
|
||
[options.entry_points] | ||
console_scripts = | ||
resolve-robotics-uri-py = resolve_robotics_uri_py.resolve_robotics_uri_py:main | ||
|
||
[options.extras_require] | ||
style = | ||
black | ||
isort | ||
testing = | ||
all = | ||
%(style)s | ||
%(testing)s | ||
|
||
[tool:pytest] | ||
addopts = -rsxX -v --strict-markers | ||
testpaths = tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import setuptools | ||
|
||
setuptools.setup() |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import argparse | ||
import os | ||
import pathlib | ||
import sys | ||
from typing import List | ||
import warnings | ||
|
||
# Function inspired from https://github.com/ami-iit/robot-log-visualizer/pull/51 | ||
def get_search_paths_from_envs(env_list): | ||
return [ | ||
pathlib.Path(f) if (env != "AMENT_PREFIX_PATH") else pathlib.Path(f) / "share" | ||
for env in env_list if os.getenv(env) is not None | ||
for f in os.getenv(env).split(os.pathsep) | ||
] | ||
|
||
def pathlist_list_to_string(path_list): | ||
return ' '.join(str(path) for path in path_list) | ||
|
||
def resolve_robotics_uri(uri: str) -> pathlib.Path: | ||
# List of environment variables to consider, see: | ||
# * https://github.com/robotology/idyntree/issues/291 | ||
# * https://github.com/gazebosim/sdformat/issues/1234 | ||
# AMENT_PREFIX_PATH is the only "special" as we need to add | ||
# "share" after each value, see https://github.com/stack-of-tasks/pinocchio/issues/1520 | ||
# This list specify the origin of each env variable: | ||
# * GAZEBO_MODEL_PATH: Used in Gazebo Classic | ||
# * ROS_PACKAGE_PATH: Used in ROS1 | ||
# * AMENT_PREFIX_PATH: Used in ROS2 | ||
# * SDF_PATH: Used in sdformat | ||
# * IGN_GAZEBO_RESOURCE_PATH: Used in Ignition Gazebo <= 7 | ||
# * GZ_SIM_RESOURCE_PATH: Used in Gazebo Sim >= 7 | ||
env_list = ["GAZEBO_MODEL_PATH", "ROS_PACKAGE_PATH", "AMENT_PREFIX_PATH", "SDF_PATH", "IGN_GAZEBO_RESOURCE_PATH", "GZ_SIM_RESOURCE_PATH"] | ||
|
||
# Preliminary step: if there is no scheme, we just consider this a path and we return it as it is | ||
if "://" not in uri: | ||
return pathlib.Path(uri) | ||
|
||
# Get scheme from URI | ||
from urllib.parse import urlparse | ||
parsed_uri = urlparse(uri) | ||
|
||
# We only support at the moment: | ||
# file:// scheme: to pass a file path directly | ||
# package:// : ROS-style package URI | ||
# model:// : SDF-style model URI | ||
if parsed_uri.scheme not in ["file", "package", "model"]: | ||
raise FileNotFoundError(f"Passed URI \"{uri}\" use non-supported scheme {parsed_uri.scheme}") | ||
|
||
model_filenames = [] | ||
|
||
if parsed_uri.scheme == "file": | ||
model_filenames.append(uri.replace("file:/", "")) | ||
|
||
if parsed_uri.scheme == "package" or parsed_uri.scheme == "model": | ||
uri_path = uri.replace(f"{parsed_uri.scheme}://","") | ||
for folder in get_search_paths_from_envs(env_list): | ||
candidate_file_name = folder / pathlib.Path(uri_path) | ||
if (candidate_file_name.is_file()): | ||
if candidate_file_name not in model_filenames: | ||
model_filenames.append(candidate_file_name) | ||
|
||
if model_filenames: | ||
if (len(model_filenames) > 1): | ||
warnings.warn(f"resolve-robotics-uri-py: Multiple files ({pathlist_list_to_string(model_filenames)}) found for uri \"{uri}\", returning the first one.") | ||
return pathlib.Path(model_filenames[0]) | ||
|
||
# If no file was found raise error | ||
raise FileNotFoundError(f"resolve-robotics-uri-py: No file corresponding to uri \"{uri}\" found") | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description="Utility resolve a robotics URI (file://, model://, package://) to an absolute filename.") | ||
parser.add_argument("uri", metavar="uri", type=str, help="URI to resolve") | ||
|
||
args = parser.parse_args() | ||
result = resolve_robotics_uri(args.uri) | ||
|
||
print(result) | ||
sys.exit(0) | ||
|
||
if __name__ == "__main__": | ||
main() |