Base ConstraintBuilder2D on correspondence cost function (#1088)
- Base `ConstraintBuilder2D` and `FastCorrelativeScanMatcher2D` on correspondence cost function instead of probabilities - No changes in the options of `ConstraintBuilder2D` and `FastCorrelativeScanMatcher2D` - Add properties `min/max_correspondence_cost` to `Grid2D` and `proto::Grid2D` - Provide backwards compatibility for `proto::Grid2D` - Step towards [RFC 0019](https://github.com/googlecartographer/rfcs/blob/master/text/0019-probability-grid-and-submap2d-restructuring.md)master
parent
f4937b5cc6
commit
20c80068b2
|
@ -20,11 +20,16 @@
|
|||
namespace cartographer {
|
||||
namespace mapping {
|
||||
|
||||
Grid2D::Grid2D(const MapLimits& limits)
|
||||
Grid2D::Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
||||
float max_correspondence_cost)
|
||||
: limits_(limits),
|
||||
correspondence_cost_cells_(
|
||||
limits_.cell_limits().num_x_cells * limits_.cell_limits().num_y_cells,
|
||||
kUnknownCorrespondenceValue) {}
|
||||
kUnknownCorrespondenceValue),
|
||||
min_correspondence_cost_(min_correspondence_cost),
|
||||
max_correspondence_cost_(max_correspondence_cost) {
|
||||
CHECK_LT(min_correspondence_cost_, max_correspondence_cost_);
|
||||
}
|
||||
|
||||
Grid2D::Grid2D(const proto::Grid2D& proto)
|
||||
: limits_(proto.limits()), correspondence_cost_cells_() {
|
||||
|
@ -39,6 +44,19 @@ Grid2D::Grid2D(const proto::Grid2D& proto)
|
|||
CHECK_LE(cell, std::numeric_limits<uint16>::max());
|
||||
correspondence_cost_cells_.push_back(cell);
|
||||
}
|
||||
if (proto.min_correspondence_cost() == 0.f &&
|
||||
proto.max_correspondence_cost() == 0.f) {
|
||||
LOG(WARNING)
|
||||
<< "proto::Grid2D: max_correspondence_cost and min_correspondence_cost "
|
||||
"are initialized with 0 indicating an older version of the "
|
||||
"protobuf format. Loading default values.";
|
||||
min_correspondence_cost_ = kMinCorrespondenceCost;
|
||||
max_correspondence_cost_ = kMaxCorrespondenceCost;
|
||||
} else {
|
||||
min_correspondence_cost_ = proto.min_correspondence_cost();
|
||||
max_correspondence_cost_ = proto.max_correspondence_cost();
|
||||
}
|
||||
CHECK_LT(min_correspondence_cost_, max_correspondence_cost_);
|
||||
}
|
||||
|
||||
// Finishes the update sequence.
|
||||
|
@ -51,21 +69,14 @@ void Grid2D::FinishUpdate() {
|
|||
}
|
||||
}
|
||||
|
||||
// Sets the probability of the cell at 'cell_index' to the given
|
||||
// 'probability'. Only allowed if the cell was unknown before.
|
||||
void Grid2D::SetCorrespondenceCost(const Eigen::Array2i& cell_index,
|
||||
const float correspondence_cost) {
|
||||
LOG(FATAL) << "Not implemented";
|
||||
}
|
||||
|
||||
// Returns the probability of the cell with 'cell_index'.
|
||||
// Returns the correspondence cost of the cell with 'cell_index'.
|
||||
float Grid2D::GetCorrespondenceCost(const Eigen::Array2i& cell_index) const {
|
||||
if (!limits().Contains(cell_index)) return kMaxCorrespondenceCost;
|
||||
return ValueToCorrespondenceCost(
|
||||
correspondence_cost_cells()[ToFlatIndex(cell_index)]);
|
||||
}
|
||||
|
||||
// Returns true if the probability at the specified index is known.
|
||||
// Returns true if the correspondence cost at the specified index is known.
|
||||
bool Grid2D::IsKnown(const Eigen::Array2i& cell_index) const {
|
||||
return limits_.Contains(cell_index) &&
|
||||
correspondence_cost_cells_[ToFlatIndex(cell_index)] !=
|
||||
|
@ -136,6 +147,8 @@ proto::Grid2D Grid2D::ToProto() const {
|
|||
box->set_min_x(known_cells_box().min().x());
|
||||
box->set_min_y(known_cells_box().min().y());
|
||||
}
|
||||
result.set_min_correspondence_cost(min_correspondence_cost_);
|
||||
result.set_max_correspondence_cost(max_correspondence_cost_);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,23 +27,24 @@ namespace mapping {
|
|||
|
||||
class Grid2D {
|
||||
public:
|
||||
explicit Grid2D(const MapLimits& limits);
|
||||
explicit Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
||||
float max_correspondence_cost);
|
||||
explicit Grid2D(const proto::Grid2D& proto);
|
||||
|
||||
// Returns the limits of this ProbabilityGrid.
|
||||
// Returns the limits of this Grid2D.
|
||||
const MapLimits& limits() const { return limits_; }
|
||||
|
||||
// Finishes the update sequence.
|
||||
void FinishUpdate();
|
||||
|
||||
// Sets the correspondence cost of the cell at 'cell_index' to the given
|
||||
// 'correspondence_cost'. Only allowed if the cell was unknown before.
|
||||
void SetCorrespondenceCost(const Eigen::Array2i& cell_index,
|
||||
const float correspondence_cost);
|
||||
|
||||
// Returns the correspondence cost of the cell with 'cell_index'.
|
||||
float GetCorrespondenceCost(const Eigen::Array2i& cell_index) const;
|
||||
|
||||
// Returns the minimum possible correspondence cost.
|
||||
float GetMinCorrespondenceCost() const { return min_correspondence_cost_; }
|
||||
|
||||
// Returns the maximum possible correspondence cost.
|
||||
float GetMaxCorrespondenceCost() const { return max_correspondence_cost_; }
|
||||
|
||||
// Returns true if the probability at the specified index is known.
|
||||
bool IsKnown(const Eigen::Array2i& cell_index) const;
|
||||
|
||||
|
@ -80,6 +81,8 @@ class Grid2D {
|
|||
private:
|
||||
MapLimits limits_;
|
||||
std::vector<uint16> correspondence_cost_cells_;
|
||||
float min_correspondence_cost_;
|
||||
float max_correspondence_cost_;
|
||||
std::vector<int> update_indices_;
|
||||
|
||||
// Bounding box of known cells to efficiently compute cropping limits.
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
namespace cartographer {
|
||||
namespace mapping {
|
||||
|
||||
ProbabilityGrid::ProbabilityGrid(const MapLimits& limits) : Grid2D(limits) {}
|
||||
ProbabilityGrid::ProbabilityGrid(const MapLimits& limits)
|
||||
: Grid2D(limits, kMinCorrespondenceCost, kMaxCorrespondenceCost) {}
|
||||
|
||||
ProbabilityGrid::ProbabilityGrid(const proto::Grid2D& proto) : Grid2D(proto) {
|
||||
CHECK(proto.has_probability_grid_2d());
|
||||
|
|
|
@ -35,4 +35,6 @@ message Grid2D {
|
|||
oneof grid {
|
||||
ProbabilityGrid probability_grid_2d = 4;
|
||||
}
|
||||
}
|
||||
float min_correspondence_cost = 6;
|
||||
float max_correspondence_cost = 7;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ void ConstraintBuilder2D::WhenDone(
|
|||
}
|
||||
|
||||
void ConstraintBuilder2D::ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
const SubmapId& submap_id, const ProbabilityGrid* const submap,
|
||||
const SubmapId& submap_id, const Grid2D* const grid,
|
||||
const std::function<void()>& work_item) {
|
||||
if (submap_scan_matchers_[submap_id].fast_correlative_scan_matcher !=
|
||||
nullptr) {
|
||||
|
@ -139,18 +139,18 @@ void ConstraintBuilder2D::ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
|||
submap_queued_work_items_[submap_id].push_back(work_item);
|
||||
if (submap_queued_work_items_[submap_id].size() == 1) {
|
||||
thread_pool_->Schedule(
|
||||
[=]() { ConstructSubmapScanMatcher(submap_id, submap); });
|
||||
[=]() { ConstructSubmapScanMatcher(submap_id, grid); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConstraintBuilder2D::ConstructSubmapScanMatcher(
|
||||
const SubmapId& submap_id, const ProbabilityGrid* const submap) {
|
||||
void ConstraintBuilder2D::ConstructSubmapScanMatcher(const SubmapId& submap_id,
|
||||
const Grid2D* const grid) {
|
||||
auto submap_scan_matcher =
|
||||
common::make_unique<scan_matching::FastCorrelativeScanMatcher2D>(
|
||||
*submap, options_.fast_correlative_scan_matcher_options());
|
||||
*grid, options_.fast_correlative_scan_matcher_options());
|
||||
common::MutexLocker locker(&mutex_);
|
||||
submap_scan_matchers_[submap_id] = {submap, std::move(submap_scan_matcher)};
|
||||
submap_scan_matchers_[submap_id] = {grid, std::move(submap_scan_matcher)};
|
||||
for (const std::function<void()>& work_item :
|
||||
submap_queued_work_items_[submap_id]) {
|
||||
thread_pool_->Schedule(work_item);
|
||||
|
@ -227,8 +227,8 @@ void ConstraintBuilder2D::ComputeConstraint(
|
|||
ceres::Solver::Summary unused_summary;
|
||||
ceres_scan_matcher_.Match(pose_estimate.translation(), pose_estimate,
|
||||
constant_data->filtered_gravity_aligned_point_cloud,
|
||||
*submap_scan_matcher->probability_grid,
|
||||
&pose_estimate, &unused_summary);
|
||||
*submap_scan_matcher->grid, &pose_estimate,
|
||||
&unused_summary);
|
||||
|
||||
const transform::Rigid2d constraint_transform =
|
||||
ComputeSubmapPose(*submap).inverse() * pose_estimate;
|
||||
|
|
|
@ -105,7 +105,7 @@ class ConstraintBuilder2D {
|
|||
|
||||
private:
|
||||
struct SubmapScanMatcher {
|
||||
const ProbabilityGrid* probability_grid;
|
||||
const Grid2D* grid;
|
||||
std::unique_ptr<scan_matching::FastCorrelativeScanMatcher2D>
|
||||
fast_correlative_scan_matcher;
|
||||
};
|
||||
|
@ -113,12 +113,11 @@ class ConstraintBuilder2D {
|
|||
// Either schedules the 'work_item', or if needed, schedules the scan matcher
|
||||
// construction and queues the 'work_item'.
|
||||
void ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
const SubmapId& submap_id, const ProbabilityGrid* submap,
|
||||
const SubmapId& submap_id, const Grid2D* grid,
|
||||
const std::function<void()>& work_item) REQUIRES(mutex_);
|
||||
|
||||
// Constructs the scan matcher for a 'submap', then schedules its work items.
|
||||
void ConstructSubmapScanMatcher(const SubmapId& submap_id,
|
||||
const ProbabilityGrid* submap)
|
||||
void ConstructSubmapScanMatcher(const SubmapId& submap_id, const Grid2D* grid)
|
||||
EXCLUDES(mutex_);
|
||||
|
||||
// Returns the scan matcher for a submap, which has to exist.
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "Eigen/Geometry"
|
||||
#include "cartographer/common/make_unique.h"
|
||||
#include "cartographer/common/math.h"
|
||||
#include "cartographer/mapping/2d/probability_grid.h"
|
||||
#include "cartographer/mapping/2d/grid_2d.h"
|
||||
#include "cartographer/sensor/point_cloud.h"
|
||||
#include "cartographer/transform/transform.h"
|
||||
#include "glog/logging.h"
|
||||
|
@ -89,11 +89,13 @@ CreateFastCorrelativeScanMatcherOptions2D(
|
|||
}
|
||||
|
||||
PrecomputationGrid2D::PrecomputationGrid2D(
|
||||
const ProbabilityGrid& probability_grid, const CellLimits& limits,
|
||||
const int width, std::vector<float>* reusable_intermediate_grid)
|
||||
const Grid2D& grid, const CellLimits& limits, const int width,
|
||||
std::vector<float>* reusable_intermediate_grid)
|
||||
: offset_(-width + 1, -width + 1),
|
||||
wide_limits_(limits.num_x_cells + width - 1,
|
||||
limits.num_y_cells + width - 1),
|
||||
min_score_(1.f - grid.GetMaxCorrespondenceCost()),
|
||||
max_score_(1.f - grid.GetMinCorrespondenceCost()),
|
||||
cells_(wide_limits_.num_x_cells * wide_limits_.num_y_cells) {
|
||||
CHECK_GE(width, 1);
|
||||
CHECK_GE(limits.num_x_cells, 1);
|
||||
|
@ -106,26 +108,26 @@ PrecomputationGrid2D::PrecomputationGrid2D(
|
|||
for (int y = 0; y != limits.num_y_cells; ++y) {
|
||||
SlidingWindowMaximum current_values;
|
||||
current_values.AddValue(
|
||||
probability_grid.GetProbability(Eigen::Array2i(0, y)));
|
||||
1.f - std::abs(grid.GetCorrespondenceCost(Eigen::Array2i(0, y))));
|
||||
for (int x = -width + 1; x != 0; ++x) {
|
||||
intermediate[x + width - 1 + y * stride] = current_values.GetMaximum();
|
||||
if (x + width < limits.num_x_cells) {
|
||||
current_values.AddValue(
|
||||
probability_grid.GetProbability(Eigen::Array2i(x + width, y)));
|
||||
current_values.AddValue(1.f - std::abs(grid.GetCorrespondenceCost(
|
||||
Eigen::Array2i(x + width, y))));
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < limits.num_x_cells - width; ++x) {
|
||||
intermediate[x + width - 1 + y * stride] = current_values.GetMaximum();
|
||||
current_values.RemoveValue(
|
||||
probability_grid.GetProbability(Eigen::Array2i(x, y)));
|
||||
current_values.AddValue(
|
||||
probability_grid.GetProbability(Eigen::Array2i(x + width, y)));
|
||||
1.f - std::abs(grid.GetCorrespondenceCost(Eigen::Array2i(x, y))));
|
||||
current_values.AddValue(1.f - std::abs(grid.GetCorrespondenceCost(
|
||||
Eigen::Array2i(x + width, y))));
|
||||
}
|
||||
for (int x = std::max(limits.num_x_cells - width, 0);
|
||||
x != limits.num_x_cells; ++x) {
|
||||
intermediate[x + width - 1 + y * stride] = current_values.GetMaximum();
|
||||
current_values.RemoveValue(
|
||||
probability_grid.GetProbability(Eigen::Array2i(x, y)));
|
||||
1.f - std::abs(grid.GetCorrespondenceCost(Eigen::Array2i(x, y))));
|
||||
}
|
||||
current_values.CheckIsEmpty();
|
||||
}
|
||||
|
@ -159,38 +161,37 @@ PrecomputationGrid2D::PrecomputationGrid2D(
|
|||
}
|
||||
|
||||
uint8 PrecomputationGrid2D::ComputeCellValue(const float probability) const {
|
||||
const int cell_value =
|
||||
common::RoundToInt((probability - kMinProbability) *
|
||||
(255.f / (kMaxProbability - kMinProbability)));
|
||||
const int cell_value = common::RoundToInt(
|
||||
(probability - min_score_) * (255.f / (max_score_ - min_score_)));
|
||||
CHECK_GE(cell_value, 0);
|
||||
CHECK_LE(cell_value, 255);
|
||||
return cell_value;
|
||||
}
|
||||
|
||||
PrecomputationGridStack2D::PrecomputationGridStack2D(
|
||||
const ProbabilityGrid& probability_grid,
|
||||
const Grid2D& grid,
|
||||
const proto::FastCorrelativeScanMatcherOptions2D& options) {
|
||||
CHECK_GE(options.branch_and_bound_depth(), 1);
|
||||
const int max_width = 1 << (options.branch_and_bound_depth() - 1);
|
||||
precomputation_grids_.reserve(options.branch_and_bound_depth());
|
||||
std::vector<float> reusable_intermediate_grid;
|
||||
const CellLimits limits = probability_grid.limits().cell_limits();
|
||||
const CellLimits limits = grid.limits().cell_limits();
|
||||
reusable_intermediate_grid.reserve((limits.num_x_cells + max_width - 1) *
|
||||
limits.num_y_cells);
|
||||
for (int i = 0; i != options.branch_and_bound_depth(); ++i) {
|
||||
const int width = 1 << i;
|
||||
precomputation_grids_.emplace_back(probability_grid, limits, width,
|
||||
precomputation_grids_.emplace_back(grid, limits, width,
|
||||
&reusable_intermediate_grid);
|
||||
}
|
||||
}
|
||||
|
||||
FastCorrelativeScanMatcher2D::FastCorrelativeScanMatcher2D(
|
||||
const ProbabilityGrid& probability_grid,
|
||||
const Grid2D& grid,
|
||||
const proto::FastCorrelativeScanMatcherOptions2D& options)
|
||||
: options_(options),
|
||||
limits_(probability_grid.limits()),
|
||||
precomputation_grid_stack_(common::make_unique<PrecomputationGridStack2D>(
|
||||
probability_grid, options)) {}
|
||||
limits_(grid.limits()),
|
||||
precomputation_grid_stack_(
|
||||
common::make_unique<PrecomputationGridStack2D>(grid, options)) {}
|
||||
|
||||
FastCorrelativeScanMatcher2D::~FastCorrelativeScanMatcher2D() {}
|
||||
|
||||
|
@ -324,7 +325,7 @@ void FastCorrelativeScanMatcher2D::ScoreCandidates(
|
|||
xy_index.y() + candidate.y_index_offset);
|
||||
sum += precomputation_grid.GetValue(proposed_xy_index);
|
||||
}
|
||||
candidate.score = PrecomputationGrid2D::ToProbability(
|
||||
candidate.score = precomputation_grid.ToScore(
|
||||
sum / static_cast<float>(discrete_scans[candidate.scan_index].size()));
|
||||
}
|
||||
std::sort(candidates->begin(), candidates->end(),
|
||||
|
|
|
@ -30,10 +30,9 @@
|
|||
|
||||
#include "Eigen/Core"
|
||||
#include "cartographer/common/port.h"
|
||||
#include "cartographer/mapping/2d/probability_grid.h"
|
||||
#include "cartographer/mapping/2d/grid_2d.h"
|
||||
#include "cartographer/mapping/2d/scan_matching/proto/fast_correlative_scan_matcher_options_2d.pb.h"
|
||||
#include "cartographer/mapping/internal/2d/scan_matching/correlative_scan_matcher_2d.h"
|
||||
#include "cartographer/mapping/probability_values.h"
|
||||
#include "cartographer/sensor/point_cloud.h"
|
||||
|
||||
namespace cartographer {
|
||||
|
@ -49,12 +48,11 @@ CreateFastCorrelativeScanMatcherOptions2D(
|
|||
// y0 <= y < y0.
|
||||
class PrecomputationGrid2D {
|
||||
public:
|
||||
PrecomputationGrid2D(const ProbabilityGrid& probability_grid,
|
||||
const CellLimits& limits, int width,
|
||||
PrecomputationGrid2D(const Grid2D& grid, const CellLimits& limits, int width,
|
||||
std::vector<float>* reusable_intermediate_grid);
|
||||
|
||||
// Returns a value between 0 and 255 to represent probabilities between
|
||||
// kMinProbability and kMaxProbability.
|
||||
// min_score and max_score.
|
||||
int GetValue(const Eigen::Array2i& xy_index) const {
|
||||
const Eigen::Array2i local_xy_index = xy_index - offset_;
|
||||
// The static_cast<unsigned> is for performance to check with 2 comparisons
|
||||
|
@ -72,10 +70,9 @@ class PrecomputationGrid2D {
|
|||
return cells_[local_xy_index.x() + local_xy_index.y() * stride];
|
||||
}
|
||||
|
||||
// Maps values from [0, 255] to [kMinProbability, kMaxProbability].
|
||||
static float ToProbability(float value) {
|
||||
return kMinProbability +
|
||||
value * ((kMaxProbability - kMinProbability) / 255.f);
|
||||
// Maps values from [0, 255] to [min_score, max_score].
|
||||
float ToScore(float value) const {
|
||||
return min_score_ + value * ((max_score_ - min_score_) / 255.f);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -88,6 +85,9 @@ class PrecomputationGrid2D {
|
|||
// Size of the precomputation grid.
|
||||
const CellLimits wide_limits_;
|
||||
|
||||
const float min_score_;
|
||||
const float max_score_;
|
||||
|
||||
// Probabilites mapped to 0 to 255.
|
||||
std::vector<uint8> cells_;
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ class PrecomputationGrid2D {
|
|||
class PrecomputationGridStack2D {
|
||||
public:
|
||||
PrecomputationGridStack2D(
|
||||
const ProbabilityGrid& probability_grid,
|
||||
const Grid2D& grid,
|
||||
const proto::FastCorrelativeScanMatcherOptions2D& options);
|
||||
|
||||
const PrecomputationGrid2D& Get(int index) {
|
||||
|
@ -112,7 +112,7 @@ class PrecomputationGridStack2D {
|
|||
class FastCorrelativeScanMatcher2D {
|
||||
public:
|
||||
FastCorrelativeScanMatcher2D(
|
||||
const ProbabilityGrid& probability_grid,
|
||||
const Grid2D& grid,
|
||||
const proto::FastCorrelativeScanMatcherOptions2D& options);
|
||||
~FastCorrelativeScanMatcher2D();
|
||||
|
||||
|
@ -120,7 +120,7 @@ class FastCorrelativeScanMatcher2D {
|
|||
FastCorrelativeScanMatcher2D& operator=(const FastCorrelativeScanMatcher2D&) =
|
||||
delete;
|
||||
|
||||
// Aligns 'point_cloud' within the 'probability_grid' given an
|
||||
// Aligns 'point_cloud' within the 'grid' given an
|
||||
// 'initial_pose_estimate'. If a score above 'min_score' (excluding equality)
|
||||
// is possible, true is returned, and 'score' and 'pose_estimate' are updated
|
||||
// with the result.
|
||||
|
@ -128,7 +128,7 @@ class FastCorrelativeScanMatcher2D {
|
|||
const sensor::PointCloud& point_cloud, float min_score,
|
||||
float* score, transform::Rigid2d* pose_estimate) const;
|
||||
|
||||
// Aligns 'point_cloud' within the full 'probability_grid', i.e., not
|
||||
// Aligns 'point_cloud' within the full 'grid', i.e., not
|
||||
// restricted to the configured search window. If a score above 'min_score'
|
||||
// (excluding equality) is possible, true is returned, and 'score' and
|
||||
// 'pose_estimate' are updated with the result.
|
||||
|
|
|
@ -41,13 +41,17 @@ TEST(PrecomputationGridTest, CorrectValues) {
|
|||
std::uniform_int_distribution<int> distribution(0, 255);
|
||||
ProbabilityGrid probability_grid(
|
||||
MapLimits(0.05, Eigen::Vector2d(5., 5.), CellLimits(250, 250)));
|
||||
std::vector<float> reusable_intermediate_grid;
|
||||
PrecomputationGrid2D precomputation_grid_dummy(
|
||||
probability_grid, probability_grid.limits().cell_limits(), 1,
|
||||
&reusable_intermediate_grid);
|
||||
for (const Eigen::Array2i& xy_index :
|
||||
XYIndexRangeIterator(Eigen::Array2i(50, 50), Eigen::Array2i(249, 249))) {
|
||||
probability_grid.SetProbability(
|
||||
xy_index, PrecomputationGrid2D::ToProbability(distribution(prng)));
|
||||
xy_index, precomputation_grid_dummy.ToScore(distribution(prng)));
|
||||
}
|
||||
|
||||
std::vector<float> reusable_intermediate_grid;
|
||||
reusable_intermediate_grid.clear();
|
||||
for (const int width : {1, 2, 3, 8}) {
|
||||
PrecomputationGrid2D precomputation_grid(
|
||||
probability_grid, probability_grid.limits().cell_limits(), width,
|
||||
|
@ -62,10 +66,10 @@ TEST(PrecomputationGridTest, CorrectValues) {
|
|||
probability_grid.GetProbability(xy_index + Eigen::Array2i(x, y)));
|
||||
}
|
||||
}
|
||||
EXPECT_NEAR(max_score,
|
||||
PrecomputationGrid2D::ToProbability(
|
||||
precomputation_grid.GetValue(xy_index)),
|
||||
1e-4);
|
||||
EXPECT_NEAR(
|
||||
max_score,
|
||||
precomputation_grid.ToScore(precomputation_grid.GetValue(xy_index)),
|
||||
1e-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +79,17 @@ TEST(PrecomputationGridTest, TinyProbabilityGrid) {
|
|||
std::uniform_int_distribution<int> distribution(0, 255);
|
||||
ProbabilityGrid probability_grid(
|
||||
MapLimits(0.05, Eigen::Vector2d(0.1, 0.1), CellLimits(4, 4)));
|
||||
std::vector<float> reusable_intermediate_grid;
|
||||
PrecomputationGrid2D precomputation_grid_dummy(
|
||||
probability_grid, probability_grid.limits().cell_limits(), 1,
|
||||
&reusable_intermediate_grid);
|
||||
for (const Eigen::Array2i& xy_index :
|
||||
XYIndexRangeIterator(probability_grid.limits().cell_limits())) {
|
||||
probability_grid.SetProbability(
|
||||
xy_index, PrecomputationGrid2D::ToProbability(distribution(prng)));
|
||||
xy_index, precomputation_grid_dummy.ToScore(distribution(prng)));
|
||||
}
|
||||
|
||||
std::vector<float> reusable_intermediate_grid;
|
||||
reusable_intermediate_grid.clear();
|
||||
for (const int width : {1, 2, 3, 8, 200}) {
|
||||
PrecomputationGrid2D precomputation_grid(
|
||||
probability_grid, probability_grid.limits().cell_limits(), width,
|
||||
|
@ -96,10 +104,10 @@ TEST(PrecomputationGridTest, TinyProbabilityGrid) {
|
|||
probability_grid.GetProbability(xy_index + Eigen::Array2i(x, y)));
|
||||
}
|
||||
}
|
||||
EXPECT_NEAR(max_score,
|
||||
PrecomputationGrid2D::ToProbability(
|
||||
precomputation_grid.GetValue(xy_index)),
|
||||
1e-4);
|
||||
EXPECT_NEAR(
|
||||
max_score,
|
||||
precomputation_grid.ToScore(precomputation_grid.GetValue(xy_index)),
|
||||
1e-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue