Skip to content

Commit 6bf4609

Browse files
committed
Initial release
1 parent 2601e68 commit 6bf4609

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+5949
-1
lines changed

.clang-format

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2+
#
3+
# NVIDIA CORPORATION and its licensors retain all intellectual property
4+
# and proprietary rights in and to this software, related documentation
5+
# and any modifications thereto. Any use, reproduction, disclosure or
6+
# distribution of this software and related documentation without an express
7+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
8+
9+
BasedOnStyle: Google
10+
ColumnLimit: 100
11+
AllowShortFunctionsOnASingleLine: Inline
12+
13+
# Google style doesn't specify a pointer and reference whitespace alignment: it allows both but
14+
# recommends consistency. We chose to enforce the style for pointers and references to be on the
15+
# left, that is to the type, with a whitespace after.
16+
DerivePointerAlignment: false
17+
PointerAlignment: Left
18+
19+
IncludeBlocks: Preserve
20+
SortIncludes: CaseInsensitive
21+
AlignAfterOpenBracket: AlwaysBreak

.gitattributes

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Images
2+
*.gif filter=lfs diff=lfs merge=lfs -text
3+
*.jpg filter=lfs diff=lfs merge=lfs -text
4+
*.png filter=lfs diff=lfs merge=lfs -text
5+
*.psd filter=lfs diff=lfs merge=lfs -text
6+
# Archives
7+
*.gz filter=lfs diff=lfs merge=lfs -text
8+
*.tar filter=lfs diff=lfs merge=lfs -text
9+
*.zip filter=lfs diff=lfs merge=lfs -text
10+
# Documents
11+
*.pdf filter=lfs diff=lfs merge=lfs -text
12+
# Shared libraries
13+
*.so filter=lfs diff=lfs merge=lfs -text
14+
*.so.* filter=lfs diff=lfs merge=lfs -text
15+
docs/images/skeleton_only.png filter=lfs diff=lfs merge=lfs -text
16+
docs/images/carter_warehouse_navigation.png filter=lfs diff=lfs merge=lfs -text
17+
docs/images/free_space_sampling.png filter=lfs diff=lfs merge=lfs -text
18+
docs/images/inflated_map.png filter=lfs diff=lfs merge=lfs -text
19+
docs/images/prune.png filter=lfs diff=lfs merge=lfs -text
20+
docs/images/shortcut.png filter=lfs diff=lfs merge=lfs -text
21+
docs/images/skeleton_and_boundary.png filter=lfs diff=lfs merge=lfs -text
22+
docs/images/coordinate_transform.png filter=lfs diff=lfs merge=lfs -text
23+
docs/images/generation_in_action.gif filter=lfs diff=lfs merge=lfs -text
24+
maps/carter_warehouse_navigation.png filter=lfs diff=lfs merge=lfs -text
25+
maps/large_warehouse.png filter=lfs diff=lfs merge=lfs -text

