| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @file    IncrementalFixedLagSmoother.cpp | 
					
						
							|  |  |  |  * @brief   An iSAM2-based fixed-lag smoother. To the extent possible, this class mimics the iSAM2 | 
					
						
							|  |  |  |  * interface. However, additional parameters, such as the smoother lag and the timestamp associated | 
					
						
							|  |  |  |  * with each variable are needed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author  Michael Kaess, Stephen Williams | 
					
						
							|  |  |  |  * @date    Oct 14, 2012 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam_unstable/nonlinear/IncrementalFixedLagSmoother.h>
 | 
					
						
							|  |  |  | #include <gtsam/base/debug.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | void recursiveMarkAffectedKeys(const Key& key, | 
					
						
							|  |  |  |     const ISAM2Clique::shared_ptr& clique, std::set<Key>& additionalKeys) { | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Check if the separator keys of the current clique contain the specified key
 | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |   if (std::find(clique->conditional()->beginParents(), | 
					
						
							|  |  |  |       clique->conditional()->endParents(), key) | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |       != clique->conditional()->endParents()) { | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Mark the frontal keys of the current clique
 | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(Key i: clique->conditional()->frontals()) { | 
					
						
							| 
									
										
										
										
											2013-08-15 03:12:24 +08:00
										 |  |  |       additionalKeys.insert(i); | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Recursively mark all of the children
 | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(const ISAM2Clique::shared_ptr& child: clique->children) { | 
					
						
							| 
									
										
										
										
											2013-08-15 03:12:24 +08:00
										 |  |  |       recursiveMarkAffectedKeys(key, child, additionalKeys); | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // If the key was not found in the separator/parents, then none of its children can have it either
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  | void IncrementalFixedLagSmoother::print(const std::string& s, | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |     const KeyFormatter& keyFormatter) const { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   FixedLagSmoother::print(s, keyFormatter); | 
					
						
							|  |  |  |   // TODO: What else to print?
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | bool IncrementalFixedLagSmoother::equals(const FixedLagSmoother& rhs, | 
					
						
							|  |  |  |     double tol) const { | 
					
						
							|  |  |  |   const IncrementalFixedLagSmoother* e = | 
					
						
							|  |  |  |       dynamic_cast<const IncrementalFixedLagSmoother*>(&rhs); | 
					
						
							| 
									
										
										
										
											2020-04-07 05:31:05 +08:00
										 |  |  |   return e != nullptr && FixedLagSmoother::equals(*e, tol) | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |       && isam_.equals(e->isam_, tol); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | FixedLagSmoother::Result IncrementalFixedLagSmoother::update( | 
					
						
							|  |  |  |     const NonlinearFactorGraph& newFactors, const Values& newTheta, | 
					
						
							| 
									
										
										
										
											2019-05-19 10:47:58 +08:00
										 |  |  |     const KeyTimestampMap& timestamps, const FactorIndices& factorsToRemove) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const bool debug = ISDEBUG("IncrementalFixedLagSmoother update"); | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) { | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  |     std::cout << "IncrementalFixedLagSmoother::update() Start" << std::endl; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     PrintSymbolicTree(isam_, "Bayes Tree Before Update:"); | 
					
						
							| 
									
										
										
										
											2013-03-19 05:32:43 +08:00
										 |  |  |     std::cout << "END" << std::endl; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   FastVector<size_t> removedFactors; | 
					
						
							| 
									
										
										
										
											2023-01-13 05:35:48 +08:00
										 |  |  |   std::optional<FastMap<Key, int> > constrainedKeys = {}; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Update the Timestamps associated with the factor keys
 | 
					
						
							|  |  |  |   updateKeyTimestampMap(timestamps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Get current timestamp
 | 
					
						
							|  |  |  |   double current_timestamp = getCurrentTimestamp(); | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) | 
					
						
							|  |  |  |     std::cout << "Current Timestamp: " << current_timestamp << std::endl; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Find the set of variables to be marginalized out
 | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |   KeyVector marginalizableKeys = findKeysBefore( | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |       current_timestamp - smootherLag_); | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     std::cout << "Marginalizable Keys: "; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(Key key: marginalizableKeys) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |       std::cout << DefaultKeyFormatter(key) << " "; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     std::cout << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Force iSAM2 to put the marginalizable variables at the beginning
 | 
					
						
							|  |  |  |   createOrderingConstraints(marginalizableKeys, constrainedKeys); | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     std::cout << "Constrained Keys: "; | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |     if (constrainedKeys) { | 
					
						
							|  |  |  |       for (FastMap<Key, int>::const_iterator iter = constrainedKeys->begin(); | 
					
						
							|  |  |  |           iter != constrainedKeys->end(); ++iter) { | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |         std::cout << DefaultKeyFormatter(iter->first) << "(" << iter->second | 
					
						
							|  |  |  |             << ")  "; | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     std::cout << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  |   // Mark additional keys between the marginalized keys and the leaves
 | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |   std::set<Key> additionalKeys; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: marginalizableKeys) { | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     ISAM2Clique::shared_ptr clique = isam_[key]; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(const ISAM2Clique::shared_ptr& child: clique->children) { | 
					
						
							| 
									
										
										
										
											2013-08-15 03:12:24 +08:00
										 |  |  |       recursiveMarkAffectedKeys(key, child, additionalKeys); | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   KeyList additionalMarkedKeys(additionalKeys.begin(), additionalKeys.end()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   // Update iSAM2
 | 
					
						
							| 
									
										
										
										
											2016-08-25 02:19:02 +08:00
										 |  |  |   isamResult_ = isam_.update(newFactors, newTheta, | 
					
						
							| 
									
										
										
										
											2023-01-13 05:35:48 +08:00
										 |  |  |       factorsToRemove, constrainedKeys, {}, additionalMarkedKeys); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) { | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |     PrintSymbolicTree(isam_, | 
					
						
							|  |  |  |         "Bayes Tree After Update, Before Marginalization:"); | 
					
						
							| 
									
										
										
										
											2013-03-19 05:32:43 +08:00
										 |  |  |     std::cout << "END" << std::endl; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Marginalize out any needed variables
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (marginalizableKeys.size() > 0) { | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |     FastList<Key> leafKeys(marginalizableKeys.begin(), | 
					
						
							|  |  |  |         marginalizableKeys.end()); | 
					
						
							| 
									
										
										
										
											2013-04-12 04:55:55 +08:00
										 |  |  |     isam_.marginalizeLeaves(leafKeys); | 
					
						
							| 
									
										
										
										
											2013-03-19 06:28:14 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   // Remove marginalized keys from the KeyTimestampMap
 | 
					
						
							|  |  |  |   eraseKeyTimestampMap(marginalizableKeys); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) { | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  |     PrintSymbolicTree(isam_, "Final Bayes Tree:"); | 
					
						
							| 
									
										
										
										
											2013-03-19 05:32:43 +08:00
										 |  |  |     std::cout << "END" << std::endl; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // TODO: Fill in result structure
 | 
					
						
							|  |  |  |   Result result; | 
					
						
							|  |  |  |   result.iterations = 1; | 
					
						
							|  |  |  |   result.linearVariables = 0; | 
					
						
							|  |  |  |   result.nonlinearVariables = 0; | 
					
						
							|  |  |  |   result.error = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (debug) | 
					
						
							|  |  |  |     std::cout << "IncrementalFixedLagSmoother::update() Finish" << std::endl; | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | void IncrementalFixedLagSmoother::eraseKeysBefore(double timestamp) { | 
					
						
							|  |  |  |   TimestampKeyMap::iterator end = timestampKeyMap_.lower_bound(timestamp); | 
					
						
							|  |  |  |   TimestampKeyMap::iterator iter = timestampKeyMap_.begin(); | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   while (iter != end) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     keyTimestampMap_.erase(iter->second); | 
					
						
							|  |  |  |     timestampKeyMap_.erase(iter++); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  | void IncrementalFixedLagSmoother::createOrderingConstraints( | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |     const KeyVector& marginalizableKeys, | 
					
						
							| 
									
										
										
										
											2023-01-13 05:35:48 +08:00
										 |  |  |     std::optional<FastMap<Key, int> >& constrainedKeys) const { | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (marginalizableKeys.size() > 0) { | 
					
						
							|  |  |  |     constrainedKeys = FastMap<Key, int>(); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     // Generate ordering constraints so that the marginalizable variables will be eliminated first
 | 
					
						
							|  |  |  |     // Set all variables to Group1
 | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(const TimestampKeyMap::value_type& timestamp_key: timestampKeyMap_) { | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  |       constrainedKeys->operator[](timestamp_key.second) = 1; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     // Set marginalizable variables to Group0
 | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(Key key: marginalizableKeys) { | 
					
						
							| 
									
										
										
										
											2013-03-06 04:54:00 +08:00
										 |  |  |       constrainedKeys->operator[](key) = 0; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | void IncrementalFixedLagSmoother::PrintKeySet(const std::set<Key>& keys, | 
					
						
							|  |  |  |     const std::string& label) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   std::cout << label; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: keys) { | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     std::cout << " " << DefaultKeyFormatter(key); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   std::cout << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | void IncrementalFixedLagSmoother::PrintSymbolicFactor( | 
					
						
							|  |  |  |     const GaussianFactor::shared_ptr& factor) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   std::cout << "f("; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: factor->keys()) { | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     std::cout << " " << DefaultKeyFormatter(key); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   std::cout << " )" << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | void IncrementalFixedLagSmoother::PrintSymbolicGraph( | 
					
						
							|  |  |  |     const GaussianFactorGraph& graph, const std::string& label) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   std::cout << label << std::endl; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(const GaussianFactor::shared_ptr& factor: graph) { | 
					
						
							| 
									
										
										
										
											2013-08-15 03:12:24 +08:00
										 |  |  |     PrintSymbolicFactor(factor); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  | void IncrementalFixedLagSmoother::PrintSymbolicTree(const ISAM2& isam, | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  |     const std::string& label) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   std::cout << label << std::endl; | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (!isam.roots().empty()) { | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |     for(const ISAM2::sharedClique& root: isam.roots()) { | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |       PrintSymbolicTreeHelper(root); | 
					
						
							| 
									
										
										
										
											2013-08-15 03:12:24 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   } else | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     std::cout << "{Empty Tree}" << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  | void IncrementalFixedLagSmoother::PrintSymbolicTreeHelper( | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     const ISAM2Clique::shared_ptr& clique, const std::string indent) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Print the current clique
 | 
					
						
							|  |  |  |   std::cout << indent << "P( "; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: clique->conditional()->frontals()) { | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     std::cout << DefaultKeyFormatter(key) << " "; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |   if (clique->conditional()->nrParents() > 0) | 
					
						
							|  |  |  |     std::cout << "| "; | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: clique->conditional()->parents()) { | 
					
						
							| 
									
										
										
										
											2016-02-26 14:07:04 +08:00
										 |  |  |     std::cout << DefaultKeyFormatter(key) << " "; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   std::cout << ")" << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Recursively print all of the children
 | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(const ISAM2Clique::shared_ptr& child: clique->children) { | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |     PrintSymbolicTreeHelper(child, indent + " "); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2015-05-14 14:44:46 +08:00
										 |  |  | } /// namespace gtsam
 |