Sparse pose graph no longer uses Submaps* for trajectory identification. (#290)
Related to #256. PAIR=wohemaster
parent
8612f5e6e5
commit
5aa968748e
|
@ -78,7 +78,7 @@ int MapBuilder::AddTrajectoryBuilder(
|
||||||
&sensor_collator_, trajectory_id, expected_sensor_ids,
|
&sensor_collator_, trajectory_id, expected_sensor_ids,
|
||||||
common::make_unique<mapping_3d::GlobalTrajectoryBuilder>(
|
common::make_unique<mapping_3d::GlobalTrajectoryBuilder>(
|
||||||
trajectory_options.trajectory_builder_3d_options(),
|
trajectory_options.trajectory_builder_3d_options(),
|
||||||
sparse_pose_graph_3d_.get())));
|
trajectory_id, sparse_pose_graph_3d_.get())));
|
||||||
} else {
|
} else {
|
||||||
CHECK(trajectory_options.has_trajectory_builder_2d_options());
|
CHECK(trajectory_options.has_trajectory_builder_2d_options());
|
||||||
trajectory_builders_.push_back(
|
trajectory_builders_.push_back(
|
||||||
|
@ -86,10 +86,8 @@ int MapBuilder::AddTrajectoryBuilder(
|
||||||
&sensor_collator_, trajectory_id, expected_sensor_ids,
|
&sensor_collator_, trajectory_id, expected_sensor_ids,
|
||||||
common::make_unique<mapping_2d::GlobalTrajectoryBuilder>(
|
common::make_unique<mapping_2d::GlobalTrajectoryBuilder>(
|
||||||
trajectory_options.trajectory_builder_2d_options(),
|
trajectory_options.trajectory_builder_2d_options(),
|
||||||
sparse_pose_graph_2d_.get())));
|
trajectory_id, sparse_pose_graph_2d_.get())));
|
||||||
}
|
}
|
||||||
trajectory_ids_.emplace(trajectory_builders_.back()->submaps(),
|
|
||||||
trajectory_id);
|
|
||||||
return trajectory_id;
|
return trajectory_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +104,6 @@ int MapBuilder::GetBlockingTrajectoryId() const {
|
||||||
return sensor_collator_.GetBlockingTrajectoryId();
|
return sensor_collator_.GetBlockingTrajectoryId();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MapBuilder::GetTrajectoryId(const Submaps* const trajectory) const {
|
|
||||||
const auto trajectory_id = trajectory_ids_.find(trajectory);
|
|
||||||
CHECK(trajectory_id != trajectory_ids_.end());
|
|
||||||
return trajectory_id->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
proto::TrajectoryConnectivity MapBuilder::GetTrajectoryConnectivity() {
|
proto::TrajectoryConnectivity MapBuilder::GetTrajectoryConnectivity() {
|
||||||
return ToProto(sparse_pose_graph_->GetConnectedTrajectories());
|
return ToProto(sparse_pose_graph_->GetConnectedTrajectories());
|
||||||
}
|
}
|
||||||
|
@ -125,10 +117,8 @@ string MapBuilder::SubmapToProto(const int trajectory_id,
|
||||||
" trajectories.";
|
" trajectories.";
|
||||||
}
|
}
|
||||||
|
|
||||||
const Submaps* const submaps =
|
|
||||||
trajectory_builders_.at(trajectory_id)->submaps();
|
|
||||||
const std::vector<transform::Rigid3d> submap_transforms =
|
const std::vector<transform::Rigid3d> submap_transforms =
|
||||||
sparse_pose_graph_->GetSubmapTransforms(submaps);
|
sparse_pose_graph_->GetSubmapTransforms(trajectory_id);
|
||||||
if (submap_index < 0 ||
|
if (submap_index < 0 ||
|
||||||
static_cast<size_t>(submap_index) >= submap_transforms.size()) {
|
static_cast<size_t>(submap_index) >= submap_transforms.size()) {
|
||||||
return "Requested submap " + std::to_string(submap_index) +
|
return "Requested submap " + std::to_string(submap_index) +
|
||||||
|
@ -137,6 +127,8 @@ string MapBuilder::SubmapToProto(const int trajectory_id,
|
||||||
" submaps in this trajectory.";
|
" submaps in this trajectory.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Submaps* const submaps =
|
||||||
|
trajectory_builders_.at(trajectory_id)->submaps();
|
||||||
response->set_submap_version(submaps->Get(submap_index)->num_range_data);
|
response->set_submap_version(submaps->Get(submap_index)->num_range_data);
|
||||||
submaps->SubmapToProto(submap_index, submap_transforms[submap_index],
|
submaps->SubmapToProto(submap_index, submap_transforms[submap_index],
|
||||||
response);
|
response);
|
||||||
|
|
|
@ -71,9 +71,6 @@ class MapBuilder {
|
||||||
// unblocked.
|
// unblocked.
|
||||||
int GetBlockingTrajectoryId() const;
|
int GetBlockingTrajectoryId() const;
|
||||||
|
|
||||||
// Returns the trajectory ID for 'trajectory'.
|
|
||||||
int GetTrajectoryId(const mapping::Submaps* trajectory) const;
|
|
||||||
|
|
||||||
// Returns the trajectory connectivity.
|
// Returns the trajectory connectivity.
|
||||||
proto::TrajectoryConnectivity GetTrajectoryConnectivity();
|
proto::TrajectoryConnectivity GetTrajectoryConnectivity();
|
||||||
|
|
||||||
|
@ -97,7 +94,6 @@ class MapBuilder {
|
||||||
|
|
||||||
sensor::Collator sensor_collator_;
|
sensor::Collator sensor_collator_;
|
||||||
std::vector<std::unique_ptr<mapping::TrajectoryBuilder>> trajectory_builders_;
|
std::vector<std::unique_ptr<mapping::TrajectoryBuilder>> trajectory_builders_;
|
||||||
std::unordered_map<const mapping::Submaps*, int> trajectory_ids_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mapping
|
} // namespace mapping
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "cartographer/mapping/id.h"
|
#include "cartographer/mapping/id.h"
|
||||||
#include "cartographer/mapping/proto/sparse_pose_graph.pb.h"
|
#include "cartographer/mapping/proto/sparse_pose_graph.pb.h"
|
||||||
#include "cartographer/mapping/proto/sparse_pose_graph_options.pb.h"
|
#include "cartographer/mapping/proto/sparse_pose_graph_options.pb.h"
|
||||||
#include "cartographer/mapping/submaps.h"
|
|
||||||
#include "cartographer/mapping/trajectory_node.h"
|
#include "cartographer/mapping/trajectory_node.h"
|
||||||
#include "cartographer/transform/rigid_transform.h"
|
#include "cartographer/transform/rigid_transform.h"
|
||||||
|
|
||||||
|
@ -71,11 +70,6 @@ class SparsePoseGraph {
|
||||||
// Get the current trajectory clusters.
|
// Get the current trajectory clusters.
|
||||||
virtual std::vector<std::vector<int>> GetConnectedTrajectories() = 0;
|
virtual std::vector<std::vector<int>> GetConnectedTrajectories() = 0;
|
||||||
|
|
||||||
// Returns the current optimized transforms for the given 'trajectory'.
|
|
||||||
// TODO(hrapp): Remove this version.
|
|
||||||
virtual std::vector<transform::Rigid3d> GetSubmapTransforms(
|
|
||||||
const Submaps* trajectory) = 0;
|
|
||||||
|
|
||||||
// Returns the current optimized transforms for the given 'trajectory_id'.
|
// Returns the current optimized transforms for the given 'trajectory_id'.
|
||||||
virtual std::vector<transform::Rigid3d> GetSubmapTransforms(
|
virtual std::vector<transform::Rigid3d> GetSubmapTransforms(
|
||||||
int trajectory_id) = 0;
|
int trajectory_id) = 0;
|
||||||
|
@ -83,8 +77,7 @@ class SparsePoseGraph {
|
||||||
// Returns the transform converting data in the local map frame (i.e. the
|
// Returns the transform converting data in the local map frame (i.e. the
|
||||||
// continuous, non-loop-closed frame) into the global map frame (i.e. the
|
// continuous, non-loop-closed frame) into the global map frame (i.e. the
|
||||||
// discontinuous, loop-closed frame).
|
// discontinuous, loop-closed frame).
|
||||||
virtual transform::Rigid3d GetLocalToGlobalTransform(
|
virtual transform::Rigid3d GetLocalToGlobalTransform(int trajectory_id) = 0;
|
||||||
const Submaps* submaps) = 0;
|
|
||||||
|
|
||||||
// Returns the current optimized trajectories.
|
// Returns the current optimized trajectories.
|
||||||
virtual std::vector<std::vector<TrajectoryNode>> GetTrajectoryNodes() = 0;
|
virtual std::vector<std::vector<TrajectoryNode>> GetTrajectoryNodes() = 0;
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace mapping_2d {
|
||||||
|
|
||||||
GlobalTrajectoryBuilder::GlobalTrajectoryBuilder(
|
GlobalTrajectoryBuilder::GlobalTrajectoryBuilder(
|
||||||
const proto::LocalTrajectoryBuilderOptions& options,
|
const proto::LocalTrajectoryBuilderOptions& options,
|
||||||
SparsePoseGraph* sparse_pose_graph)
|
const int trajectory_id, SparsePoseGraph* sparse_pose_graph)
|
||||||
: options_(options),
|
: trajectory_id_(trajectory_id),
|
||||||
sparse_pose_graph_(sparse_pose_graph),
|
sparse_pose_graph_(sparse_pose_graph),
|
||||||
local_trajectory_builder_(options) {}
|
local_trajectory_builder_(options) {}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ void GlobalTrajectoryBuilder::AddRangefinderData(
|
||||||
insertion_result->range_data_in_tracking_2d,
|
insertion_result->range_data_in_tracking_2d,
|
||||||
insertion_result->pose_estimate_2d,
|
insertion_result->pose_estimate_2d,
|
||||||
kalman_filter::Project2D(insertion_result->covariance_estimate),
|
kalman_filter::Project2D(insertion_result->covariance_estimate),
|
||||||
insertion_result->submaps, insertion_result->matching_submap,
|
trajectory_id_, insertion_result->matching_submap,
|
||||||
insertion_result->insertion_submaps);
|
insertion_result->insertion_submaps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ void GlobalTrajectoryBuilder::AddImuData(
|
||||||
const Eigen::Vector3d& angular_velocity) {
|
const Eigen::Vector3d& angular_velocity) {
|
||||||
local_trajectory_builder_.AddImuData(time, linear_acceleration,
|
local_trajectory_builder_.AddImuData(time, linear_acceleration,
|
||||||
angular_velocity);
|
angular_velocity);
|
||||||
sparse_pose_graph_->AddImuData(local_trajectory_builder_.submaps(), time,
|
sparse_pose_graph_->AddImuData(trajectory_id_, time, linear_acceleration,
|
||||||
linear_acceleration, angular_velocity);
|
angular_velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalTrajectoryBuilder::AddOdometerData(const common::Time time,
|
void GlobalTrajectoryBuilder::AddOdometerData(const common::Time time,
|
||||||
|
|
|
@ -28,6 +28,7 @@ class GlobalTrajectoryBuilder
|
||||||
: public mapping::GlobalTrajectoryBuilderInterface {
|
: public mapping::GlobalTrajectoryBuilderInterface {
|
||||||
public:
|
public:
|
||||||
GlobalTrajectoryBuilder(const proto::LocalTrajectoryBuilderOptions& options,
|
GlobalTrajectoryBuilder(const proto::LocalTrajectoryBuilderOptions& options,
|
||||||
|
int trajectory_id,
|
||||||
SparsePoseGraph* sparse_pose_graph);
|
SparsePoseGraph* sparse_pose_graph);
|
||||||
~GlobalTrajectoryBuilder() override;
|
~GlobalTrajectoryBuilder() override;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ class GlobalTrajectoryBuilder
|
||||||
const transform::Rigid3d& pose) override;
|
const transform::Rigid3d& pose) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const proto::LocalTrajectoryBuilderOptions options_;
|
const int trajectory_id_;
|
||||||
SparsePoseGraph* const sparse_pose_graph_;
|
SparsePoseGraph* const sparse_pose_graph_;
|
||||||
LocalTrajectoryBuilder local_trajectory_builder_;
|
LocalTrajectoryBuilder local_trajectory_builder_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -236,9 +236,8 @@ LocalTrajectoryBuilder::AddHorizontalRangeData(
|
||||||
transform::Embed3D(pose_estimate_2d.cast<float>())));
|
transform::Embed3D(pose_estimate_2d.cast<float>())));
|
||||||
|
|
||||||
return common::make_unique<InsertionResult>(InsertionResult{
|
return common::make_unique<InsertionResult>(InsertionResult{
|
||||||
time, &submaps_, matching_submap, insertion_submaps,
|
time, matching_submap, insertion_submaps, tracking_to_tracking_2d,
|
||||||
tracking_to_tracking_2d, tracking_2d_to_map, range_data_in_tracking_2d,
|
range_data_in_tracking_2d, pose_estimate_2d, covariance_observation});
|
||||||
pose_estimate_2d, covariance_observation});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapping::GlobalTrajectoryBuilderInterface::PoseEstimate&
|
const mapping::GlobalTrajectoryBuilderInterface::PoseEstimate&
|
||||||
|
|
|
@ -45,11 +45,9 @@ class LocalTrajectoryBuilder {
|
||||||
public:
|
public:
|
||||||
struct InsertionResult {
|
struct InsertionResult {
|
||||||
common::Time time;
|
common::Time time;
|
||||||
const mapping::Submaps* submaps;
|
|
||||||
const mapping::Submap* matching_submap;
|
const mapping::Submap* matching_submap;
|
||||||
std::vector<const mapping::Submap*> insertion_submaps;
|
std::vector<const mapping::Submap*> insertion_submaps;
|
||||||
transform::Rigid3d tracking_to_tracking_2d;
|
transform::Rigid3d tracking_to_tracking_2d;
|
||||||
transform::Rigid3d tracking_2d_to_map;
|
|
||||||
sensor::RangeData range_data_in_tracking_2d;
|
sensor::RangeData range_data_in_tracking_2d;
|
||||||
transform::Rigid2d pose_estimate_2d;
|
transform::Rigid2d pose_estimate_2d;
|
||||||
kalman_filter::PoseCovariance covariance_estimate;
|
kalman_filter::PoseCovariance covariance_estimate;
|
||||||
|
|
|
@ -90,16 +90,13 @@ void SparsePoseGraph::GrowSubmapTransformsAsNeeded(
|
||||||
void SparsePoseGraph::AddScan(
|
void SparsePoseGraph::AddScan(
|
||||||
common::Time time, const transform::Rigid3d& tracking_to_pose,
|
common::Time time, const transform::Rigid3d& tracking_to_pose,
|
||||||
const sensor::RangeData& range_data_in_pose, const transform::Rigid2d& pose,
|
const sensor::RangeData& range_data_in_pose, const transform::Rigid2d& pose,
|
||||||
const kalman_filter::Pose2DCovariance& covariance,
|
const kalman_filter::Pose2DCovariance& covariance, const int trajectory_id,
|
||||||
const mapping::Submaps* const trajectory,
|
|
||||||
const mapping::Submap* const matching_submap,
|
const mapping::Submap* const matching_submap,
|
||||||
const std::vector<const mapping::Submap*>& insertion_submaps) {
|
const std::vector<const mapping::Submap*>& insertion_submaps) {
|
||||||
const transform::Rigid3d optimized_pose(
|
const transform::Rigid3d optimized_pose(
|
||||||
GetLocalToGlobalTransform(trajectory) * transform::Embed3D(pose));
|
GetLocalToGlobalTransform(trajectory_id) * transform::Embed3D(pose));
|
||||||
|
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
trajectory_ids_.emplace(trajectory, trajectory_ids_.size());
|
|
||||||
const int trajectory_id = trajectory_ids_.at(trajectory);
|
|
||||||
const int flat_scan_index = trajectory_nodes_.size();
|
const int flat_scan_index = trajectory_nodes_.size();
|
||||||
CHECK_LT(flat_scan_index, std::numeric_limits<int>::max());
|
CHECK_LT(flat_scan_index, std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
@ -150,15 +147,13 @@ void SparsePoseGraph::AddWorkItem(std::function<void()> work_item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparsePoseGraph::AddImuData(const mapping::Submaps* trajectory,
|
void SparsePoseGraph::AddImuData(const int trajectory_id, common::Time time,
|
||||||
common::Time time,
|
|
||||||
const Eigen::Vector3d& linear_acceleration,
|
const Eigen::Vector3d& linear_acceleration,
|
||||||
const Eigen::Vector3d& angular_velocity) {
|
const Eigen::Vector3d& angular_velocity) {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
trajectory_ids_.emplace(trajectory, trajectory_ids_.size());
|
|
||||||
AddWorkItem([=]() REQUIRES(mutex_) {
|
AddWorkItem([=]() REQUIRES(mutex_) {
|
||||||
optimization_problem_.AddImuData(trajectory_ids_.at(trajectory), time,
|
optimization_problem_.AddImuData(trajectory_id, time, linear_acceleration,
|
||||||
linear_acceleration, angular_velocity);
|
angular_velocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +168,6 @@ void SparsePoseGraph::ComputeConstraint(const int scan_index,
|
||||||
.at(node_id.trajectory_id)
|
.at(node_id.trajectory_id)
|
||||||
.at(node_id.node_index)
|
.at(node_id.node_index)
|
||||||
.point_cloud_pose;
|
.point_cloud_pose;
|
||||||
|
|
||||||
const int scan_trajectory_id =
|
const int scan_trajectory_id =
|
||||||
trajectory_nodes_[scan_index].constant_data->trajectory_id;
|
trajectory_nodes_[scan_index].constant_data->trajectory_id;
|
||||||
|
|
||||||
|
@ -423,9 +417,10 @@ void SparsePoseGraph::RunOptimization() {
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>>
|
std::vector<std::vector<mapping::TrajectoryNode>>
|
||||||
SparsePoseGraph::GetTrajectoryNodes() {
|
SparsePoseGraph::GetTrajectoryNodes() {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>> result(
|
std::vector<std::vector<mapping::TrajectoryNode>> result;
|
||||||
trajectory_ids_.size());
|
|
||||||
for (const auto& node : trajectory_nodes_) {
|
for (const auto& node : trajectory_nodes_) {
|
||||||
|
result.resize(
|
||||||
|
std::max<size_t>(result.size(), node.constant_data->trajectory_id + 1));
|
||||||
result.at(node.constant_data->trajectory_id).push_back(node);
|
result.at(node.constant_data->trajectory_id).push_back(node);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -437,11 +432,18 @@ std::vector<SparsePoseGraph::Constraint> SparsePoseGraph::constraints() {
|
||||||
}
|
}
|
||||||
|
|
||||||
transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
||||||
const mapping::Submaps* const submaps) {
|
const int trajectory_id) {
|
||||||
const auto extrapolated_submap_transforms = GetSubmapTransforms(submaps);
|
common::MutexLocker locker(&mutex_);
|
||||||
|
if (submap_states_.size() <= static_cast<size_t>(trajectory_id) ||
|
||||||
|
submap_states_.at(trajectory_id).empty()) {
|
||||||
|
return transform::Rigid3d::Identity();
|
||||||
|
}
|
||||||
|
const auto extrapolated_submap_transforms =
|
||||||
|
ExtrapolateSubmapTransforms(optimized_submap_transforms_, trajectory_id);
|
||||||
return extrapolated_submap_transforms.back() *
|
return extrapolated_submap_transforms.back() *
|
||||||
submaps->Get(extrapolated_submap_transforms.size() - 1)
|
submap_states_.at(trajectory_id)
|
||||||
->local_pose()
|
.at(extrapolated_submap_transforms.size() - 1)
|
||||||
|
.submap->local_pose()
|
||||||
.inverse();
|
.inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,16 +452,6 @@ std::vector<std::vector<int>> SparsePoseGraph::GetConnectedTrajectories() {
|
||||||
return connected_components_;
|
return connected_components_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
|
||||||
const mapping::Submaps* const trajectory) {
|
|
||||||
common::MutexLocker locker(&mutex_);
|
|
||||||
if (trajectory_ids_.count(trajectory) == 0) {
|
|
||||||
return {transform::Rigid3d::Identity()};
|
|
||||||
}
|
|
||||||
return ExtrapolateSubmapTransforms(optimized_submap_transforms_,
|
|
||||||
trajectory_ids_.at(trajectory));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
||||||
const int trajectory_id) {
|
const int trajectory_id) {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
|
|
|
@ -70,23 +70,20 @@ class SparsePoseGraph : public mapping::SparsePoseGraph {
|
||||||
const sensor::RangeData& range_data_in_pose,
|
const sensor::RangeData& range_data_in_pose,
|
||||||
const transform::Rigid2d& pose,
|
const transform::Rigid2d& pose,
|
||||||
const kalman_filter::Pose2DCovariance& pose_covariance,
|
const kalman_filter::Pose2DCovariance& pose_covariance,
|
||||||
const mapping::Submaps* trajectory,
|
int trajectory_id, const mapping::Submap* matching_submap,
|
||||||
const mapping::Submap* matching_submap,
|
|
||||||
const std::vector<const mapping::Submap*>& insertion_submaps)
|
const std::vector<const mapping::Submap*>& insertion_submaps)
|
||||||
EXCLUDES(mutex_);
|
EXCLUDES(mutex_);
|
||||||
|
|
||||||
// Adds new IMU data to be used in the optimization.
|
// Adds new IMU data to be used in the optimization.
|
||||||
void AddImuData(const mapping::Submaps* trajectory, common::Time time,
|
void AddImuData(int trajectory_id, common::Time time,
|
||||||
const Eigen::Vector3d& linear_acceleration,
|
const Eigen::Vector3d& linear_acceleration,
|
||||||
const Eigen::Vector3d& angular_velocity);
|
const Eigen::Vector3d& angular_velocity);
|
||||||
|
|
||||||
void RunFinalOptimization() override;
|
void RunFinalOptimization() override;
|
||||||
std::vector<std::vector<int>> GetConnectedTrajectories() override;
|
std::vector<std::vector<int>> GetConnectedTrajectories() override;
|
||||||
std::vector<transform::Rigid3d> GetSubmapTransforms(
|
|
||||||
const mapping::Submaps* trajectory) EXCLUDES(mutex_) override;
|
|
||||||
std::vector<transform::Rigid3d> GetSubmapTransforms(int trajectory_id)
|
std::vector<transform::Rigid3d> GetSubmapTransforms(int trajectory_id)
|
||||||
EXCLUDES(mutex_) override;
|
EXCLUDES(mutex_) override;
|
||||||
transform::Rigid3d GetLocalToGlobalTransform(const mapping::Submaps* submaps)
|
transform::Rigid3d GetLocalToGlobalTransform(int trajectory_id)
|
||||||
EXCLUDES(mutex_) override;
|
EXCLUDES(mutex_) override;
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>> GetTrajectoryNodes()
|
std::vector<std::vector<mapping::TrajectoryNode>> GetTrajectoryNodes()
|
||||||
override EXCLUDES(mutex_);
|
override EXCLUDES(mutex_);
|
||||||
|
@ -209,10 +206,6 @@ class SparsePoseGraph : public mapping::SparsePoseGraph {
|
||||||
// Current submap transforms used for displaying data.
|
// Current submap transforms used for displaying data.
|
||||||
std::vector<std::vector<sparse_pose_graph::SubmapData>>
|
std::vector<std::vector<sparse_pose_graph::SubmapData>>
|
||||||
optimized_submap_transforms_ GUARDED_BY(mutex_);
|
optimized_submap_transforms_ GUARDED_BY(mutex_);
|
||||||
|
|
||||||
// Map from submap pointers to trajectory IDs.
|
|
||||||
std::unordered_map<const mapping::Submaps*, int> trajectory_ids_
|
|
||||||
GUARDED_BY(mutex_);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mapping_2d
|
} // namespace mapping_2d
|
||||||
|
|
|
@ -158,11 +158,12 @@ class SparsePoseGraphTest : public ::testing::Test {
|
||||||
const sensor::RangeData range_data{
|
const sensor::RangeData range_data{
|
||||||
Eigen::Vector3f::Zero(), new_point_cloud, {}};
|
Eigen::Vector3f::Zero(), new_point_cloud, {}};
|
||||||
const transform::Rigid2d pose_estimate = noise * current_pose_;
|
const transform::Rigid2d pose_estimate = noise * current_pose_;
|
||||||
|
constexpr int kTrajectoryId = 0;
|
||||||
submaps_->InsertRangeData(TransformRangeData(
|
submaps_->InsertRangeData(TransformRangeData(
|
||||||
range_data, transform::Embed3D(pose_estimate.cast<float>())));
|
range_data, transform::Embed3D(pose_estimate.cast<float>())));
|
||||||
sparse_pose_graph_->AddScan(common::FromUniversal(0),
|
sparse_pose_graph_->AddScan(common::FromUniversal(0),
|
||||||
transform::Rigid3d::Identity(), range_data,
|
transform::Rigid3d::Identity(), range_data,
|
||||||
pose_estimate, covariance, submaps_.get(),
|
pose_estimate, covariance, kTrajectoryId,
|
||||||
matching_submap, insertion_submaps);
|
matching_submap, insertion_submaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,9 @@ namespace mapping_3d {
|
||||||
|
|
||||||
GlobalTrajectoryBuilder::GlobalTrajectoryBuilder(
|
GlobalTrajectoryBuilder::GlobalTrajectoryBuilder(
|
||||||
const proto::LocalTrajectoryBuilderOptions& options,
|
const proto::LocalTrajectoryBuilderOptions& options,
|
||||||
SparsePoseGraph* sparse_pose_graph)
|
const int trajectory_id, SparsePoseGraph* sparse_pose_graph)
|
||||||
: sparse_pose_graph_(sparse_pose_graph),
|
: trajectory_id_(trajectory_id),
|
||||||
|
sparse_pose_graph_(sparse_pose_graph),
|
||||||
local_trajectory_builder_(CreateLocalTrajectoryBuilder(options)) {}
|
local_trajectory_builder_(CreateLocalTrajectoryBuilder(options)) {}
|
||||||
|
|
||||||
GlobalTrajectoryBuilder::~GlobalTrajectoryBuilder() {}
|
GlobalTrajectoryBuilder::~GlobalTrajectoryBuilder() {}
|
||||||
|
@ -38,8 +39,8 @@ void GlobalTrajectoryBuilder::AddImuData(
|
||||||
const Eigen::Vector3d& angular_velocity) {
|
const Eigen::Vector3d& angular_velocity) {
|
||||||
local_trajectory_builder_->AddImuData(time, linear_acceleration,
|
local_trajectory_builder_->AddImuData(time, linear_acceleration,
|
||||||
angular_velocity);
|
angular_velocity);
|
||||||
sparse_pose_graph_->AddImuData(local_trajectory_builder_->submaps(), time,
|
sparse_pose_graph_->AddImuData(trajectory_id_, time, linear_acceleration,
|
||||||
linear_acceleration, angular_velocity);
|
angular_velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalTrajectoryBuilder::AddRangefinderData(
|
void GlobalTrajectoryBuilder::AddRangefinderData(
|
||||||
|
@ -55,7 +56,7 @@ void GlobalTrajectoryBuilder::AddRangefinderData(
|
||||||
sparse_pose_graph_->AddScan(
|
sparse_pose_graph_->AddScan(
|
||||||
insertion_result->time, insertion_result->range_data_in_tracking,
|
insertion_result->time, insertion_result->range_data_in_tracking,
|
||||||
insertion_result->pose_observation, insertion_result->covariance_estimate,
|
insertion_result->pose_observation, insertion_result->covariance_estimate,
|
||||||
insertion_result->submaps, insertion_result->matching_submap,
|
trajectory_id_, insertion_result->matching_submap,
|
||||||
insertion_result->insertion_submaps);
|
insertion_result->insertion_submaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ class GlobalTrajectoryBuilder
|
||||||
: public mapping::GlobalTrajectoryBuilderInterface {
|
: public mapping::GlobalTrajectoryBuilderInterface {
|
||||||
public:
|
public:
|
||||||
GlobalTrajectoryBuilder(const proto::LocalTrajectoryBuilderOptions& options,
|
GlobalTrajectoryBuilder(const proto::LocalTrajectoryBuilderOptions& options,
|
||||||
|
int trajectory_id,
|
||||||
mapping_3d::SparsePoseGraph* sparse_pose_graph);
|
mapping_3d::SparsePoseGraph* sparse_pose_graph);
|
||||||
~GlobalTrajectoryBuilder() override;
|
~GlobalTrajectoryBuilder() override;
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ class GlobalTrajectoryBuilder
|
||||||
const PoseEstimate& pose_estimate() const override;
|
const PoseEstimate& pose_estimate() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const int trajectory_id_;
|
||||||
mapping_3d::SparsePoseGraph* const sparse_pose_graph_;
|
mapping_3d::SparsePoseGraph* const sparse_pose_graph_;
|
||||||
std::unique_ptr<LocalTrajectoryBuilderInterface> local_trajectory_builder_;
|
std::unique_ptr<LocalTrajectoryBuilderInterface> local_trajectory_builder_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -230,7 +230,7 @@ KalmanLocalTrajectoryBuilder::InsertIntoSubmap(
|
||||||
trajectory_node_index);
|
trajectory_node_index);
|
||||||
return std::unique_ptr<InsertionResult>(new InsertionResult{
|
return std::unique_ptr<InsertionResult>(new InsertionResult{
|
||||||
time, range_data_in_tracking, pose_observation, covariance_estimate,
|
time, range_data_in_tracking, pose_observation, covariance_estimate,
|
||||||
submaps_.get(), matching_submap, insertion_submaps});
|
matching_submap, insertion_submaps});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mapping_3d
|
} // namespace mapping_3d
|
||||||
|
|
|
@ -38,7 +38,6 @@ class LocalTrajectoryBuilderInterface {
|
||||||
sensor::RangeData range_data_in_tracking;
|
sensor::RangeData range_data_in_tracking;
|
||||||
transform::Rigid3d pose_observation;
|
transform::Rigid3d pose_observation;
|
||||||
kalman_filter::PoseCovariance covariance_estimate;
|
kalman_filter::PoseCovariance covariance_estimate;
|
||||||
const Submaps* submaps;
|
|
||||||
const Submap* matching_submap;
|
const Submap* matching_submap;
|
||||||
std::vector<const Submap*> insertion_submaps;
|
std::vector<const Submap*> insertion_submaps;
|
||||||
};
|
};
|
||||||
|
|
|
@ -406,9 +406,9 @@ OptimizingLocalTrajectoryBuilder::InsertIntoSubmap(
|
||||||
const kalman_filter::PoseCovariance kCovariance =
|
const kalman_filter::PoseCovariance kCovariance =
|
||||||
1e-7 * kalman_filter::PoseCovariance::Identity();
|
1e-7 * kalman_filter::PoseCovariance::Identity();
|
||||||
|
|
||||||
return std::unique_ptr<InsertionResult>(new InsertionResult{
|
return std::unique_ptr<InsertionResult>(
|
||||||
time, range_data_in_tracking, pose_observation, kCovariance,
|
new InsertionResult{time, range_data_in_tracking, pose_observation,
|
||||||
submaps_.get(), matching_submap, insertion_submaps});
|
kCovariance, matching_submap, insertion_submaps});
|
||||||
}
|
}
|
||||||
|
|
||||||
OptimizingLocalTrajectoryBuilder::State
|
OptimizingLocalTrajectoryBuilder::State
|
||||||
|
|
|
@ -89,15 +89,13 @@ void SparsePoseGraph::GrowSubmapTransformsAsNeeded(
|
||||||
void SparsePoseGraph::AddScan(
|
void SparsePoseGraph::AddScan(
|
||||||
common::Time time, const sensor::RangeData& range_data_in_tracking,
|
common::Time time, const sensor::RangeData& range_data_in_tracking,
|
||||||
const transform::Rigid3d& pose,
|
const transform::Rigid3d& pose,
|
||||||
const kalman_filter::PoseCovariance& covariance,
|
const kalman_filter::PoseCovariance& covariance, const int trajectory_id,
|
||||||
const Submaps* const trajectory, const Submap* const matching_submap,
|
const Submap* const matching_submap,
|
||||||
const std::vector<const Submap*>& insertion_submaps) {
|
const std::vector<const Submap*>& insertion_submaps) {
|
||||||
const transform::Rigid3d optimized_pose(
|
const transform::Rigid3d optimized_pose(
|
||||||
GetLocalToGlobalTransform(trajectory) * pose);
|
GetLocalToGlobalTransform(trajectory_id) * pose);
|
||||||
|
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
trajectory_ids_.emplace(trajectory, trajectory_ids_.size());
|
|
||||||
const int trajectory_id = trajectory_ids_.at(trajectory);
|
|
||||||
const int flat_scan_index = trajectory_nodes_.size();
|
const int flat_scan_index = trajectory_nodes_.size();
|
||||||
CHECK_LT(flat_scan_index, std::numeric_limits<int>::max());
|
CHECK_LT(flat_scan_index, std::numeric_limits<int>::max());
|
||||||
|
|
||||||
|
@ -150,15 +148,13 @@ void SparsePoseGraph::AddWorkItem(std::function<void()> work_item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparsePoseGraph::AddImuData(const mapping::Submaps* trajectory,
|
void SparsePoseGraph::AddImuData(const int trajectory_id, common::Time time,
|
||||||
common::Time time,
|
|
||||||
const Eigen::Vector3d& linear_acceleration,
|
const Eigen::Vector3d& linear_acceleration,
|
||||||
const Eigen::Vector3d& angular_velocity) {
|
const Eigen::Vector3d& angular_velocity) {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
trajectory_ids_.emplace(trajectory, trajectory_ids_.size());
|
|
||||||
AddWorkItem([=]() REQUIRES(mutex_) {
|
AddWorkItem([=]() REQUIRES(mutex_) {
|
||||||
optimization_problem_.AddImuData(trajectory_ids_.at(trajectory), time,
|
optimization_problem_.AddImuData(trajectory_id, time, linear_acceleration,
|
||||||
linear_acceleration, angular_velocity);
|
angular_velocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,9 +409,10 @@ void SparsePoseGraph::RunOptimization() {
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>>
|
std::vector<std::vector<mapping::TrajectoryNode>>
|
||||||
SparsePoseGraph::GetTrajectoryNodes() {
|
SparsePoseGraph::GetTrajectoryNodes() {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>> result(
|
std::vector<std::vector<mapping::TrajectoryNode>> result;
|
||||||
trajectory_ids_.size());
|
|
||||||
for (const auto& node : trajectory_nodes_) {
|
for (const auto& node : trajectory_nodes_) {
|
||||||
|
result.resize(
|
||||||
|
std::max<size_t>(result.size(), node.constant_data->trajectory_id + 1));
|
||||||
result.at(node.constant_data->trajectory_id).push_back(node);
|
result.at(node.constant_data->trajectory_id).push_back(node);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -427,11 +424,18 @@ std::vector<SparsePoseGraph::Constraint> SparsePoseGraph::constraints() {
|
||||||
}
|
}
|
||||||
|
|
||||||
transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
transform::Rigid3d SparsePoseGraph::GetLocalToGlobalTransform(
|
||||||
const mapping::Submaps* const submaps) {
|
const int trajectory_id) {
|
||||||
const auto extrapolated_submap_transforms = GetSubmapTransforms(submaps);
|
common::MutexLocker locker(&mutex_);
|
||||||
|
if (submap_states_.size() <= static_cast<size_t>(trajectory_id) ||
|
||||||
|
submap_states_.at(trajectory_id).empty()) {
|
||||||
|
return transform::Rigid3d::Identity();
|
||||||
|
}
|
||||||
|
const auto extrapolated_submap_transforms =
|
||||||
|
ExtrapolateSubmapTransforms(optimized_submap_transforms_, trajectory_id);
|
||||||
return extrapolated_submap_transforms.back() *
|
return extrapolated_submap_transforms.back() *
|
||||||
submaps->Get(extrapolated_submap_transforms.size() - 1)
|
submap_states_.at(trajectory_id)
|
||||||
->local_pose()
|
.at(extrapolated_submap_transforms.size() - 1)
|
||||||
|
.submap->local_pose()
|
||||||
.inverse();
|
.inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,16 +444,6 @@ std::vector<std::vector<int>> SparsePoseGraph::GetConnectedTrajectories() {
|
||||||
return connected_components_;
|
return connected_components_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
|
||||||
const mapping::Submaps* const trajectory) {
|
|
||||||
common::MutexLocker locker(&mutex_);
|
|
||||||
if (trajectory_ids_.count(trajectory) == 0) {
|
|
||||||
return {transform::Rigid3d::Identity()};
|
|
||||||
}
|
|
||||||
return ExtrapolateSubmapTransforms(optimized_submap_transforms_,
|
|
||||||
trajectory_ids_.at(trajectory));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
std::vector<transform::Rigid3d> SparsePoseGraph::GetSubmapTransforms(
|
||||||
const int trajectory_id) {
|
const int trajectory_id) {
|
||||||
common::MutexLocker locker(&mutex_);
|
common::MutexLocker locker(&mutex_);
|
||||||
|
|
|
@ -69,7 +69,7 @@ class SparsePoseGraph : public mapping::SparsePoseGraph {
|
||||||
const sensor::RangeData& range_data_in_tracking,
|
const sensor::RangeData& range_data_in_tracking,
|
||||||
const transform::Rigid3d& pose,
|
const transform::Rigid3d& pose,
|
||||||
const kalman_filter::PoseCovariance& pose_covariance,
|
const kalman_filter::PoseCovariance& pose_covariance,
|
||||||
const Submaps* trajectory, const Submap* matching_submap,
|
int trajectory_id, const Submap* matching_submap,
|
||||||
const std::vector<const Submap*>& insertion_submaps)
|
const std::vector<const Submap*>& insertion_submaps)
|
||||||
EXCLUDES(mutex_);
|
EXCLUDES(mutex_);
|
||||||
|
|
||||||
|
@ -78,17 +78,15 @@ class SparsePoseGraph : public mapping::SparsePoseGraph {
|
||||||
int GetNextTrajectoryNodeIndex() EXCLUDES(mutex_);
|
int GetNextTrajectoryNodeIndex() EXCLUDES(mutex_);
|
||||||
|
|
||||||
// Adds new IMU data to be used in the optimization.
|
// Adds new IMU data to be used in the optimization.
|
||||||
void AddImuData(const mapping::Submaps* trajectory, common::Time time,
|
void AddImuData(int trajectory_id, common::Time time,
|
||||||
const Eigen::Vector3d& linear_acceleration,
|
const Eigen::Vector3d& linear_acceleration,
|
||||||
const Eigen::Vector3d& angular_velocity);
|
const Eigen::Vector3d& angular_velocity);
|
||||||
|
|
||||||
void RunFinalOptimization() override;
|
void RunFinalOptimization() override;
|
||||||
std::vector<std::vector<int>> GetConnectedTrajectories() override;
|
std::vector<std::vector<int>> GetConnectedTrajectories() override;
|
||||||
std::vector<transform::Rigid3d> GetSubmapTransforms(
|
|
||||||
const mapping::Submaps* trajectory) EXCLUDES(mutex_) override;
|
|
||||||
std::vector<transform::Rigid3d> GetSubmapTransforms(int trajectory_id)
|
std::vector<transform::Rigid3d> GetSubmapTransforms(int trajectory_id)
|
||||||
EXCLUDES(mutex_) override;
|
EXCLUDES(mutex_) override;
|
||||||
transform::Rigid3d GetLocalToGlobalTransform(const mapping::Submaps* submaps)
|
transform::Rigid3d GetLocalToGlobalTransform(int trajectory_id)
|
||||||
EXCLUDES(mutex_) override;
|
EXCLUDES(mutex_) override;
|
||||||
std::vector<std::vector<mapping::TrajectoryNode>> GetTrajectoryNodes()
|
std::vector<std::vector<mapping::TrajectoryNode>> GetTrajectoryNodes()
|
||||||
override EXCLUDES(mutex_);
|
override EXCLUDES(mutex_);
|
||||||
|
@ -209,10 +207,6 @@ class SparsePoseGraph : public mapping::SparsePoseGraph {
|
||||||
// Current submap transforms used for displaying data.
|
// Current submap transforms used for displaying data.
|
||||||
std::vector<std::vector<sparse_pose_graph::SubmapData>>
|
std::vector<std::vector<sparse_pose_graph::SubmapData>>
|
||||||
optimized_submap_transforms_ GUARDED_BY(mutex_);
|
optimized_submap_transforms_ GUARDED_BY(mutex_);
|
||||||
|
|
||||||
// Map from submap pointers to trajectory IDs.
|
|
||||||
std::unordered_map<const mapping::Submaps*, int> trajectory_ids_
|
|
||||||
GUARDED_BY(mutex_);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mapping_3d
|
} // namespace mapping_3d
|
||||||
|
|
Loading…
Reference in New Issue