Introduce Grid and RangeDataInserter (#1108)
- Introduce `RangeDataInserterInterface` as common interface for all range data inserters - Introduce a minimal `GridInterface` as a base for a common interface for 2D and 3D grids - Rename `RangeDataInserter2D` to `ProbabilityGridRangeDataInserter2D` - Move grid generation logic from `Submap2D` to `ActiveSubmaps2D` - Update proto and configuration structure to mirror the code structure - backwards compatibility is maintained - Step towards [RFC 0019](https://github.com/googlecartographer/rfcs/blob/master/text/0019-probability-grid-and-submap2d-restructuring.md)master
parent
91fda93757
commit
41f17e57cd
|
@ -57,8 +57,8 @@ uint8 ProbabilityToColor(float probability_from_grid) {
|
||||||
|
|
||||||
ProbabilityGridPointsProcessor::ProbabilityGridPointsProcessor(
|
ProbabilityGridPointsProcessor::ProbabilityGridPointsProcessor(
|
||||||
const double resolution,
|
const double resolution,
|
||||||
const mapping::proto::RangeDataInserterOptions2D&
|
const mapping::proto::ProbabilityGridRangeDataInserterOptions2D&
|
||||||
range_data_inserter_options,
|
probability_grid_range_data_inserter_options,
|
||||||
const DrawTrajectories& draw_trajectories,
|
const DrawTrajectories& draw_trajectories,
|
||||||
std::unique_ptr<FileWriter> file_writer,
|
std::unique_ptr<FileWriter> file_writer,
|
||||||
const std::vector<mapping::proto::Trajectory>& trajectories,
|
const std::vector<mapping::proto::Trajectory>& trajectories,
|
||||||
|
@ -67,7 +67,7 @@ ProbabilityGridPointsProcessor::ProbabilityGridPointsProcessor(
|
||||||
trajectories_(trajectories),
|
trajectories_(trajectories),
|
||||||
file_writer_(std::move(file_writer)),
|
file_writer_(std::move(file_writer)),
|
||||||
next_(next),
|
next_(next),
|
||||||
range_data_inserter_(range_data_inserter_options),
|
range_data_inserter_(probability_grid_range_data_inserter_options),
|
||||||
probability_grid_(CreateProbabilityGrid(resolution)) {}
|
probability_grid_(CreateProbabilityGrid(resolution)) {}
|
||||||
|
|
||||||
std::unique_ptr<ProbabilityGridPointsProcessor>
|
std::unique_ptr<ProbabilityGridPointsProcessor>
|
||||||
|
@ -82,7 +82,7 @@ ProbabilityGridPointsProcessor::FromDictionary(
|
||||||
: DrawTrajectories::kNo;
|
: DrawTrajectories::kNo;
|
||||||
return common::make_unique<ProbabilityGridPointsProcessor>(
|
return common::make_unique<ProbabilityGridPointsProcessor>(
|
||||||
dictionary->GetDouble("resolution"),
|
dictionary->GetDouble("resolution"),
|
||||||
mapping::CreateRangeDataInserterOptions2D(
|
mapping::CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
dictionary->GetDictionary("range_data_inserter").get()),
|
dictionary->GetDictionary("range_data_inserter").get()),
|
||||||
draw_trajectories,
|
draw_trajectories,
|
||||||
file_writer_factory(dictionary->GetString("filename") + ".png"),
|
file_writer_factory(dictionary->GetString("filename") + ".png"),
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#include "cartographer/io/points_batch.h"
|
#include "cartographer/io/points_batch.h"
|
||||||
#include "cartographer/io/points_processor.h"
|
#include "cartographer/io/points_processor.h"
|
||||||
#include "cartographer/mapping/2d/probability_grid.h"
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
#include "cartographer/mapping/2d/proto/range_data_inserter_options_2d.pb.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/proto/probability_grid_range_data_inserter_options_2d.pb.h"
|
||||||
#include "cartographer/mapping/proto/trajectory.pb.h"
|
#include "cartographer/mapping/proto/trajectory.pb.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
|
@ -42,8 +42,8 @@ class ProbabilityGridPointsProcessor : public PointsProcessor {
|
||||||
enum class DrawTrajectories { kNo, kYes };
|
enum class DrawTrajectories { kNo, kYes };
|
||||||
ProbabilityGridPointsProcessor(
|
ProbabilityGridPointsProcessor(
|
||||||
double resolution,
|
double resolution,
|
||||||
const mapping::proto::RangeDataInserterOptions2D&
|
const mapping::proto::ProbabilityGridRangeDataInserterOptions2D&
|
||||||
range_data_inserter_options,
|
probability_grid_range_data_inserter_options,
|
||||||
const DrawTrajectories& draw_trajectories,
|
const DrawTrajectories& draw_trajectories,
|
||||||
std::unique_ptr<FileWriter> file_writer,
|
std::unique_ptr<FileWriter> file_writer,
|
||||||
const std::vector<mapping::proto::Trajectory>& trajectorios,
|
const std::vector<mapping::proto::Trajectory>& trajectorios,
|
||||||
|
@ -68,7 +68,7 @@ class ProbabilityGridPointsProcessor : public PointsProcessor {
|
||||||
const std::vector<mapping::proto::Trajectory> trajectories_;
|
const std::vector<mapping::proto::Trajectory> trajectories_;
|
||||||
std::unique_ptr<FileWriter> file_writer_;
|
std::unique_ptr<FileWriter> file_writer_;
|
||||||
PointsProcessor* const next_;
|
PointsProcessor* const next_;
|
||||||
mapping::RangeDataInserter2D range_data_inserter_;
|
mapping::ProbabilityGridRangeDataInserter2D range_data_inserter_;
|
||||||
mapping::ProbabilityGrid probability_grid_;
|
mapping::ProbabilityGrid probability_grid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,19 @@
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace mapping {
|
namespace mapping {
|
||||||
|
|
||||||
|
proto::GridOptions2D CreateGridOptions2D(
|
||||||
|
common::LuaParameterDictionary* const parameter_dictionary) {
|
||||||
|
proto::GridOptions2D options;
|
||||||
|
const std::string grid_type_string =
|
||||||
|
parameter_dictionary->GetString("grid_type");
|
||||||
|
proto::GridOptions2D_GridType grid_type;
|
||||||
|
CHECK(proto::GridOptions2D_GridType_Parse(grid_type_string, &grid_type))
|
||||||
|
<< "Unknown GridOptions2D_GridType kind: " << grid_type_string;
|
||||||
|
options.set_grid_type(grid_type);
|
||||||
|
options.set_resolution(parameter_dictionary->GetDouble("resolution"));
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
Grid2D::Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
Grid2D::Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
||||||
float max_correspondence_cost)
|
float max_correspondence_cost)
|
||||||
: limits_(limits),
|
: limits_(limits),
|
||||||
|
|
|
@ -21,12 +21,17 @@
|
||||||
|
|
||||||
#include "cartographer/mapping/2d/map_limits.h"
|
#include "cartographer/mapping/2d/map_limits.h"
|
||||||
#include "cartographer/mapping/2d/proto/grid_2d.pb.h"
|
#include "cartographer/mapping/2d/proto/grid_2d.pb.h"
|
||||||
|
#include "cartographer/mapping/2d/proto/submaps_options_2d.pb.h"
|
||||||
|
#include "cartographer/mapping/grid_interface.h"
|
||||||
#include "cartographer/mapping/proto/submap_visualization.pb.h"
|
#include "cartographer/mapping/proto/submap_visualization.pb.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace mapping {
|
namespace mapping {
|
||||||
|
|
||||||
class Grid2D {
|
proto::GridOptions2D CreateGridOptions2D(
|
||||||
|
common::LuaParameterDictionary* const parameter_dictionary);
|
||||||
|
|
||||||
|
class Grid2D : public GridInterface {
|
||||||
public:
|
public:
|
||||||
explicit Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
explicit Grid2D(const MapLimits& limits, float min_correspondence_cost,
|
||||||
float max_correspondence_cost);
|
float max_correspondence_cost);
|
||||||
|
@ -57,7 +62,7 @@ class Grid2D {
|
||||||
// Grows the map as necessary to include 'point'. This changes the meaning of
|
// Grows the map as necessary to include 'point'. This changes the meaning of
|
||||||
// these coordinates going forward. This method must be called immediately
|
// these coordinates going forward. This method must be called immediately
|
||||||
// after 'FinishUpdate', before any calls to 'ApplyLookupTable'.
|
// after 'FinishUpdate', before any calls to 'ApplyLookupTable'.
|
||||||
void GrowLimits(const Eigen::Vector2f& point);
|
virtual void GrowLimits(const Eigen::Vector2f& point);
|
||||||
|
|
||||||
virtual std::unique_ptr<Grid2D> ComputeCroppedGrid() const = 0;
|
virtual std::unique_ptr<Grid2D> ComputeCroppedGrid() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ float ProbabilityGrid::GetProbability(const Eigen::Array2i& cell_index) const {
|
||||||
return CorrespondenceCostToProbability(ValueToCorrespondenceCost(
|
return CorrespondenceCostToProbability(ValueToCorrespondenceCost(
|
||||||
correspondence_cost_cells()[ToFlatIndex(cell_index)]));
|
correspondence_cost_cells()[ToFlatIndex(cell_index)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
proto::Grid2D ProbabilityGrid::ToProto() const {
|
proto::Grid2D ProbabilityGrid::ToProto() const {
|
||||||
proto::Grid2D result;
|
proto::Grid2D result;
|
||||||
result = Grid2D::ToProto();
|
result = Grid2D::ToProto();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
@ -28,9 +28,10 @@
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace mapping {
|
namespace mapping {
|
||||||
|
|
||||||
proto::RangeDataInserterOptions2D CreateRangeDataInserterOptions2D(
|
proto::ProbabilityGridRangeDataInserterOptions2D
|
||||||
common::LuaParameterDictionary* const parameter_dictionary) {
|
CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
proto::RangeDataInserterOptions2D options;
|
common::LuaParameterDictionary* parameter_dictionary) {
|
||||||
|
proto::ProbabilityGridRangeDataInserterOptions2D options;
|
||||||
options.set_hit_probability(
|
options.set_hit_probability(
|
||||||
parameter_dictionary->GetDouble("hit_probability"));
|
parameter_dictionary->GetDouble("hit_probability"));
|
||||||
options.set_miss_probability(
|
options.set_miss_probability(
|
||||||
|
@ -44,21 +45,22 @@ proto::RangeDataInserterOptions2D CreateRangeDataInserterOptions2D(
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeDataInserter2D::RangeDataInserter2D(
|
ProbabilityGridRangeDataInserter2D::ProbabilityGridRangeDataInserter2D(
|
||||||
const proto::RangeDataInserterOptions2D& options)
|
const proto::ProbabilityGridRangeDataInserterOptions2D& options)
|
||||||
: options_(options),
|
: options_(options),
|
||||||
hit_table_(ComputeLookupTableToApplyCorrespondenceCostOdds(
|
hit_table_(ComputeLookupTableToApplyCorrespondenceCostOdds(
|
||||||
Odds(options.hit_probability()))),
|
Odds(options.hit_probability()))),
|
||||||
miss_table_(ComputeLookupTableToApplyCorrespondenceCostOdds(
|
miss_table_(ComputeLookupTableToApplyCorrespondenceCostOdds(
|
||||||
Odds(options.miss_probability()))) {}
|
Odds(options.miss_probability()))) {}
|
||||||
|
|
||||||
void RangeDataInserter2D::Insert(const sensor::RangeData& range_data,
|
void ProbabilityGridRangeDataInserter2D::Insert(
|
||||||
Grid2D* const grid) const {
|
const sensor::RangeData& range_data, GridInterface* const grid) const {
|
||||||
|
ProbabilityGrid* const probability_grid = static_cast<ProbabilityGrid*>(grid);
|
||||||
// By not finishing the update after hits are inserted, we give hits priority
|
// By not finishing the update after hits are inserted, we give hits priority
|
||||||
// (i.e. no hits will be ignored because of a miss in the same cell).
|
// (i.e. no hits will be ignored because of a miss in the same cell).
|
||||||
CastRays(range_data, hit_table_, miss_table_, options_.insert_free_space(),
|
CastRays(range_data, hit_table_, miss_table_, options_.insert_free_space(),
|
||||||
CHECK_NOTNULL(static_cast<ProbabilityGrid*>(grid)));
|
CHECK_NOTNULL(probability_grid));
|
||||||
grid->FinishUpdate();
|
probability_grid->FinishUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mapping
|
} // namespace mapping
|
|
@ -14,8 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_H_
|
#ifndef CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_PROBABILITY_GRID_H_
|
||||||
#define CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_H_
|
#define CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_PROBABILITY_GRID_H_
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -23,30 +23,35 @@
|
||||||
#include "cartographer/common/lua_parameter_dictionary.h"
|
#include "cartographer/common/lua_parameter_dictionary.h"
|
||||||
#include "cartographer/common/port.h"
|
#include "cartographer/common/port.h"
|
||||||
#include "cartographer/mapping/2d/probability_grid.h"
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
#include "cartographer/mapping/2d/proto/range_data_inserter_options_2d.pb.h"
|
#include "cartographer/mapping/2d/proto/probability_grid_range_data_inserter_options_2d.pb.h"
|
||||||
#include "cartographer/mapping/2d/xy_index.h"
|
#include "cartographer/mapping/2d/xy_index.h"
|
||||||
|
#include "cartographer/mapping/range_data_inserter_interface.h"
|
||||||
#include "cartographer/sensor/point_cloud.h"
|
#include "cartographer/sensor/point_cloud.h"
|
||||||
#include "cartographer/sensor/range_data.h"
|
#include "cartographer/sensor/range_data.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace mapping {
|
namespace mapping {
|
||||||
|
|
||||||
proto::RangeDataInserterOptions2D CreateRangeDataInserterOptions2D(
|
proto::ProbabilityGridRangeDataInserterOptions2D
|
||||||
|
CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
common::LuaParameterDictionary* parameter_dictionary);
|
common::LuaParameterDictionary* parameter_dictionary);
|
||||||
|
|
||||||
class RangeDataInserter2D {
|
class ProbabilityGridRangeDataInserter2D : public RangeDataInserterInterface {
|
||||||
public:
|
public:
|
||||||
explicit RangeDataInserter2D(
|
explicit ProbabilityGridRangeDataInserter2D(
|
||||||
const proto::RangeDataInserterOptions2D& options);
|
const proto::ProbabilityGridRangeDataInserterOptions2D& options);
|
||||||
|
|
||||||
RangeDataInserter2D(const RangeDataInserter2D&) = delete;
|
ProbabilityGridRangeDataInserter2D(
|
||||||
RangeDataInserter2D& operator=(const RangeDataInserter2D&) = delete;
|
const ProbabilityGridRangeDataInserter2D&) = delete;
|
||||||
|
ProbabilityGridRangeDataInserter2D& operator=(
|
||||||
|
const ProbabilityGridRangeDataInserter2D&) = delete;
|
||||||
|
|
||||||
// Inserts 'range_data' into 'probability_grid'.
|
// Inserts 'range_data' into 'probability_grid'.
|
||||||
void Insert(const sensor::RangeData& range_data, Grid2D* grid) const;
|
virtual void Insert(const sensor::RangeData& range_data,
|
||||||
|
GridInterface* grid) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const proto::RangeDataInserterOptions2D options_;
|
const proto::ProbabilityGridRangeDataInserterOptions2D options_;
|
||||||
const std::vector<uint16> hit_table_;
|
const std::vector<uint16> hit_table_;
|
||||||
const std::vector<uint16> miss_table_;
|
const std::vector<uint16> miss_table_;
|
||||||
};
|
};
|
||||||
|
@ -54,4 +59,4 @@ class RangeDataInserter2D {
|
||||||
} // namespace mapping
|
} // namespace mapping
|
||||||
} // namespace cartographer
|
} // namespace cartographer
|
||||||
|
|
||||||
#endif // CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_H_
|
#endif // CARTOGRAPHER_MAPPING_2D_RANGE_DATA_INSERTER_2D_PROBABILITY_GRID_H_
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2018 The Cartographer Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package cartographer.mapping.proto;
|
||||||
|
|
||||||
|
message GridOptions2D {
|
||||||
|
enum GridType {
|
||||||
|
INVALID_GRID = 0;
|
||||||
|
PROBABILITY_GRID = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridType grid_type = 1;
|
||||||
|
float resolution = 2;
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ syntax = "proto3";
|
||||||
|
|
||||||
package cartographer.mapping.proto;
|
package cartographer.mapping.proto;
|
||||||
|
|
||||||
message RangeDataInserterOptions2D {
|
message ProbabilityGridRangeDataInserterOptions2D {
|
||||||
// Probability change for a hit (this will be converted to odds and therefore
|
// Probability change for a hit (this will be converted to odds and therefore
|
||||||
// must be greater than 0.5).
|
// must be greater than 0.5).
|
||||||
double hit_probability = 1;
|
double hit_probability = 1;
|
|
@ -14,18 +14,17 @@
|
||||||
|
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
import "cartographer/mapping/2d/proto/range_data_inserter_options_2d.proto";
|
import "cartographer/mapping/2d/proto/grid_2d_options.proto";
|
||||||
|
import "cartographer/mapping/2d/proto/probability_grid_range_data_inserter_options_2d.proto";
|
||||||
|
import "cartographer/mapping/proto/range_data_inserter_options.proto";
|
||||||
|
|
||||||
package cartographer.mapping.proto;
|
package cartographer.mapping.proto;
|
||||||
|
|
||||||
message SubmapsOptions2D {
|
message SubmapsOptions2D {
|
||||||
// Resolution of the map in meters.
|
|
||||||
double resolution = 1;
|
|
||||||
|
|
||||||
// Number of range data before adding a new submap. Each submap will get twice
|
// Number of range data before adding a new submap. Each submap will get twice
|
||||||
// the number of range data inserted: First for initialization without being
|
// the number of range data inserted: First for initialization without being
|
||||||
// matched against, then while being matched.
|
// matched against, then while being matched.
|
||||||
int32 num_range_data = 3;
|
int32 num_range_data = 1;
|
||||||
|
GridOptions2D grid_options_2d = 2;
|
||||||
RangeDataInserterOptions2D range_data_inserter_options = 5;
|
RangeDataInserterOptions range_data_inserter_options = 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -40,8 +40,10 @@ class RangeDataInserterTest2D : public ::testing::Test {
|
||||||
"hit_probability = 0.7, "
|
"hit_probability = 0.7, "
|
||||||
"miss_probability = 0.4, "
|
"miss_probability = 0.4, "
|
||||||
"}");
|
"}");
|
||||||
options_ = CreateRangeDataInserterOptions2D(parameter_dictionary.get());
|
options_ = CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
range_data_inserter_ = common::make_unique<RangeDataInserter2D>(options_);
|
parameter_dictionary.get());
|
||||||
|
range_data_inserter_ =
|
||||||
|
common::make_unique<ProbabilityGridRangeDataInserter2D>(options_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertPointCloud() {
|
void InsertPointCloud() {
|
||||||
|
@ -57,8 +59,8 @@ class RangeDataInserterTest2D : public ::testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProbabilityGrid probability_grid_;
|
ProbabilityGrid probability_grid_;
|
||||||
std::unique_ptr<RangeDataInserter2D> range_data_inserter_;
|
std::unique_ptr<ProbabilityGridRangeDataInserter2D> range_data_inserter_;
|
||||||
proto::RangeDataInserterOptions2D options_;
|
proto::ProbabilityGridRangeDataInserterOptions2D options_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(RangeDataInserterTest2D, InsertPointCloud) {
|
TEST_F(RangeDataInserterTest2D, InsertPointCloud) {
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "Eigen/Geometry"
|
#include "Eigen/Geometry"
|
||||||
#include "cartographer/common/make_unique.h"
|
#include "cartographer/common/make_unique.h"
|
||||||
#include "cartographer/common/port.h"
|
#include "cartographer/common/port.h"
|
||||||
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
|
#include "cartographer/mapping/range_data_inserter_interface.h"
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
|
@ -33,20 +35,37 @@ namespace mapping {
|
||||||
proto::SubmapsOptions2D CreateSubmapsOptions2D(
|
proto::SubmapsOptions2D CreateSubmapsOptions2D(
|
||||||
common::LuaParameterDictionary* const parameter_dictionary) {
|
common::LuaParameterDictionary* const parameter_dictionary) {
|
||||||
proto::SubmapsOptions2D options;
|
proto::SubmapsOptions2D options;
|
||||||
options.set_resolution(parameter_dictionary->GetDouble("resolution"));
|
|
||||||
options.set_num_range_data(
|
options.set_num_range_data(
|
||||||
parameter_dictionary->GetNonNegativeInt("num_range_data"));
|
parameter_dictionary->GetNonNegativeInt("num_range_data"));
|
||||||
|
*options.mutable_grid_options_2d() = CreateGridOptions2D(
|
||||||
|
parameter_dictionary->GetDictionary("grid_options_2d").get());
|
||||||
*options.mutable_range_data_inserter_options() =
|
*options.mutable_range_data_inserter_options() =
|
||||||
CreateRangeDataInserterOptions2D(
|
CreateRangeDataInserterOptions(
|
||||||
parameter_dictionary->GetDictionary("range_data_inserter").get());
|
parameter_dictionary->GetDictionary("range_data_inserter").get());
|
||||||
|
|
||||||
|
bool valid_range_data_inserter_grid_combination = false;
|
||||||
|
const proto::GridOptions2D_GridType& grid_type =
|
||||||
|
options.grid_options_2d().grid_type();
|
||||||
|
const proto::RangeDataInserterOptions_RangeDataInserterType&
|
||||||
|
range_data_inserter_type =
|
||||||
|
options.range_data_inserter_options().range_data_inserter_type();
|
||||||
|
if (grid_type == proto::GridOptions2D::PROBABILITY_GRID &&
|
||||||
|
range_data_inserter_type ==
|
||||||
|
proto::RangeDataInserterOptions::PROBABILITY_GRID_INSERTER_2D) {
|
||||||
|
valid_range_data_inserter_grid_combination = true;
|
||||||
|
}
|
||||||
|
CHECK(valid_range_data_inserter_grid_combination)
|
||||||
|
<< "Invalid combination grid_type " << grid_type
|
||||||
|
<< " with range_data_inserter_type " << range_data_inserter_type;
|
||||||
CHECK_GT(options.num_range_data(), 0);
|
CHECK_GT(options.num_range_data(), 0);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
Submap2D::Submap2D(const MapLimits& limits, const Eigen::Vector2f& origin)
|
Submap2D::Submap2D(const Eigen::Vector2f& origin, std::unique_ptr<Grid2D> grid)
|
||||||
: Submap(transform::Rigid3d::Translation(
|
: Submap(transform::Rigid3d::Translation(
|
||||||
Eigen::Vector3d(origin.x(), origin.y(), 0.))),
|
Eigen::Vector3d(origin.x(), origin.y(), 0.))) {
|
||||||
grid_(common::make_unique<ProbabilityGrid>(limits)) {}
|
grid_ = std::move(grid);
|
||||||
|
}
|
||||||
|
|
||||||
Submap2D::Submap2D(const proto::Submap2D& proto)
|
Submap2D::Submap2D(const proto::Submap2D& proto)
|
||||||
: Submap(transform::ToRigid3(proto.local_pose())) {
|
: Submap(transform::ToRigid3(proto.local_pose())) {
|
||||||
|
@ -91,11 +110,12 @@ void Submap2D::ToResponseProto(
|
||||||
grid()->DrawToSubmapTexture(texture, local_pose());
|
grid()->DrawToSubmapTexture(texture, local_pose());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Submap2D::InsertRangeData(const sensor::RangeData& range_data,
|
void Submap2D::InsertRangeData(
|
||||||
const RangeDataInserter2D& range_data_inserter) {
|
const sensor::RangeData& range_data,
|
||||||
|
const RangeDataInserterInterface* range_data_inserter) {
|
||||||
CHECK(grid_);
|
CHECK(grid_);
|
||||||
CHECK(!finished());
|
CHECK(!finished());
|
||||||
range_data_inserter.Insert(range_data, grid_.get());
|
range_data_inserter->Insert(range_data, grid_.get());
|
||||||
set_num_range_data(num_range_data() + 1);
|
set_num_range_data(num_range_data() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,27 +128,45 @@ void Submap2D::Finish() {
|
||||||
|
|
||||||
ActiveSubmaps2D::ActiveSubmaps2D(const proto::SubmapsOptions2D& options)
|
ActiveSubmaps2D::ActiveSubmaps2D(const proto::SubmapsOptions2D& options)
|
||||||
: options_(options),
|
: options_(options),
|
||||||
range_data_inserter_(options.range_data_inserter_options()) {
|
range_data_inserter_(std::move(CreateRangeDataInserter())) {
|
||||||
// We always want to have at least one likelihood field which we can return,
|
// We always want to have at least one likelihood field which we can return,
|
||||||
// and will create it at the origin in absence of a better choice.
|
// and will create it at the origin in absence of a better choice.
|
||||||
AddSubmap(Eigen::Vector2f::Zero());
|
AddSubmap(Eigen::Vector2f::Zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActiveSubmaps2D::InsertRangeData(const sensor::RangeData& range_data) {
|
|
||||||
for (auto& submap : submaps_) {
|
|
||||||
submap->InsertRangeData(range_data, range_data_inserter_);
|
|
||||||
}
|
|
||||||
if (submaps_.back()->num_range_data() == options_.num_range_data()) {
|
|
||||||
AddSubmap(range_data.origin.head<2>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Submap2D>> ActiveSubmaps2D::submaps() const {
|
std::vector<std::shared_ptr<Submap2D>> ActiveSubmaps2D::submaps() const {
|
||||||
return submaps_;
|
return submaps_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActiveSubmaps2D::matching_index() const { return matching_submap_index_; }
|
int ActiveSubmaps2D::matching_index() const { return matching_submap_index_; }
|
||||||
|
|
||||||
|
void ActiveSubmaps2D::InsertRangeData(const sensor::RangeData& range_data) {
|
||||||
|
for (auto& submap : submaps_) {
|
||||||
|
submap->InsertRangeData(range_data, range_data_inserter_.get());
|
||||||
|
}
|
||||||
|
if (submaps_.back()->num_range_data() == options_.num_range_data()) {
|
||||||
|
AddSubmap(range_data.origin.head<2>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<RangeDataInserterInterface>
|
||||||
|
ActiveSubmaps2D::CreateRangeDataInserter() {
|
||||||
|
return common::make_unique<ProbabilityGridRangeDataInserter2D>(
|
||||||
|
options_.range_data_inserter_options()
|
||||||
|
.probability_grid_range_data_inserter_options_2d());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<GridInterface> ActiveSubmaps2D::CreateGrid(
|
||||||
|
const Eigen::Vector2f& origin) {
|
||||||
|
constexpr int kInitialSubmapSize = 100;
|
||||||
|
float resolution = options_.grid_options_2d().resolution();
|
||||||
|
return common::make_unique<ProbabilityGrid>(
|
||||||
|
MapLimits(resolution,
|
||||||
|
origin.cast<double>() + 0.5 * kInitialSubmapSize * resolution *
|
||||||
|
Eigen::Vector2d::Ones(),
|
||||||
|
CellLimits(kInitialSubmapSize, kInitialSubmapSize)));
|
||||||
|
}
|
||||||
|
|
||||||
void ActiveSubmaps2D::FinishSubmap() {
|
void ActiveSubmaps2D::FinishSubmap() {
|
||||||
Submap2D* submap = submaps_.front().get();
|
Submap2D* submap = submaps_.front().get();
|
||||||
submap->Finish();
|
submap->Finish();
|
||||||
|
@ -142,14 +180,10 @@ void ActiveSubmaps2D::AddSubmap(const Eigen::Vector2f& origin) {
|
||||||
// reduce peak memory usage a bit.
|
// reduce peak memory usage a bit.
|
||||||
FinishSubmap();
|
FinishSubmap();
|
||||||
}
|
}
|
||||||
constexpr int kInitialSubmapSize = 100;
|
|
||||||
submaps_.push_back(common::make_unique<Submap2D>(
|
submaps_.push_back(common::make_unique<Submap2D>(
|
||||||
MapLimits(options_.resolution(),
|
origin, std::unique_ptr<Grid2D>(
|
||||||
origin.cast<double>() + 0.5 * kInitialSubmapSize *
|
static_cast<Grid2D*>(CreateGrid(origin).release()))));
|
||||||
options_.resolution() *
|
|
||||||
Eigen::Vector2d::Ones(),
|
|
||||||
CellLimits(kInitialSubmapSize, kInitialSubmapSize)),
|
|
||||||
origin));
|
|
||||||
LOG(INFO) << "Added submap " << matching_submap_index_ + submaps_.size();
|
LOG(INFO) << "Added submap " << matching_submap_index_ + submaps_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
#include "cartographer/mapping/2d/grid_2d.h"
|
#include "cartographer/mapping/2d/grid_2d.h"
|
||||||
#include "cartographer/mapping/2d/map_limits.h"
|
#include "cartographer/mapping/2d/map_limits.h"
|
||||||
#include "cartographer/mapping/2d/proto/submaps_options_2d.pb.h"
|
#include "cartographer/mapping/2d/proto/submaps_options_2d.pb.h"
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
|
||||||
#include "cartographer/mapping/proto/serialization.pb.h"
|
#include "cartographer/mapping/proto/serialization.pb.h"
|
||||||
#include "cartographer/mapping/proto/submap_visualization.pb.h"
|
#include "cartographer/mapping/proto/submap_visualization.pb.h"
|
||||||
|
#include "cartographer/mapping/range_data_inserter_interface.h"
|
||||||
#include "cartographer/mapping/submaps.h"
|
#include "cartographer/mapping/submaps.h"
|
||||||
#include "cartographer/mapping/trajectory_node.h"
|
#include "cartographer/mapping/trajectory_node.h"
|
||||||
#include "cartographer/sensor/range_data.h"
|
#include "cartographer/sensor/range_data.h"
|
||||||
|
@ -41,7 +41,7 @@ proto::SubmapsOptions2D CreateSubmapsOptions2D(
|
||||||
|
|
||||||
class Submap2D : public Submap {
|
class Submap2D : public Submap {
|
||||||
public:
|
public:
|
||||||
Submap2D(const MapLimits& limits, const Eigen::Vector2f& origin);
|
Submap2D(const Eigen::Vector2f& origin, std::unique_ptr<Grid2D> grid);
|
||||||
explicit Submap2D(const proto::Submap2D& proto);
|
explicit Submap2D(const proto::Submap2D& proto);
|
||||||
|
|
||||||
void ToProto(proto::Submap* proto,
|
void ToProto(proto::Submap* proto,
|
||||||
|
@ -56,7 +56,7 @@ class Submap2D : public Submap {
|
||||||
// Insert 'range_data' into this submap using 'range_data_inserter'. The
|
// Insert 'range_data' into this submap using 'range_data_inserter'. The
|
||||||
// submap must not be finished yet.
|
// submap must not be finished yet.
|
||||||
void InsertRangeData(const sensor::RangeData& range_data,
|
void InsertRangeData(const sensor::RangeData& range_data,
|
||||||
const RangeDataInserter2D& range_data_inserter);
|
const RangeDataInserterInterface* range_data_inserter);
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -89,13 +89,15 @@ class ActiveSubmaps2D {
|
||||||
std::vector<std::shared_ptr<Submap2D>> submaps() const;
|
std::vector<std::shared_ptr<Submap2D>> submaps() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<RangeDataInserterInterface> CreateRangeDataInserter();
|
||||||
|
std::unique_ptr<GridInterface> CreateGrid(const Eigen::Vector2f& origin);
|
||||||
void FinishSubmap();
|
void FinishSubmap();
|
||||||
void AddSubmap(const Eigen::Vector2f& origin);
|
void AddSubmap(const Eigen::Vector2f& origin);
|
||||||
|
|
||||||
const proto::SubmapsOptions2D options_;
|
const proto::SubmapsOptions2D options_;
|
||||||
int matching_submap_index_ = 0;
|
int matching_submap_index_ = 0;
|
||||||
std::vector<std::shared_ptr<Submap2D>> submaps_;
|
std::vector<std::shared_ptr<Submap2D>> submaps_;
|
||||||
RangeDataInserter2D range_data_inserter_;
|
std::unique_ptr<RangeDataInserterInterface> range_data_inserter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mapping
|
} // namespace mapping
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cartographer/mapping/2d/submap_2d.h"
|
#include "cartographer/mapping/2d/submap_2d.h"
|
||||||
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -35,15 +36,21 @@ TEST(Submap2DTest, TheRightNumberOfRangeDataAreInserted) {
|
||||||
constexpr int kNumRangeData = 10;
|
constexpr int kNumRangeData = 10;
|
||||||
auto parameter_dictionary = common::MakeDictionary(
|
auto parameter_dictionary = common::MakeDictionary(
|
||||||
"return {"
|
"return {"
|
||||||
"resolution = 0.05, "
|
|
||||||
"num_range_data = " +
|
"num_range_data = " +
|
||||||
std::to_string(kNumRangeData) +
|
std::to_string(kNumRangeData) +
|
||||||
", "
|
", "
|
||||||
|
"grid_options_2d = {"
|
||||||
|
"grid_type = \"PROBABILITY_GRID\","
|
||||||
|
"resolution = 0.05, "
|
||||||
|
"},"
|
||||||
"range_data_inserter = {"
|
"range_data_inserter = {"
|
||||||
|
"range_data_inserter_type = \"PROBABILITY_GRID_INSERTER_2D\","
|
||||||
|
"probability_grid_range_data_inserter = {"
|
||||||
"insert_free_space = true, "
|
"insert_free_space = true, "
|
||||||
"hit_probability = 0.53, "
|
"hit_probability = 0.53, "
|
||||||
"miss_probability = 0.495, "
|
"miss_probability = 0.495, "
|
||||||
"},"
|
"},"
|
||||||
|
"},"
|
||||||
"}");
|
"}");
|
||||||
ActiveSubmaps2D submaps{CreateSubmapsOptions2D(parameter_dictionary.get())};
|
ActiveSubmaps2D submaps{CreateSubmapsOptions2D(parameter_dictionary.get())};
|
||||||
std::set<std::shared_ptr<Submap2D>> all_submaps;
|
std::set<std::shared_ptr<Submap2D>> all_submaps;
|
||||||
|
@ -69,9 +76,10 @@ TEST(Submap2DTest, TheRightNumberOfRangeDataAreInserted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Submap2DTest, ToFromProto) {
|
TEST(Submap2DTest, ToFromProto) {
|
||||||
Submap2D expected(
|
MapLimits expected_map_limits(1., Eigen::Vector2d(2., 3.),
|
||||||
MapLimits(1., Eigen::Vector2d(2., 3.), CellLimits(100, 110)),
|
CellLimits(100, 110));
|
||||||
Eigen::Vector2f(4.f, 5.f));
|
Submap2D expected(Eigen::Vector2f(4.f, 5.f),
|
||||||
|
common::make_unique<ProbabilityGrid>(expected_map_limits));
|
||||||
proto::Submap proto;
|
proto::Submap proto;
|
||||||
expected.ToProto(&proto, true /* include_probability_grid_data */);
|
expected.ToProto(&proto, true /* include_probability_grid_data */);
|
||||||
EXPECT_TRUE(proto.has_submap_2d());
|
EXPECT_TRUE(proto.has_submap_2d());
|
||||||
|
|
|
@ -407,13 +407,13 @@ class DynamicGrid {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
using Grid = DynamicGrid<NestedGrid<FlatGrid<ValueType, 3>, 3>>;
|
using GridBase = DynamicGrid<NestedGrid<FlatGrid<ValueType, 3>, 3>>;
|
||||||
|
|
||||||
// Represents a 3D grid as a wide, shallow tree.
|
// Represents a 3D grid as a wide, shallow tree.
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
class HybridGridBase : public Grid<ValueType> {
|
class HybridGridBase : public GridBase<ValueType> {
|
||||||
public:
|
public:
|
||||||
using Iterator = typename Grid<ValueType>::Iterator;
|
using Iterator = typename GridBase<ValueType>::Iterator;
|
||||||
|
|
||||||
// Creates a new tree-based probability grid with voxels having edge length
|
// Creates a new tree-based probability grid with voxels having edge length
|
||||||
// 'resolution' around the origin which becomes the center of the cell at
|
// 'resolution' around the origin which becomes the center of the cell at
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 The Cartographer Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CARTOGRAPHER_MAPPING_GRID_H_
|
||||||
|
#define CARTOGRAPHER_MAPPING_GRID_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace cartographer {
|
||||||
|
namespace mapping {
|
||||||
|
|
||||||
|
class GridInterface {
|
||||||
|
// todo(kdaun) move mutual functions of Grid2D/3D here
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mapping
|
||||||
|
} // namespace cartographer
|
||||||
|
|
||||||
|
#endif // CARTOGRAPHER_MAPPING_GRID_H_
|
|
@ -76,7 +76,8 @@ std::unique_ptr<transform::Rigid2d> LocalTrajectoryBuilder2D::ScanMatch(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (options_.use_online_correlative_scan_matching()) {
|
if (options_.use_online_correlative_scan_matching()) {
|
||||||
// todo(kdaun) add CHECK on options to guarantee grid is a probability grid
|
CHECK_EQ(options_.submaps_options().grid_options_2d().grid_type(),
|
||||||
|
proto::GridOptions2D_GridType_PROBABILITY_GRID);
|
||||||
double score = real_time_correlative_scan_matcher_.Match(
|
double score = real_time_correlative_scan_matcher_.Match(
|
||||||
pose_prediction, filtered_gravity_aligned_point_cloud,
|
pose_prediction, filtered_gravity_aligned_point_cloud,
|
||||||
*static_cast<const ProbabilityGrid*>(matching_submap->grid()),
|
*static_cast<const ProbabilityGrid*>(matching_submap->grid()),
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "cartographer/common/make_unique.h"
|
#include "cartographer/common/make_unique.h"
|
||||||
#include "cartographer/common/thread_pool.h"
|
#include "cartographer/common/thread_pool.h"
|
||||||
#include "cartographer/common/time.h"
|
#include "cartographer/common/time.h"
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
#include "cartographer/mapping/2d/submap_2d.h"
|
#include "cartographer/mapping/2d/submap_2d.h"
|
||||||
#include "cartographer/transform/rigid_transform.h"
|
#include "cartographer/transform/rigid_transform.h"
|
||||||
#include "cartographer/transform/rigid_transform_test_helpers.h"
|
#include "cartographer/transform/rigid_transform_test_helpers.h"
|
||||||
|
@ -50,12 +50,18 @@ class PoseGraph2DTest : public ::testing::Test {
|
||||||
{
|
{
|
||||||
auto parameter_dictionary = common::MakeDictionary(R"text(
|
auto parameter_dictionary = common::MakeDictionary(R"text(
|
||||||
return {
|
return {
|
||||||
resolution = 0.05,
|
|
||||||
num_range_data = 1,
|
num_range_data = 1,
|
||||||
|
grid_options_2d = {
|
||||||
|
grid_type = "PROBABILITY_GRID",
|
||||||
|
resolution = 0.05,
|
||||||
|
},
|
||||||
range_data_inserter = {
|
range_data_inserter = {
|
||||||
insert_free_space = true,
|
range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D",
|
||||||
hit_probability = 0.53,
|
probability_grid_range_data_inserter = {
|
||||||
miss_probability = 0.495,
|
insert_free_space = true,
|
||||||
|
hit_probability = 0.53,
|
||||||
|
miss_probability = 0.495,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})text");
|
})text");
|
||||||
active_submaps_ = common::make_unique<ActiveSubmaps2D>(
|
active_submaps_ = common::make_unique<ActiveSubmaps2D>(
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "cartographer/common/lua_parameter_dictionary_test_helpers.h"
|
#include "cartographer/common/lua_parameter_dictionary_test_helpers.h"
|
||||||
#include "cartographer/mapping/2d/probability_grid.h"
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
#include "cartographer/transform/rigid_transform_test_helpers.h"
|
#include "cartographer/transform/rigid_transform_test_helpers.h"
|
||||||
#include "cartographer/transform/transform.h"
|
#include "cartographer/transform/transform.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
@ -125,7 +125,7 @@ CreateFastCorrelativeScanMatcherTestOptions2D(
|
||||||
return CreateFastCorrelativeScanMatcherOptions2D(parameter_dictionary.get());
|
return CreateFastCorrelativeScanMatcherOptions2D(parameter_dictionary.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping::proto::RangeDataInserterOptions2D
|
mapping::proto::ProbabilityGridRangeDataInserterOptions2D
|
||||||
CreateRangeDataInserterTestOptions2D() {
|
CreateRangeDataInserterTestOptions2D() {
|
||||||
auto parameter_dictionary = common::MakeDictionary(R"text(
|
auto parameter_dictionary = common::MakeDictionary(R"text(
|
||||||
return {
|
return {
|
||||||
|
@ -133,13 +133,14 @@ CreateRangeDataInserterTestOptions2D() {
|
||||||
hit_probability = 0.7,
|
hit_probability = 0.7,
|
||||||
miss_probability = 0.4,
|
miss_probability = 0.4,
|
||||||
})text");
|
})text");
|
||||||
return mapping::CreateRangeDataInserterOptions2D(parameter_dictionary.get());
|
return mapping::CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
|
parameter_dictionary.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FastCorrelativeScanMatcherTest, CorrectPose) {
|
TEST(FastCorrelativeScanMatcherTest, CorrectPose) {
|
||||||
std::mt19937 prng(42);
|
std::mt19937 prng(42);
|
||||||
std::uniform_real_distribution<float> distribution(-1.f, 1.f);
|
std::uniform_real_distribution<float> distribution(-1.f, 1.f);
|
||||||
RangeDataInserter2D range_data_inserter(
|
ProbabilityGridRangeDataInserter2D range_data_inserter(
|
||||||
CreateRangeDataInserterTestOptions2D());
|
CreateRangeDataInserterTestOptions2D());
|
||||||
constexpr float kMinScore = 0.1f;
|
constexpr float kMinScore = 0.1f;
|
||||||
const auto options = CreateFastCorrelativeScanMatcherTestOptions2D(3);
|
const auto options = CreateFastCorrelativeScanMatcherTestOptions2D(3);
|
||||||
|
@ -187,7 +188,7 @@ TEST(FastCorrelativeScanMatcherTest, CorrectPose) {
|
||||||
TEST(FastCorrelativeScanMatcherTest, FullSubmapMatching) {
|
TEST(FastCorrelativeScanMatcherTest, FullSubmapMatching) {
|
||||||
std::mt19937 prng(42);
|
std::mt19937 prng(42);
|
||||||
std::uniform_real_distribution<float> distribution(-1.f, 1.f);
|
std::uniform_real_distribution<float> distribution(-1.f, 1.f);
|
||||||
RangeDataInserter2D range_data_inserter(
|
ProbabilityGridRangeDataInserter2D range_data_inserter(
|
||||||
CreateRangeDataInserterTestOptions2D());
|
CreateRangeDataInserterTestOptions2D());
|
||||||
constexpr float kMinScore = 0.1f;
|
constexpr float kMinScore = 0.1f;
|
||||||
const auto options = CreateFastCorrelativeScanMatcherTestOptions2D(6);
|
const auto options = CreateFastCorrelativeScanMatcherTestOptions2D(6);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "cartographer/common/lua_parameter_dictionary_test_helpers.h"
|
#include "cartographer/common/lua_parameter_dictionary_test_helpers.h"
|
||||||
#include "cartographer/common/make_unique.h"
|
#include "cartographer/common/make_unique.h"
|
||||||
#include "cartographer/mapping/2d/probability_grid.h"
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
#include "cartographer/mapping/2d/range_data_inserter_2d.h"
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
#include "cartographer/mapping/internal/scan_matching/real_time_correlative_scan_matcher.h"
|
#include "cartographer/mapping/internal/scan_matching/real_time_correlative_scan_matcher.h"
|
||||||
#include "cartographer/sensor/point_cloud.h"
|
#include "cartographer/sensor/point_cloud.h"
|
||||||
#include "cartographer/transform/transform.h"
|
#include "cartographer/transform/transform.h"
|
||||||
|
@ -46,8 +46,10 @@ class RealTimeCorrelativeScanMatcherTest : public ::testing::Test {
|
||||||
"hit_probability = 0.7, "
|
"hit_probability = 0.7, "
|
||||||
"miss_probability = 0.4, "
|
"miss_probability = 0.4, "
|
||||||
"}");
|
"}");
|
||||||
range_data_inserter_ = common::make_unique<RangeDataInserter2D>(
|
range_data_inserter_ =
|
||||||
CreateRangeDataInserterOptions2D(parameter_dictionary.get()));
|
common::make_unique<ProbabilityGridRangeDataInserter2D>(
|
||||||
|
CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
|
parameter_dictionary.get()));
|
||||||
}
|
}
|
||||||
point_cloud_.emplace_back(0.025f, 0.175f, 0.f);
|
point_cloud_.emplace_back(0.025f, 0.175f, 0.f);
|
||||||
point_cloud_.emplace_back(-0.025f, 0.175f, 0.f);
|
point_cloud_.emplace_back(-0.025f, 0.175f, 0.f);
|
||||||
|
@ -76,7 +78,7 @@ class RealTimeCorrelativeScanMatcherTest : public ::testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProbabilityGrid probability_grid_;
|
ProbabilityGrid probability_grid_;
|
||||||
std::unique_ptr<RangeDataInserter2D> range_data_inserter_;
|
std::unique_ptr<ProbabilityGridRangeDataInserter2D> range_data_inserter_;
|
||||||
sensor::PointCloud point_cloud_;
|
sensor::PointCloud point_cloud_;
|
||||||
std::unique_ptr<RealTimeCorrelativeScanMatcher2D>
|
std::unique_ptr<RealTimeCorrelativeScanMatcher2D>
|
||||||
real_time_correlative_scan_matcher_;
|
real_time_correlative_scan_matcher_;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cartographer/mapping/internal/constraints/constraint_builder_2d.h"
|
#include "cartographer/mapping/internal/constraints/constraint_builder_2d.h"
|
||||||
|
#include "cartographer/mapping/2d/probability_grid.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -71,8 +72,9 @@ TEST_F(ConstraintBuilder2DTest, FindsConstraints) {
|
||||||
node_data.gravity_alignment = Eigen::Quaterniond::Identity();
|
node_data.gravity_alignment = Eigen::Quaterniond::Identity();
|
||||||
node_data.local_pose = transform::Rigid3d::Identity();
|
node_data.local_pose = transform::Rigid3d::Identity();
|
||||||
SubmapId submap_id{0, 1};
|
SubmapId submap_id{0, 1};
|
||||||
Submap2D submap(MapLimits(1., Eigen::Vector2d(2., 3.), CellLimits(100, 110)),
|
MapLimits map_limits(1., Eigen::Vector2d(2., 3.), CellLimits(100, 110));
|
||||||
Eigen::Vector2f(4.f, 5.f));
|
Submap2D submap(Eigen::Vector2f(4.f, 5.f),
|
||||||
|
common::make_unique<ProbabilityGrid>(map_limits));
|
||||||
int expected_nodes = 0;
|
int expected_nodes = 0;
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
EXPECT_EQ(constraint_builder_->GetNumFinishedNodes(), expected_nodes);
|
EXPECT_EQ(constraint_builder_->GetNumFinishedNodes(), expected_nodes);
|
||||||
|
|
|
@ -130,6 +130,7 @@ int MapBuilder::AddTrajectoryBuilder(
|
||||||
trimmer_options.min_covered_area() /
|
trimmer_options.min_covered_area() /
|
||||||
common::Pow2(trajectory_options.trajectory_builder_2d_options()
|
common::Pow2(trajectory_options.trajectory_builder_2d_options()
|
||||||
.submaps_options()
|
.submaps_options()
|
||||||
|
.grid_options_2d()
|
||||||
.resolution()),
|
.resolution()),
|
||||||
trimmer_options.min_added_submaps_count()));
|
trimmer_options.min_added_submaps_count()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2018 The Cartographer Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "cartographer/mapping/2d/proto/probability_grid_range_data_inserter_options_2d.proto";
|
||||||
|
|
||||||
|
package cartographer.mapping.proto;
|
||||||
|
|
||||||
|
message RangeDataInserterOptions {
|
||||||
|
enum RangeDataInserterType {
|
||||||
|
INVALID_INSERTER = 0;
|
||||||
|
PROBABILITY_GRID_INSERTER_2D = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeDataInserterType range_data_inserter_type = 1;
|
||||||
|
ProbabilityGridRangeDataInserterOptions2D
|
||||||
|
probability_grid_range_data_inserter_options_2d = 2;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 The Cartographer Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cartographer/mapping/range_data_inserter_interface.h"
|
||||||
|
#include "cartographer/mapping/2d/probability_grid_range_data_inserter_2d.h"
|
||||||
|
|
||||||
|
namespace cartographer {
|
||||||
|
namespace mapping {
|
||||||
|
|
||||||
|
proto::RangeDataInserterOptions CreateRangeDataInserterOptions(
|
||||||
|
common::LuaParameterDictionary* const parameter_dictionary) {
|
||||||
|
proto::RangeDataInserterOptions options;
|
||||||
|
const std::string range_data_inserter_type_string =
|
||||||
|
parameter_dictionary->GetString("range_data_inserter_type");
|
||||||
|
proto::RangeDataInserterOptions_RangeDataInserterType
|
||||||
|
range_data_inserter_type;
|
||||||
|
CHECK(proto::RangeDataInserterOptions_RangeDataInserterType_Parse(
|
||||||
|
range_data_inserter_type_string, &range_data_inserter_type))
|
||||||
|
<< "Unknown RangeDataInserterOptions_RangeDataInserterType kind: "
|
||||||
|
<< range_data_inserter_type_string;
|
||||||
|
options.set_range_data_inserter_type(range_data_inserter_type);
|
||||||
|
*options.mutable_probability_grid_range_data_inserter_options_2d() =
|
||||||
|
CreateProbabilityGridRangeDataInserterOptions2D(
|
||||||
|
parameter_dictionary
|
||||||
|
->GetDictionary("probability_grid_range_data_inserter")
|
||||||
|
.get());
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
} // namespace mapping
|
||||||
|
} // namespace cartographer
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 The Cartographer Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CARTOGRAPHER_MAPPING_RANGE_DATA_INSERTER_H_
|
||||||
|
#define CARTOGRAPHER_MAPPING_RANGE_DATA_INSERTER_H_
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cartographer/mapping/2d/proto/submaps_options_2d.pb.h"
|
||||||
|
#include "cartographer/mapping/grid_interface.h"
|
||||||
|
#include "cartographer/sensor/range_data.h"
|
||||||
|
|
||||||
|
namespace cartographer {
|
||||||
|
namespace mapping {
|
||||||
|
|
||||||
|
proto::RangeDataInserterOptions CreateRangeDataInserterOptions(
|
||||||
|
common::LuaParameterDictionary* const parameter_dictionary);
|
||||||
|
|
||||||
|
class RangeDataInserterInterface {
|
||||||
|
public:
|
||||||
|
// Inserts 'range_data' into 'grid'.
|
||||||
|
virtual void Insert(const sensor::RangeData& range_data,
|
||||||
|
GridInterface* grid) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mapping
|
||||||
|
} // namespace cartographer
|
||||||
|
|
||||||
|
#endif // CARTOGRAPHER_MAPPING_RANGE_DATA_INSERTER_H_
|
|
@ -62,12 +62,18 @@ TRAJECTORY_BUILDER_2D = {
|
||||||
imu_gravity_time_constant = 10.,
|
imu_gravity_time_constant = 10.,
|
||||||
|
|
||||||
submaps = {
|
submaps = {
|
||||||
resolution = 0.05,
|
|
||||||
num_range_data = 90,
|
num_range_data = 90,
|
||||||
|
grid_options_2d = {
|
||||||
|
grid_type = "PROBABILITY_GRID",
|
||||||
|
resolution = 0.05,
|
||||||
|
},
|
||||||
range_data_inserter = {
|
range_data_inserter = {
|
||||||
insert_free_space = true,
|
range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D",
|
||||||
hit_probability = 0.55,
|
probability_grid_range_data_inserter = {
|
||||||
miss_probability = 0.49,
|
insert_free_space = true,
|
||||||
|
hit_probability = 0.55,
|
||||||
|
miss_probability = 0.49,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue