diff --git a/cartographer/io/outlier_removing_points_processor.cc b/cartographer/io/outlier_removing_points_processor.cc index 0cec8d2..4e21021 100644 --- a/cartographer/io/outlier_removing_points_processor.cc +++ b/cartographer/io/outlier_removing_points_processor.cc @@ -36,7 +36,7 @@ OutlierRemovingPointsProcessor::OutlierRemovingPointsProcessor( : voxel_size_(voxel_size), next_(next), state_(State::kPhase1), - voxels_(voxel_size_, Eigen::Vector3f::Zero()) { + voxels_(voxel_size_) { LOG(INFO) << "Marking hits..."; } diff --git a/cartographer/io/xray_points_processor.cc b/cartographer/io/xray_points_processor.cc index 902a8ac..0a442d6 100644 --- a/cartographer/io/xray_points_processor.cc +++ b/cartographer/io/xray_points_processor.cc @@ -142,9 +142,8 @@ XRayPointsProcessor::XRayPointsProcessor( output_filename_(output_filename), transform_(transform) { for (size_t i = 0; i < (floors_.empty() ? 1 : floors.size()); ++i) { - aggregations_.emplace_back(Aggregation{ - mapping_3d::HybridGridBase(voxel_size, Eigen::Vector3f::Zero()), - {}}); + aggregations_.emplace_back( + Aggregation{mapping_3d::HybridGridBase(voxel_size), {}}); } } diff --git a/cartographer/mapping_3d/hybrid_grid.h b/cartographer/mapping_3d/hybrid_grid.h index ca1e186..0472546 100644 --- a/cartographer/mapping_3d/hybrid_grid.h +++ b/cartographer/mapping_3d/hybrid_grid.h @@ -415,20 +415,18 @@ class HybridGridBase : public Grid { public: using Iterator = typename Grid::Iterator; - // Creates a new tree-based probability grid around 'origin' which becomes the - // center of the cell at index (0, 0, 0). Each voxel has edge length - // 'resolution'. - HybridGridBase(const float resolution, const Eigen::Vector3f& origin) - : resolution_(resolution), origin_(origin) {} + // Creates a new tree-based probability grid with voxels having edge length + // 'resolution' around the origin which becomes the center of the cell at + // index (0, 0, 0). + explicit HybridGridBase(const float resolution) : resolution_(resolution) {} float resolution() const { return resolution_; } - Eigen::Vector3f origin() const { return origin_; } // Returns the index of the cell containing the 'point'. Indices are integer - // vectors identifying cells, for this the relative distance from the origin - // is rounded to the next multiple of the resolution. + // vectors identifying cells, for this the coordinates are rounded to the next + // multiple of the resolution. Eigen::Array3i GetCellIndex(const Eigen::Vector3f& point) const { - Eigen::Array3f index = (point - origin_).array() / resolution_; + Eigen::Array3f index = point.array() / resolution_; return Eigen::Array3i(common::RoundToInt(index.x()), common::RoundToInt(index.y()), common::RoundToInt(index.z())); @@ -444,7 +442,7 @@ class HybridGridBase : public Grid { // Returns the center of the cell at 'index'. Eigen::Vector3f GetCenterOfCell(const Eigen::Array3i& index) const { - return index.matrix().cast() * resolution_ + origin_; + return index.matrix().cast() * resolution_; } // Iterator functions for range-based for loops. @@ -459,20 +457,17 @@ class HybridGridBase : public Grid { private: // Edge length of each voxel. const float resolution_; - - // Position of the center of the octree. - const Eigen::Vector3f origin_; }; // A grid containing probability values stored using 15 bits, and an update // marker per voxel. class HybridGrid : public HybridGridBase { public: - HybridGrid(const float resolution, const Eigen::Vector3f& origin) - : HybridGridBase(resolution, origin) {} + explicit HybridGrid(const float resolution) + : HybridGridBase(resolution) {} - HybridGrid(const proto::HybridGrid& proto) - : HybridGrid(proto.resolution(), transform::ToEigen(proto.origin())) { + explicit HybridGrid(const proto::HybridGrid& proto) + : HybridGrid(proto.resolution()) { CHECK_EQ(proto.values_size(), proto.x_indices_size()); CHECK_EQ(proto.values_size(), proto.y_indices_size()); CHECK_EQ(proto.values_size(), proto.z_indices_size()); @@ -535,7 +530,6 @@ class HybridGrid : public HybridGridBase { inline proto::HybridGrid ToProto(const HybridGrid& grid) { proto::HybridGrid result; result.set_resolution(grid.resolution()); - *result.mutable_origin() = transform::ToProto(grid.origin()); for (const auto it : grid) { result.add_x_indices(it.first.x()); result.add_y_indices(it.first.y()); diff --git a/cartographer/mapping_3d/hybrid_grid_test.cc b/cartographer/mapping_3d/hybrid_grid_test.cc index e3b324f..ba78622 100644 --- a/cartographer/mapping_3d/hybrid_grid_test.cc +++ b/cartographer/mapping_3d/hybrid_grid_test.cc @@ -27,7 +27,7 @@ namespace mapping_3d { namespace { TEST(HybridGridTest, ApplyOdds) { - HybridGrid hybrid_grid(1.f, Eigen::Vector3f(-0.5f, -0.5f, -0.5f)); + HybridGrid hybrid_grid(1.f); EXPECT_FALSE(hybrid_grid.IsKnown(Eigen::Array3i(0, 0, 0))); EXPECT_FALSE(hybrid_grid.IsKnown(Eigen::Array3i(0, 1, 0))); @@ -74,18 +74,18 @@ TEST(HybridGridTest, ApplyOdds) { } TEST(HybridGridTest, GetProbability) { - HybridGrid hybrid_grid(1.f, Eigen::Vector3f(-0.5f, -0.5f, -0.5f)); + HybridGrid hybrid_grid(1.f); hybrid_grid.SetProbability( - hybrid_grid.GetCellIndex(Eigen::Vector3f(-0.5f, 0.5f, 0.5f)), + hybrid_grid.GetCellIndex(Eigen::Vector3f(0.f, 1.f, 1.f)), mapping::kMaxProbability); EXPECT_NEAR(hybrid_grid.GetProbability( - hybrid_grid.GetCellIndex(Eigen::Vector3f(-0.5f, 0.5f, 0.5f))), + hybrid_grid.GetCellIndex(Eigen::Vector3f(0.f, 1.f, 1.f))), mapping::kMaxProbability, 1e-6); for (const Eigen::Array3i& index : - {hybrid_grid.GetCellIndex(Eigen::Vector3f(-0.5f, 1.5, 0.5f)), - hybrid_grid.GetCellIndex(Eigen::Vector3f(.5f, 0.5, 0.5f)), - hybrid_grid.GetCellIndex(Eigen::Vector3f(0.5f, 1.5, 0.5f))}) { + {hybrid_grid.GetCellIndex(Eigen::Vector3f(0.f, 2.f, 1.f)), + hybrid_grid.GetCellIndex(Eigen::Vector3f(1.f, 1.f, 1.f)), + hybrid_grid.GetCellIndex(Eigen::Vector3f(1.f, 2.f, 1.f))}) { EXPECT_FALSE(hybrid_grid.IsKnown(index)); } } @@ -93,43 +93,42 @@ TEST(HybridGridTest, GetProbability) { MATCHER_P(AllCwiseEqual, index, "") { return (arg == index).all(); } TEST(HybridGridTest, GetCellIndex) { - HybridGrid hybrid_grid(2.f, Eigen::Vector3f(-7.f, -13.f, -2.f)); + HybridGrid hybrid_grid(2.f); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(-7.f, -13.f, -2.f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(0.f, 0.f, 0.f)), AllCwiseEqual(Eigen::Array3i(0, 0, 0))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(-7.f, 13.f, 8.f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(0.f, 26.f, 10.f)), AllCwiseEqual(Eigen::Array3i(0, 13, 5))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(7.f, -13.f, 8.f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(14.f, 0.f, 10.f)), AllCwiseEqual(Eigen::Array3i(7, 0, 5))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(7.f, 13.f, -2.f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(14.f, 26.f, 0.f)), AllCwiseEqual(Eigen::Array3i(7, 13, 0))); // Check around the origin. - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(1.5f, -1.5f, -1.5f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(8.5f, 11.5f, 0.5f)), AllCwiseEqual(Eigen::Array3i(4, 6, 0))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(0.5f, -0.5f, -0.5f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(7.5f, 12.5f, 1.5f)), AllCwiseEqual(Eigen::Array3i(4, 6, 1))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(-0.5f, 1.5f, 0.5f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(6.5f, 14.5f, 2.5f)), AllCwiseEqual(Eigen::Array3i(3, 7, 1))); - EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(-1.5f, 0.5f, 1.5f)), + EXPECT_THAT(hybrid_grid.GetCellIndex(Eigen::Vector3f(5.5f, 13.5f, 3.5f)), AllCwiseEqual(Eigen::Array3i(3, 7, 2))); } TEST(HybridGridTest, GetCenterOfCell) { - HybridGrid hybrid_grid(2.f, Eigen::Vector3f(-7.f, -13.f, -2.f)); + HybridGrid hybrid_grid(2.f); const Eigen::Array3i index(3, 2, 1); const Eigen::Vector3f center = hybrid_grid.GetCenterOfCell(index); - EXPECT_NEAR(-1.f, center.x(), 1e-6); - EXPECT_NEAR(-9.f, center.y(), 1e-6); - EXPECT_NEAR(0.f, center.z(), 1e-6); + EXPECT_NEAR(6.f, center.x(), 1e-6); + EXPECT_NEAR(4.f, center.y(), 1e-6); + EXPECT_NEAR(2.f, center.z(), 1e-6); EXPECT_THAT(hybrid_grid.GetCellIndex(center), AllCwiseEqual(index)); } class RandomHybridGridTest : public ::testing::Test { public: - RandomHybridGridTest() - : hybrid_grid_(2.f, Eigen::Vector3f(-7.f, -12.f, 0.f)), values_() { + RandomHybridGridTest() : hybrid_grid_(2.f), values_() { std::mt19937 rng(1285120005); std::uniform_real_distribution value_distribution( mapping::kMinProbability, mapping::kMaxProbability); @@ -189,9 +188,6 @@ TEST_F(RandomHybridGridTest, TestIteration) { TEST_F(RandomHybridGridTest, ToProto) { const auto proto = ToProto(hybrid_grid_); EXPECT_EQ(hybrid_grid_.resolution(), proto.resolution()); - EXPECT_EQ(hybrid_grid_.origin().x(), proto.origin().x()); - EXPECT_EQ(hybrid_grid_.origin().y(), proto.origin().y()); - EXPECT_EQ(hybrid_grid_.origin().z(), proto.origin().z()); ASSERT_EQ(proto.x_indices_size(), proto.y_indices_size()); ASSERT_EQ(proto.x_indices_size(), proto.z_indices_size()); diff --git a/cartographer/mapping_3d/kalman_local_trajectory_builder.cc b/cartographer/mapping_3d/kalman_local_trajectory_builder.cc index 4264c58..69cb072 100644 --- a/cartographer/mapping_3d/kalman_local_trajectory_builder.cc +++ b/cartographer/mapping_3d/kalman_local_trajectory_builder.cc @@ -140,19 +140,24 @@ KalmanLocalTrajectoryBuilder::AddAccumulatedRangeData( pose_tracker_->GetPoseEstimateMeanAndCovariance( time, &pose_prediction, &unused_covariance_prediction); - transform::Rigid3d initial_ceres_pose = pose_prediction; + const Submap* const matching_submap = + submaps_->Get(submaps_->matching_index()); + transform::Rigid3d initial_ceres_pose = + 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 = adaptive_voxel_filter.Filter(filtered_range_data.returns); if (options_.kalman_local_trajectory_builder_options() .use_online_correlative_scan_matching()) { + // We take a copy since we use 'intial_ceres_pose' as an output argument. + const transform::Rigid3d initial_pose = initial_ceres_pose; real_time_correlative_scan_matcher_->Match( - pose_prediction, filtered_point_cloud_in_tracking, - submaps_->high_resolution_matching_grid(), &initial_ceres_pose); + initial_pose, filtered_point_cloud_in_tracking, + matching_submap->high_resolution_hybrid_grid, &initial_ceres_pose); } - transform::Rigid3d pose_observation; + transform::Rigid3d pose_observation_in_submap; ceres::Solver::Summary summary; sensor::AdaptiveVoxelFilter low_resolution_adaptive_voxel_filter( @@ -161,10 +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, - &submaps_->high_resolution_matching_grid()}, + &matching_submap->high_resolution_hybrid_grid}, {&low_resolution_point_cloud_in_tracking, - &submaps_->low_resolution_matching_grid()}}, - &pose_observation, &summary); + &matching_submap->low_resolution_hybrid_grid}}, + &pose_observation_in_submap, &summary); + const transform::Rigid3d pose_observation = + matching_submap->local_pose() * pose_observation_in_submap; pose_tracker_->AddPoseObservation( time, pose_observation, options_.kalman_local_trajectory_builder_options() diff --git a/cartographer/mapping_3d/optimizing_local_trajectory_builder.cc b/cartographer/mapping_3d/optimizing_local_trajectory_builder.cc index 0c1bf8b..ab1c927 100644 --- a/cartographer/mapping_3d/optimizing_local_trajectory_builder.cc +++ b/cartographer/mapping_3d/optimizing_local_trajectory_builder.cc @@ -176,7 +176,8 @@ OptimizingLocalTrajectoryBuilder::AddRangefinderData( batches_.push_back( Batch{time, point_cloud, high_resolution_filtered_points, low_resolution_filtered_points, - State{{{1., 0., 0., 0.}}, {{0., 0., 0.}}, {{0., 0., 0.}}}}); + State(Eigen::Vector3d::Zero(), Eigen::Quaterniond::Identity(), + Eigen::Vector3d::Zero())}); } else { const Batch& last_batch = batches_.back(); batches_.push_back(Batch{ @@ -214,6 +215,19 @@ void OptimizingLocalTrajectoryBuilder::RemoveObsoleteSensorData() { } } +void OptimizingLocalTrajectoryBuilder::TransformStates( + const transform::Rigid3d& transform) { + for (Batch& batch : batches_) { + const transform::Rigid3d new_pose = transform * batch.state.ToRigid(); + const auto& velocity = batch.state.velocity; + const Eigen::Vector3d new_velocity = + transform.rotation() * + Eigen::Vector3d(velocity[0], velocity[1], velocity[2]); + batch.state = + State(new_pose.translation(), new_pose.rotation(), new_velocity); + } +} + std::unique_ptr OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) { // TODO(hrapp): Make the number of optimizations configurable. @@ -223,6 +237,12 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) { } ceres::Problem problem; + const Submap* const matching_submap = + submaps_->Get(submaps_->matching_index()); + // 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()); for (size_t i = 0; i < batches_.size(); ++i) { Batch& batch = batches_[i]; problem.AddResidualBlock( @@ -234,7 +254,7 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) { std::sqrt(static_cast( batch.high_resolution_filtered_points.size())), batch.high_resolution_filtered_points, - submaps_->high_resolution_matching_grid()), + matching_submap->high_resolution_hybrid_grid), batch.high_resolution_filtered_points.size()), nullptr, batch.state.translation.data(), batch.state.rotation.data()); problem.AddResidualBlock( @@ -246,15 +266,15 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) { std::sqrt(static_cast( batch.low_resolution_filtered_points.size())), batch.low_resolution_filtered_points, - submaps_->low_resolution_matching_grid()), + matching_submap->low_resolution_hybrid_grid), batch.low_resolution_filtered_points.size()), nullptr, batch.state.translation.data(), batch.state.rotation.data()); if (i == 0) { problem.SetParameterBlockConstant(batch.state.translation.data()); + problem.SetParameterBlockConstant(batch.state.rotation.data()); problem.AddParameterBlock(batch.state.velocity.data(), 3); problem.SetParameterBlockConstant(batch.state.velocity.data()); - problem.SetParameterBlockConstant(batch.state.rotation.data()); } else { problem.SetParameterization(batch.state.rotation.data(), new ceres::QuaternionParameterization()); @@ -329,6 +349,9 @@ OptimizingLocalTrajectoryBuilder::MaybeOptimize(const common::Time time) { ceres::Solver::Summary summary; 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()); if (num_accumulated_ < options_.scans_per_accumulation()) { return nullptr; } @@ -433,10 +456,7 @@ OptimizingLocalTrajectoryBuilder::PredictState(const State& start_state, start_rotation * result.delta_velocity - gravity_constant_ * delta_time_seconds * Eigen::Vector3d::UnitZ(); - return State{ - {{orientation.w(), orientation.x(), orientation.y(), orientation.z()}}, - {{position.x(), position.y(), position.z()}}, - {{velocity.x(), velocity.y(), velocity.z()}}}; + return State(position, orientation, velocity); } } // namespace mapping_3d diff --git a/cartographer/mapping_3d/optimizing_local_trajectory_builder.h b/cartographer/mapping_3d/optimizing_local_trajectory_builder.h index 5b1c76d..770be8b 100644 --- a/cartographer/mapping_3d/optimizing_local_trajectory_builder.h +++ b/cartographer/mapping_3d/optimizing_local_trajectory_builder.h @@ -61,12 +61,16 @@ class OptimizingLocalTrajectoryBuilder private: struct State { - // TODO(hrapp): This should maybe use a CeresPose. - // Rotation quaternion as (w, x, y, z). - std::array rotation; std::array translation; + std::array rotation; // Rotation quaternion as (w, x, y, z). std::array velocity; + State(const Eigen::Vector3d& translation, + const Eigen::Quaterniond& rotation, const Eigen::Vector3d& velocity) + : translation{{translation.x(), translation.y(), translation.z()}}, + rotation{{rotation.w(), rotation.x(), rotation.y(), rotation.z()}}, + velocity{{velocity.x(), velocity.y(), velocity.z()}} {} + Eigen::Quaterniond ToQuaternion() const { return Eigen::Quaterniond(rotation[0], rotation[1], rotation[2], rotation[3]); @@ -107,6 +111,7 @@ class OptimizingLocalTrajectoryBuilder const common::Time time, const sensor::RangeData& range_data_in_tracking, const transform::Rigid3d& pose_observation); + void TransformStates(const transform::Rigid3d& transform); std::unique_ptr MaybeOptimize(common::Time time); const proto::LocalTrajectoryBuilderOptions options_; diff --git a/cartographer/mapping_3d/proto/hybrid_grid.proto b/cartographer/mapping_3d/proto/hybrid_grid.proto index 84b523c..b6fc592 100644 --- a/cartographer/mapping_3d/proto/hybrid_grid.proto +++ b/cartographer/mapping_3d/proto/hybrid_grid.proto @@ -14,13 +14,10 @@ syntax = "proto2"; -import "cartographer/transform/proto/transform.proto"; - package cartographer.mapping_3d.proto; message HybridGrid { optional float resolution = 1; - optional transform.proto.Vector3f origin = 2; // '{x, y, z}_indices[i]' is the index of 'values[i]'. repeated sint32 x_indices = 3 [packed = true]; repeated sint32 y_indices = 4 [packed = true]; diff --git a/cartographer/mapping_3d/range_data_inserter_test.cc b/cartographer/mapping_3d/range_data_inserter_test.cc index c1fb5ef..e970247 100644 --- a/cartographer/mapping_3d/range_data_inserter_test.cc +++ b/cartographer/mapping_3d/range_data_inserter_test.cc @@ -28,8 +28,7 @@ namespace { class RangeDataInserterTest : public ::testing::Test { protected: - RangeDataInserterTest() - : hybrid_grid_(1.f, Eigen::Vector3f(0.5f, 0.5f, 0.5f)) { + RangeDataInserterTest() : hybrid_grid_(1.f) { auto parameter_dictionary = common::MakeDictionary( "return { " "hit_probability = 0.7, " @@ -41,11 +40,9 @@ class RangeDataInserterTest : public ::testing::Test { } void InsertPointCloud() { - const Eigen::Vector3f origin = Eigen::Vector3f(0.5f, 0.5f, -3.5f); - sensor::PointCloud returns = {{-2.5f, -0.5f, 4.5f}, - {-1.5f, 0.5f, 4.5f}, - {-0.5f, 1.5f, 4.5f}, - {0.5f, 2.5f, 4.5f}}; + const Eigen::Vector3f origin = Eigen::Vector3f(0.f, 0.f, -4.f); + sensor::PointCloud returns = { + {-3.f, -1.f, 4.f}, {-2.f, 0.f, 4.f}, {-1.f, 1.f, 4.f}, {0.f, 2.f, 4.f}}; range_data_inserter_->Insert(sensor::RangeData{origin, returns, {}}, &hybrid_grid_); } @@ -70,19 +67,19 @@ class RangeDataInserterTest : public ::testing::Test { TEST_F(RangeDataInserterTest, InsertPointCloud) { InsertPointCloud(); - EXPECT_NEAR(options().miss_probability(), GetProbability(0.5f, 0.5f, -3.5f), + EXPECT_NEAR(options().miss_probability(), GetProbability(0.f, 0.f, -4.f), 1e-4); - EXPECT_NEAR(options().miss_probability(), GetProbability(0.5f, 0.5f, -2.5f), + EXPECT_NEAR(options().miss_probability(), GetProbability(0.f, 0.f, -3.f), 1e-4); - EXPECT_NEAR(options().miss_probability(), GetProbability(0.5f, 0.5f, -1.5f), + EXPECT_NEAR(options().miss_probability(), GetProbability(0.f, 0.f, -2.f), 1e-4); for (int x = -4; x <= 4; ++x) { for (int y = -4; y <= 4; ++y) { if (x < -3 || x > 0 || y != x + 2) { - EXPECT_FALSE(IsKnown(x + 0.5f, y + 0.5f, 4.5f)); + EXPECT_FALSE(IsKnown(x, y, 4.f)); } else { - EXPECT_NEAR(options().hit_probability(), - GetProbability(x + 0.5f, y + 0.5f, 4.5f), 1e-4); + EXPECT_NEAR(options().hit_probability(), GetProbability(x, y, 4.f), + 1e-4); } } } @@ -90,22 +87,19 @@ TEST_F(RangeDataInserterTest, InsertPointCloud) { TEST_F(RangeDataInserterTest, ProbabilityProgression) { InsertPointCloud(); - EXPECT_NEAR(options().hit_probability(), GetProbability(-1.5f, 0.5f, 4.5f), + EXPECT_NEAR(options().hit_probability(), GetProbability(-2.f, 0.f, 4.f), 1e-4); - EXPECT_NEAR(options().miss_probability(), GetProbability(-1.5f, 0.5f, 3.5f), + EXPECT_NEAR(options().miss_probability(), GetProbability(-2.f, 0.f, 3.f), 1e-4); - EXPECT_NEAR(options().miss_probability(), GetProbability(0.5f, 0.5f, -2.5f), + EXPECT_NEAR(options().miss_probability(), GetProbability(0.f, 0.f, -3.f), 1e-4); for (int i = 0; i < 1000; ++i) { InsertPointCloud(); } - EXPECT_NEAR(mapping::kMaxProbability, GetProbability(-1.5f, 0.5f, 4.5f), - 1e-3); - EXPECT_NEAR(mapping::kMinProbability, GetProbability(-1.5f, 0.5f, 3.5f), - 1e-3); - EXPECT_NEAR(mapping::kMinProbability, GetProbability(0.5f, 0.5f, -2.5f), - 1e-3); + EXPECT_NEAR(mapping::kMaxProbability, GetProbability(-2.f, 0.f, 4.f), 1e-3); + EXPECT_NEAR(mapping::kMinProbability, GetProbability(-2.f, 0.f, 3.f), 1e-3); + EXPECT_NEAR(mapping::kMinProbability, GetProbability(0.f, 0.f, -3.f), 1e-3); } } // namespace diff --git a/cartographer/mapping_3d/scan_matching/ceres_scan_matcher_test.cc b/cartographer/mapping_3d/scan_matching/ceres_scan_matcher_test.cc index 939209f..ed2310b 100644 --- a/cartographer/mapping_3d/scan_matching/ceres_scan_matcher_test.cc +++ b/cartographer/mapping_3d/scan_matching/ceres_scan_matcher_test.cc @@ -34,10 +34,9 @@ namespace { class CeresScanMatcherTest : public ::testing::Test { protected: CeresScanMatcherTest() - : hybrid_grid_(1.f /* resolution */, - Eigen::Vector3f(0.5f, 0.5f, 0.5f) /* origin */), + : hybrid_grid_(1.f), expected_pose_( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5))) { + transform::Rigid3d::Translation(Eigen::Vector3d(-1., 0., 0.))) { for (const auto& point : {Eigen::Vector3f(-3.f, 2.f, 0.f), Eigen::Vector3f(-4.f, 2.f, 0.f), Eigen::Vector3f(-5.f, 2.f, 0.f), Eigen::Vector3f(-6.f, 2.f, 0.f), @@ -84,23 +83,23 @@ class CeresScanMatcherTest : public ::testing::Test { TEST_F(CeresScanMatcherTest, PerfectEstimate) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5))); + transform::Rigid3d::Translation(Eigen::Vector3d(-1., 0., 0.))); } TEST_F(CeresScanMatcherTest, AlongX) { ceres_scan_matcher_.reset(new CeresScanMatcher(options_)); TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.3, 0.5, 0.5))); + transform::Rigid3d::Translation(Eigen::Vector3d(-0.8, 0., 0.))); } TEST_F(CeresScanMatcherTest, AlongZ) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.3))); + transform::Rigid3d::Translation(Eigen::Vector3d(-1., 0., -0.2))); } TEST_F(CeresScanMatcherTest, AlongXYZ) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.4, 0.3, 0.7))); + transform::Rigid3d::Translation(Eigen::Vector3d(-0.9, -0.2, 0.2))); } TEST_F(CeresScanMatcherTest, FullPoseCorrection) { @@ -112,9 +111,8 @@ TEST_F(CeresScanMatcherTest, FullPoseCorrection) { expected_pose_ = expected_pose_ * additional_transform.inverse(); // ...starting initially with rotation around x. TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.45, 0.45, 0.55)) * - transform::Rigid3d::Rotation( - Eigen::AngleAxisd(0.05, Eigen::Vector3d(1., 0., 0.)))); + transform::Rigid3d(Eigen::Vector3d(-0.95, -0.05, 0.05), + Eigen::AngleAxisd(0.05, Eigen::Vector3d(1., 0., 0.)))); } } // namespace diff --git a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.cc b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.cc index 153ac7e..8a8b8a4 100644 --- a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.cc +++ b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.cc @@ -95,7 +95,6 @@ FastCorrelativeScanMatcher::FastCorrelativeScanMatcher( const proto::FastCorrelativeScanMatcherOptions& options) : options_(options), resolution_(hybrid_grid.resolution()), - origin_(hybrid_grid.origin()), width_in_voxels_(hybrid_grid.grid_size()), precomputation_grid_stack_( common::make_unique(hybrid_grid, options)), @@ -122,7 +121,7 @@ bool FastCorrelativeScanMatcher::MatchFullSubmap( const sensor::PointCloud& coarse_point_cloud, const sensor::PointCloud& fine_point_cloud, const float min_score, float* const score, transform::Rigid3d* const pose_estimate) const { - const transform::Rigid3d initial_pose_estimate(origin_.cast(), + const transform::Rigid3d initial_pose_estimate(Eigen::Vector3d::Zero(), gravity_alignment); float max_point_distance = 0.f; for (const Eigen::Vector3f& point : coarse_point_cloud) { diff --git a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.h b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.h index 5e1d9ef..3eb21c1 100644 --- a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.h +++ b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher.h @@ -136,7 +136,6 @@ class FastCorrelativeScanMatcher { const proto::FastCorrelativeScanMatcherOptions options_; const float resolution_; - const Eigen::Vector3f origin_; const int width_in_voxels_; std::unique_ptr precomputation_grid_stack_; RotationalScanMatcher rotational_scan_matcher_; diff --git a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher_test.cc b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher_test.cc index a680c8c..505ee3d 100644 --- a/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher_test.cc +++ b/cartographer/mapping_3d/scan_matching/fast_correlative_scan_matcher_test.cc @@ -87,8 +87,7 @@ TEST(FastCorrelativeScanMatcherTest, CorrectPose) { transform::Rigid3f::Rotation( Eigen::AngleAxisf(theta, Eigen::Vector3f::UnitZ())); - HybridGrid hybrid_grid(0.05f /* resolution */, - Eigen::Vector3f(0.5f, 1.5f, 2.5f) /* origin */); + HybridGrid hybrid_grid(0.05f); hybrid_grid.StartUpdate(); range_data_inserter.Insert( sensor::RangeData{ diff --git a/cartographer/mapping_3d/scan_matching/interpolated_grid_test.cc b/cartographer/mapping_3d/scan_matching/interpolated_grid_test.cc index e7c2478..e793523 100644 --- a/cartographer/mapping_3d/scan_matching/interpolated_grid_test.cc +++ b/cartographer/mapping_3d/scan_matching/interpolated_grid_test.cc @@ -28,9 +28,7 @@ namespace { class InterpolatedGridTest : public ::testing::Test { protected: InterpolatedGridTest() - : hybrid_grid_(0.1f /* resolution */, - Eigen::Vector3f(1.5f, 2.5f, 3.5f) /* origin */), - interpolated_grid_(hybrid_grid_) { + : hybrid_grid_(0.1f), interpolated_grid_(hybrid_grid_) { for (const auto& point : {Eigen::Vector3f(-3.f, 2.f, 0.f), Eigen::Vector3f(-4.f, 2.f, 0.f), Eigen::Vector3f(-5.f, 2.f, 0.f), Eigen::Vector3f(-6.f, 2.f, 0.f), diff --git a/cartographer/mapping_3d/scan_matching/precomputation_grid.cc b/cartographer/mapping_3d/scan_matching/precomputation_grid.cc index 4f43677..fe16e4e 100644 --- a/cartographer/mapping_3d/scan_matching/precomputation_grid.cc +++ b/cartographer/mapping_3d/scan_matching/precomputation_grid.cc @@ -48,7 +48,7 @@ Eigen::Array3i CellIndexAtHalfResolution(const Eigen::Array3i& cell_index) { } // namespace PrecomputationGrid ConvertToPrecomputationGrid(const HybridGrid& hybrid_grid) { - PrecomputationGrid result(hybrid_grid.resolution(), hybrid_grid.origin()); + PrecomputationGrid result(hybrid_grid.resolution()); for (auto it = HybridGrid::Iterator(hybrid_grid); !it.Done(); it.Next()) { const int cell_value = common::RoundToInt( (mapping::ValueToProbability(it.GetValue()) - @@ -64,7 +64,7 @@ PrecomputationGrid ConvertToPrecomputationGrid(const HybridGrid& hybrid_grid) { PrecomputationGrid PrecomputeGrid(const PrecomputationGrid& grid, const bool half_resolution, const Eigen::Array3i& shift) { - PrecomputationGrid result(grid.resolution(), grid.origin()); + PrecomputationGrid result(grid.resolution()); for (auto it = PrecomputationGrid::Iterator(grid); !it.Done(); it.Next()) { for (int i = 0; i != 8; ++i) { // We use this value to update 8 values in the resulting grid, at diff --git a/cartographer/mapping_3d/scan_matching/precomputation_grid.h b/cartographer/mapping_3d/scan_matching/precomputation_grid.h index 964f7bf..37ffa08 100644 --- a/cartographer/mapping_3d/scan_matching/precomputation_grid.h +++ b/cartographer/mapping_3d/scan_matching/precomputation_grid.h @@ -25,8 +25,8 @@ namespace scan_matching { class PrecomputationGrid : public HybridGridBase { public: - PrecomputationGrid(const float resolution, const Eigen::Vector3f& origin) - : HybridGridBase(resolution, origin) {} + explicit PrecomputationGrid(const float resolution) + : HybridGridBase(resolution) {} // Maps values from [0, 255] to [kMinProbability, kMaxProbability]. static float ToProbability(float value) { diff --git a/cartographer/mapping_3d/scan_matching/precomputation_grid_test.cc b/cartographer/mapping_3d/scan_matching/precomputation_grid_test.cc index 1ff78c7..73d5242 100644 --- a/cartographer/mapping_3d/scan_matching/precomputation_grid_test.cc +++ b/cartographer/mapping_3d/scan_matching/precomputation_grid_test.cc @@ -29,7 +29,7 @@ namespace scan_matching { namespace { TEST(PrecomputedGridGeneratorTest, TestAgainstNaiveAlgorithm) { - HybridGrid hybrid_grid(2.f, Eigen::Vector3f(-7.f, -12.f, 0.f)); + HybridGrid hybrid_grid(2.f); std::mt19937 rng(23847); std::uniform_int_distribution coordinate_distribution(-50, 49); diff --git a/cartographer/mapping_3d/scan_matching/real_time_correlative_scan_matcher_test.cc b/cartographer/mapping_3d/scan_matching/real_time_correlative_scan_matcher_test.cc index a7763ba..5cc2acb 100644 --- a/cartographer/mapping_3d/scan_matching/real_time_correlative_scan_matcher_test.cc +++ b/cartographer/mapping_3d/scan_matching/real_time_correlative_scan_matcher_test.cc @@ -36,9 +36,8 @@ namespace { class RealTimeCorrelativeScanMatcherTest : public ::testing::Test { protected: RealTimeCorrelativeScanMatcherTest() - : hybrid_grid_(0.1f /* resolution */, - Eigen::Vector3f(0.5f, 0.5f, 0.5f) /* origin */), - expected_pose_(Eigen::Vector3d(-0.5, 0.5, 0.5), + : hybrid_grid_(0.1f), + expected_pose_(Eigen::Vector3d(-1., 0., 0.), Eigen::Quaterniond::Identity()) { for (const auto& point : {Eigen::Vector3f(-3.f, 2.f, 0.f), Eigen::Vector3f(-4.f, 2.f, 0.f), @@ -82,43 +81,40 @@ class RealTimeCorrelativeScanMatcherTest : public ::testing::Test { TEST_F(RealTimeCorrelativeScanMatcherTest, PerfectEstimate) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5))); + transform::Rigid3d::Translation(Eigen::Vector3d(-1., 0., 0.))); } TEST_F(RealTimeCorrelativeScanMatcherTest, AlongX) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.3, 0.5, 0.5))); + transform::Rigid3d::Translation(Eigen::Vector3d(-0.8, 0., 0.))); } TEST_F(RealTimeCorrelativeScanMatcherTest, AlongZ) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.3))); + transform::Rigid3d::Translation(Eigen::Vector3d(-1., 0., -0.2))); } TEST_F(RealTimeCorrelativeScanMatcherTest, AlongXYZ) { TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.4, 0.3, 0.7))); + transform::Rigid3d::Translation(Eigen::Vector3d(-0.9, -0.2, 0.2))); } TEST_F(RealTimeCorrelativeScanMatcherTest, RotationAroundX) { - TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5)) * - transform::Rigid3d::Rotation( - Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(1., 0., 0.)))); + TestFromInitialPose(transform::Rigid3d( + Eigen::Vector3d(-1., 0., 0.), + Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(1., 0., 0.)))); } TEST_F(RealTimeCorrelativeScanMatcherTest, RotationAroundY) { - TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5)) * - transform::Rigid3d::Rotation( - Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(0., 1., 0.)))); + TestFromInitialPose(transform::Rigid3d( + Eigen::Vector3d(-1., 0., 0.), + Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(0., 1., 0.)))); } TEST_F(RealTimeCorrelativeScanMatcherTest, RotationAroundYZ) { - TestFromInitialPose( - transform::Rigid3d::Translation(Eigen::Vector3d(-0.5, 0.5, 0.5)) * - transform::Rigid3d::Rotation( - Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(0., 1., 1.)))); + TestFromInitialPose(transform::Rigid3d( + Eigen::Vector3d(-1., 0., 0.), + Eigen::AngleAxisd(0.8 / 180. * M_PI, Eigen::Vector3d(0., 1., 1.)))); } } // namespace diff --git a/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.cc b/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.cc index 2491082..ef2b4c4 100644 --- a/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.cc +++ b/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.cc @@ -61,9 +61,8 @@ void ConstraintBuilder::MaybeAddConstraint( const mapping::NodeId& node_id, const sensor::CompressedPointCloud* const compressed_point_cloud, const std::vector& submap_nodes, - const transform::Rigid3d& initial_relative_pose) { - if (initial_relative_pose.translation().norm() > - options_.max_constraint_distance()) { + const transform::Rigid3d& initial_pose) { + if (initial_pose.translation().norm() > options_.max_constraint_distance()) { return; } if (sampler_.Pulse()) { @@ -75,10 +74,10 @@ void ConstraintBuilder::MaybeAddConstraint( ScheduleSubmapScanMatcherConstructionAndQueueWorkItem( submap_id, submap_nodes, &submap->high_resolution_hybrid_grid, [=]() EXCLUDES(mutex_) { - ComputeConstraint( - submap_id, submap, node_id, false, /* match_full_submap */ - nullptr, /* trajectory_connectivity */ - compressed_point_cloud, initial_relative_pose, constraint); + ComputeConstraint(submap_id, submap, node_id, + false, /* match_full_submap */ + nullptr, /* trajectory_connectivity */ + compressed_point_cloud, initial_pose, constraint); FinishComputation(current_computation); }); } @@ -171,23 +170,19 @@ void ConstraintBuilder::ComputeConstraint( const mapping::NodeId& node_id, bool match_full_submap, mapping::TrajectoryConnectivity* trajectory_connectivity, const sensor::CompressedPointCloud* const compressed_point_cloud, - const transform::Rigid3d& initial_relative_pose, + const transform::Rigid3d& initial_pose, std::unique_ptr* constraint) { - const transform::Rigid3d initial_pose = - submap->local_pose() * initial_relative_pose; const SubmapScanMatcher* const submap_scan_matcher = GetSubmapScanMatcher(submap_id); const sensor::PointCloud point_cloud = compressed_point_cloud->Decompress(); const sensor::PointCloud filtered_point_cloud = adaptive_voxel_filter_.Filter(point_cloud); - // The 'constraint_transform' (i <- j) is computed from: - // - a 'filtered_point_cloud' in j, - // - the initial guess 'initial_pose' for (map <- j), - // - the result 'pose_estimate' of Match() (map <- j). - // - the submap->pose() (map <- i) + // The 'constraint_transform' (submap 'i' <- scan 'j') is computed from the + // initial guess 'initial_pose' for (submap 'i' <- scan 'j') and a + // 'filtered_point_cloud' in 'j'. float score = 0.; - transform::Rigid3d pose_estimate = transform::Rigid3d::Identity(); + transform::Rigid3d pose_estimate; if (match_full_submap) { if (submap_scan_matcher->fast_correlative_scan_matcher->MatchFullSubmap( @@ -220,13 +215,12 @@ void ConstraintBuilder::ComputeConstraint( // effect that, in the absence of better information, we prefer the original // CSM estimate. ceres::Solver::Summary unused_summary; + transform::Rigid3d constraint_transform; ceres_scan_matcher_.Match( pose_estimate, pose_estimate, {{&filtered_point_cloud, submap_scan_matcher->hybrid_grid}}, - &pose_estimate, &unused_summary); + &constraint_transform, &unused_summary); - const transform::Rigid3d constraint_transform = - submap->local_pose().inverse() * pose_estimate; constraint->reset(new OptimizationProblem::Constraint{ submap_id, node_id, @@ -243,7 +237,7 @@ void ConstraintBuilder::ComputeConstraint( info << " matches"; } else { const transform::Rigid3d difference = - initial_pose.inverse() * pose_estimate; + initial_pose.inverse() * constraint_transform; info << " differs by translation " << std::setprecision(2) << difference.translation().norm() << " rotation " << std::setprecision(3) << transform::GetAngle(difference); diff --git a/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.h b/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.h index c853a75..9778b48 100644 --- a/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.h +++ b/cartographer/mapping_3d/sparse_pose_graph/constraint_builder.h @@ -68,8 +68,8 @@ class ConstraintBuilder { ConstraintBuilder& operator=(const ConstraintBuilder&) = delete; // Schedules exploring a new constraint between 'submap' identified by - // 'submap_id', and the 'point_cloud' for 'node_id'. - // The 'initial_relative_pose' is relative to the 'submap'. + // 'submap_id', and the 'point_cloud' for 'node_id'. The 'intial_pose' is + // relative to the 'submap'. // // The pointees of 'submap' and 'compressed_point_cloud' must stay valid until // all computations are finished. @@ -78,7 +78,7 @@ class ConstraintBuilder { const mapping::NodeId& node_id, const sensor::CompressedPointCloud* compressed_point_cloud, const std::vector& submap_nodes, - const transform::Rigid3d& initial_relative_pose); + const transform::Rigid3d& initial_pose); // Schedules exploring a new constraint between 'submap' identified by // 'submap_id' and the 'compressed_point_cloud' for 'node_id'. @@ -141,7 +141,7 @@ class ConstraintBuilder { const mapping::NodeId& node_id, bool match_full_submap, mapping::TrajectoryConnectivity* trajectory_connectivity, const sensor::CompressedPointCloud* compressed_point_cloud, - const transform::Rigid3d& initial_relative_pose, + const transform::Rigid3d& initial_pose, std::unique_ptr* constraint) EXCLUDES(mutex_); // Decrements the 'pending_computations_' count. If all computations are done, diff --git a/cartographer/mapping_3d/submaps.cc b/cartographer/mapping_3d/submaps.cc index 4a78563..f919315 100644 --- a/cartographer/mapping_3d/submaps.cc +++ b/cartographer/mapping_3d/submaps.cc @@ -219,8 +219,8 @@ proto::SubmapsOptions CreateSubmapsOptions( Submap::Submap(const float high_resolution, const float low_resolution, const Eigen::Vector3f& origin) : mapping::Submap(origin), - high_resolution_hybrid_grid(high_resolution, origin), - low_resolution_hybrid_grid(low_resolution, origin) {} + high_resolution_hybrid_grid(high_resolution), + low_resolution_hybrid_grid(low_resolution) {} Submaps::Submaps(const proto::SubmapsOptions& options) : options_(options), @@ -250,9 +250,7 @@ void Submaps::SubmapToProto( Eigen::Array2i min_index(INT_MAX, INT_MAX); Eigen::Array2i max_index(INT_MIN, INT_MIN); const std::vector voxel_indices_and_probabilities = - ExtractVoxelData(hybrid_grid, - (global_submap_pose * Get(index)->local_pose().inverse()) - .cast(), + ExtractVoxelData(hybrid_grid, global_submap_pose.cast(), &min_index, &max_index); const int width = max_index.y() - min_index.y() + 1; @@ -276,11 +274,13 @@ void Submaps::SubmapToProto( 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()); range_data_inserter_.Insert( - FilterRangeDataByMaxRange(range_data, + FilterRangeDataByMaxRange(transformed_range_data, options_.high_resolution_max_range()), &submap->high_resolution_hybrid_grid); - range_data_inserter_.Insert(range_data, + range_data_inserter_.Insert(transformed_range_data, &submap->low_resolution_hybrid_grid); ++submap->num_range_data; } @@ -290,14 +290,6 @@ void Submaps::InsertRangeData(const sensor::RangeData& range_data) { } } -const HybridGrid& Submaps::high_resolution_matching_grid() const { - return submaps_[matching_index()]->high_resolution_hybrid_grid; -} - -const HybridGrid& Submaps::low_resolution_matching_grid() const { - return submaps_[matching_index()]->low_resolution_hybrid_grid; -} - void Submaps::AddSubmap(const Eigen::Vector3f& origin) { if (size() > 1) { Submap* submap = submaps_[size() - 2].get(); @@ -350,9 +342,9 @@ std::vector Submaps::ExtractVoxelData( continue; } - const Eigen::Vector3f cell_center_local = + const Eigen::Vector3f cell_center_submap = hybrid_grid.GetCenterOfCell(it.GetCellIndex()); - const Eigen::Vector3f cell_center_global = transform * cell_center_local; + const Eigen::Vector3f cell_center_global = transform * cell_center_submap; const Eigen::Array4i voxel_index_and_probability( common::RoundToInt(cell_center_global.x() * resolution_inverse), common::RoundToInt(cell_center_global.y() * resolution_inverse), diff --git a/cartographer/mapping_3d/submaps.h b/cartographer/mapping_3d/submaps.h index a9fb028..08caa5f 100644 --- a/cartographer/mapping_3d/submaps.h +++ b/cartographer/mapping_3d/submaps.h @@ -72,12 +72,6 @@ class Submaps : public mapping::Submaps { // Inserts 'range_data' into the Submap collection. void InsertRangeData(const sensor::RangeData& range_data); - // Returns the 'high_resolution' HybridGrid to be used for matching. - const HybridGrid& high_resolution_matching_grid() const; - - // Returns the 'low_resolution' HybridGrid to be used for matching. - const HybridGrid& low_resolution_matching_grid() const; - private: struct PixelData { int min_z = INT_MAX; diff --git a/cartographer/sensor/compressed_point_cloud.cc b/cartographer/sensor/compressed_point_cloud.cc index 01b24fa..933bc77 100644 --- a/cartographer/sensor/compressed_point_cloud.cc +++ b/cartographer/sensor/compressed_point_cloud.cc @@ -104,7 +104,7 @@ CompressedPointCloud::CompressedPointCloud(const PointCloud& point_cloud) int index; }; using Blocks = mapping_3d::HybridGridBase>; - Blocks blocks(kPrecision, Eigen::Vector3f::Zero()); + Blocks blocks(kPrecision); int num_blocks = 0; CHECK_LE(point_cloud.size(), std::numeric_limits::max()); for (int point_index = 0; point_index < static_cast(point_cloud.size()); diff --git a/cartographer/sensor/voxel_filter.cc b/cartographer/sensor/voxel_filter.cc index bdbd3f7..9bb6d47 100644 --- a/cartographer/sensor/voxel_filter.cc +++ b/cartographer/sensor/voxel_filter.cc @@ -83,8 +83,7 @@ PointCloud VoxelFiltered(const PointCloud& point_cloud, const float size) { return voxel_filter.point_cloud(); } -VoxelFilter::VoxelFilter(const float size) - : voxels_(size, Eigen::Vector3f::Zero()) {} +VoxelFilter::VoxelFilter(const float size) : voxels_(size) {} void VoxelFilter::InsertPointCloud(const PointCloud& point_cloud) { for (const Eigen::Vector3f& point : point_cloud) {