Skip to content

Commit a00c750

Browse files
zkingstontwill777wbthomason
authored
Add the FCIT* asymptotically optimal motion planner (#35)
* doc: note about incremental rebuilds * feat: initial implementation * feat: Python RNG functions * fix: Halton sequence blows up after around 1.5M iters - restart and rotate bases after 1M * wip: refactor names, remove old RNG code * feat: added xorshift * fix/feat: xorshift mapping fixed + sampling feature on other scripts * feat: final script fix + documentation * format: applied clang-format * Update LLVM version * goof, update format version * yapf format * Added fcit.hh * Got rid of unecessary left over function * Brought in support for fcit* * format * RNG refactor for FCIT * use pdqsort_branchless for a modest perf improvement * Add batch size and ASAO mode to settings for FCIT * Minor readability updates * changed simplification semantics so will work with FCIT paths * reducing uncessary scopes * Fixes after merge * format * Added paper link to README * Added other paper link to README * Addressing suggestions for PR: - Fixed "simplificiation" typo in README + Also changed "simplification_interpolation" in README to "simplification_interpolate" to reflect correct argument + Arguments not beginning in "simplification_" were being skipped in configure_robot_and_planner_with_kwargs -- fixed by changing a "continue" into an if statement - Changed "fcit_single"/"fcit" to "fcit"/"fcit_multi_goal" - Moved "QueueEdge" out of utils.hh and into fcit.hh + Should we also move "FCITRoadmapNode" out of roadmap.hh as well? It's only used by FCIT* - Changed "(*it)." to "it->" - Changed invalidList to an unordered_set (best results) * Moved FCITRoadmapNode out of roadmap.hh to fcit.hh * Update README.md Co-authored-by: Wil Thomason <[email protected]> * fix for yapf format check * Added FCIT arXiv information --------- Co-authored-by: twill777 <[email protected]> Co-authored-by: Wil Thomason <[email protected]>
1 parent 0d13c50 commit a00c750

File tree

13 files changed

+548
-30
lines changed

13 files changed

+548
-30
lines changed

README.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
[![arXiv VAMP](https://img.shields.io/badge/arXiv-2309.14545-b31b1b.svg)](https://arxiv.org/abs/2309.14545)
44
[![arXiv CAPT](https://img.shields.io/badge/arXiv-2406.02807-b31b1b.svg)](https://arxiv.org/abs/2406.02807)
5+
[![arXiv FCIT](https://img.shields.io/badge/arXiv-2411.17902-b31b1b.svg)](https://arxiv.org/abs/2411.17902)
56
[![Build Check](https://github.com/KavrakiLab/vamp/actions/workflows/build.yml/badge.svg)](https://github.com/KavrakiLab/vamp/actions/workflows/build.yml)
67
[![Format Check](https://github.com/KavrakiLab/vamp/actions/workflows/format.yml/badge.svg)](https://github.com/KavrakiLab/vamp/actions/workflows/format.yml)
78

8-
This repository hosts the code for the ICRA 2024 paper [“Motions in Microseconds via Vectorized Sampling-Based Planning”](https://arxiv.org/abs/2309.14545) as well as an implementation of the Collision-Affording Point Tree (CAPT) from the forthcoming RSS 2024 paper [“Collision-Affording Point Trees: SIMD-Amenable Nearest Neighbors for Fast Collision Checking”](http://arxiv.org/abs/2406.02807).
9+
This repository hosts the code for:
10+
- the ICRA 2024 paper [“Motions in Microseconds via Vectorized Sampling-Based Planning”](https://arxiv.org/abs/2309.14545),
11+
- an implementation of the Collision-Affording Point Tree (CAPT) from the RSS 2024 paper [“Collision-Affording Point Trees: SIMD-Amenable Nearest Neighbors for Fast Collision Checking”](http://arxiv.org/abs/2406.02807),
12+
- an implementation of the Fully Connected Informed Trees (FCIT*) algorithm from the ICRA 2025 submission [“Nearest-Neighbourless Asymptotically Optimal Motion Planning with Fully Connected Informed Trees (FCIT*)”](https://robotic-esp.com/papers/wilson_arxiv24).
913

1014
**TL;DR**: By exploiting ubiquitous [CPU SIMD instructions](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data) to accelerate collision checking and forward kinematics (FK), `vamp`'s RRT-Connect [[1]](#1) solves problems for the Franka Emika Panda from the MotionBenchMaker dataset [[3]](#3) at a median speed of 35 microseconds (on one core of a consumer desktop PC).
1115
This approach to hardware-accelerated parallel sampling-based motion planning extends to other planning algorithms without modification (e.g., PRM [[2]](#2)) and also works on low-power systems (e.g., an ARM-based [OrangePi](http://www.orangepi.org/)).
@@ -17,8 +21,10 @@ If you found this research useful for your own work, please use the following ci
1721
title = {Motions in Microseconds via Vectorized Sampling-Based Planning},
1822
author = {Thomason, Wil and Kingston, Zachary and Kavraki, Lydia E.},
1923
booktitle = {IEEE International Conference on Robotics and Automation},
20-
date = {2024},
24+
pages = {8749--8756},
2125
url = {http://arxiv.org/abs/2309.14545},
26+
doi = {10.1109/ICRA57147.2024.10611190},
27+
date = {2024},
2228
}
2329
```
2430

@@ -28,9 +34,19 @@ If you use CAPTs or the pointcloud collision checking components of this reposit
2834
title = {Collision-Affording Point Trees: {SIMD}-Amenable Nearest Neighbors for Fast Collision Checking},
2935
author = {Ramsey, Clayton W. and Kingston, Zachary and Thomason, Wil and Kavraki, Lydia E.},
3036
booktitle = {Robotics: Science and Systems},
31-
date = {2024},
3237
url = {http://arxiv.org/abs/2406.02807},
33-
note = {To Appear.}
38+
doi = {10.15607/RSS.2024.XX.038},
39+
date = {2024},
40+
}
41+
```
42+
43+
If you use FCIT*, please use the following citation:
44+
```bibtex
45+
@misc{fcit_2024,
46+
title = {Nearest-Neighbourless Asymptotically Optimal Motion Planning with Fully Connected Informed Trees (FCIT*)},
47+
author = {Wilson, Tyler S. and Thomason, Wil and Kingston, Zachary and Kavraki, Lydia E. and Gammell, Jonathan D.},
48+
url = {https://arxiv.org/abs/2411.17902},
49+
date = {2024}
3450
}
3551
```
3652

@@ -151,6 +167,7 @@ We ship implementations of the following pseudorandom number generators (PRNGs):
151167
We currently ship two planners:
152168
- `rrtc`, which is an implementation of a dynamic-domain [[6]](#6) balanced [[7]](#7) RRT-Connect [[1]](#1).
153169
- `prm`, which is an implementation of basic PRM [[2]](#2) (i.e., PRM without the bounce heuristic, etc.).
170+
- `fcit`, which is an asymptotically optimal planner, described in the [linked paper](https://robotic-esp.com/papers/wilson_arxiv24).
154171

155172
Note that these planners support planning to a set of goals, not just a single goal.
156173

@@ -183,17 +200,22 @@ For `rrtc`:
183200
- `--start_tree_first`: `True` or `False`, grow from start tree or goal tree first.
184201
See `rrtc_settings.hh` for more information.
185202

186-
For `prm`, the settings must be configured with a neighbor parameter structure, e.g.:
203+
For `prm` and `fcit`, the settings must be configured with a neighbor parameter structure, e.g.:
187204
```py
188205
robot_module = vamp.panda # or other robot submodule
189206
prmstar_params = vamp.PRMNeighborParams(robot_module.dimension(), robot_module.space_measure())
190207
prm_settings = vamp.PRMSettings(prmstar_params)
191208
```
192209
This is handled by default in the configuration function.
193210

211+
For `fcit`, there are also the settings:
212+
- `--batch_size`: The number of samples to evaluate in a batch per iteration. Default is 1000.
213+
- `--optimize`: If true, will use all iterations and samples available to find the best possible solution. Default is False. If true, set `--max_samples` to the desired value of refinement.
214+
194215
For simplification:
195216
- `--simplification_operations`: sequence of shortcutting heuristics to apply each iteration. By default, `[SHORTCUT,BSPLINE]`. Can specify any sequence of the above keys.
196-
- `--max_iterations`: maximum iterations of simplification. If no heuristics do any work, then early terminates from simplification.
217+
- `--simplification_max_iterations`: maximum iterations of simplification. If no heuristics do any work, then early terminates from simplification.
218+
- `--simplification_interpolate`: if non-zero, will interpolate the path before simplification heuristics are applied to the desired resolution.
197219
- `--bspline_max_steps`: maximum iterations of B-spline smoothing.
198220
- `--bspline_min_change`: minimum change before smoothing is done.
199221
- `--bspline_midpoint_interpolation`: point along each axis B-spline interpolation is done from.
@@ -250,6 +272,7 @@ Inside `impl/vamp`, the code is divided into the following directories:
250272
Planning and simplification routines.
251273
`rrtc.hh` and `rrtc_settings.hh` are for our RRT-Connect implementation.
252274
`prm.hh` and `roadmap.hh` are for our PRM implementation.
275+
`fcit.hh` is for the FCIT* implementation.
253276
`simplify.hh` and `simplify_settings.hh` are for simplification heuristics.
254277
`validate.hh` contains the raked motion validator.
255278

@@ -268,6 +291,7 @@ Inside `impl/vamp`, the code is divided into the following directories:
268291
- [X] Pointcloud collision checking
269292
- [ ] Manifold-constrained planning
270293
- [ ] Time-optimal trajectory parameterization
294+
- [X] Asymptotically-optimal planning
271295
- and more...
272296

273297
## References

resources/problem_tar_to_pkl_json.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,10 @@ def main(robot: str = "panda"):
121121
data['problems'][k] = [
122122
{
123123
**s, **r
124-
} for s,
125-
r in zip(
126-
sorted(scenes[k], key = lambda e: e['index']),
127-
sorted(requests[k], key = lambda e: e['index'])
128-
)
124+
} for (s, r) in zip(
125+
sorted(scenes[k], key = lambda e: e['index']),
126+
sorted(requests[k], key = lambda e: e['index'])
127+
)
129128
]
130129

131130
for problem in data['problems'][k]:

scripts/evaluate_mbm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def main(
1717
dataset: str = "problems.pkl", # Pickled dataset to use
1818
problem: Union[str, List[str]] = [], # Problem name or list of problems to evaluate
1919
trials: int = 1, # Number of trials to evaluate each instance
20-
sampler_name: str = "halton", # Sampler to use.
20+
sampler: str = "halton", # Sampler to use.
2121
skip_rng_iterations: int = 0, # Skip a number of RNG iterations
2222
print_failures: bool = False, # Print out failures and invalid problems
2323
pointcloud: bool = False, # Use pointcloud rather than primitive geometry
@@ -50,7 +50,7 @@ def main(
5050
(vamp_module, planner_func, plan_settings,
5151
simp_settings) = vamp.configure_robot_and_planner_with_kwargs(robot, planner, **kwargs)
5252

53-
sampler = getattr(vamp_module, sampler_name)()
53+
sampler = getattr(vamp_module, sampler)()
5454

5555
total_problems = 0
5656
valid_problems = 0

src/impl/vamp/bindings/common.hh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <vamp/planning/simplify.hh>
1616
#include <vamp/planning/plan.hh>
1717
#include <vamp/planning/prm.hh>
18+
#include <vamp/planning/fcit.hh>
1819
#include <vamp/planning/rrtc.hh>
1920
#include <vamp/vector.hh>
2021

@@ -103,6 +104,7 @@ namespace vamp::binding
103104

104105
using PRM = vamp::planning::PRM<Robot, rake, Robot::resolution>;
105106
using RRTC = vamp::planning::RRTC<Robot, rake, Robot::resolution>;
107+
using FCIT = vamp::planning::FCIT<Robot, rake, Robot::resolution>;
106108

107109
inline static auto halton() -> typename RNG::Ptr
108110
{
@@ -233,6 +235,36 @@ namespace vamp::binding
233235
return PRM::solve(start_v, goals_v, EnvironmentVector(environment), settings, rng);
234236
}
235237

238+
inline static auto fcit(
239+
const ConfigurationArray &start,
240+
const ConfigurationArray &goal,
241+
const EnvironmentInput &environment,
242+
const vamp::planning::RoadmapSettings<vamp::planning::FCITStarNeighborParams> &settings,
243+
typename RNG::Ptr rng) -> PlanningResult
244+
{
245+
return FCIT::solve(
246+
Configuration(start), Configuration(goal), EnvironmentVector(environment), settings, rng);
247+
}
248+
249+
inline static auto fcit_multi_goal(
250+
const ConfigurationArray &start,
251+
const std::vector<ConfigurationArray> &goals,
252+
const EnvironmentInput &environment,
253+
const vamp::planning::RoadmapSettings<vamp::planning::FCITStarNeighborParams> &settings,
254+
typename RNG::Ptr rng) -> PlanningResult
255+
{
256+
std::vector<Configuration> goals_v;
257+
goals_v.reserve(goals.size());
258+
259+
for (const auto &goal : goals)
260+
{
261+
goals_v.emplace_back(goal);
262+
}
263+
264+
const Configuration start_v(start);
265+
return FCIT::solve(start_v, goals_v, EnvironmentVector(environment), settings, rng);
266+
}
267+
236268
inline static auto roadmap(
237269
const ConfigurationArray &start,
238270
const ConfigurationArray &goal,
@@ -527,6 +559,26 @@ namespace vamp::binding
527559
"rng"_a,
528560
"Solve the motion planning problem with PRM.");
529561

562+
submodule.def(
563+
"fcit",
564+
RH::fcit,
565+
"start"_a,
566+
"goal"_a,
567+
"environment"_a,
568+
"settings"_a,
569+
"rng"_a,
570+
"Solve the motion planning problem with FCIT*.");
571+
572+
submodule.def(
573+
"fcit",
574+
RH::fcit_multi_goal,
575+
"start"_a,
576+
"goal"_a,
577+
"environment"_a,
578+
"settings"_a,
579+
"rng"_a,
580+
"Solve the motion planning problem with FCIT*.");
581+
530582
submodule.def(
531583
"roadmap",
532584
RH::roadmap,

src/impl/vamp/bindings/settings.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ void vamp::binding::init_settings(nanobind::module_ &pymodule)
4242
.def("max_neighbors", &PRMStarSettings::max_neighbors)
4343
.def("neighbor_radius", &PRMStarSettings::neighbor_radius);
4444

45+
nb::class_<vp::FCITStarNeighborParams>(pymodule, "FCITNeighborParams")
46+
.def(nb::init<std::size_t, double>())
47+
.def_rw("dim", &vp::FCITStarNeighborParams::dim)
48+
.def_rw("space_measure", &vp::FCITStarNeighborParams::space_measure)
49+
.def_rw("gamma_scale", &vp::FCITStarNeighborParams::gamma_scale)
50+
.def("max_neighbors", &vp::FCITStarNeighborParams::max_neighbors)
51+
.def("neighbor_radius", &vp::FCITStarNeighborParams::neighbor_radius);
52+
53+
using FCITStarSettings = vp::RoadmapSettings<vp::FCITStarNeighborParams>;
54+
nb::class_<FCITStarSettings>(pymodule, "FCITSettings")
55+
.def(nb::init<vp::FCITStarNeighborParams>())
56+
.def_rw("max_iterations", &FCITStarSettings::max_iterations)
57+
.def_rw("max_samples", &FCITStarSettings::max_samples)
58+
.def_rw("batch_size", &FCITStarSettings::batch_size)
59+
.def_rw("optimize", &FCITStarSettings::optimize)
60+
.def_rw("neighbor_params", &FCITStarSettings::neighbor_params)
61+
.def("max_neighbors", &FCITStarSettings::max_neighbors)
62+
.def("neighbor_radius", &FCITStarSettings::neighbor_radius);
63+
4564
nb::enum_<vp::SimplifyRoutine>(pymodule, "SimplifyRoutine")
4665
.value("BSPLINE", vp::SimplifyRoutine::BSPLINE)
4766
.value("REDUCE", vp::SimplifyRoutine::REDUCE)
@@ -73,6 +92,7 @@ void vamp::binding::init_settings(nanobind::module_ &pymodule)
7392
nb::class_<vp::SimplifySettings>(pymodule, "SimplifySettings")
7493
.def(nb::init<>())
7594
.def_rw("max_iterations", &vp::SimplifySettings::max_iterations)
95+
.def_rw("interpolate", &vp::SimplifySettings::interpolate)
7696
.def_rw("operations", &vp::SimplifySettings::operations)
7797
.def_rw("reduce", &vp::SimplifySettings::reduce)
7898
.def_rw("shortcut", &vp::SimplifySettings::shortcut)

0 commit comments

Comments
 (0)