Skip to content
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
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<h4 align="center">Mesh Navigation Documentation</h4>

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;" >
<iframe src="https://www.youtube.com/embed/gvKsW5MEC4Y?si=WohSZ_lEdIbxAZZK?autoplay=1&mute=1"
<iframe src="https://www.youtube.com/embed/gvKsW5MEC4Y?si=p9EVZZCI3o6BnOAY?autoplay=1&mute=1"
title="YouTube Video"
frameborder="0"
allow="autoplay; encrypted-media"
Expand Down
6 changes: 5 additions & 1 deletion docs/library/controller_plugin.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Controller Plugin
# Controller Plugin

!!! Important

Under construction. Go to the guide [MeshNav Plugins](/guides/meshnav_plugins.md) for now.
7 changes: 6 additions & 1 deletion docs/library/cost_layer_plugin.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# Cost Layer Plugin
# Cost Layer Plugin

!!! Important

Under construction. Go to the guide [MeshNav Plugins](/guides/meshnav_plugins.md) for now.

39 changes: 38 additions & 1 deletion docs/library/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
# Library

TODO: More in-depth library overview
This section gives a more in-depth description of MeshNav seen as a library / as a plugin system which might be of interest for 3D navigation developers. MeshNav provides plugin interfaces for

- Path Planning
- Motion Control
- Mesh Layers

which means, developer can use what's already there and implement own layers/planners/controllers on top, while beeing able to keep their code in their own codebases.

## Package Structure

