Skip to content

Commit

Permalink
Feature/refactor grid id label (#20)
Browse files Browse the repository at this point in the history
* refactor label id to identity type

* update to_padded_id to be more efficient

* Bug fix from pad to unpad xy. Added const noexcept to grid conversion.

* constants.h bug fixes
  • Loading branch information
heavenfall authored Nov 14, 2024
1 parent 2f74e73 commit f3e5d9e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 56 deletions.
7 changes: 4 additions & 3 deletions include/warthog/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//

#include <bit>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
Expand All @@ -34,7 +35,7 @@ struct identity_base
requires(!std::same_as<IdType, IdType2>) explicit(
std::numeric_limits<IdType>::max() < std::numeric_limits<IdType2>::
max()) constexpr identity_base(identity_base<Tag, IdType2> alt)
: id(IdType{alt.id})
: id(static_cast<IdType>(alt.id))
{
assert(id == alt.id);
}
Expand Down Expand Up @@ -121,8 +122,8 @@ constexpr uint64_t INFTY
// undefined values

using cost_t = double;
constexpr cost_t COST_MAX = DBL_MAX;
constexpr cost_t COST_MIN = DBL_MIN;
constexpr cost_t COST_MAX = std::numeric_limits<cost_t>::max();
constexpr cost_t COST_MIN = std::numeric_limits<cost_t>::max();

// hashing constants
constexpr uint32_t FNV32_offset_basis = 2166136261;
Expand Down
88 changes: 53 additions & 35 deletions include/warthog/domain/gridmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <warthog/util/gm_parser.h>
#include <warthog/util/helpers.h>

#include <cassert>
#include <climits>
#include <cstdint>
#include <limits>
Expand All @@ -41,8 +42,9 @@ class gridmap
// here we convert from the coordinate space of
// the original grid to the coordinate space of db_.
pad_id
to_padded_id(pack_id node_id)
to_padded_id(pack_id node_id) const noexcept
{
assert(header_.width_ != 0);
return pad_id{
uint32_t{node_id} +
// padded rows before the actual map data starts
Expand All @@ -54,32 +56,39 @@ class gridmap
// here we convert from the coordinate space of
// the original grid to the coordinate space of db_.
pad_id
to_padded_id(uint32_t x, uint32_t y)
to_padded_id(uint32_t x, uint32_t y) const noexcept
{
return to_padded_id(pack_id{y * this->header_width() + x});
return pad_id{(y + padded_rows_before_first_row_) * padded_width_ + x};
}

void
to_unpadded_xy(pack_id grid_id_p, uint32_t& x, uint32_t& y)
to_unpadded_xy(pack_id grid_id, uint32_t& x, uint32_t& y) const noexcept
{
y = uint32_t{grid_id_p} / padded_width_;
x = uint32_t{grid_id_p} % padded_width_;
y = uint32_t{grid_id} / header_.width_;
x = uint32_t{grid_id} % header_.width_;
}

void
to_unpadded_xy(pad_id grid_id_p, uint32_t& x, uint32_t& y)
to_unpadded_xy(pad_id grid_id, uint32_t& x, uint32_t& y) const noexcept
{
uint32_t id = uint32_t{grid_id_p}
- padded_rows_before_first_row_ * padded_width_;
y = id / padded_width_;
x = id % padded_width_;
to_padded_xy(grid_id, x, y);
y -= padded_rows_before_first_row_;
assert(x < header_.width_ && y < header_.height_);
}

void
to_padded_xy(pad_id grid_id, uint32_t& x, uint32_t& y) const noexcept
{
y = uint32_t{grid_id} / padded_width_;
x = uint32_t{grid_id} % padded_width_;
assert(x < padded_width_ && y < padded_height_);
}

pack_id
to_unpadded_id(pad_id padded_id)
to_unpadded_id(pad_id grid_id) const noexcept
{
uint32_t x, y;
to_unpadded_xy(padded_id, x, y);
to_unpadded_xy(grid_id, x, y);
return pack_id{y * header_.width_ + x};
}

Expand All @@ -91,12 +100,14 @@ class gridmap
// lowest positions of the byte.
// position :0 is the nei in direction NW, :1 is N and :2 is NE
void
get_neighbours(uint32_t grid_id_p, uint8_t tiles[3])
get_neighbours(pad_id grid_id, uint8_t tiles[3])
{
// 1. calculate the dbword offset for the node at index grid_id_p
// 2. convert grid_id_p into a dbword index.
uint32_t bit_offset = (grid_id_p & warthog::DBWORD_BITS_MASK);
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
uint32_t bit_offset
= static_cast<uint32_t>(grid_id.id & warthog::DBWORD_BITS_MASK);
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);

// compute dbword indexes for tiles immediately above
// and immediately below node_id
Expand All @@ -119,12 +130,14 @@ class gridmap
// tiles are from the row immediately above and immediately below
// grid_id_p.
void
get_neighbours_32bit(uint32_t grid_id_p, uint32_t tiles[3])
get_neighbours_32bit(pad_id grid_id, uint32_t tiles[3])
{
// 1. calculate the dbword offset for the node at index grid_id_p
// 2. convert grid_id_p into a dbword index.
uint32_t bit_offset = (grid_id_p & warthog::DBWORD_BITS_MASK);
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
uint32_t bit_offset
= static_cast<uint32_t>(grid_id.id & warthog::DBWORD_BITS_MASK);
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);

// compute dbword indexes for tiles immediately above
// and immediately below node_id
Expand All @@ -143,12 +156,14 @@ class gridmap
// upper bit of the return value. this variant is useful when jumping
// toward smaller memory addresses (i.e. west instead of east).
void
get_neighbours_upper_32bit(uint32_t grid_id_p, uint32_t tiles[3])
get_neighbours_upper_32bit(pad_id grid_id, uint32_t tiles[3])
{
// 1. calculate the dbword offset for the node at index grid_id_p
// 2. convert grid_id_p into a dbword index.
uint32_t bit_offset = (grid_id_p & warthog::DBWORD_BITS_MASK);
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
uint32_t bit_offset
= static_cast<uint32_t>(grid_id.id & warthog::DBWORD_BITS_MASK);
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);

// start reading from a prior index. this way everything
// up to grid_id_p is cached.
Expand All @@ -171,10 +186,10 @@ class gridmap
// the middle row contains tile grid_id_p.
// the other tiles are from the row above and below grid_id_p.
void
get_neighbours_64bit(uint32_t grid_id_p, uint64_t tiles[3])
get_neighbours_64bit(pad_id grid_id, uint64_t tiles[3])
{
// convert grid_id_p into a 64bit db_ index.
uint32_t dbindex = grid_id_p >> 6;
uint32_t dbindex = static_cast<uint32_t>(grid_id.id >> 6);

// compute 64bit dbword indexes for the tiles
// above and below node_id
Expand All @@ -192,43 +207,46 @@ class gridmap
bool
get_label(uint32_t x, uint32_t y)
{
return this->get_label(y * padded_width_ + x);
return this->get_label(to_padded_id(x, y));
}

// TODO: for now, kept internal as uint32_t for smaller call size, decide
// later
warthog::dbword
get_label(uint32_t grid_id_p)
get_label(pad_id grid_id)
{
// now we can fetch the label
uint32_t bitmask = 1;
bitmask <<= (grid_id_p & warthog::DBWORD_BITS_MASK);
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
bitmask <<= (grid_id.id & warthog::DBWORD_BITS_MASK);
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);
if(dbindex > max_id_) { return 0; }
return (db_[dbindex] & bitmask) != 0;
}

// get a pointer to the word that contains the label of node @grid_id_p
warthog::dbword*
get_mem_ptr(uint32_t grid_id_p)
get_mem_ptr(pad_id grid_id)
{
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);
if(dbindex > max_id_) { return 0; }
return &db_[dbindex];
}

// set the label associated with the padded coordinate pair (x, y)
void
set_label(uint32_t x, unsigned int y, bool label)
set_label(uint32_t x, uint32_t y, bool label)
{
this->set_label(y * padded_width_ + x, label);
this->set_label(to_padded_id(x, y), label);
}

void
set_label(uint32_t grid_id_p, bool label)
set_label(pad_id grid_id, bool label)
{
uint32_t dbindex = grid_id_p >> warthog::LOG2_DBWORD_BITS;
uint32_t bitmask = 1u << (grid_id_p & warthog::DBWORD_BITS_MASK);
uint32_t dbindex
= static_cast<uint32_t>(grid_id.id >> warthog::LOG2_DBWORD_BITS);
uint32_t bitmask = 1u << (grid_id.id & warthog::DBWORD_BITS_MASK);

if(dbindex > max_id_) { return; }

Expand Down
10 changes: 5 additions & 5 deletions src/domain/gridmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ gridmap::gridmap(const char* filename)
case 'T':
case '@':
case 'O': // these terrain types are obstacles
this->set_label(uint32_t{to_padded_id(pack_id{i})}, 0);
assert(this->get_label(uint32_t{to_padded_id(pack_id{i})}) == 0);
this->set_label(to_padded_id(pack_id{i}), 0);
assert(this->get_label(to_padded_id(pack_id{i})) == 0);
break;
default: // everything else is traversable
this->set_label(uint32_t{to_padded_id(pack_id{i})}, 1);
this->set_label(to_padded_id(pack_id{i}), 1);
num_traversable_++;
assert(this->get_label(uint32_t{to_padded_id(pack_id{i})}) == 1);
assert(this->get_label(to_padded_id(pack_id{i})) == 1);
break;
}
}
Expand Down Expand Up @@ -95,7 +95,7 @@ gridmap::print(std::ostream& out)
{
for(unsigned int x = 0; x < this->width(); x++)
{
warthog::dbword c = this->get_label(y * this->width() + x);
warthog::dbword c = this->get_label(pad_id{y * this->width() + x});
out << (c ? '.' : '@');
}
out << std::endl;
Expand Down
26 changes: 13 additions & 13 deletions src/search/gridmap_expansion_policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ gridmap_expansion_policy::expand(

// get terrain type of each tile in the 3x3 square around (x, y)
uint32_t tiles = 0;
uint32_t nodeid = uint32_t{current->get_id()};
pad_id nodeid = current->get_id();
map_->get_neighbours(nodeid, (uint8_t*)&tiles);

// #ifndef NDEBUG
Expand All @@ -37,48 +37,48 @@ gridmap_expansion_policy::expand(
// #endif

// NB: no corner cutting or squeezing between obstacles!
uint32_t nid_m_w = nodeid - map_->width();
uint32_t nid_p_w = nodeid + map_->width();
pad_id nid_m_w = pad_id{nodeid.id - map_->width()};
pad_id nid_p_w = pad_id{nodeid.id + map_->width()};

// generate cardinal moves
if((tiles & 514) == 514) // N
{
add_neighbour(this->generate(pad_id{nid_m_w}), 1);
add_neighbour(this->generate(nid_m_w), 1);
}
if((tiles & 1536) == 1536) // E
{
add_neighbour(this->generate(pad_id{nodeid + 1}), 1);
add_neighbour(this->generate(pad_id{nodeid.id + 1}), 1);
}
if((tiles & 131584) == 131584) // S
{
add_neighbour(this->generate(pad_id{nid_p_w}), 1);
add_neighbour(this->generate(nid_p_w), 1);
}
if((tiles & 768) == 768) // W
{
add_neighbour(this->generate(pad_id{nodeid - 1}), 1);
add_neighbour(this->generate(pad_id{nodeid.id - 1}), 1);
}
if(manhattan_) { return; }

// generate diagonal moves
if((tiles & 1542) == 1542) // NE
{
add_neighbour(
this->generate(pad_id{nid_m_w + 1}), warthog::DBL_ROOT_TWO);
this->generate(pad_id{nid_m_w.id + 1}), warthog::DBL_ROOT_TWO);
}
if((tiles & 394752) == 394752) // SE
{
add_neighbour(
this->generate(pad_id{nid_p_w + 1}), warthog::DBL_ROOT_TWO);
this->generate(pad_id{nid_p_w.id + 1}), warthog::DBL_ROOT_TWO);
}
if((tiles & 197376) == 197376) // SW
{
add_neighbour(
this->generate(pad_id{nid_p_w - 1}), warthog::DBL_ROOT_TWO);
this->generate(pad_id{nid_p_w.id - 1}), warthog::DBL_ROOT_TWO);
}
if((tiles & 771) == 771) // NW
{
add_neighbour(
this->generate(pad_id{nid_m_w - 1}), warthog::DBL_ROOT_TWO);
this->generate(pad_id{nid_m_w.id - 1}), warthog::DBL_ROOT_TWO);
}
}

Expand Down Expand Up @@ -132,7 +132,7 @@ gridmap_expansion_policy::generate_start_node(search_problem_instance* pi)
{
uint32_t max_id = map_->width() * map_->height();
if(uint32_t{pi->start_} >= max_id) { return 0; }
if(map_->get_label(uint32_t{pi->start_}) == 0) { return 0; }
if(map_->get_label(pi->start_) == 0) { return 0; }
return generate(pi->start_);
}

Expand All @@ -141,7 +141,7 @@ gridmap_expansion_policy::generate_target_node(search_problem_instance* pi)
{
uint32_t max_id = map_->width() * map_->height();
if((uint32_t)pi->target_ >= max_id) { return 0; }
if(map_->get_label(uint32_t{pi->target_}) == 0) { return 0; }
if(map_->get_label(pi->target_) == 0) { return 0; }
return generate(pi->target_);
}

Expand Down

0 comments on commit f3e5d9e

Please sign in to comment.