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
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ Warthog is an optimised C++ library for pathfinding search.
Warthog-JPS is an extension to Warthog with JPS support.
See [warthog-core](https://github.com/ShortestPathLab/warthog-core) for more details on Warthog setup.

@article{Harabor_Grastien_2014,
title={Improving Jump Point Search},
volume={24},
url={https://ojs.aaai.org/index.php/ICAPS/article/view/13633},
DOI={10.1609/icaps.v24i1.13633},
number={1},
journal={Proceedings of the International Conference on Automated Planning and Scheduling},
author={Harabor, Daniel and Grastien, Alban},
year={2014},
pages={128-135}
}

# Using JPS

## Compile
Expand All @@ -17,8 +29,29 @@ cmake --build build
./build/warthog-jps --alg jps --scen example.scen
```

The example scenario `example.scen` is not a part of this repo.
Get benchmark from places like MovingAI or pathfinding.ai found in the resource section.

JPS requires `warthog-core` repo to compile, and by default will fetch the repo.

## JPS Variants

JPS comes with several variants.
All variants use block-based symmetry breaking for finding jump-point locations,
making them at least JPS (B).
These jump points are found in namespace `jps::jump`, while `jps::search` uses provided `jps::jump` locators
to produce successors used in warthog-core.

The algorithms provided to `--alg` parameter, along with their `jps::search` and `jps::jump` classes presented
in the table below:

| `--alg` | `jps::search` | `jps::jump` |
|------------------------------------------------------------------------------|
| `jps` | `jps_expansion_policy<>` | `jump_point_online` |
| `jpsP` or `jps2` | `jps_prune_expansion_policy<>` | `jump_point_online` |
| `jps+` | `jps_expansion_policy` | `jump_point_offline<>` |
| `jpsP+` or `jps2+` | `jps_prune_expansion_policy<>` | `jump_point_offline<>` |

## Use in project

If elements of warthog is used in a project, follow guides from `warthog-core` to set up the project structure.
Expand Down
12 changes: 3 additions & 9 deletions apps/jps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ help(std::ostream& out)
<< "Invoking the program this way solves all instances in [scen "
"file] with algorithm [alg]\n"
<< "Currently recognised values for [alg]:\n"
<< "\tjps, jpsP, jpsP32, jps+, jpsP+\n";
<< "\tjps, jpsP or jps2, jps+, jpsP+ or jps2+\n";
// << ""
// << "The following are valid parameters for GENERATING instances:\n"
// << "\t --gen [map file (required)]\n"
Expand Down Expand Up @@ -246,25 +246,19 @@ main(int argc, char** argv)
return run_jps<jps_expansion_policy<jump_point>>(
scenmgr, mapfile, alg);
}
else if(alg == "jpsP")
else if(alg == "jpsP" || alg == "jps2")
{
using jump_point = jps::jump::jump_point_online;
return run_jps<jps_prune_expansion_policy<jump_point>>(
scenmgr, mapfile, alg);
}
else if(alg == "jpsP32")
{
using jump_point = jps::jump::jump_point_online;
return run_jps<jps_prune_expansion_policy<jump_point, 32, 64>>(
scenmgr, mapfile, alg);
}
else if(alg == "jps+")
{
using jump_point = jps::jump::jump_point_offline<>;
return run_jps<jps_expansion_policy<jump_point>>(
scenmgr, mapfile, alg);
}
else if(alg == "jpsP+")
else if(alg == "jpsP+" || alg == "jps2+")
{
using jump_point = jps::jump::jump_point_offline<>;
return run_jps<jps_prune_expansion_policy<jump_point>>(
Expand Down
45 changes: 40 additions & 5 deletions include/jps/domain/rotate_gridmap.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
#ifndef WARTHOG_DOMAIN_ROTATE_GRIDMAP_H
#define WARTHOG_DOMAIN_ROTATE_GRIDMAP_H

// domain::gridmap.h
//
// A uniform cost domain::gridmap implementation. The map is stored in
// a compact matrix form. Nodes are represented as single bit quantities.
// jps/domain/rotate_gridmap.h
//
// An extended domain of gridmap that uses 2 gridmaps, one rotated
// for use in JPS block-based jump-point location.
//
// Class rotate_gridmap is the main implementation.
// It supports pointing to a user-supplied gridmap and rotated gridmap,
// or just a user provided gridmap, which it would generate and own the
// rotated gridmap.
//
// Small copyable storage of these maps are provided in utility structs:
// gridmap_rotate_ptr, gridmap_rotate_ptr_convs: 2 pointers to gridmap,
// accessing the grid would require 2-level of indirects (gridmap->data[i])
// gridmap_rotate_table, gridmap_rotate_table_convs: 2 gridmap::bitarray,
// accessing the grid is only a single redirect
// Use of these datatypes do not copy the tables themselves, and are quite
// compact. The non _convs variants should be 2-pointer sized (16-bytes). The
// _convs variants are supplied with width and height, allowing for x/y and
// grid_id and rgrid_id conversions between the two grid (24-bytes).
//
// @author Ryan Hechenberger
// @created 2025-11-20
//

#include <array>
Expand Down Expand Up @@ -385,7 +404,8 @@ struct gridmap_rotate_ptr : std::array<domain::gridmap*, 2>
}
operator bool() const noexcept { return (*this)[0]; }
};
/// @brief a copy-by-value class pointing to grid/rgrid with conversions
/// @brief a copy-by-value class pointing to grid/rgrid with id conversions
/// functions
struct gridmap_rotate_ptr_convs : gridmap_rotate_ptr,
rgridmap_point_conversions
{
Expand Down Expand Up @@ -429,7 +449,8 @@ struct gridmap_rotate_table : std::array<domain::gridmap::bitarray, 2>
}
operator bool() const noexcept { return (*this)[0].data(); }
};
/// @brief a copy-by-value class for fast access to grid/rgrid with conversions
/// @brief a copy-by-value class for fast access to grid/rgrid with id
/// conversions functions
struct gridmap_rotate_table_convs : gridmap_rotate_table,
rgridmap_point_conversions
{
Expand Down Expand Up @@ -462,6 +483,14 @@ struct gridmap_rotate_table_convs : gridmap_rotate_table,
}
};

/// The main rotate gridmap class.
/// Stores a pointer to a gridmap and rotated gridmap.
/// The rotated gridmap memory may be created and owned by this class, or
/// provided and controlled by the user.
///
/// Supports static_cast operations for all gridmap_rotate_(ptr|table)(_conv)?.
/// They will act as valid small pointer classes (16-24 bytes) with various
/// levels if indirection to the grid data.
class rotate_gridmap : public rgridmap_point_conversions
{
private:
Expand Down Expand Up @@ -589,6 +618,12 @@ class rotate_gridmap : public rgridmap_point_conversions
return gridmap_rotate_table_convs(
*this, static_cast<rgridmap_point_conversions>(*this));
}

size_t
mem() const noexcept
{
return rmap_obj != nullptr ? rmap_obj->mem() : 0;
}
};

} // namespace warthog::grid
Expand Down
15 changes: 10 additions & 5 deletions include/jps/forward.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#ifndef JPS_FORWARD_H
#define JPS_FORWARD_H

#include <vector>
//
// jps/forward.h
//
// Global namespace types include.
//
// @author Ryan Hechenberger
// @created 2025-11-20
//

#include <warthog/constants.h>
#include <warthog/defines.h>
#include <warthog/domain/grid.h>
Expand All @@ -10,17 +18,14 @@
namespace jps
{

using namespace warthog::grid;
using namespace ::warthog::grid;
using ::warthog::pad_id;
// using jps_id = grid_id;
struct rmap_id_tag
{ };
using rgrid_id = warthog::identity_base<rmap_id_tag, grid_id::id_type>;
using warthog::cost_t;

using vec_jps_id = std::vector<grid_id>;
using vec_jps_cost = std::vector<cost_t>;

} // namespace jps

#include <jps/jump/jump.h>
Expand Down
Loading