| 
									
										
										
										
											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    FixedLagSmoother.cpp | 
					
						
							|  |  |  |  * @brief   The base class for different fixed-lag smoother implementations. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author  Stephen Williams | 
					
						
							|  |  |  |  * @date    Feb 27, 2013 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam_unstable/nonlinear/FixedLagSmoother.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 05:13:32 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | void FixedLagSmoother::Result::print() const { | 
					
						
							|  |  |  |   std::cout << "Nr iterations: " << iterations << '\n' | 
					
						
							|  |  |  |             << "Nr intermediateSteps: " << intermediateSteps << '\n' | 
					
						
							|  |  |  |             << "Nr nonlinear variables: " << nonlinearVariables << '\n' | 
					
						
							|  |  |  |             << "Nr linear variables: " << linearVariables << '\n' | 
					
						
							|  |  |  |             << "error: " << error << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | void FixedLagSmoother::print(const std::string& s, const KeyFormatter& keyFormatter) const { | 
					
						
							|  |  |  |   std::cout << s; | 
					
						
							|  |  |  |   std::cout << "  smoother lag: " << smootherLag_ << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | bool FixedLagSmoother::equals(const FixedLagSmoother& rhs, double tol) const { | 
					
						
							| 
									
										
										
										
											2019-09-19 03:24:09 +08:00
										 |  |  |   return std::abs(smootherLag_ - rhs.smootherLag_) < tol | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |       && std::equal(timestampKeyMap_.begin(), timestampKeyMap_.end(), rhs.timestampKeyMap_.begin()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | void FixedLagSmoother::updateKeyTimestampMap(const KeyTimestampMap& timestamps) { | 
					
						
							|  |  |  |   // Loop through each key and add/update it in the map
 | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |   for(const auto& key_timestamp: timestamps) { | 
					
						
							| 
									
										
										
										
											2015-05-14 13:26:24 +08:00
										 |  |  |     // Check to see if this key already exists in the database
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     KeyTimestampMap::iterator keyIter = keyTimestampMap_.find(key_timestamp.first); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // If the key already exists
 | 
					
						
							|  |  |  |     if(keyIter != keyTimestampMap_.end()) { | 
					
						
							|  |  |  |       // Find the entry in the Timestamp-Key database
 | 
					
						
							|  |  |  |       std::pair<TimestampKeyMap::iterator,TimestampKeyMap::iterator> range = timestampKeyMap_.equal_range(keyIter->second); | 
					
						
							|  |  |  |       TimestampKeyMap::iterator timeIter = range.first; | 
					
						
							|  |  |  |       while(timeIter->second != key_timestamp.first) { | 
					
						
							|  |  |  |         ++timeIter; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       // remove the entry in the Timestamp-Key database
 | 
					
						
							|  |  |  |       timestampKeyMap_.erase(timeIter); | 
					
						
							|  |  |  |       // insert an entry at the new time
 | 
					
						
							|  |  |  |       timestampKeyMap_.insert(TimestampKeyMap::value_type(key_timestamp.second, key_timestamp.first)); | 
					
						
							|  |  |  |       // update the Key-Timestamp database
 | 
					
						
							|  |  |  |       keyIter->second = key_timestamp.second; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // Add the Key-Timestamp database
 | 
					
						
							|  |  |  |       keyTimestampMap_.insert(key_timestamp); | 
					
						
							|  |  |  |       // Add the key to the Timestamp-Key database
 | 
					
						
							|  |  |  |       timestampKeyMap_.insert(TimestampKeyMap::value_type(key_timestamp.second, key_timestamp.first)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  | void FixedLagSmoother::eraseKeyTimestampMap(const KeyVector& keys) { | 
					
						
							| 
									
										
										
										
											2016-05-21 23:52:14 +08:00
										 |  |  |   for(Key key: keys) { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |     // Erase the key from the Timestamp->Key map
 | 
					
						
							|  |  |  |     double timestamp = keyTimestampMap_.at(key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TimestampKeyMap::iterator iter = timestampKeyMap_.lower_bound(timestamp); | 
					
						
							|  |  |  |     while(iter != timestampKeyMap_.end() && iter->first == timestamp) { | 
					
						
							|  |  |  |       if(iter->second == key) { | 
					
						
							|  |  |  |         timestampKeyMap_.erase(iter++); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         ++iter; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Erase the key from the Key->Timestamp map
 | 
					
						
							|  |  |  |     keyTimestampMap_.erase(key); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | double FixedLagSmoother::getCurrentTimestamp() const { | 
					
						
							|  |  |  |   if(timestampKeyMap_.size() > 0) { | 
					
						
							|  |  |  |     return timestampKeyMap_.rbegin()->first; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return -std::numeric_limits<double>::max(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  | KeyVector FixedLagSmoother::findKeysBefore(double timestamp) const { | 
					
						
							|  |  |  |   KeyVector keys; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   TimestampKeyMap::const_iterator end = timestampKeyMap_.lower_bound(timestamp); | 
					
						
							|  |  |  |   for(TimestampKeyMap::const_iterator iter = timestampKeyMap_.begin(); iter != end; ++iter) { | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |     keys.push_back(iter->second); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return keys; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  | KeyVector FixedLagSmoother::findKeysAfter(double timestamp) const { | 
					
						
							|  |  |  |   KeyVector keys; | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   TimestampKeyMap::const_iterator begin = timestampKeyMap_.upper_bound(timestamp); | 
					
						
							|  |  |  |   for(TimestampKeyMap::const_iterator iter = begin; iter != timestampKeyMap_.end(); ++iter) { | 
					
						
							| 
									
										
										
										
											2016-06-19 14:13:59 +08:00
										 |  |  |     keys.push_back(iter->second); | 
					
						
							| 
									
										
										
										
											2013-02-28 04:23:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return keys; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | } /// namespace gtsam
 |