.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Virtual Environment
24+
venv/
25+
env/
26+
ENV/
27+
28+
# IDE
29+
.idea/
30+
.vscode/
31+
*.swp
32+
*.swo
33+
34+
# Project specific
35+
graphs/*
36+
results/*
37+
visualizations/*
38+
39+
# OS specific
40+
.DS_Store
41+
Thumbs.db
42+
43+
# Cupy
44+
cufile.log

.pre-commit-config.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
repos:
2+
- repo: https://github.com/python/black
3+
rev: 25.1.0
4+
hooks:
5+
- id: black
6+
args: ["--line-length", "120", "--preview"]
7+
- repo: https://github.com/pycqa/flake8
8+
rev: 7.2.0
9+
hooks:
10+
- id: flake8
11+
additional_dependencies: [flake8-simplify, flake8-return]
12+
args: ["--max-line-length", "120"]
13+
- repo: https://github.com/pre-commit/pre-commit-hooks
14+
rev: v5.0.0
15+
hooks:
16+
- id: trailing-whitespace
17+
- id: check-symlinks
18+
- id: destroyed-symlinks
19+
- id: check-yaml
20+
- id: check-merge-conflict
21+
- id: check-case-conflict
22+
- id: check-executables-have-shebangs
23+
- id: check-toml
24+
- id: end-of-file-fixer
25+
- id: check-shebang-scripts-are-executable
26+
- id: detect-private-key
27+
- id: debug-statements
28+
- repo: https://github.com/pycqa/isort
29+
rev: 6.0.1
30+
hooks:
31+
- id: isort
32+
name: isort (python)
33+
args: ["--profile", "black", "--filter-files"]
34+
- repo: https://github.com/asottile/pyupgrade
35+
rev: v3.19.1
36+
hooks:
37+
- id: pyupgrade
38+
args: ["--py37-plus"]
39+
- repo: https://github.com/codespell-project/codespell
40+
rev: v2.4.1
41+
hooks:
42+
- id: codespell
43+
additional_dependencies:
44+
- tomli
45+
- repo: https://github.com/pre-commit/pygrep-hooks
46+
rev: v1.10.0
47+
hooks:
48+
- id: rst-backticks
49+
- id: rst-directive-colons
50+
- id: rst-inline-touching-normal
51+
- repo: https://github.com/pre-commit/mirrors-clang-format
52+
rev: v20.1.0
53+
hooks:
54+
- id: clang-format
55+
types_or: [c++, c, cuda]
56+
args: [--style=file]

README.md

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,170 @@
1-
# SWAGGER: Sparse WAypoint Graph Generator for Efficient Routing
1+
# SWAGGER: Sparse WAypoint Graph Generation for Efficient Routing
2+
3+
[![Python](https://img.shields.io/badge/python-3.10-blue.svg)](https://docs.python.org/3/whatsnew/3.10.html)
4+
[![Linux platform](https://img.shields.io/badge/ubuntu-22.04-red)](https://releases.ubuntu.com/22.04/)
5+
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://pre-commit.com/)
6+
7+
A Python package that generates sparse waypoint graphs from occupancy grid maps for route planning.
8+
9+
<img src="docs/images/generation_in_action.gif" alt="Graph Generation in Action" height="300"/>
10+
11+
See [algorithm overview](docs/algorithm.md) for an introduction of the method.
12+
13+
14+
## Table of Contents
15+
- [Algorithm Overview](docs/algorithm.md)
16+
- [System Requirements](#system-requirements)
17+
- [Installation](#installation)
18+
- [Set up the Environment](#set-up-the-environment)
19+
- [Install Package](#install-package)
20+
- [Usage](#usage)
21+
- [Data Prepration](#data-preparation)
22+
- [Tutorial and Examples](#tutorial-and-examples)
23+
- [Command Line Interface](#command-line-interface)
24+
- [Evaluation](#evaluation)
25+
- [REST API](#rest-api-service)
26+
- [Containerized Environment](#containerized-environment)
27+
- [Development](#development)
28+
- [Testing](#testing)
29+
- [Linting and Formatting](#linting-and-formatting)
30+
31+
32+
## System Requirements
33+
* Python 3.10 or newer
34+
* [CUDA 12.5](https://developer.nvidia.com/cuda-12-5-0-download-archive) or newer (including NVIDIA CUDA toolkit)
35+
36+
## Installation
37+
38+
### Set up the Environment
39+
40+
Choose one of the following methods to set up your environment:
41+
42+
1. Using Conda
43+
```bash
44+
conda create -n swagger python=3.10
45+
conda activate swagger
46+
```
47+
48+
2. Using Virtual Environment
49+
```bash
50+
python -m venv swagger
51+
source swagger/bin/activate
52+
```
53+
54+
55+
Clone the repository:
56+
57+
58+
59+
```bash
60+
git clone git@github.com:nvidia-isaac/SWAGGER.git
61+
cd SWAGGER
62+
git lfs pull
63+
```
64+
65+
### Install Package
66+
```bash
67+
sudo apt update && sudo apt install -y libgl1-mesa-glx libglib2.0-0
68+
pip install -e . # Install in development mode
69+
```
70+
71+
## Usage
72+
73+
### Data Preparation
74+
75+
The following data is required for waypoint graph generation:
76+
77+
* **Occupancy Grid Map**:
78+
* **Image Format**: A grayscale image where each pixel represents the occupancy probability in a 2D world:
79+
* 0 (black) = completely occupied
80+
* 255 (white) = completely free
81+
* **Occupancy Threshold**: A value that determines which pixels are considered free space. Pixels with values above this threshold will be used for graph generation.
82+
83+
* **Robot Parameters**:
84+
* **Safety Distance**: The minimum distance (in meters) that graph nodes and edges must maintain from obstacles to ensure safe robot navigation.
85+
86+
* **Coordinate Transform**: Parameters to convert pixel coordinates to real-world coordinates:
87+
* **Resolution**: The size of each pixel in meters (meters/pixel)
88+
* **X Offset**: The X coordinate of the bottom-left pixel in the world frame in meters.
89+
* **Y Offset**: The Y coordinate of the bottom-left pixel in the world frame in meters.
90+
* **Rotation**: Rotation angle from image frame to world frame in radians.
91+
92+
#### Coordinate Transform
93+
94+
In the image frame:
95+
- Origin (0,0) is at the top-left corner
96+
- X-axis points down (rows)
97+
- Y-axis points right (columns)
98+
99+
When converting from image to world coordinates:
100+
1. Image coordinates are scaled by the resolution to convert from pixels to meters
101+
2. Rotation is applied around the origin using the provided rotation angle
102+
3. X and Y offsets are added to translate the coordinates to the final world position
103+
104+
![coordinate_transform](docs/images/coordinate_transform.png)
105+
106+
### Command Line Interface
107+
Generate a waypoint graph from an occupancy grid map:
108+
```bash
109+
python scripts/generate_graph.py \
110+
--map-path <path_to_map.png> \
111+
--resolution <meters_per_pixel> \
112+
--safety-distance <meters> \
113+
--output-dir <output_directory>
114+
```
115+
116+
Default parameters:
117+
- Map: `maps/carter_warehouse_navigation.png`
118+
- Resolution: 0.05 meters/pixel
119+
- Safety distance: 0.3 meters
120+
121+
Outputs:
122+
- `<output_dir>/waypoint_graph.png`: Visualization of the generated graph
123+
- `<output_dir>/graph.gml`: Graph data in GML format
124+
125+
### Evaluation
126+
127+
To evaluate the graph, see the tutorial on [evaluation](docs/evaluation.md).
128+
129+
### REST API Service
130+
131+
Start the service locally:
132+
```bash
133+
python scripts/rest_api.py
134+
```
135+
136+
The service will be available at `http://localhost:8000`. Visit `http://localhost:8000/v1/docs` in your browser to view the interactive API documentation. If accessing from a different machine, replace `localhost` with the host name or the IP address of the server running the REST API. For more information about the REST API, check out the [tutorial](docs/tutorial.md#rest-api).
137+
138+
The REST API is also available as a docker compose service.
139+
140+
```bash
141+
cd docker
142+
docker compose build swagger
143+
docker compose up rest-api
144+
```
145+
146+
We provide a sample script, `scripts/test_api_client.py`, to demonstrate the usage the REST API service. With the REST API service running in a separate terminal, run the following command in your virtual environment:
147+
```bash
148+
python scripts/test_api_client.py --map_path maps/carter_warehouse_navigation.png
149+
```
150+
151+
152+
### Tutorial
153+
154+
This [tutorial](docs/tutorial.md) provides a comprehensive guide on how to use the SWAGGER library, including graph building, visualization, route finding, parameter tuning, and using both the Python API and REST API interfaces.
155+
156+
157+
## Development
158+
159+
### Testing
160+
```bash
161+
python -m unittest
162+
```
163+
164+
### Linting and Formatting
165+
This project uses pre-commit hooks for linting and formatting:
166+
```bash
167+
pip install pre-commit
168+
pre-commit install
169+
pre-commit run --all-files # Run manually
170+
```

0 commit comments

Comments
 (0)