Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring #11

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions .github/workflows/runTests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

name: Unit Tests

on:
Expand All @@ -17,38 +16,41 @@ jobs:
include:
- name: ubuntu-gcc
os: ubuntu-latest
compiler_opt: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -G \"Unix Makefiles\""
compiler_opt: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++"
build_system: '-G Ninja'
- name: ubuntu-clang
os: ubuntu-latest
compiler_opt: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -G \"Unix Makefiles\""
compiler_opt: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
build_system: '-G Ninja'
- name: windows-VS
os: windows-latest
compiler_opt: ""
build_system: ""

runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/[email protected]
- name: Checkout submodules
run: git submodule update --init --recursive
- name: show HEAD
run: git rev-parse HEAD
- name: Install openMp
if: matrix.name == 'ubuntu-clang'
run: sudo apt-get update; sudo apt-get install -y libomp5 libomp-dev
- name: Install Ninja
if: matrix.build_system == '-G Ninja'
uses: seanmiddleditch/gha-setup-ninja@master
- name: CMake configure
run: cmake -B./build -DCMAKE_INSTALL_PREFIX:STRING=./artifacts/ -DBUILD_MT_RRT_SAMPLES=ON -DBUILD_MT_RRT_TESTS=ON -DENABLE_MT_RRT_TESTS_LOGGING=ON -DCMAKE_CONFIGURATION_TYPES="Release" -DCMAKE_BUILD_TYPE:STRING=Release ${{ matrix.compiler_opt }}
run: cmake -B./build -DCMAKE_INSTALL_PREFIX:STRING=./artifacts/ -D BUILD_MT_RRT_SAMPLES=ON -DBUILD_MT_RRT_TESTS=ON -DCMAKE_CONFIGURATION_TYPES="Release" -DCMAKE_BUILD_TYPE:STRING=Release ${{ matrix.build_system }} ${{ matrix.compiler_opt }}
- name: Build
run: cmake --build ./build --config Release
- name: Install
run: cmake --install ./build --config Release
- name: carpet tests
run: ./artifacts/bin/MT-RRT-carpet-tests
- name: trivial problem tests
run: ./artifacts/bin/MT-RRT-sample-TrivialProblem-lib-tests
- name: core tests
run: ./artifacts/bin/MT-RRT-core-tests
- name: multi threaded planners tests
run: ./artifacts/bin/MT-RRT-multi-threaded-tests
- name: planar robots problem tests
run: ./artifacts/bin/MT-RRT-sample-PlanarRobotsProblem-lib-tests
- name: navigation problem tests
run: ./artifacts/bin/MT-RRT-sample-NavigationProblem-lib-tests
- name: Tests-show
run: python script/RunTests.py --folder ./artifacts/bin --list
- name: Tests
run: python script/RunTests.py --folder ./artifacts/bin
- uses: actions/upload-artifact@v2
with:
path: artifacts
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ build
.vscode
log-*
.vs
TODO
__pycache__
*.pyc
47 changes: 28 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/MakeTest.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/MakeLibrary.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FetchJSONlib.cmake)

project(MT-RRT)

option(LIB_OPT "Compile shared libraries (ON) or static (OFF)" OFF)
set(MT_RRT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/script)

option(BUILD_MT_RRT_TESTS "Build MT-RRT tests" OFF)
if(BUILD_MT_RRT_TESTS)
message("fetching catch2")
include(FetchContent)
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 4ff8b27bb6bed4b8b309e56cd269b4f1fbc24e89
)
FetchContent_MakeAvailable(catch2)

option(ENABLE_MT_RRT_TESTS_LOGGING "Enable log generations when running tests" ON)
include(${MT_RRT_SCRIPTS}/Fetch.cmake)
include(${MT_RRT_SCRIPTS}/Terraform.cmake)

if(DEFINED PYTHON_EXECUTABLE)
# indeed, this env var is defined by the setup.py script
# if here the package is being built in order to generate a wheel
set(PYTHON_CMD ${PYTHON_EXECUTABLE})
else()
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonLibs 3 REQUIRED)
set(PYTHON_CMD "${Python3_EXECUTABLE}")
endif()
set(COMMON_KIT_PATH ${CMAKE_SOURCE_DIR}/script)

option(LIB_OPT "Compile shared libraries (ON) or static (OFF)" OFF)

