Skip constraint search against unfinished submaps. (#1362)

The uplink server only receives the grid content of a submap after
that submap is finished for efficiency. Therefore, constraint
searches against that submap need to be skipped.
Also add checks to avoid this in the future.

FIXES=#1360
master
gaschler 2018-08-06 17:34:40 +02:00 committed by Wally B. Feed
parent 3f3428e8d4
commit 54f7f4f969
7 changed files with 17 additions and 4 deletions

View File

@ -242,6 +242,11 @@ void PoseGraph2D::ComputeConstraint(const NodeId& node_id,
{ {
common::MutexLocker locker(&mutex_); common::MutexLocker locker(&mutex_);
CHECK(data_.submap_data.at(submap_id).state == SubmapState::kFinished); CHECK(data_.submap_data.at(submap_id).state == SubmapState::kFinished);
if (!data_.submap_data.at(submap_id).submap->finished()) {
// Uplink server only receives grids when they are finished, so skip
// constraint search before that.
return;
}
const common::Time node_time = GetLatestNodeTime(node_id, submap_id); const common::Time node_time = GetLatestNodeTime(node_id, submap_id);
const common::Time last_connection_time = const common::Time last_connection_time =

View File

@ -256,6 +256,11 @@ void PoseGraph3D::ComputeConstraint(const NodeId& node_id,
{ {
common::MutexLocker locker(&mutex_); common::MutexLocker locker(&mutex_);
CHECK(data_.submap_data.at(submap_id).state == SubmapState::kFinished); CHECK(data_.submap_data.at(submap_id).state == SubmapState::kFinished);
if (!data_.submap_data.at(submap_id).submap->finished()) {
// Uplink server only receives grids when they are finished, so skip
// constraint search before that.
return;
}
for (const NodeId& submap_node_id : for (const NodeId& submap_node_id :
data_.submap_data.at(submap_id).node_ids) { data_.submap_data.at(submap_id).node_ids) {

View File

@ -158,6 +158,7 @@ void ConstraintBuilder2D::WhenDone(
const ConstraintBuilder2D::SubmapScanMatcher* const ConstraintBuilder2D::SubmapScanMatcher*
ConstraintBuilder2D::DispatchScanMatcherConstruction(const SubmapId& submap_id, ConstraintBuilder2D::DispatchScanMatcherConstruction(const SubmapId& submap_id,
const Grid2D* const grid) { const Grid2D* const grid) {
CHECK(grid);
if (submap_scan_matchers_.count(submap_id) != 0) { if (submap_scan_matchers_.count(submap_id) != 0) {
return &submap_scan_matchers_.at(submap_id); return &submap_scan_matchers_.at(submap_id);
} }
@ -183,6 +184,7 @@ void ConstraintBuilder2D::ComputeConstraint(
const transform::Rigid2d& initial_relative_pose, const transform::Rigid2d& initial_relative_pose,
const SubmapScanMatcher& submap_scan_matcher, const SubmapScanMatcher& submap_scan_matcher,
std::unique_ptr<ConstraintBuilder2D::Constraint>* constraint) { std::unique_ptr<ConstraintBuilder2D::Constraint>* constraint) {
CHECK(submap_scan_matcher.fast_correlative_scan_matcher);
const transform::Rigid2d initial_pose = const transform::Rigid2d initial_pose =
ComputeSubmapPose(*submap) * initial_relative_pose; ComputeSubmapPose(*submap) * initial_relative_pose;

View File

@ -107,7 +107,7 @@ class ConstraintBuilder2D {
private: private:
struct SubmapScanMatcher { struct SubmapScanMatcher {
const Grid2D* grid; const Grid2D* grid = nullptr;
std::unique_ptr<scan_matching::FastCorrelativeScanMatcher2D> std::unique_ptr<scan_matching::FastCorrelativeScanMatcher2D>
fast_correlative_scan_matcher; fast_correlative_scan_matcher;
std::weak_ptr<common::Task> creation_task_handle; std::weak_ptr<common::Task> creation_task_handle;

View File

@ -199,6 +199,7 @@ void ConstraintBuilder3D::ComputeConstraint(
const transform::Rigid3d& global_submap_pose, const transform::Rigid3d& global_submap_pose,
const SubmapScanMatcher& submap_scan_matcher, const SubmapScanMatcher& submap_scan_matcher,
std::unique_ptr<Constraint>* constraint) { std::unique_ptr<Constraint>* constraint) {
CHECK(submap_scan_matcher.fast_correlative_scan_matcher);
// The 'constraint_transform' (submap i <- node j) is computed from: // The 'constraint_transform' (submap i <- node j) is computed from:
// - a 'high_resolution_point_cloud' in node j and // - a 'high_resolution_point_cloud' in node j and
// - the initial guess 'initial_pose' (submap i <- node j). // - the initial guess 'initial_pose' (submap i <- node j).

View File

@ -116,8 +116,8 @@ class ConstraintBuilder3D {
private: private:
struct SubmapScanMatcher { struct SubmapScanMatcher {
const HybridGrid* high_resolution_hybrid_grid; const HybridGrid* high_resolution_hybrid_grid = nullptr;
const HybridGrid* low_resolution_hybrid_grid; const HybridGrid* low_resolution_hybrid_grid = nullptr;
std::unique_ptr<scan_matching::FastCorrelativeScanMatcher3D> std::unique_ptr<scan_matching::FastCorrelativeScanMatcher3D>
fast_correlative_scan_matcher; fast_correlative_scan_matcher;
std::weak_ptr<common::Task> creation_task_handle; std::weak_ptr<common::Task> creation_task_handle;

View File

@ -443,7 +443,7 @@ TEST_P(MapBuilderTestByGridType, LocalizationOnFrozenTrajectory2D) {
++num_cross_trajectory_constraints; ++num_cross_trajectory_constraints;
} }
} }
EXPECT_GT(num_cross_trajectory_constraints, 3); EXPECT_GE(num_cross_trajectory_constraints, 3);
// TODO(gaschler): Subscribe global slam callback, verify that all nodes are // TODO(gaschler): Subscribe global slam callback, verify that all nodes are
// optimized. // optimized.
EXPECT_THAT(constraints, ::testing::Contains(::testing::Field( EXPECT_THAT(constraints, ::testing::Contains(::testing::Field(