19 #ifndef FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_ 
   20 #define FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_ 
   27 #include <gtsam/slam/BetweenFactor.h> 
   34 template <
typename PoseVelocityNodeAdderType>
 
   41                         const std::shared_ptr<PoseVelocityNodeAdderType> node_adder);
 
   49                                      gtsam::NonlinearFactorGraph& factors) 
final;
 
   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_);
 
   71   std::shared_ptr<PoseVelocityNodeAdderType> node_adder_;
 
   73   gtsam::SharedNoiseModel zero_velocity_noise_;
 
   74   gtsam::SharedNoiseModel zero_relative_pose_noise_;
 
   78 template <
typename PoseVelocityNodeAdderType>
 
   81     : 
Base(params), params_(params), node_adder_(node_adder) {
 
   83   const gtsam::Vector3 velocity_prior_noise_sigmas(
 
   87     gtsam::noiseModel::Diagonal::Sigmas(Eigen::Ref<const Eigen::VectorXd>(velocity_prior_noise_sigmas)),
 
   91   const gtsam::Vector6 pose_between_noise_sigmas(
 
   97     gtsam::noiseModel::Diagonal::Sigmas(Eigen::Ref<const Eigen::VectorXd>(pose_between_noise_sigmas)), params_.
huber_k);
 
  100 template <
typename PoseVelocityNodeAdderType>
 
  103   gtsam::NonlinearFactorGraph& factors) {
 
  104   int num_factors_added = 0;
 
  105   if (params_.add_pose_between_factor) {
 
  109   if (params_.add_velocity_prior) {
 
  110     if (AddZeroVelocityPrior(standstill_measurement.
timestamp, factors)) ++num_factors_added;
 
  112   return num_factors_added;
 
  115 template <
typename PoseVelocityNodeAdderType>
 
  116 bool StandstillFactorAdder<PoseVelocityNodeAdderType>::CanAddFactor(
 
  118   return node_adder_->CanAddNode(measurement.
timestamp);
 
  121 template <
typename PoseVelocityNodeAdderType>
 
  123                                                                             gtsam::NonlinearFactorGraph& factors) {
 
  124   if (!node_adder_->AddNode(timestamp, factors)) {
 
  127   const auto keys = node_adder_->Keys(timestamp);
 
  129     LogError(
"AddZeroVelocityPrior: Failed to get keys for timestamp.");
 
  133   const auto& velocity_key = keys[1];
 
  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.");
 
  143 template <
typename PoseVelocityNodeAdderType>
 
  144 bool StandstillFactorAdder<PoseVelocityNodeAdderType>::AddZeroRelativePoseFactor(
 
  146   gtsam::NonlinearFactorGraph& factors) {
 
  147   if (!(node_adder_->AddNode(timestamp_a, factors) && node_adder_->AddNode(timestamp_b, factors))) {
 
  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.");
 
  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.");
 
  162   const auto& pose_key_a = keys_a[0];
 
  163   const auto& pose_key_b = keys_b[0];
 
  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.");
 
  173 #endif  // FACTOR_ADDERS_STANDSTILL_FACTOR_ADDER_H_