NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
standstill_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 
19 #ifndef FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_
20 #define FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_
21 
26 
27 #include <gtsam/slam/BetweenFactor.h>
28 
29 #include <vector>
30 
31 namespace factor_adders {
32 // SingleMeasurementBasedFactorAdder that generates standstill factors (zero velocity prior and zero relative pose
33 // between factors) based on provided params.
34 template <typename PoseVelocityNodeAdderType>
36  : public SingleMeasurementBasedFactorAdder<localization_measurements::StandstillMeasurement> {
38 
39  public:
41  const std::shared_ptr<PoseVelocityNodeAdderType> node_adder);
42 
43  // Default constructor for serialization only
44  StandstillFactorAdder() = default;
45 
46  private:
47  // Adds zero velocity and/or zero relative pose factors depending on params.
48  int AddFactorsForSingleMeasurement(const localization_measurements::StandstillMeasurement& standstill_measurement,
49  gtsam::NonlinearFactorGraph& factors) final;
50 
51  // Returns whether the node adder can add a node at the provided time.
52  bool CanAddFactor(const localization_measurements::StandstillMeasurement& measurement) const final;
53 
54  // Adds a velocity prior at the provided timestamp with zero velocity.
55  bool AddZeroVelocityPrior(const localization_common::Time timestamp, gtsam::NonlinearFactorGraph& factors);
56  // Adds a relative pose between factor with zero relative movement between nodes at timestamp a and b.
57  bool AddZeroRelativePoseFactor(const localization_common::Time timestamp_a,
58  const localization_common::Time timestamp_b, gtsam::NonlinearFactorGraph& factors);
59 
60  // Serialization function
62  template <class Archive>
63  void serialize(Archive& ar, const unsigned int file_version) {
64  ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
65  ar& BOOST_SERIALIZATION_NVP(node_adder_);
66  ar& BOOST_SERIALIZATION_NVP(params_);
67  ar& BOOST_SERIALIZATION_NVP(zero_velocity_noise_);
68  ar& BOOST_SERIALIZATION_NVP(zero_relative_pose_noise_);
69  }
70 
71  std::shared_ptr<PoseVelocityNodeAdderType> node_adder_;
73  gtsam::SharedNoiseModel zero_velocity_noise_;
74  gtsam::SharedNoiseModel zero_relative_pose_noise_;
75 };
76 
77 // Implementation
78 template <typename PoseVelocityNodeAdderType>
80  const StandstillFactorAdderParams& params, const std::shared_ptr<PoseVelocityNodeAdderType> node_adder)
81  : Base(params), params_(params), node_adder_(node_adder) {
82  // Create zero velocity noise
83  const gtsam::Vector3 velocity_prior_noise_sigmas(
84  (gtsam::Vector(3) << params_.prior_velocity_stddev, params_.prior_velocity_stddev, params_.prior_velocity_stddev)
85  .finished());
86  zero_velocity_noise_ = localization_common::Robust(
87  gtsam::noiseModel::Diagonal::Sigmas(Eigen::Ref<const Eigen::VectorXd>(velocity_prior_noise_sigmas)),
88  params_.huber_k);
89 
90  // Create zero relative pose noise
91  const gtsam::Vector6 pose_between_noise_sigmas(
95  .finished());
96  zero_relative_pose_noise_ = localization_common::Robust(
97  gtsam::noiseModel::Diagonal::Sigmas(Eigen::Ref<const Eigen::VectorXd>(pose_between_noise_sigmas)), params_.huber_k);
98 }
99 
100 template <typename PoseVelocityNodeAdderType>
102  const localization_measurements::StandstillMeasurement& standstill_measurement,
103  gtsam::NonlinearFactorGraph& factors) {
104  int num_factors_added = 0;
105  if (params_.add_pose_between_factor) {
106  if (AddZeroRelativePoseFactor(standstill_measurement.previous_timestamp, standstill_measurement.timestamp, factors))
107  ++num_factors_added;
108  }
109  if (params_.add_velocity_prior) {
110  if (AddZeroVelocityPrior(standstill_measurement.timestamp, factors)) ++num_factors_added;
111  }
112  return num_factors_added;
113 }
114 
115 template <typename PoseVelocityNodeAdderType>
116 bool StandstillFactorAdder<PoseVelocityNodeAdderType>::CanAddFactor(
117  const localization_measurements::StandstillMeasurement& measurement) const {
118  return node_adder_->CanAddNode(measurement.timestamp);
119 }
120 
121 template <typename PoseVelocityNodeAdderType>
122 bool StandstillFactorAdder<PoseVelocityNodeAdderType>::AddZeroVelocityPrior(const localization_common::Time timestamp,
123  gtsam::NonlinearFactorGraph& factors) {
124  if (!node_adder_->AddNode(timestamp, factors)) {
125  return false;
126  }
127  const auto keys = node_adder_->Keys(timestamp);
128  if (keys.empty()) {
129  LogError("AddZeroVelocityPrior: Failed to get keys for timestamp.");
130  return false;
131  }
132  // Assumes second key is velocity
133  const auto& velocity_key = keys[1];
134 
135  // Create factor
136  gtsam::PriorFactor<gtsam::Velocity3>::shared_ptr velocity_prior_factor(
137  new gtsam::PriorFactor<gtsam::Velocity3>(velocity_key, gtsam::Velocity3::Zero(), zero_velocity_noise_));
138  factors.push_back(velocity_prior_factor);
139  LogDebug("AddFactorsForSingleMeasurement: Added standstill velocity prior factor.");
140  return true;
141 }
142 
143 template <typename PoseVelocityNodeAdderType>
144 bool StandstillFactorAdder<PoseVelocityNodeAdderType>::AddZeroRelativePoseFactor(
145  const localization_common::Time timestamp_a, const localization_common::Time timestamp_b,
146  gtsam::NonlinearFactorGraph& factors) {
147  if (!(node_adder_->AddNode(timestamp_a, factors) && node_adder_->AddNode(timestamp_b, factors))) {
148  return false;
149  }
150 
151  const auto keys_a = node_adder_->Keys(timestamp_a);
152  if (keys_a.empty()) {
153  LogError("AddZeroVelocityPrior: Failed to get keys for timestamp_a.");
154  return false;
155  }
156  const auto keys_b = node_adder_->Keys(timestamp_b);
157  if (keys_b.empty()) {
158  LogError("AddZeroVelocityPrior: Failed to get keys for timestamp_b.");
159  return false;
160  }
161  // Assumes first key is pose
162  const auto& pose_key_a = keys_a[0];
163  const auto& pose_key_b = keys_b[0];
164 
165  gtsam::BetweenFactor<gtsam::Pose3>::shared_ptr pose_between_factor(new gtsam::BetweenFactor<gtsam::Pose3>(
166  pose_key_a, pose_key_b, gtsam::Pose3::identity(), zero_relative_pose_noise_));
167  factors.push_back(pose_between_factor);
168  LogDebug("AddFactorsForSingleMeasurement: Added standstill pose between factor.");
169  return true;
170 }
171 } // namespace factor_adders
172 
173 #endif // FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_
factor_adders::SingleMeasurementBasedFactorAdder
Definition: single_measurement_based_factor_adder.h:28
factor_adders::StandstillFactorAdderParams
Definition: standstill_factor_adder_params.h:25
localization_measurements::Measurement::timestamp
localization_common::Time timestamp
Definition: measurement.h:29
localization_measurements::StandstillMeasurement::previous_timestamp
localization_common::Time previous_timestamp
Definition: standstill_measurement.h:31
LogError
#define LogError(msg)
Definition: logger.h:55
utilities.h
factor_adders::StandstillFactorAdderParams::prior_velocity_stddev
double prior_velocity_stddev
Definition: standstill_factor_adder_params.h:28
factor_adders::StandstillFactorAdder
Definition: standstill_factor_adder.h:35
factor_adders::StandstillFactorAdderParams::pose_between_factor_rotation_stddev
double pose_between_factor_rotation_stddev
Definition: standstill_factor_adder_params.h:30
factor_adders::StandstillFactorAdder::access
friend class boost::serialization::access
Definition: standstill_factor_adder.h:61
factor_adders::StandstillFactorAdder::StandstillFactorAdder
StandstillFactorAdder()=default
factor_adders::StandstillFactorAdderParams::pose_between_factor_translation_stddev
double pose_between_factor_translation_stddev
Definition: standstill_factor_adder_params.h:29
single_measurement_based_factor_adder.h
factor_adders
Definition: depth_odometry_factor_adder.h:31
LogDebug
#define LogDebug(msg)
Definition: logger.h:69
localization_measurements::StandstillMeasurement
Definition: standstill_measurement.h:28
standstill_factor_adder_params.h
localization_common::Robust
gtsam::noiseModel::Robust::shared_ptr Robust(const gtsam::SharedNoiseModel &noise, const double huber_k)
Definition: utilities.cc:334
standstill_measurement.h
factor_adders::FactorAdderParams::huber_k
double huber_k
Definition: factor_adder_params.h:25
localization_common::Time
double Time
Definition: time.h:23