option(BUILD_MT_RRT_TESTS "Build MT-RRT tests" OFF)
option(BUILD_MT_RRT_SAMPLES "Build MT-RRT samples" ON)

add_subdirectory(src)
add_subdirectory(samples)
set(MT_RRT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})

add_subdirectory(extern)

Terraform(src)
Terraform(problems)

option(BUILD_MT_RRT_README_SAMPLE "" OFF)
if(BUILD_MT_RRT_README_SAMPLE)
add_executable(ReadMeExample ReadMeExample.cpp)
target_link_libraries(ReadMeExample MT-RRT-multi-threaded)
endif()
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

## INTRO

**Multi Thread Rapidly Random exploring Trees**, aka **MT-RRT**, is a C++ library that can be used for path or trajectory planning, implementing different multi-threaded versions of the well known **Rapidly Random exploring Trees**, aka **RRT** algorithm. Inded, **RRT** are a popular cathegory of robotic algorithms used for computing paths or trajectories in a constrained environment.
The multi-threaded strategies contained in this library are able to significantly speed up the normal **RRT**, **bidirectional RRT** and **RRT***.
**Multi Thread Rapidly Random exploring Trees**, aka **MT-RRT**, is a **C++** library that can be used for path or trajectory planning, implementing different multi-threaded versions of the well known **Rapidly Random exploring Trees**, aka **RRT** algorithm. Inded, **RRT** are a popular cathegory of robotic algorithms used for computing paths or trajectories in a constrained environment.
The multi-threaded strategies contained in this library are able to significantly speed up the normal **RRT**, **bidirectional RRT** and **RRT* **.

This work is based on the results published in this **IROS** paper:
The initial implementation of this work was based on the results published in this **IROS** paper:
Andrea Casalino et al. :"Mt-rrt: a general purpose multithreading library for path planning", In IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS 2019), pages 1510–1517. IEEE, 2019
even though, it evolved much after the initial implementation.

