Converted Submap from struct to class. (#333)
parent
2d75f4ef56
commit
cff0c73857
|
@ -125,7 +125,7 @@ string MapBuilder::SubmapToProto(const int trajectory_id,
|
|||
|
||||
const Submap* const submap =
|
||||
trajectory_builders_.at(trajectory_id)->submaps()->Get(submap_index);
|
||||
response->set_submap_version(submap->num_range_data);
|
||||
response->set_submap_version(submap->num_range_data());
|
||||
submap->ToResponseProto(submap_transforms[submap_index], response);
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -56,26 +56,36 @@ inline uint8 ProbabilityToLogOddsInteger(const float probability) {
|
|||
// track of how many range data were inserted into it, and sets the
|
||||
// 'finished_probability_grid' to be used for loop closing once the map no
|
||||
// longer changes.
|
||||
// TODO(hrapp): This should be a class now.
|
||||
struct Submap {
|
||||
Submap(const transform::Rigid3d& local_pose) : local_pose(local_pose) {}
|
||||
class Submap {
|
||||
public:
|
||||
Submap(const transform::Rigid3d& local_pose) : local_pose_(local_pose) {}
|
||||
virtual ~Submap() {}
|
||||
|
||||
// Local SLAM pose of this submap.
|
||||
const transform::Rigid3d local_pose;
|
||||
transform::Rigid3d local_pose() const { return local_pose_; }
|
||||
|
||||
// Number of RangeData inserted.
|
||||
int num_range_data = 0;
|
||||
size_t num_range_data() const { return num_range_data_; }
|
||||
|
||||
// The 'finished_probability_grid' when this submap is finished and will not
|
||||
// change anymore. Otherwise, this is nullptr and the next call to
|
||||
// InsertRangeData() will change the submap.
|
||||
const mapping_2d::ProbabilityGrid* finished_probability_grid = nullptr;
|
||||
const mapping_2d::ProbabilityGrid* finished_probability_grid() const {
|
||||
return finished_probability_grid_;
|
||||
}
|
||||
|
||||
// Fills data into the 'response'.
|
||||
virtual void ToResponseProto(
|
||||
const transform::Rigid3d& global_submap_pose,
|
||||
proto::SubmapQuery::Response* response) const = 0;
|
||||
|
||||
private:
|
||||
const transform::Rigid3d local_pose_;
|
||||
|
||||
protected:
|
||||
// TODO(hrapp): All of this should be private.
|
||||
int num_range_data_ = 0;
|
||||
const mapping_2d::ProbabilityGrid* finished_probability_grid_ = nullptr;
|
||||
};
|
||||
|
||||
// Submaps is a sequence of maps to which scans are matched and into which scans
|
||||
|
|
|
@ -71,7 +71,7 @@ void LocalTrajectoryBuilder::ScanMatch(
|
|||
const sensor::RangeData& range_data_in_tracking_2d,
|
||||
transform::Rigid3d* pose_observation) {
|
||||
const ProbabilityGrid& probability_grid =
|
||||
submaps_.Get(submaps_.matching_index())->probability_grid;
|
||||
submaps_.Get(submaps_.matching_index())->probability_grid();
|
||||
transform::Rigid2d pose_prediction_2d =
|
||||
transform::Project2D(pose_prediction * tracking_to_tracking_2d.inverse());
|
||||
// The online correlative scan matcher will refine the initial estimate for
|
||||
|
|
|
@ -116,7 +116,7 @@ void SparsePoseGraph::AddScan(
|
|||
submap_data_.at(submap_id).submap = insertion_submaps.back();
|
||||
}
|
||||
const mapping::Submap* const finished_submap =
|
||||
insertion_submaps.front()->finished_probability_grid != nullptr
|
||||
insertion_submaps.front()->finished_probability_grid() != nullptr
|
||||
? insertion_submaps.front()
|
||||
: nullptr;
|
||||
|
||||
|
@ -430,7 +430,8 @@ transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
|||
.at(mapping::SubmapId{
|
||||
trajectory_id,
|
||||
static_cast<int>(extrapolated_submap_transforms.size()) - 1})
|
||||
.submap->local_pose.inverse();
|
||||
.submap->local_pose()
|
||||
.inverse();
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>> SparsePoseGraph::GetConnectedTrajectories() {
|
||||
|
@ -474,8 +475,8 @@ std::vector<transform::Rigid3d> SparsePoseGraph::ExtrapolateSubmapTransforms(
|
|||
trajectory_id, static_cast<int>(result.size()) - 1};
|
||||
result.push_back(
|
||||
result.back() *
|
||||
submap_data_.at(previous_submap_id).submap->local_pose.inverse() *
|
||||
submap_data.submap->local_pose);
|
||||
submap_data_.at(previous_submap_id).submap->local_pose().inverse() *
|
||||
submap_data.submap->local_pose());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace mapping_2d {
|
|||
namespace sparse_pose_graph {
|
||||
|
||||
transform::Rigid2d ComputeSubmapPose(const mapping::Submap& submap) {
|
||||
return transform::Project2D(submap.local_pose);
|
||||
return transform::Project2D(submap.local_pose());
|
||||
}
|
||||
|
||||
ConstraintBuilder::ConstraintBuilder(
|
||||
|
@ -74,7 +74,7 @@ void ConstraintBuilder::MaybeAddConstraint(
|
|||
++pending_computations_[current_computation_];
|
||||
const int current_computation = current_computation_;
|
||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
submap_id, submap->finished_probability_grid, [=]() EXCLUDES(mutex_) {
|
||||
submap_id, submap->finished_probability_grid(), [=]() EXCLUDES(mutex_) {
|
||||
ComputeConstraint(submap_id, submap, node_id,
|
||||
false, /* match_full_submap */
|
||||
nullptr, /* trajectory_connectivity */
|
||||
|
@ -94,7 +94,7 @@ void ConstraintBuilder::MaybeAddGlobalConstraint(
|
|||
++pending_computations_[current_computation_];
|
||||
const int current_computation = current_computation_;
|
||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
submap_id, submap->finished_probability_grid, [=]() EXCLUDES(mutex_) {
|
||||
submap_id, submap->finished_probability_grid(), [=]() EXCLUDES(mutex_) {
|
||||
ComputeConstraint(submap_id, submap, node_id,
|
||||
true, /* match_full_submap */
|
||||
trajectory_connectivity, point_cloud,
|
||||
|
|
|
@ -103,18 +103,18 @@ proto::SubmapsOptions CreateSubmapsOptions(
|
|||
Submap::Submap(const MapLimits& limits, const Eigen::Vector2f& origin)
|
||||
: mapping::Submap(transform::Rigid3d::Translation(
|
||||
Eigen::Vector3d(origin.x(), origin.y(), 0.))),
|
||||
probability_grid(limits) {}
|
||||
probability_grid_(limits) {}
|
||||
|
||||
void Submap::ToResponseProto(
|
||||
const transform::Rigid3d&,
|
||||
mapping::proto::SubmapQuery::Response* const response) const {
|
||||
Eigen::Array2i offset;
|
||||
CellLimits limits;
|
||||
probability_grid.ComputeCroppedLimits(&offset, &limits);
|
||||
probability_grid_.ComputeCroppedLimits(&offset, &limits);
|
||||
|
||||
string cells;
|
||||
for (const Eigen::Array2i& xy_index : XYIndexRangeIterator(limits)) {
|
||||
if (probability_grid.IsKnown(xy_index + offset)) {
|
||||
if (probability_grid_.IsKnown(xy_index + offset)) {
|
||||
// We would like to add 'delta' but this is not possible using a value and
|
||||
// alpha. We use premultiplied alpha, so when 'delta' is positive we can
|
||||
// add it by setting 'alpha' to zero. If it is negative, we set 'value' to
|
||||
|
@ -123,7 +123,7 @@ void Submap::ToResponseProto(
|
|||
// detect visually for the user, though.
|
||||
const int delta =
|
||||
128 - mapping::ProbabilityToLogOddsInteger(
|
||||
probability_grid.GetProbability(xy_index + offset));
|
||||
probability_grid_.GetProbability(xy_index + offset));
|
||||
const uint8 alpha = delta > 0 ? 0 : -delta;
|
||||
const uint8 value = delta > 0 ? delta : 0;
|
||||
cells.push_back(value);
|
||||
|
@ -138,14 +138,14 @@ void Submap::ToResponseProto(
|
|||
|
||||
response->set_width(limits.num_x_cells);
|
||||
response->set_height(limits.num_y_cells);
|
||||
const double resolution = probability_grid.limits().resolution();
|
||||
const double resolution = probability_grid_.limits().resolution();
|
||||
response->set_resolution(resolution);
|
||||
const double max_x =
|
||||
probability_grid.limits().max().x() - resolution * offset.y();
|
||||
probability_grid_.limits().max().x() - resolution * offset.y();
|
||||
const double max_y =
|
||||
probability_grid.limits().max().y() - resolution * offset.x();
|
||||
probability_grid_.limits().max().y() - resolution * offset.x();
|
||||
*response->mutable_slice_pose() = transform::ToProto(
|
||||
local_pose.inverse() *
|
||||
local_pose().inverse() *
|
||||
transform::Rigid3d::Translation(Eigen::Vector3d(max_x, max_y, 0.)));
|
||||
}
|
||||
|
||||
|
@ -160,12 +160,12 @@ Submaps::Submaps(const proto::SubmapsOptions& options)
|
|||
void Submaps::InsertRangeData(const sensor::RangeData& range_data) {
|
||||
for (const int index : insertion_indices()) {
|
||||
Submap* submap = submaps_[index].get();
|
||||
CHECK(submap->finished_probability_grid == nullptr);
|
||||
range_data_inserter_.Insert(range_data, &submap->probability_grid);
|
||||
++submap->num_range_data;
|
||||
CHECK(submap->finished_probability_grid_ == nullptr);
|
||||
range_data_inserter_.Insert(range_data, &submap->probability_grid_);
|
||||
++submap->num_range_data_;
|
||||
}
|
||||
const Submap* const last_submap = Get(size() - 1);
|
||||
if (last_submap->num_range_data == options_.num_range_data()) {
|
||||
if (last_submap->num_range_data_ == options_.num_range_data()) {
|
||||
AddSubmap(range_data.origin.head<2>());
|
||||
}
|
||||
}
|
||||
|
@ -182,14 +182,14 @@ void Submaps::FinishSubmap(int index) {
|
|||
// Crop the finished Submap before inserting a new Submap to reduce peak
|
||||
// memory usage a bit.
|
||||
Submap* submap = submaps_[index].get();
|
||||
CHECK(submap->finished_probability_grid == nullptr);
|
||||
submap->probability_grid =
|
||||
ComputeCroppedProbabilityGrid(submap->probability_grid);
|
||||
submap->finished_probability_grid = &submap->probability_grid;
|
||||
CHECK(submap->finished_probability_grid_ == nullptr);
|
||||
submap->probability_grid_ =
|
||||
ComputeCroppedProbabilityGrid(submap->probability_grid_);
|
||||
submap->finished_probability_grid_ = &submap->probability_grid_;
|
||||
if (options_.output_debug_images()) {
|
||||
// Output the Submap that won't be changed from now on.
|
||||
WriteDebugImage("submap" + std::to_string(index) + ".webp",
|
||||
submap->probability_grid);
|
||||
submap->probability_grid_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,14 +41,21 @@ ProbabilityGrid ComputeCroppedProbabilityGrid(
|
|||
proto::SubmapsOptions CreateSubmapsOptions(
|
||||
common::LuaParameterDictionary* parameter_dictionary);
|
||||
|
||||
struct Submap : public mapping::Submap {
|
||||
class Submap : public mapping::Submap {
|
||||
public:
|
||||
Submap(const MapLimits& limits, const Eigen::Vector2f& origin);
|
||||
|
||||
ProbabilityGrid probability_grid;
|
||||
const ProbabilityGrid& probability_grid() const { return probability_grid_; }
|
||||
|
||||
void ToResponseProto(
|
||||
const transform::Rigid3d& global_submap_pose,
|
||||
mapping::proto::SubmapQuery::Response* response) const override;
|
||||
|
||||
private:
|
||||
// TODO(hrapp): Remove friend declaration.
|
||||
friend class Submaps;
|
||||
|
||||
ProbabilityGrid probability_grid_;
|
||||
};
|
||||
|
||||
// A container of Submaps.
|
||||
|
|
|
@ -51,12 +51,12 @@ TEST(SubmapsTest, TheRightNumberOfScansAreInserted) {
|
|||
const int matching = submaps.matching_index();
|
||||
// Except for the first, maps should only be returned after enough scans.
|
||||
if (matching != 0) {
|
||||
EXPECT_LE(kNumRangeData, submaps.Get(matching)->num_range_data);
|
||||
EXPECT_LE(kNumRangeData, submaps.Get(matching)->num_range_data());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != submaps.size() - 2; ++i) {
|
||||
// Submaps should not be left without the right number of scans in them.
|
||||
EXPECT_EQ(kNumRangeData * 2, submaps.Get(i)->num_range_data);
|
||||
EXPECT_EQ(kNumRangeData * 2, submaps.Get(i)->num_range_data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ KalmanLocalTrajectoryBuilder::AddAccumulatedRangeData(
|
|||
const Submap* const matching_submap =
|
||||
submaps_->Get(submaps_->matching_index());
|
||||
transform::Rigid3d initial_ceres_pose =
|
||||
matching_submap->local_pose.inverse() * pose_prediction;
|
||||
matching_submap->local_pose().inverse() * pose_prediction;
|
||||
sensor::AdaptiveVoxelFilter adaptive_voxel_filter(
|
||||
options_.high_resolution_adaptive_voxel_filter_options());
|
||||
const sensor::PointCloud filtered_point_cloud_in_tracking =
|
||||
|
@ -154,7 +154,7 @@ KalmanLocalTrajectoryBuilder::AddAccumulatedRangeData(
|
|||
const transform::Rigid3d initial_pose = initial_ceres_pose;
|
||||
real_time_correlative_scan_matcher_->Match(
|
||||
initial_pose, filtered_point_cloud_in_tracking,
|
||||
matching_submap->high_resolution_hybrid_grid, &initial_ceres_pose);
|
||||
matching_submap->high_resolution_hybrid_grid(), &initial_ceres_pose);
|
||||
}
|
||||
|
||||
transform::Rigid3d pose_observation_in_submap;
|
||||
|
@ -166,12 +166,12 @@ KalmanLocalTrajectoryBuilder::AddAccumulatedRangeData(
|
|||
low_resolution_adaptive_voxel_filter.Filter(filtered_range_data.returns);
|
||||
ceres_scan_matcher_->Match(scan_matcher_pose_estimate_, initial_ceres_pose,
|
||||
{{&filtered_point_cloud_in_tracking,
|
||||
&matching_submap->high_resolution_hybrid_grid},
|
||||
&matching_submap->high_resolution_hybrid_grid()},
|
||||
{&low_resolution_point_cloud_in_tracking,
|
||||
&matching_submap->low_resolution_hybrid_grid}},
|
||||
&matching_submap->low_resolution_hybrid_grid()}},
|
||||
&pose_observation_in_submap, &summary);
|
||||
const transform::Rigid3d pose_observation =
|
||||
matching_submap->local_pose * pose_observation_in_submap;
|
||||
matching_submap->local_pose() * pose_observation_in_submap;
|
||||
pose_tracker_->AddPoseObservation(
|
||||
time, pose_observation,
|
||||
options_.kalman_local_trajectory_builder_options()
|
||||
|
|
|
@ -241,7 +241,7 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) {
|
|||
// We transform the states in 'batches_' in place to be in the submap frame as
|
||||
// expected by the OccupiedSpaceCostFunctor. This is reverted after solving
|
||||
// the optimization problem.
|
||||
TransformStates(matching_submap->local_pose.inverse());
|
||||
TransformStates(matching_submap->local_pose().inverse());
|
||||
for (size_t i = 0; i < batches_.size(); ++i) {
|
||||
Batch& batch = batches_[i];
|
||||
problem.AddResidualBlock(
|
||||
|
@ -253,7 +253,7 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) {
|
|||
std::sqrt(static_cast<double>(
|
||||
batch.high_resolution_filtered_points.size())),
|
||||
batch.high_resolution_filtered_points,
|
||||
matching_submap->high_resolution_hybrid_grid),
|
||||
matching_submap->high_resolution_hybrid_grid()),
|
||||
batch.high_resolution_filtered_points.size()),
|
||||
nullptr, batch.state.translation.data(), batch.state.rotation.data());
|
||||
problem.AddResidualBlock(
|
||||
|
@ -265,7 +265,7 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) {
|
|||
std::sqrt(static_cast<double>(
|
||||
batch.low_resolution_filtered_points.size())),
|
||||
batch.low_resolution_filtered_points,
|
||||
matching_submap->low_resolution_hybrid_grid),
|
||||
matching_submap->low_resolution_hybrid_grid()),
|
||||
batch.low_resolution_filtered_points.size()),
|
||||
nullptr, batch.state.translation.data(), batch.state.rotation.data());
|
||||
|
||||
|
@ -350,7 +350,7 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) {
|
|||
ceres::Solve(ceres_solver_options_, &problem, &summary);
|
||||
// The optimized states in 'batches_' are in the submap frame and we transform
|
||||
// them in place to be in the local SLAM frame again.
|
||||
TransformStates(matching_submap->local_pose);
|
||||
TransformStates(matching_submap->local_pose());
|
||||
if (num_accumulated_ < options_.scans_per_accumulation()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -81,8 +81,8 @@ void SparsePoseGraph::GrowSubmapTransformsAsNeeded(
|
|||
submap_data.at(trajectory_id).at(first_submap_id.submap_index).pose;
|
||||
optimization_problem_.AddSubmap(
|
||||
trajectory_id, first_submap_pose *
|
||||
insertion_submaps[0]->local_pose.inverse() *
|
||||
insertion_submaps[1]->local_pose);
|
||||
insertion_submaps[0]->local_pose().inverse() *
|
||||
insertion_submaps[1]->local_pose());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,8 +113,9 @@ void SparsePoseGraph::AddScan(
|
|||
submap_ids_.emplace(insertion_submaps.back(), submap_id);
|
||||
submap_data_.at(submap_id).submap = insertion_submaps.back();
|
||||
}
|
||||
const Submap* const finished_submap =
|
||||
insertion_submaps.front()->finished ? insertion_submaps.front() : nullptr;
|
||||
const Submap* const finished_submap = insertion_submaps.front()->finished()
|
||||
? insertion_submaps.front()
|
||||
: nullptr;
|
||||
|
||||
// Make sure we have a sampler for this trajectory.
|
||||
if (!global_localization_samplers_[trajectory_id]) {
|
||||
|
@ -235,7 +236,7 @@ void SparsePoseGraph::ComputeConstraintsForScan(
|
|||
.at(matching_id.trajectory_id)
|
||||
.at(matching_id.submap_index)
|
||||
.pose *
|
||||
matching_submap->local_pose.inverse() * pose;
|
||||
matching_submap->local_pose().inverse() * pose;
|
||||
const mapping::NodeId node_id{
|
||||
matching_id.trajectory_id,
|
||||
static_cast<size_t>(matching_id.trajectory_id) <
|
||||
|
@ -252,7 +253,7 @@ void SparsePoseGraph::ComputeConstraintsForScan(
|
|||
CHECK(submap_data_.at(submap_id).state == SubmapState::kActive);
|
||||
submap_data_.at(submap_id).node_ids.emplace(node_id);
|
||||
const transform::Rigid3d constraint_transform =
|
||||
submap->local_pose.inverse() * pose;
|
||||
submap->local_pose().inverse() * pose;
|
||||
constraints_.push_back(
|
||||
Constraint{submap_id,
|
||||
node_id,
|
||||
|
@ -432,7 +433,8 @@ transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
|||
.at(mapping::SubmapId{
|
||||
trajectory_id,
|
||||
static_cast<int>(extrapolated_submap_transforms.size()) - 1})
|
||||
.submap->local_pose.inverse();
|
||||
.submap->local_pose()
|
||||
.inverse();
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>> SparsePoseGraph::GetConnectedTrajectories() {
|
||||
|
@ -476,8 +478,8 @@ std::vector<transform::Rigid3d> SparsePoseGraph::ExtrapolateSubmapTransforms(
|
|||
trajectory_id, static_cast<int>(result.size()) - 1};
|
||||
result.push_back(
|
||||
result.back() *
|
||||
submap_data_.at(previous_submap_id).submap->local_pose.inverse() *
|
||||
submap_data.submap->local_pose);
|
||||
submap_data_.at(previous_submap_id).submap->local_pose().inverse() *
|
||||
submap_data.submap->local_pose());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ void ConstraintBuilder::MaybeAddConstraint(
|
|||
++pending_computations_[current_computation_];
|
||||
const int current_computation = current_computation_;
|
||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
submap_id, submap_nodes, &submap->high_resolution_hybrid_grid,
|
||||
submap_id, submap_nodes, &submap->high_resolution_hybrid_grid(),
|
||||
[=]() EXCLUDES(mutex_) {
|
||||
ComputeConstraint(submap_id, submap, node_id,
|
||||
false, /* match_full_submap */
|
||||
|
@ -96,7 +96,7 @@ void ConstraintBuilder::MaybeAddGlobalConstraint(
|
|||
++pending_computations_[current_computation_];
|
||||
const int current_computation = current_computation_;
|
||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||
submap_id, submap_nodes, &submap->high_resolution_hybrid_grid,
|
||||
submap_id, submap_nodes, &submap->high_resolution_hybrid_grid(),
|
||||
[=]() EXCLUDES(mutex_) {
|
||||
ComputeConstraint(
|
||||
submap_id, submap, node_id, true, /* match_full_submap */
|
||||
|
|
|
@ -224,9 +224,9 @@ std::vector<Eigen::Array4i> ExtractVoxelData(
|
|||
const HybridGrid& hybrid_grid, const transform::Rigid3f& transform,
|
||||
Eigen::Array2i* min_index, Eigen::Array2i* max_index) {
|
||||
std::vector<Eigen::Array4i> voxel_indices_and_probabilities;
|
||||
const float resolution_inverse = 1. / hybrid_grid.resolution();
|
||||
const float resolution_inverse = 1.f / hybrid_grid.resolution();
|
||||
|
||||
constexpr double kXrayObstructedCellProbabilityLimit = 0.501;
|
||||
constexpr float kXrayObstructedCellProbabilityLimit = 0.501f;
|
||||
for (auto it = HybridGrid::Iterator(hybrid_grid); !it.Done(); it.Next()) {
|
||||
const uint16 probability_value = it.GetValue();
|
||||
const float probability = mapping::ValueToProbability(probability_value);
|
||||
|
@ -323,22 +323,22 @@ proto::SubmapsOptions CreateSubmapsOptions(
|
|||
Submap::Submap(const float high_resolution, const float low_resolution,
|
||||
const transform::Rigid3d& local_pose)
|
||||
: mapping::Submap(local_pose),
|
||||
high_resolution_hybrid_grid(high_resolution),
|
||||
low_resolution_hybrid_grid(low_resolution) {}
|
||||
high_resolution_hybrid_grid_(high_resolution),
|
||||
low_resolution_hybrid_grid_(low_resolution) {}
|
||||
|
||||
void Submap::ToResponseProto(
|
||||
const transform::Rigid3d& global_submap_pose,
|
||||
mapping::proto::SubmapQuery::Response* const response) const {
|
||||
// Generate an X-ray view through the 'hybrid_grid', aligned to the xy-plane
|
||||
// in the global map frame.
|
||||
const float resolution = high_resolution_hybrid_grid.resolution();
|
||||
const float resolution = high_resolution_hybrid_grid_.resolution();
|
||||
response->set_resolution(resolution);
|
||||
|
||||
// Compute a bounding box for the texture.
|
||||
Eigen::Array2i min_index(INT_MAX, INT_MAX);
|
||||
Eigen::Array2i max_index(INT_MIN, INT_MIN);
|
||||
const std::vector<Eigen::Array4i> voxel_indices_and_probabilities =
|
||||
ExtractVoxelData(high_resolution_hybrid_grid,
|
||||
ExtractVoxelData(high_resolution_hybrid_grid_,
|
||||
global_submap_pose.cast<float>(), &min_index,
|
||||
&max_index);
|
||||
|
||||
|
@ -383,17 +383,17 @@ void Submaps::InsertRangeData(const sensor::RangeData& range_data,
|
|||
for (const int index : insertion_indices()) {
|
||||
Submap* submap = submaps_[index].get();
|
||||
const sensor::RangeData transformed_range_data = sensor::TransformRangeData(
|
||||
range_data, submap->local_pose.inverse().cast<float>());
|
||||
range_data, submap->local_pose().inverse().cast<float>());
|
||||
range_data_inserter_.Insert(
|
||||
FilterRangeDataByMaxRange(transformed_range_data,
|
||||
options_.high_resolution_max_range()),
|
||||
&submap->high_resolution_hybrid_grid);
|
||||
&submap->high_resolution_hybrid_grid_);
|
||||
range_data_inserter_.Insert(transformed_range_data,
|
||||
&submap->low_resolution_hybrid_grid);
|
||||
++submap->num_range_data;
|
||||
&submap->low_resolution_hybrid_grid_);
|
||||
++submap->num_range_data_;
|
||||
}
|
||||
const Submap* const last_submap = Get(size() - 1);
|
||||
if (last_submap->num_range_data == options_.num_range_data()) {
|
||||
if (last_submap->num_range_data_ == options_.num_range_data()) {
|
||||
AddSubmap(transform::Rigid3d(range_data.origin.cast<double>(),
|
||||
gravity_alignment));
|
||||
}
|
||||
|
@ -402,8 +402,8 @@ void Submaps::InsertRangeData(const sensor::RangeData& range_data,
|
|||
void Submaps::AddSubmap(const transform::Rigid3d& local_pose) {
|
||||
if (size() > 1) {
|
||||
Submap* submap = submaps_[size() - 2].get();
|
||||
CHECK(!submap->finished);
|
||||
submap->finished = true;
|
||||
CHECK(!submap->finished_);
|
||||
submap->finished_ = true;
|
||||
}
|
||||
submaps_.emplace_back(new Submap(options_.high_resolution(),
|
||||
options_.low_resolution(), local_pose));
|
||||
|
|
|
@ -47,17 +47,30 @@ void InsertIntoProbabilityGrid(
|
|||
proto::SubmapsOptions CreateSubmapsOptions(
|
||||
common::LuaParameterDictionary* parameter_dictionary);
|
||||
|
||||
struct Submap : public mapping::Submap {
|
||||
class Submap : public mapping::Submap {
|
||||
public:
|
||||
Submap(float high_resolution, float low_resolution,
|
||||
const transform::Rigid3d& local_pose);
|
||||
|
||||
HybridGrid high_resolution_hybrid_grid;
|
||||
HybridGrid low_resolution_hybrid_grid;
|
||||
bool finished = false;
|
||||
const HybridGrid& high_resolution_hybrid_grid() const {
|
||||
return high_resolution_hybrid_grid_;
|
||||
}
|
||||
const HybridGrid& low_resolution_hybrid_grid() const {
|
||||
return low_resolution_hybrid_grid_;
|
||||
}
|
||||
const bool finished() const { return finished_; }
|
||||
|
||||
void ToResponseProto(
|
||||
const transform::Rigid3d& global_submap_pose,
|
||||
mapping::proto::SubmapQuery::Response* response) const override;
|
||||
|
||||
private:
|
||||
// TODO(hrapp): Remove friend declaration.
|
||||
friend class Submaps;
|
||||
|
||||
HybridGrid high_resolution_hybrid_grid_;
|
||||
HybridGrid low_resolution_hybrid_grid_;
|
||||
bool finished_ = false;
|
||||
};
|
||||
|
||||
// A container of Submaps.
|
||||
|
|
Loading…
Reference in New Issue