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_