Rename CompressedLaserFan to CompressedRangeData. (#223)
CompressedLaserFan is misleading since data can come from a different type of sensor, e.g. a depth camera.master
parent
c78f29fdac
commit
a2abe45542
|
@ -38,8 +38,8 @@ struct TrajectoryNode {
|
||||||
// LaserFan in 'pose' frame. Only used in the 2D case.
|
// LaserFan in 'pose' frame. Only used in the 2D case.
|
||||||
sensor::LaserFan laser_fan_2d;
|
sensor::LaserFan laser_fan_2d;
|
||||||
|
|
||||||
// LaserFan in 'pose' frame. Only used in the 3D case.
|
// Range data in 'pose' frame. Only used in the 3D case.
|
||||||
sensor::CompressedLaserFan laser_fan_3d;
|
sensor::CompressedRangeData range_data_3d;
|
||||||
|
|
||||||
// Trajectory this node belongs to.
|
// Trajectory this node belongs to.
|
||||||
// TODO(macmason): The naming here is confusing because 'trajectory'
|
// TODO(macmason): The naming here is confusing because 'trajectory'
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include "Eigen/Core"
|
#include "Eigen/Core"
|
||||||
#include "Eigen/Geometry"
|
#include "Eigen/Geometry"
|
||||||
#include "cartographer/common/math.h"
|
#include "cartographer/common/math.h"
|
||||||
|
#include "cartographer/mapping/trajectory_node.h"
|
||||||
#include "cartographer/mapping_2d/proto/map_limits.pb.h"
|
#include "cartographer/mapping_2d/proto/map_limits.pb.h"
|
||||||
#include "cartographer/mapping_2d/xy_index.h"
|
#include "cartographer/mapping_2d/xy_index.h"
|
||||||
#include "cartographer/mapping/trajectory_node.h"
|
|
||||||
#include "cartographer/sensor/laser.h"
|
#include "cartographer/sensor/laser.h"
|
||||||
#include "cartographer/sensor/point_cloud.h"
|
#include "cartographer/sensor/point_cloud.h"
|
||||||
#include "cartographer/transform/rigid_transform.h"
|
#include "cartographer/transform/rigid_transform.h"
|
||||||
|
@ -79,8 +79,9 @@ class MapLimits {
|
||||||
// Returns true of the ProbabilityGrid contains 'xy_index'.
|
// Returns true of the ProbabilityGrid contains 'xy_index'.
|
||||||
bool Contains(const Eigen::Array2i& xy_index) const {
|
bool Contains(const Eigen::Array2i& xy_index) const {
|
||||||
return (Eigen::Array2i(0, 0) <= xy_index).all() &&
|
return (Eigen::Array2i(0, 0) <= xy_index).all() &&
|
||||||
(xy_index < Eigen::Array2i(cell_limits_.num_x_cells,
|
(xy_index <
|
||||||
cell_limits_.num_y_cells)).all();
|
Eigen::Array2i(cell_limits_.num_x_cells, cell_limits_.num_y_cells))
|
||||||
|
.all();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes MapLimits that contain the origin, and all laser rays (both
|
// Computes MapLimits that contain the origin, and all laser rays (both
|
||||||
|
@ -106,9 +107,9 @@ class MapLimits {
|
||||||
Eigen::AlignedBox2f bounding_box(Eigen::Vector2f::Zero());
|
Eigen::AlignedBox2f bounding_box(Eigen::Vector2f::Zero());
|
||||||
for (const auto& node : trajectory_nodes) {
|
for (const auto& node : trajectory_nodes) {
|
||||||
const auto& data = *node.constant_data;
|
const auto& data = *node.constant_data;
|
||||||
if (!data.laser_fan_3d.returns.empty()) {
|
if (!data.range_data_3d.returns.empty()) {
|
||||||
const sensor::LaserFan laser_fan = sensor::TransformLaserFan(
|
const sensor::LaserFan laser_fan = sensor::TransformLaserFan(
|
||||||
Decompress(data.laser_fan_3d), node.pose.cast<float>());
|
Decompress(data.range_data_3d), node.pose.cast<float>());
|
||||||
bounding_box.extend(laser_fan.origin.head<2>());
|
bounding_box.extend(laser_fan.origin.head<2>());
|
||||||
for (const Eigen::Vector3f& hit : laser_fan.returns) {
|
for (const Eigen::Vector3f& hit : laser_fan.returns) {
|
||||||
bounding_box.extend(hit.head<2>());
|
bounding_box.extend(hit.head<2>());
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
|
|
||||||
#include "cartographer/common/math.h"
|
#include "cartographer/common/math.h"
|
||||||
#include "cartographer/common/port.h"
|
#include "cartographer/common/port.h"
|
||||||
|
#include "cartographer/mapping/probability_values.h"
|
||||||
#include "cartographer/mapping_2d/map_limits.h"
|
#include "cartographer/mapping_2d/map_limits.h"
|
||||||
#include "cartographer/mapping_2d/proto/probability_grid.pb.h"
|
#include "cartographer/mapping_2d/proto/probability_grid.pb.h"
|
||||||
#include "cartographer/mapping_2d/xy_index.h"
|
#include "cartographer/mapping_2d/xy_index.h"
|
||||||
#include "cartographer/mapping/probability_values.h"
|
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
|
@ -123,9 +123,8 @@ class ProbabilityGrid {
|
||||||
|
|
||||||
// Returns true if the probability at the specified index is known.
|
// Returns true if the probability at the specified index is known.
|
||||||
bool IsKnown(const Eigen::Array2i& xy_index) const {
|
bool IsKnown(const Eigen::Array2i& xy_index) const {
|
||||||
return limits_.Contains(xy_index) &&
|
return limits_.Contains(xy_index) && cells_[GetIndexOfCell(xy_index)] !=
|
||||||
cells_[GetIndexOfCell(xy_index)] !=
|
mapping::kUnknownProbabilityValue;
|
||||||
mapping::kUnknownProbabilityValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills in 'offset' and 'limits' to define a subregion of that contains all
|
// Fills in 'offset' and 'limits' to define a subregion of that contains all
|
||||||
|
|
|
@ -146,26 +146,35 @@ TEST(ProbabilityGridTest, GetXYIndexOfCellContainingPoint) {
|
||||||
const CellLimits& cell_limits = limits.cell_limits();
|
const CellLimits& cell_limits = limits.cell_limits();
|
||||||
ASSERT_EQ(14, cell_limits.num_x_cells);
|
ASSERT_EQ(14, cell_limits.num_x_cells);
|
||||||
ASSERT_EQ(8, cell_limits.num_y_cells);
|
ASSERT_EQ(8, cell_limits.num_y_cells);
|
||||||
EXPECT_TRUE((Eigen::Array2i(0, 0) ==
|
EXPECT_TRUE(
|
||||||
limits.GetXYIndexOfCellContainingPoint(7, 13)).all());
|
(Eigen::Array2i(0, 0) == limits.GetXYIndexOfCellContainingPoint(7, 13))
|
||||||
EXPECT_TRUE((Eigen::Array2i(13, 0) ==
|
.all());
|
||||||
limits.GetXYIndexOfCellContainingPoint(7, -13)).all());
|
EXPECT_TRUE(
|
||||||
EXPECT_TRUE((Eigen::Array2i(0, 7) ==
|
(Eigen::Array2i(13, 0) == limits.GetXYIndexOfCellContainingPoint(7, -13))
|
||||||
limits.GetXYIndexOfCellContainingPoint(-7, 13)).all());
|
.all());
|
||||||
EXPECT_TRUE((Eigen::Array2i(13, 7) ==
|
EXPECT_TRUE(
|
||||||
limits.GetXYIndexOfCellContainingPoint(-7, -13)).all());
|
(Eigen::Array2i(0, 7) == limits.GetXYIndexOfCellContainingPoint(-7, 13))
|
||||||
|
.all());
|
||||||
|
EXPECT_TRUE(
|
||||||
|
(Eigen::Array2i(13, 7) == limits.GetXYIndexOfCellContainingPoint(-7, -13))
|
||||||
|
.all());
|
||||||
|
|
||||||
// Check around the origin.
|
// Check around the origin.
|
||||||
EXPECT_TRUE((Eigen::Array2i(6, 3) ==
|
EXPECT_TRUE(
|
||||||
limits.GetXYIndexOfCellContainingPoint(0.5, 0.5)).all());
|
(Eigen::Array2i(6, 3) == limits.GetXYIndexOfCellContainingPoint(0.5, 0.5))
|
||||||
EXPECT_TRUE((Eigen::Array2i(6, 3) ==
|
.all());
|
||||||
limits.GetXYIndexOfCellContainingPoint(1.5, 1.5)).all());
|
EXPECT_TRUE(
|
||||||
|
(Eigen::Array2i(6, 3) == limits.GetXYIndexOfCellContainingPoint(1.5, 1.5))
|
||||||
|
.all());
|
||||||
EXPECT_TRUE((Eigen::Array2i(7, 3) ==
|
EXPECT_TRUE((Eigen::Array2i(7, 3) ==
|
||||||
limits.GetXYIndexOfCellContainingPoint(0.5, -0.5)).all());
|
limits.GetXYIndexOfCellContainingPoint(0.5, -0.5))
|
||||||
|
.all());
|
||||||
EXPECT_TRUE((Eigen::Array2i(6, 4) ==
|
EXPECT_TRUE((Eigen::Array2i(6, 4) ==
|
||||||
limits.GetXYIndexOfCellContainingPoint(-0.5, 0.5)).all());
|
limits.GetXYIndexOfCellContainingPoint(-0.5, 0.5))
|
||||||
|
.all());
|
||||||
EXPECT_TRUE((Eigen::Array2i(7, 4) ==
|
EXPECT_TRUE((Eigen::Array2i(7, 4) ==
|
||||||
limits.GetXYIndexOfCellContainingPoint(-0.5, -0.5)).all());
|
limits.GetXYIndexOfCellContainingPoint(-0.5, -0.5))
|
||||||
|
.all());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ProbabilityGridTest, CorrectCropping) {
|
TEST(ProbabilityGridTest, CorrectCropping) {
|
||||||
|
|
|
@ -311,12 +311,13 @@ void SparsePoseGraph::WaitForAllComputations() {
|
||||||
std::cout << "\r\x1b[K" << progress_info.str() << std::flush;
|
std::cout << "\r\x1b[K" << progress_info.str() << std::flush;
|
||||||
}
|
}
|
||||||
std::cout << "\r\x1b[KOptimizing: Done. " << std::endl;
|
std::cout << "\r\x1b[KOptimizing: Done. " << std::endl;
|
||||||
constraint_builder_.WhenDone([this, ¬ification](
|
constraint_builder_.WhenDone(
|
||||||
const sparse_pose_graph::ConstraintBuilder::Result& result) {
|
[this, ¬ification](
|
||||||
constraints_.insert(constraints_.end(), result.begin(), result.end());
|
const sparse_pose_graph::ConstraintBuilder::Result& result) {
|
||||||
common::MutexLocker locker(&mutex_);
|
constraints_.insert(constraints_.end(), result.begin(), result.end());
|
||||||
notification = true;
|
common::MutexLocker locker(&mutex_);
|
||||||
});
|
notification = true;
|
||||||
|
});
|
||||||
locker.Await([¬ification]() { return notification; });
|
locker.Await([¬ification]() { return notification; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#include "cartographer/common/make_unique.h"
|
#include "cartographer/common/make_unique.h"
|
||||||
#include "cartographer/common/math.h"
|
#include "cartographer/common/math.h"
|
||||||
#include "cartographer/common/port.h"
|
#include "cartographer/common/port.h"
|
||||||
#include "cartographer/mapping_3d/proto/hybrid_grid.pb.h"
|
|
||||||
#include "cartographer/mapping/probability_values.h"
|
#include "cartographer/mapping/probability_values.h"
|
||||||
|
#include "cartographer/mapping_3d/proto/hybrid_grid.pb.h"
|
||||||
#include "cartographer/transform/transform.h"
|
#include "cartographer/transform/transform.h"
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ RotationalScanMatcher::RotationalScanMatcher(
|
||||||
for (const mapping::TrajectoryNode& node : nodes) {
|
for (const mapping::TrajectoryNode& node : nodes) {
|
||||||
AddValuesToHistogram(
|
AddValuesToHistogram(
|
||||||
GetValuesForHistogram(sensor::TransformPointCloud(
|
GetValuesForHistogram(sensor::TransformPointCloud(
|
||||||
node.constant_data->laser_fan_3d.returns.Decompress(),
|
node.constant_data->range_data_3d.returns.Decompress(),
|
||||||
node.pose.cast<float>())),
|
node.pose.cast<float>())),
|
||||||
0.f, &histogram_);
|
0.f, &histogram_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,12 +302,13 @@ void SparsePoseGraph::WaitForAllComputations() {
|
||||||
std::cout << "\r\x1b[K" << progress_info.str() << std::flush;
|
std::cout << "\r\x1b[K" << progress_info.str() << std::flush;
|
||||||
}
|
}
|
||||||
std::cout << "\r\x1b[KOptimizing: Done. " << std::endl;
|
std::cout << "\r\x1b[KOptimizing: Done. " << std::endl;
|
||||||
constraint_builder_.WhenDone([this, ¬ification](
|
constraint_builder_.WhenDone(
|
||||||
const sparse_pose_graph::ConstraintBuilder::Result& result) {
|
[this, ¬ification](
|
||||||
constraints_.insert(constraints_.end(), result.begin(), result.end());
|
const sparse_pose_graph::ConstraintBuilder::Result& result) {
|
||||||
common::MutexLocker locker(&mutex_);
|
constraints_.insert(constraints_.end(), result.begin(), result.end());
|
||||||
notification = true;
|
common::MutexLocker locker(&mutex_);
|
||||||
});
|
notification = true;
|
||||||
|
});
|
||||||
locker.Await([¬ification]() { return notification; });
|
locker.Await([¬ification]() { return notification; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ void ConstraintBuilder::MaybeAddConstraint(
|
||||||
++pending_computations_[current_computation_];
|
++pending_computations_[current_computation_];
|
||||||
const int current_computation = current_computation_;
|
const int current_computation = current_computation_;
|
||||||
const auto* const point_cloud =
|
const auto* const point_cloud =
|
||||||
&trajectory_nodes[scan_index].constant_data->laser_fan_3d.returns;
|
&trajectory_nodes[scan_index].constant_data->range_data_3d.returns;
|
||||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||||
submap_index, submap_nodes, &submap->high_resolution_hybrid_grid,
|
submap_index, submap_nodes, &submap->high_resolution_hybrid_grid,
|
||||||
[=]() EXCLUDES(mutex_) {
|
[=]() EXCLUDES(mutex_) {
|
||||||
|
@ -124,7 +124,7 @@ void ConstraintBuilder::MaybeAddGlobalConstraint(
|
||||||
++pending_computations_[current_computation_];
|
++pending_computations_[current_computation_];
|
||||||
const int current_computation = current_computation_;
|
const int current_computation = current_computation_;
|
||||||
const auto* const point_cloud =
|
const auto* const point_cloud =
|
||||||
&trajectory_nodes[scan_index].constant_data->laser_fan_3d.returns;
|
&trajectory_nodes[scan_index].constant_data->range_data_3d.returns;
|
||||||
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
ScheduleSubmapScanMatcherConstructionAndQueueWorkItem(
|
||||||
submap_index, submap_nodes, &submap->high_resolution_hybrid_grid,
|
submap_index, submap_nodes, &submap->high_resolution_hybrid_grid,
|
||||||
[=]() EXCLUDES(mutex_) {
|
[=]() EXCLUDES(mutex_) {
|
||||||
|
|
|
@ -68,10 +68,10 @@ class ConstraintBuilder {
|
||||||
ConstraintBuilder& operator=(const ConstraintBuilder&) = delete;
|
ConstraintBuilder& operator=(const ConstraintBuilder&) = delete;
|
||||||
|
|
||||||
// Schedules exploring a new constraint between 'submap' identified by
|
// Schedules exploring a new constraint between 'submap' identified by
|
||||||
// 'submap_index', and the 'laser_fan_3d.returns' in 'trajectory_nodes' for
|
// 'submap_index', and the 'range_data_3d.returns' in 'trajectory_nodes' for
|
||||||
// 'scan_index'. The 'initial_relative_pose' is relative to the 'submap'.
|
// 'scan_index'. The 'initial_relative_pose' is relative to the 'submap'.
|
||||||
//
|
//
|
||||||
// The pointees of 'submap' and 'laser_fan_3d.returns' must stay valid until
|
// The pointees of 'submap' and 'range_data_3d.returns' must stay valid until
|
||||||
// all computations are finished.
|
// all computations are finished.
|
||||||
void MaybeAddConstraint(
|
void MaybeAddConstraint(
|
||||||
int submap_index, const Submap* submap, int scan_index,
|
int submap_index, const Submap* submap, int scan_index,
|
||||||
|
@ -79,15 +79,15 @@ class ConstraintBuilder {
|
||||||
const transform::Rigid3d& initial_relative_pose);
|
const transform::Rigid3d& initial_relative_pose);
|
||||||
|
|
||||||
// Schedules exploring a new constraint between 'submap' identified by
|
// Schedules exploring a new constraint between 'submap' identified by
|
||||||
// 'submap_index' and the 'laser_fan_3d.returns' in 'trajectory_nodes' for
|
// 'submap_index' and the 'range_data_3d.returns' in 'trajectory_nodes' for
|
||||||
// 'scan_index'. This performs full-submap matching.
|
// 'scan_index'. This performs full-submap matching.
|
||||||
//
|
//
|
||||||
// The scan at 'scan_index' should be from trajectory 'scan_trajectory', and
|
// The scan at 'scan_index' should be from trajectory 'scan_trajectory', and
|
||||||
// the 'submap' should be from 'submap_trajectory'. The
|
// the 'submap' should be from 'submap_trajectory'. The
|
||||||
// 'trajectory_connectivity' is updated if the full-submap match succeeds.
|
// 'trajectory_connectivity' is updated if the full-submap match succeeds.
|
||||||
//
|
//
|
||||||
// The pointees of 'submap' and 'point_cloud' must stay valid until all
|
// The pointees of 'submap' and 'range_data_3d.returns' must stay valid until
|
||||||
// computations are finished.
|
// all computations are finished.
|
||||||
void MaybeAddGlobalConstraint(
|
void MaybeAddGlobalConstraint(
|
||||||
int submap_index, const Submap* submap, int scan_index,
|
int submap_index, const Submap* submap, int scan_index,
|
||||||
const mapping::Submaps* scan_trajectory,
|
const mapping::Submaps* scan_trajectory,
|
||||||
|
|
|
@ -108,22 +108,22 @@ LaserFan CropLaserFan(const LaserFan& laser_fan, const float min_z,
|
||||||
Crop(laser_fan.misses, min_z, max_z)};
|
Crop(laser_fan.misses, min_z, max_z)};
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedLaserFan Compress(const LaserFan& laser_fan) {
|
CompressedRangeData Compress(const LaserFan& laser_fan) {
|
||||||
std::vector<int> new_to_old;
|
std::vector<int> new_to_old;
|
||||||
CompressedPointCloud compressed_returns =
|
CompressedPointCloud compressed_returns =
|
||||||
CompressedPointCloud::CompressAndReturnOrder(laser_fan.returns,
|
CompressedPointCloud::CompressAndReturnOrder(laser_fan.returns,
|
||||||
&new_to_old);
|
&new_to_old);
|
||||||
return CompressedLaserFan{
|
return CompressedRangeData{
|
||||||
laser_fan.origin, std::move(compressed_returns),
|
laser_fan.origin, std::move(compressed_returns),
|
||||||
CompressedPointCloud(laser_fan.misses),
|
CompressedPointCloud(laser_fan.misses),
|
||||||
ReorderReflectivities(laser_fan.reflectivities, new_to_old)};
|
ReorderReflectivities(laser_fan.reflectivities, new_to_old)};
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserFan Decompress(const CompressedLaserFan& compressed_laser_fan) {
|
LaserFan Decompress(const CompressedRangeData& compressed_range_data) {
|
||||||
return LaserFan{compressed_laser_fan.origin,
|
return LaserFan{compressed_range_data.origin,
|
||||||
compressed_laser_fan.returns.Decompress(),
|
compressed_range_data.returns.Decompress(),
|
||||||
compressed_laser_fan.misses.Decompress(),
|
compressed_range_data.misses.Decompress(),
|
||||||
compressed_laser_fan.reflectivities};
|
compressed_range_data.reflectivities};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sensor
|
} // namespace sensor
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace sensor {
|
namespace sensor {
|
||||||
|
|
||||||
// A 3D variant of LaserFan. Rays begin at 'origin'. 'returns' are the points
|
// Rays begin at 'origin'. 'returns' are the points where laser returns were
|
||||||
// where laser returns were detected. 'misses' are points in the direction of
|
// detected. 'misses' are points in the direction of rays for which no return
|
||||||
// rays for which no return was detected, and were inserted at a configured
|
// was detected, and were inserted at a configured distance. It is assumed that
|
||||||
// distance. It is assumed that between the 'origin' and 'misses' is free space.
|
// between the 'origin' and 'misses' is free space.
|
||||||
struct LaserFan {
|
struct LaserFan {
|
||||||
Eigen::Vector3f origin;
|
Eigen::Vector3f origin;
|
||||||
PointCloud returns;
|
PointCloud returns;
|
||||||
|
@ -63,7 +63,7 @@ LaserFan CropLaserFan(const LaserFan& laser_fan, float min_z, float max_z);
|
||||||
|
|
||||||
// Like LaserFan but with compressed point clouds. The point order changes
|
// Like LaserFan but with compressed point clouds. The point order changes
|
||||||
// when converting from LaserFan.
|
// when converting from LaserFan.
|
||||||
struct CompressedLaserFan {
|
struct CompressedRangeData {
|
||||||
Eigen::Vector3f origin;
|
Eigen::Vector3f origin;
|
||||||
CompressedPointCloud returns;
|
CompressedPointCloud returns;
|
||||||
CompressedPointCloud misses;
|
CompressedPointCloud misses;
|
||||||
|
@ -72,9 +72,9 @@ struct CompressedLaserFan {
|
||||||
std::vector<uint8> reflectivities;
|
std::vector<uint8> reflectivities;
|
||||||
};
|
};
|
||||||
|
|
||||||
CompressedLaserFan Compress(const LaserFan& laser_fan);
|
CompressedRangeData Compress(const LaserFan& laser_fan);
|
||||||
|
|
||||||
LaserFan Decompress(const CompressedLaserFan& compressed_laser_fan);
|
LaserFan Decompress(const CompressedRangeData& compressed_range_Data);
|
||||||
|
|
||||||
} // namespace sensor
|
} // namespace sensor
|
||||||
} // namespace cartographer
|
} // namespace cartographer
|
||||||
|
|
Loading…
Reference in New Issue