19 #ifndef NODE_ADDERS_TIMESTAMPED_NODE_ADDER_H_ 
   20 #define NODE_ADDERS_TIMESTAMPED_NODE_ADDER_H_ 
   36 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
   44                        std::shared_ptr<nodes::Values> values);
 
   49                        std::shared_ptr<TimestampedNodesType> timestamped_nodes);
 
   59   void AddInitialNodesAndPriors(
const NodeType& initial_node, 
const std::vector<gtsam::SharedNoiseModel>& initial_noise,
 
   71                    const boost::optional<const gtsam::Marginals&>& marginals, 
const gtsam::KeyVector& old_keys,
 
   72                    const double huber_k, gtsam::NonlinearFactorGraph& factors) 
override;
 
   85                            const gtsam::NonlinearFactorGraph& graph) 
const final;
 
   87   boost::optional<localization_common::Time> 
StartTime() 
const final;
 
   89   boost::optional<localization_common::Time> 
EndTime() 
const final;
 
   95   const TimestampedNodesType& 
nodes()
 const { 
return *nodes_; }
 
   97   std::shared_ptr<const TimestampedNodesType> 
nodes_ptr() { 
return nodes_; }
 
  102   void RemovePriors(
const gtsam::KeyVector& old_keys, gtsam::NonlinearFactorGraph& factors);
 
  107   friend class boost::serialization::access;
 
  108   template <