This **[mesh_navigation](https://github.com/naturerobots/mesh_navigation)** stack provides a navigation server for **[Move Base Flex (MBF)](https://github.com/naturerobots/move_base_flex)**. It provides a couple of configuration files and launch files to start the navigation server with the configured layer plugins for the layered mesh map, and the configured planners and controller to perform path planning and motion control in 3D (or more specifically on 2D-manifold).

The package structure is as follows:

* `mesh_navigation` The corresponding ROS meta package.

* `mbf_mesh_core` contains the plugin interfaces derived from the abstract MBF plugin interfaces to initialize planner and controller plugins with one `mesh_map` instance. It provides the following three interfaces:
- MeshPlanner - `mbf_mesh_core/mesh_planner.h`
- MeshController - `mbf_mesh_core/mesh_controller.h`
- MeshRecovery - `mbf_mesh_core/mesh_recovery.h`

* `mbf_mesh_nav` contains the mesh navigation server which is built on top of the abstract MBF navigation server. It uses the plugin interfaces in `mbf_mesh_core` to load and initialize plugins of the types described above.

* `mesh_map` contains an implementation of a mesh map representation building on top of the generic mesh interface implemented in **[lvr2](https://github.com/uos/lvr2)**. This package provides a layered mesh map implementation. Layers can be loaded as plugins to allow a highly configurable 3D navigation stack for robots traversing on the ground in outdoor and rough terrain.

* `mesh_layers` The package provides a couple of mesh layers to compute trafficability/traversibility properties of the terrain. Furthermore, these plugins have access to the HDF5 map file and can load and store layer information. The mesh layers can be configured for the robots abilities and needs. Currently we provide the following layer plugins:
- HeightDiffLayer - `mesh_layers/HeightDiffLayer`
- RoughnessLayer - `mesh_layers/RoughnessLayer`
- SteepnessLayer - `mesh_layers/SteepnessLayer`
- RidgeLayer - `mesh_layer/RidgeLayer`
- ClearanceLayer - `mesh_layers/ClearanceLayer`
- InflationLayer - `mesh_layers/InflationLayer`
- BorderLayer - `mesh_layers/BorderLayer`
- ObstacleLayer - `mesh_layers/ObstacleLayer`

* `dijkstra_mesh_planner` contains a mesh planner plugin providing a path planning method based on Dijkstra's algorithm. It plans by using the edges of the mesh map. The propagation start a the goal pose, thus a path from every accessed vertex to the goal pose can be computed. This leads to a sub-optimal potential field, which highly depends on the mesh structure.

* `cvp_mesh_planner` contains a Fast Marching Method (FMM) wave front path planner to take the 2D-manifold into account. This planner is able to plan over the surface, due to that it results in shorter paths than the `dijkstra_mesh_planner`, since it is not restricted to the edges or topology of the mesh. A comparison is shown below. Please refer to the paper `Continuous Shortest Path Vector Field Navigation on 3D Triangular Meshes for Mobile Robots`.
4 changes: 4 additions & 0 deletions docs/library/planner_plugin.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Planner Plugin

!!! Important

Under construction. Go to the guide [MeshNav Plugins](/guides/meshnav_plugins.md) for now.
Binary file added docs/media/stone_quarry/cloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/dem_side.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/dijkstra_pot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/fmm_pot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/height_diff.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/mesh_rgb.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/pot_fmm_vs_dijkstra.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/stone_quarry/pot_paths.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions docs/showcases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


## Driving in Complex Environments

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;" >
<iframe src="https://www.youtube.com/embed/gvKsW5MEC4Y?si=p9EVZZCI3o6BnOAY?autoplay=1&mute=1"
title="YouTube Video"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
</iframe>
</div>

## Dynamic Obstacle Avoidance & Kinematic-aware control


<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;" >
<iframe src="https://www.youtube.com/embed/4OgxDKcWIXM?si=NyoUc1iDYFN_6Pte?autoplay=1&mute=1"
title="YouTube Video"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
</iframe>
</div>
35 changes: 35 additions & 0 deletions docs/theory/control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Control


In classic mobile robot navigation, we like to distinguish between global path planning and local motion planning to balance long-term goals with real-time feasibility.
The local planner (or controller), adapts a route to the robot’s immediate surroundings and dynamics, handling obstacles and uncertainties as they appear.
Modern navigation on 3D surface meshes requires control strategies that can follow complex terrain while respecting the robot's kinematics.
MeshNav provides multiple controllers tailored to this task—from a simple vector-field–based controller to a full Model Predictive Path Integral (MPPI) controller.
This section introduces the available controllers, explains how they operate, and highlights when each should be used.

## Vector Field Controller

![Vector Field Controller](/media/vector_field_controller.png)

The vector field controller is the default controller used in the tutorials. It takes the vector field that was attached to the mesh by the planner and controls the robot along the field until it arrives at the desired goal.

Source Code: [mesh_controller](https://github.com/naturerobots/mesh_navigation/tree/main/mesh_controller).

??? note "No Obstacle Avoidance"

In the current implementation (!), the vector field does not react to the new dynamic obstacle layer. Therefore, it is not possible to respond to dynamic obstacles. Implementing this capability would be a substantial improvement. Don't forget to open a PR!

### Mesh MPPI

[![MeshMPPI GIF](/media/mesh_mppi/mesh_mppi_floor_is_lava.gif)](https://github.com/uos/mesh_mppi)

MeshMPPI is an adaptation of the model predictive path integral (MPPI) control algorithm to surface meshes.
The MPPI algorithm generates control signals by simulating the trajectories resulting from a set of random samples.
This adaptation constrains the trajectory prediction to the surface defined by a triangular mesh.
The implementation provided in this repository integrates the MeshMPPI algorithm into the ROS 2–based MeshNav 3D navigation stack.

It can be used when extra attention is needed to ensure that motion planning is both kinematically and terrain feasible. It currently implements two kinematic models that can be used with either differential-drive or bicycle-drive robots. Furthermore, it reacts to dynamic cost layers, enabling it to avoid dynamic or previously unmapped obstacles.
Additionally, it provides a mechanism to easily extend the controller with custom kinematic models.

Source Code: [mesh_mppi](https://github.com/uos/mesh_mppi), developed at [Osnabrück University (UOS)](https://github.com/uos).

82 changes: 82 additions & 0 deletions docs/theory/path_planning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Path Planning

In classic mobile robot navigation, we like to distinguish between global path planning and local motion planning to balance long-term goals with real-time feasibility.
The global planner provides a high-level route through the environment, ensuring the robot moves efficiently toward its destination.
Mesh navigation provides several global planners designed to compute feasible paths across 3D surfaces.
All implemented planners share the core principle of computing shortest paths on a triangular mesh. Depending on configuration, they can also take into account obstacle avoidance.


### Dijkstra Planner

The Dijkstra Planner implements the classic [Dijkstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm). It operates on the graph representation of the triangle mesh, where mesh vertices represent graph nodes and mesh edges represent graph edges.

![Dijkstra potential field](/media/dijkstra_pot.jpg)

This planner is well-suited for applications where simplicity, robustness, and deterministic behavior are desired, but it is limited to edge-based paths rather than continuous trajectories over the surface.

### Continuous Vector Field Planner

The Continuous Vector Field Planner (CVP) extends beyond edge-based search by planning directly over the surface of the mesh instead of its connectivity graph.
CVP uses a wavefront propagation technique to generate a globally consistent vector field that encodes the continuous shortest path direction from any point on the mesh to the goal.
Therefore, can flow smoothly across triangle faces, producing shorter and more natural trajectories than the ones found by the Dijkstra planner.
Similar to Dijkstra, CVP can integrate surface costs, allowing navigation that avoids obstacles or prefers favorable terrain.
This makes CVP particularly useful for mobile robots operating on uneven or natural terrain, where edge-restricted paths would otherwise be suboptimal or unnatural.
Furthermore, CVP is less sensitive to the density of the triangles in the mesh.

![CVP potential field](/media/cvp_pot.jpg)

!!! note

For the theoretical background and implementation details, see:

```bib
@inproceedings{puetz21cvp,
author = {Pütz, Sebastian and Wiemann, Thomas and Kleine Piening, Malte and Hertzberg, Joachim},
title = {Continuous Shortest Path Vector Field Navigation on 3D Triangular Meshes for Mobile Robots},
booktitle = {2021 IEEE International Conference on Robotics and Automation (ICRA)},
year = 2021,
url = {https://github.com/uos/mesh_navigation},
note = {Software available at \url{https://github.com/uos/mesh_navigation}}
}
```

It is available on [IEEE Xplore](https://ieeexplore.ieee.org/document/9560981).

Config:

```yaml
mesh_planner:
type: 'cvp_mesh_planner/CVPMeshPlanner'
cost_limit: 0.99 # Vertices with costs higher than this value will be avoided. Has to be set *below* the inflation layer inscribed value to avoid obstacles in planning
publish_vector_field: true
```

### Obstacle-aware planning

After the cost layers have been computed, the resulting vertex costs are transformed into edge costs inside the mesh map. In this step, the parameter of the mesh map `edge_cost_factor` determines how much the vertex costs are added (!) to the edge distance. We add the costs to the edge distances to preserve the admissible property of future heuristic search implementations: When using pre-computed distances or the air-line to the target as heuristics, the actual costs collected along the way will be always at least higher.

Setting the `edge_cost_factor` parameter to zero will let the planners ignore all static obstacles. An example configuration that takes (static) obstacles into account while planning could be:

```yaml
mesh_map:
# An edge cost equals the total costs that are collected along a
# triangle's edge by linearly interpolating the combined vertex costs
# This factor defines the factor that is used for the final edge weight
# -> edge_weight = edge_length + edge_cost_factor * edge_cost
# This edge_weight is then passed to the global planner to search for
# the best path
# Note: Set this to 0.0 if you need the shortest path
edge_cost_factor: 5.0

# [...] Other parameters of mesh_map
```


## Comparison

| Vector Field Planner | Dijkstra Mesh Planner | ROS Global Planner on 2.5D DEM |
| ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| ![VectorFieldPlanner](/media/cvp_pot.jpg "Vector Field Planner") | ![DijkstraMeshPlanner](/media/dijkstra_pot.jpg "Dijkstra Mesh Planner") | ![2D-DEM-Planner](/media/stone_quarry/dem_side.jpg "2D DEM Planner") |



3 changes: 3 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ nav:
- Home:
- Overview: index.md
- Installation: installation.md
- Showcases: showcases.md
- Theory:
- Overview: theory/index.md
- Why Meshes: theory/mesh_maps.md
- Path Planning: theory/path_planning.md
- Control: theory/control.md
- Tutorials:
- Overview: tutorials/index.md
- Getting Started:
Expand Down