NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
depth_odometry_factor_adder.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 #ifndef FACTOR_ADDERS_DEPTH_ODOMETRY_FACTOR_ADDER_H_
19 #define FACTOR_ADDERS_DEPTH_ODOMETRY_FACTOR_ADDER_H_
20 
27 
28 #include <gtsam/linear/NoiseModel.h>
29 #include <gtsam/slam/BetweenFactor.h>
30 
31 namespace factor_adders {
32 // Adds GTSAM Pose Between factors for depth odometry relative pose measurements
33 // point to point between factors for depth odometry correspondence measurements.
34 // Adds pose nodes using PoseNodeAdder at the same timestamps as the measurements.
35 template <class PoseNodeAdderType>
37  : public SingleMeasurementBasedFactorAdder<localization_measurements::DepthOdometryMeasurement> {
38  public:
40  const std::shared_ptr<PoseNodeAdderType> node_adder);
41 
42  private:
43  // Creates a pose between factor or point to point between factors and pose nodes for the given measurement.
44  int AddFactorsForSingleMeasurement(const localization_measurements::DepthOdometryMeasurement& measurement,
45  gtsam::NonlinearFactorGraph& factors) final;
46 
47  bool CanAddFactor(const localization_measurements::DepthOdometryMeasurement& measurement) const final;
48 
49  std::shared_ptr<PoseNodeAdderType> node_adder_;
51 };
52 
53 template <class PoseNodeAdderType>
55  const DepthOdometryFactorAdderParams& params, const std::shared_ptr<PoseNodeAdderType> node_adder)
56  : SingleMeasurementBasedFactorAdder<localization_measurements::DepthOdometryMeasurement>(params),
57  params_(params),
58  node_adder_(node_adder) {}
59 
60 template <class PoseNodeAdderType>
62  const localization_measurements::DepthOdometryMeasurement& measurement, gtsam::NonlinearFactorGraph& factors) {
63  const double translation_norm = measurement.odometry.sensor_F_source_T_target.pose.translation().norm();
64  if (params_.reject_large_translation_norm && translation_norm > params_.pose_translation_norm_threshold) {
65  LogDebug("AddFactors: Ignoring pose with large translation norm. Norm: "
66  << translation_norm << ", threshold: " << params_.pose_translation_norm_threshold);
67  return 0;
68  }
69 
70  if (!node_adder_->AddNode(measurement.odometry.source_time, factors) ||
71  !node_adder_->AddNode(measurement.odometry.target_time, factors)) {
72  LogError("AddFactorsForSingleMeasurement: Failed to add nodes at source and target time.");
73  return 0;
74  }
75  const auto keys_a = node_adder_->Keys(measurement.odometry.source_time);
76  // First key is pose key
77  const auto& pose_key_a = keys_a[0];
78  const auto keys_b = node_adder_->Keys(measurement.odometry.target_time);
79  const auto& pose_key_b = keys_b[0];
80 
81  if (params_.use_points_between_factor) {
82  int num_between_factors = 0;
83  for (int i = 0; i < measurement.correspondences.source_3d_points.size() &&
84  num_between_factors < params_.max_num_points_between_factors;
85  ++i) {
86  const Eigen::Vector3d& sensor_t_point_source = measurement.correspondences.source_3d_points[i];
87  const Eigen::Vector3d& sensor_t_point_target = measurement.correspondences.target_3d_points[i];
88 
89  double noise_sigma = 1.0;
90  if (params_.scale_point_between_factors_with_inverse_distance) {
91  noise_sigma = sensor_t_point_source.norm();
92  } else if (params_.scale_point_between_factors_with_estimate_error) {
93  const Eigen::Vector3d estimate_error =
94  sensor_t_point_source - measurement.odometry.sensor_F_source_T_target.pose * sensor_t_point_target;
95  noise_sigma = estimate_error.norm();
96  }
97  if (params_.reject_large_point_to_point_error) {
98  const Eigen::Vector3d estimate_error =
99  sensor_t_point_source - measurement.odometry.sensor_F_source_T_target.pose * sensor_t_point_target;
100  if (estimate_error.norm() > params_.point_to_point_error_threshold) {
101  continue;
102  }
103  }
104 
105  const auto points_between_factor_noise = localization_common::Robust(
106  gtsam::noiseModel::Isotropic::Sigma(3, noise_sigma * params_.point_noise_scale), params_.huber_k);
107  gtsam::PointToPointBetweenFactor::shared_ptr points_between_factor(
108  new gtsam::PointToPointBetweenFactor(sensor_t_point_source, sensor_t_point_target, params_.body_T_sensor,
109  points_between_factor_noise, pose_key_a, pose_key_b));
110  factors.push_back(points_between_factor);
111  ++num_between_factors;
112  }
113  LogDebug("AddFactors: Added " << num_between_factors << " points between factors.");
114  return num_between_factors;
115  } else {
116  const auto relative_pose_noise = localization_common::Robust(
117  gtsam::noiseModel::Gaussian::Covariance(params_.pose_covariance_scale *
119  params_.huber_k);
120  const gtsam::BetweenFactor<gtsam::Pose3>::shared_ptr pose_between_factor(new gtsam::BetweenFactor<gtsam::Pose3>(
121  pose_key_a, pose_key_b, localization_common::GtPose(measurement.odometry.body_F_source_T_target.pose),
122  relative_pose_noise));
123  factors.push_back(pose_between_factor);
124  return 1;
125  }
126 }
127 
128 template <class PoseNodeAdderType>
129 bool DepthOdometryFactorAdder<PoseNodeAdderType>::CanAddFactor(
130  const localization_measurements::DepthOdometryMeasurement& measurement) const {
131  return node_adder_->CanAddNode(measurement.odometry.source_time) &&
132  node_adder_->CanAddNode(measurement.odometry.target_time);
133 }
134 } // namespace factor_adders
135 
136 #endif // FACTOR_ADDERS_DEPTH_ODOMETRY_FACTOR_ADDER_H_
localization_measurements::DepthOdometryMeasurement::odometry
Odometry odometry
Definition: depth_odometry_measurement.h:32
depth_odometry_measurement.h
factor_adders::SingleMeasurementBasedFactorAdder
Definition: single_measurement_based_factor_adder.h:28
gtsam::PointToPointBetweenFactor
Definition: point_to_point_between_factor.h:29
node_adders::Covariance
gtsam::Matrix Covariance(const gtsam::SharedNoiseModel &robust_gaussian_noise)
Definition: utilities.cc:22
localization_common::PoseWithCovariance::covariance
PoseCovariance covariance
Definition: pose_with_covariance.h:38
localization_measurements::Odometry::sensor_F_source_T_target
localization_common::PoseWithCovariance sensor_F_source_T_target
Definition: odometry.h:31
LogError
#define LogError(msg)
Definition: logger.h:55
utilities.h
localization_measurements::Odometry::body_F_source_T_target
localization_common::PoseWithCovariance body_F_source_T_target
Definition: odometry.h:32
factor_adders::DepthOdometryFactorAdder
Definition: depth_odometry_factor_adder.h:36
point_to_point_between_factor.h
point_cloud_common::Vector3d
Eigen::Vector3d Vector3d(const PointType &point)
Definition: utilities.h:328
localization_measurements::Odometry::target_time
localization_common::Time target_time
Definition: odometry.h:30
factor_adders::DepthOdometryFactorAdderParams
Definition: depth_odometry_factor_adder_params.h:27
time.h
localization_common::PoseWithCovariance::pose
Eigen::Isometry3d pose
Definition: pose_with_covariance.h:37
localization_measurements
Definition: depth_correspondences.h:25
localization_measurements::DepthCorrespondences::source_3d_points
std::vector< Eigen::Vector3d > source_3d_points
Definition: depth_correspondences.h:49
localization_measurements::DepthCorrespondences::target_3d_points
std::vector< Eigen::Vector3d > target_3d_points
Definition: depth_correspondences.h:50
localization_measurements::DepthOdometryMeasurement
Definition: depth_odometry_measurement.h:28
localization_measurements::DepthOdometryMeasurement::correspondences
DepthCorrespondences correspondences
Definition: depth_odometry_measurement.h:33
single_measurement_based_factor_adder.h
factor_adders
Definition: depth_odometry_factor_adder.h:31
depth_odometry_factor_adder_params.h
LogDebug
#define LogDebug(msg)
Definition: logger.h:69
localization_common::GtPose
gtsam::Pose3 GtPose(const Eigen::Isometry3d &eigen_pose)
Definition: utilities.cc:60
localization_measurements::Odometry::source_time
localization_common::Time source_time
Definition: odometry.h:29
factor_adders::DepthOdometryFactorAdder::DepthOdometryFactorAdder
DepthOdometryFactorAdder(const DepthOdometryFactorAdderParams &params, const std::shared_ptr< PoseNodeAdderType > node_adder)
Definition: depth_odometry_factor_adder.h:54
localization_common::Robust
gtsam::noiseModel::Robust::shared_ptr Robust(const gtsam::SharedNoiseModel &noise, const double huber_k)
Definition: utilities.cc:334