| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2019-02-28 02:04:38 +08:00
										 |  |  | GTSAM Copyright 2010-2018, Georgia Tech Research Corporation, | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  | Demonstration of the fixed-lag smoothers using a planar robot example | 
					
						
							|  |  |  | and multiple odometry-like sensors | 
					
						
							|  |  |  | Author: Frank Dellaert (C++), Jeremy Aguilon (Python) | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import numpy as np | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import gtsam | 
					
						
							|  |  |  | import gtsam_unstable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _timestamp_key_value(key, value): | 
					
						
							| 
									
										
										
										
											2019-02-28 02:04:38 +08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-28 02:04:38 +08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |     return gtsam_unstable.FixedLagSmootherKeyTimestampMapValue( | 
					
						
							|  |  |  |         key, value | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def BatchFixedLagSmootherExample(): | 
					
						
							| 
									
										
										
										
											2019-02-28 02:04:38 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Runs a batch fixed smoother on an agent with two odometry | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |     sensors that is simply moving to the | 
					
						
							| 
									
										
										
										
											2019-02-28 02:04:38 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |     # Define a batch fixed lag smoother, which uses | 
					
						
							|  |  |  |     # Levenberg-Marquardt to perform the nonlinear optimization | 
					
						
							|  |  |  |     lag = 2.0 | 
					
						
							|  |  |  |     smoother_batch = gtsam_unstable.BatchFixedLagSmoother(lag) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create containers to store the factors and linearization points | 
					
						
							|  |  |  |     # that will be sent to the smoothers | 
					
						
							|  |  |  |     new_factors = gtsam.NonlinearFactorGraph() | 
					
						
							|  |  |  |     new_values = gtsam.Values() | 
					
						
							|  |  |  |     new_timestamps = gtsam_unstable.FixedLagSmootherKeyTimestampMap() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create  a prior on the first pose, placing it at the origin | 
					
						
							|  |  |  |     prior_mean = gtsam.Pose2(0, 0, 0) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:55:15 +08:00
										 |  |  |     prior_noise = gtsam.noiseModel_Diagonal.Sigmas(np.array([0.3, 0.3, 0.1])) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |     X1 = 0 | 
					
						
							| 
									
										
										
										
											2019-02-27 17:55:15 +08:00
										 |  |  |     new_factors.push_back(gtsam.PriorFactorPose2(X1, prior_mean, prior_noise)) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |     new_values.insert(X1, prior_mean) | 
					
						
							|  |  |  |     new_timestamps.insert(_timestamp_key_value(X1, 0.0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     delta_time = 0.25 | 
					
						
							|  |  |  |     time = 0.25 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while time <= 3.0: | 
					
						
							|  |  |  |         previous_key = 1000 * (time - delta_time) | 
					
						
							|  |  |  |         current_key = 1000 * time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # assign current key to the current timestamp | 
					
						
							|  |  |  |         new_timestamps.insert(_timestamp_key_value(current_key, time)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Add a guess for this pose to the new values | 
					
						
							|  |  |  |         # Assume that the robot moves at 2 m/s. Position is time[s] * 2[m/s] | 
					
						
							|  |  |  |         current_pose = gtsam.Pose2(time * 2, 0, 0) | 
					
						
							|  |  |  |         new_values.insert(current_key, current_pose) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |         # Add odometry factors from two different sources with different error | 
					
						
							|  |  |  |         # stats | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |         odometry_measurement_1 = gtsam.Pose2(0.61, -0.08, 0.02) | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |         odometry_noise_1 = gtsam.noiseModel_Diagonal.Sigmas( | 
					
						
							|  |  |  |             np.array([0.1, 0.1, 0.05])) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |         new_factors.push_back(gtsam.BetweenFactorPose2( | 
					
						
							|  |  |  |             previous_key, current_key, odometry_measurement_1, odometry_noise_1 | 
					
						
							|  |  |  |         )) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         odometry_measurement_2 = gtsam.Pose2(0.47, 0.03, 0.01) | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |         odometry_noise_2 = gtsam.noiseModel_Diagonal.Sigmas( | 
					
						
							|  |  |  |             np.array([0.05, 0.05, 0.05])) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  |         new_factors.push_back(gtsam.BetweenFactorPose2( | 
					
						
							|  |  |  |             previous_key, current_key, odometry_measurement_2, odometry_noise_2 | 
					
						
							|  |  |  |         )) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |         # Update the smoothers with the new factors. In this case, | 
					
						
							|  |  |  |         # one iteration must pass for Levenberg-Marquardt to accurately | 
					
						
							|  |  |  |         # estimate | 
					
						
							|  |  |  |         if time >= 0.50: | 
					
						
							|  |  |  |             smoother_batch.update(new_factors, new_values, new_timestamps) | 
					
						
							|  |  |  |             print("Timestamp = " + str(time) + ", Key = " + str(current_key)) | 
					
						
							|  |  |  |             print(smoother_batch.calculateEstimatePose2(current_key)) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  |             new_timestamps.clear() | 
					
						
							|  |  |  |             new_values.clear() | 
					
						
							|  |  |  |             new_factors.resize(0) | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         time += delta_time | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-07 06:47:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 17:37:02 +08:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     BatchFixedLagSmootherExample() | 
					
						
							|  |  |  |     print("Example complete") |