This library was conceived to solve any kind of planning problem. The only thing you need to do when solving a new kind of problem, is to derive a couple of objects that contain all the
problem-specific information, refer to the [documentation](./doc/MT-RRT.pdf) and the [samples](#samples).
This library was conceived to solve any kind of planning problem. The only thing you need to do when solving your specific class, is to derive a couple of objects that contain all the problem-specific information, refer to the [documentation](./doc/MT-RRT.pdf) and the [samples](#samples).

**MT-RRT** is completely **cross platform**, let [CMake](#cmake-support) do all the work for you, and has no thirdy party dependency.

Expand All @@ -29,27 +29,28 @@ If you have found this library useful, please find the time to leave a **star**

This repository contains:
- [documentation](./doc/MT-RRT.pdf): pdf discussing generalities about **RRT** together with info explaining how to use this library
- [readme](./ReadMeExample.cpp): hello world example showing you how to use in a nutshell this library. Have a look also [here](#usage).
- [src](./src/): the sources containing the main features offered by this library. In particular:
- [src/core](./src/core/): containing **MT-RRT-core**, that provides background functionalities and the classical mon-thread implementation of the **RRT** algorithm.
- [src/core](./src/core/): containing **MT-RRT-multi-threaded**, that stores the multithreaded **RRT** planners characterizing this library
- [samples](./samples/): containing 3 classes of examples, explaining how to consume and use this library. Have a look also [here](#samples).
- [src/core](./src/core/): containing **MT-RRT-core**, that provides basic functionalities and the classical mono-thread implementation of the **RRT** algorithm.
- [src/multi-threaded](./src/multi-threaded/): containing **MT-RRT-multi-threaded**, that stores the multithreaded **RRT** planners proposed by this library
- [problems](./problems/): explaining how to use this library through 3 concrete planning problems examples, check the [ReadMe.md](./problems/ReadMe.md) of the samples. Have a look also [here](#samples).

## DOCUMENTATION

It is strongly encouraged to start from the [documentation](doc/MT-RRT.pdf).
This one provides a general background on the **RRT** algorithms and terminology in general and at the same time explains how to use and what to expect from the **RRT** planners implemented in this library.
Indeed, the documentation provides a general background on the **RRT** algorithms and terminology in general and at the same time explains how to use and what to expect from the **RRT** planners implemented in this library.

## USAGE

Haven't already left a **star**? Do it now ;)!

These are the steps to follow in order to solve any planning problem (refer also to this [ReadMe.md](./samples/ReadMe.md)):
These are the steps to follow in order to solve any planning problem (refer also to [ReadMeExample.md](./ReadMeExample.cpp)):
- explain to **MT-RRT** how the problem you want to solve is made. In order to do this you need to:
- define your own **mt_rrt::Sampler**, i.e. an object having the responsability to sample random states (some default ones, which are ok for 99% of the cases, are already provided by this library). Let's say your sampler is named **MySampler**:
```cpp
mt_rrt::SamplerPtr my_sampler = std::make_unique<MySampler>(...);
```
- define your own **mt_rrt::Conenctor**, i.e. an object having the responsability to compute trajectories that connects pair of states.
- define your own **mt_rrt::Connector**, i.e. an object having the responsability to compute trajectories that connects pair of states.
In [samples](./samples/), three classes of examples were implemented in order to show you how to do this for your own problem. Let's say your connector is named **MyConnector**:
```cpp
mt_rrt::ConnectorPtr my_connector = std::make_unique<MyConnector>(...);
Expand All @@ -61,7 +62,7 @@ These are the steps to follow in order to solve any planning problem (refer also
problem_description.sampler = std::move(my_sampler);
// and a couple of more ... see the samples
```
- build a planner. The planner will absorb all the problem specific information. YOu can opt for a standard mono-threaded planner:
- build a planner. The planner will absorb all the problem specific information. You can opt for a standard mono-threaded planner:
```cpp
mt_rrt::StandardPlanner planner(std::move(problem_description));
```
Expand Down Expand Up @@ -106,12 +107,14 @@ mt_rrt::PlannerSolution solution = planner.solve(start_state, end_state, paramet

Haven't already left a **star**? Do it now ;)!

Tree classes of samples are contained in [./samples](./samples/). Such samples represent sample planning problems and aims at showing how to use **MT-RRT** in order to solve them.
The [documentation](doc/MT-RRT.pdf) extensively describes the samples and it is strongly encouraged also to have a look to [ReadMe.md](./samples/ReadMe.md) and [ReadMe.cpp](./samples/ReadMe.cpp) in the samples folder before dive into the samples implementations.
Three classes of samples are contained in [./problems](./problems/). These are planning problemexamples showing how to use **MT-RRT** in order to solve them.
The [documentation](doc/MT-RRT.pdf) extensively describes the samples and it is strongly encouraged also to have a look to the samples [ReadMe.md](./problems/ReadMe.md).
In particular:
- [./samples/TrivialProblems](./samples/TrivialProblems) represents a 2D maze problem
- [./samples/PlanarRobotsProblems](./samples/PlanarRobotsProblems) represents a planar robots planning problem
- [./samples/NavigationProblems](./samples/NavigationProblems) represents a 2D moving cart problem
- [./problems/problem-trivial](./problems/problem-trivial) represents a 2D maze problem
- [./problems/problem-planarRobots](./problems/problem-planarRobots) represents a planar robots planning problem
- [./problems/problem-navigation](./problems/problem-navigation) represents a 2D moving cart problem

Notice that these are just samples, but as long as you provide a connector and a sampler suitable for your specific problem, you can solve ANY kind of problem with this library!!

## CMAKE SUPPORT

Expand All @@ -135,12 +138,12 @@ target_link_libraries(${TARGET_NAME} MT-RRT-multi-threaded
)
```

If you are only interested in the **MT-RRT-core** you can fecth as done before and link to this one:
If you are only interested in the standard **RRT** implementation contained in **MT-RRT-core**, you can link just to that library:
```cmake
target_link_libraries(${TARGET_NAME} MT-RRT-core
)
```

**MT-RRT** internally makes use of [omp](https://en.wikipedia.org/wiki/OpenMP), which should be natively supported by any kind of modern compiler. **CMake** will automatically look for the latest **omp** version installed and in case nothing is found an error will occour.

Sometimes is is usefull to check the progress of the solver, printing on the console the iterations done so far. This is not the default behaviour of **MT-RRT** but can be enabled turning to **ON** the **CMake** option called **MT_RRT_SHOW_PLANNER_PROGRESS**. This of course will affects the performance and should be done only for debugging purposes.
Sometimes is is usefull to check the progress of the solver, printing on the console the iterations done so far. This is not the default behaviour of **MT-RRT** but can be enabled turning to **ON** the **CMake** option called **MT-RRT-SHOW_PLANNER_PROGRESS**. This of course will affects the performance and should be done mostly for debugging purposes.
101 changes: 101 additions & 0 deletions ReadMeExample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include <MT-RRT/Planner.h>

#include <MT-RRT/MultiAgentPlanner.h>
#include <MT-RRT/StandardPlanner.h>

void main() {
// First of all, you need to explain to MT-RRT how the particular class of
// problem(s) you want to solve is made.
// This is done by defining the specific conenctor, i.e. an object extending
// mt_rrt::Connector, which will contain the knowledge of the problem and is
// foundamental to let MT-RRT extend the search tree(s). Examples of
// connectors can be found in the samples folder:
// -
//[TrivialProblem](./problems/problem-trivial/header/TrivialProblem.h), check
// also `Planar maze problem` Section of the documentation
// -
//[PlanarRobotsProblem](./problems/problem-planarRobots/header/PlanarRobotsProblem.h),
// check
// also `Articulated arm problem` Section of the documentation
// -
//[NavigationProblem](./problems/problem-navigation/header/NavigationProblem.h),
// check
// also `Navigation problem` Section of the documentation
//
//
// Let's assume you defined a connector named MyConnector
mt_rrt::ConnectorPtr my_connector = std::make_unique<MyConnector>(...);

// secondly, you need to define a sampler, i.e. an object extending
// mt_rrt::Sampler. This object is used to sample new random states toward
// which the trees will be extended in the attempt explore the state space and
// find a solution that connects the starting and ending state you want to
// connect. In a certain sense, also this object stores some knowledge of the
// particular problem you want to solve. Most of the time, you can use the
// ready to use sampler named mt_rrt::HyperBox. Let's say your concrete
// sampler is called MySampler
mt_rrt::SamplerPtr my_sampler = std::make_unique<MySampler>(...);

// The abvoe pieces of information has to be grouped to a structure called
// mt_rrt::ProblemDescription
mt_rrt::ProblemDescription problem_description;
problem_description.simmetry =
true; // true / false, if the problem is simmetric or not, i.e. the
// trajectory conencting A to B can be trivially inverted to get the
// one going from B to A
problem_description.gamma.set(
...); // the parameters regulating the RRT* strategy, refer to Section
// "Compute the optimal solution: the RRT*" of the documentation
problem_description.connector = std::move(my_connector);
problem_description.sampler = std::move(my_sampler);

// You are now ready to build a planner.
// This planner will absorb the problem description and will be able to solve
// 1 or many problems of the kind represented by the above parameters. The
// easiest planner you can build is mt_rrt::StandardPlanner, implementing the
// single threaded classic RRT. More advanced multi threaded
// planners can be found [here](src/multi-threaded/header/MT-RRT), check also
// the Documentation.
mt_rrt::StandardPlanner planner(std::move(problem_description));

{
// solve the first problem
// define the states to connect
std::vector<float> start_state = ...;
std::vector<float> end_state = ...;

// define the parameters
mt_rrt::Parameters parameters;
parameters.iterations.set(1500); // number of maximum iterations
parameters.expansion_strategy =
mt_rrt::ExpansionStrategy::Star; // set the strategy, see Section
// "Background on RRT" of the
// documentation
// ... and the others, check the mt_rrt::Parameters definition

// solve the problem
mt_rrt::PlannerSolution solution =
planner.solve(start_state, end_state, parameters);
std::vector<std::vector<float>> found_sequence =
solution.solution; // access the found solution (is an empty vector if
// no solution was found)
auto time =
solution
.time; // access the time spent by the planner to find a solution
// ... you can access in that structure also some other info
}

{
// solve another problem ... you don't need to build a new planner if the
// problem is of the same kind. Indeed, you can re-use the same planner, but
// passing the info of this other particular problem to solve.
//
// IMPORTANT !!! Clearly, in order to avoid data race, you can solve only 1
// problem at a time per planner
std::vector<float> start_state = ...;
std::vector<float> end_state = ...;
mt_rrt::Parameters parameters = ...;
mt_rrt::PlannerSolution solution =
planner.solve(start_state, end_state, parameters);
}
}
12 changes: 0 additions & 12 deletions cmake/FetchJSONlib.cmake

This file was deleted.

34 changes: 0 additions & 34 deletions cmake/MakeLibrary.cmake

This file was deleted.

Loading