class Archive>
 
  109   void serialize(Archive& ar, 
const unsigned int file_version) {
 
  110     ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Base);
 
  111     ar& BOOST_SERIALIZATION_NVP(nodes_);
 
  112     ar& BOOST_SERIALIZATION_NVP(node_adder_model_);
 
  113     ar& BOOST_SERIALIZATION_NVP(params_);
 
  117   NodeAdderModelType node_adder_model_;
 
  118   std::shared_ptr<TimestampedNodesType> nodes_;
 
  122 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  127       nodes_(
std::make_shared<TimestampedNodesType>(values)),
 
  128       node_adder_model_(node_adder_model_params) {}
 
  130 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  134   std::shared_ptr<TimestampedNodesType> timestamped_nodes)
 
  135     : params_(params), nodes_(timestamped_nodes), node_adder_model_(node_adder_model_params) {}
 
  137 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  139   gtsam::NonlinearFactorGraph& factors) {
 
  140   AddInitialNodesAndPriors(params_.start_node, params_.start_noise_models, params_.starting_time, factors);
 
  143 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  145   const NodeType& initial_node, 
const std::vector<gtsam::SharedNoiseModel>& initial_noise,
 
  147   nodes_->Add(timestamp, initial_node);
 
  148   node_adder_model_.AddPriors(initial_node, initial_noise, timestamp, *nodes_, factors);
 
  152 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  155   const gtsam::KeyVector& old_keys, 
const double huber_k, gtsam::NonlinearFactorGraph& factors) {
 
  156   if (oldest_allowed_timestamp <= *(StartTime())) {
 
  157     LogDebug(
"SlideWindow: Oldest allowed timestamp older than current start time, nothing to do.");
 
  160   nodes_->RemoveOldNodes(oldest_allowed_timestamp);
 
  161   if (params_.add_priors) {
 
  164     const auto oldest_node = nodes_->OldestNode();
 
  165     const auto start_time = StartTime();
 
  166     if (!oldest_node || !start_time) {
 
  167       LogError(
"SlideWindow: Failed to get oldest node and timestamp.");
 
  172     RemovePriors(old_keys, factors);
 
  174       const auto keys = nodes_->Keys(*start_time);
 
  176         LogError(
"SlideWindow: Failed to get oldest keys.");
 
  180       std::vector<gtsam::SharedNoiseModel> prior_noise_models;
 
  181       for (
const auto& key : keys) {
 
  187           prior_noise_models.emplace_back(prior_noise);
 
  189           prior_noise_models = params_.start_noise_models;
 
  193       node_adder_model_.AddPriors(*oldest_node, prior_noise_models, *start_time, *nodes_, factors);
 
  196       node_adder_model_.AddPriors(*oldest_node, params_.start_noise_models, *start_time, *nodes_, factors);
 
  203 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  204 boost::optional<localization_common::Time>
 
  206   if (nodes_->empty()) {
 
  207     LogDebug(
"SlideWindowNewStartTime: No states in map.");
 
  211   const int size = nodes_->size();
 
  212   if (size <= params_.min_num_states) {
 
  213     LogDebug(
"SlideWindowNewStartTime: Not enough states to remove.");
 
  217   const double total_duration = nodes_->Duration();
 
  218   LogDebug(
"SlideWindowNewStartTime: Starting total num states: " << nodes_->size());
 
  219   LogDebug(
"SlideWindowNewStartTime: Starting total duration is " << total_duration);
 
  226   int num_states_to_be_removed = 0;
 
  227   for (
const auto& timestamp : nodes_->Timestamps()) {
 
  228     const int new_num_states = size - num_states_to_be_removed++;
 
  230     if (new_num_states <= params_.min_num_states) 
return timestamp;
 
  232     if (new_num_states > params_.max_num_states) 
continue;
 
  234     if (timestamp >= ideal_oldest_allowed_state) 
return timestamp;
 
  239   LogError(
"SlideWindowNewStartTime: Invalid sliding window params set, max num states: " 
  240            << params_.max_num_states << 
", min num states: " << params_.min_num_states
 
  241            << 
", ideal duration: " << params_.ideal_duration);
 
  245 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  248   return nodes_->
OldKeys(oldest_allowed_time);
 
  251 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  252 boost::optional<localization_common::Time>
 
  254   return nodes_->OldestTimestamp();
 
  257 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  258 boost::optional<localization_common::Time>
 
  260   return nodes_->LatestTimestamp();
 
  263 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  266   return node_adder_model_.
CanAddNode(timestamp);
 
  269 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  272   return nodes_->
Keys(timestamp);
 
  275 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  277   const gtsam::KeyVector& old_keys, gtsam::NonlinearFactorGraph& factors) {
 
  278   int removed_factors = 0;
 
  279   for (
auto factor_it = factors.begin(); factor_it != factors.end();) {
 
  280     bool erase_factor = 
false;
 
  281     const auto prior_factor = 
dynamic_cast<gtsam::PriorFactor<NodeType>*
>(factor_it->get());
 
  284       for (
const auto& old_key : old_keys) {
 
  285         if (prior_factor->key() == old_key) {
 
  287           factor_it = factors.erase(factor_it);
 
  298   LogDebug(
"RemovePriors: Erase " << removed_factors << 
" factors.");
 
  301 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  304   if (nodes_->Contains(timestamp)) {
 
  306       "Adder: Node exists at " 
  307       "timestamp, nothing to do.");
 
  311   const auto end_time = EndTime();
 
  313     LogError(
"Adder: Failed to get end timestamp.");
 
  316   if (timestamp > *end_time) {
 
  317     LogDebug(
"Adder: Adding new nodes and relative factors.");
 
  318     return AddNewNodesAndRelativeFactors(timestamp, factors);
 
  320     LogDebug(
"Adder: Splitting old relative factor.");
 
  321     return SplitOldRelativeFactor(timestamp, factors);
 
  325 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  328   const auto timestamp_a = EndTime();
 
  330     LogError(
"AddNewNodesAndRelativeFactor: Failed to get end timestamp.");
 
  333   return node_adder_model_.AddNodesAndRelativeFactors(*timestamp_a, timestamp, *nodes_, factors);
 
  336 template <
typename NodeType, 
typename TimestampedNodesType, 
typename NodeAdderModelType>
 
  337 bool TimestampedNodeAdder<NodeType, TimestampedNodesType, NodeAdderModelType>::SplitOldRelativeFactor(
 
  339   const auto timestamp_bounds = nodes_->LowerAndUpperBoundTimestamps(timestamp);
 
  341   if (!timestamp_bounds.first || !timestamp_bounds.second) {
 
  342     LogError(
"SplitOldRelativeFactor: Failed to get upper and lower bound timestamp.");
 
  349   if (timestamp < lower_bound_time || timestamp > upper_bound_time) {
 
  350     LogError(
"SplitOldRelativeFactor: Timestamp is not within bounds of existing timestamps.");
 
  354   const bool removed_old_factors =
 
  355     node_adder_model_.RemoveRelativeFactors(lower_bound_time, upper_bound_time, *nodes_, factors);
 
  356   if (!removed_old_factors) {
 
  358       "SplitOldRelativeFactor: Failed to remove " 
  362   if (!node_adder_model_.AddNodesAndRelativeFactors(lower_bound_time, timestamp, *nodes_, factors)) {
 
  363     LogError(
"SplitOldRelativeFactor: Failed to add first relative node and factor.");
 
  366   if (!node_adder_model_.AddRelativeFactors(timestamp, upper_bound_time, *nodes_, factors)) {
 
  367     LogError(
"SplitOldRelativeFactor: Failed to add second relative factor.");
 
  374 #endif  // NODE_ADDERS_TIMESTAMPED_NODE_ADDER_H_