| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  | #include <gtsam/geometry/SimpleCamera.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/Symbol.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | #include <gtsam/navigation/ImuBias.h>
 | 
					
						
							|  |  |  | #include <gtsam/navigation/ImuFactor.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  | #include <gtsam/navigation/Scenario.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  | #include <gtsam/nonlinear/ISAM2.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | #include <gtsam/slam/BetweenFactor.h>
 | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  | #include <gtsam/slam/PriorFactor.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  | // Shorthand for velocity and pose variables
 | 
					
						
							|  |  |  | using symbol_shorthand::V; | 
					
						
							|  |  |  | using symbol_shorthand::X; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const double kGravity = 9.81; | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main(int argc, char* argv[]) { | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   auto params = PreintegrationParams::MakeSharedU(kGravity); | 
					
						
							|  |  |  |   params->setAccelerometerCovariance(I_3x3 * 0.1); | 
					
						
							|  |  |  |   params->setGyroscopeCovariance(I_3x3 * 0.1); | 
					
						
							|  |  |  |   params->setIntegrationCovariance(I_3x3 * 0.1); | 
					
						
							|  |  |  |   params->setUse2ndOrderCoriolis(false); | 
					
						
							|  |  |  |   params->setOmegaCoriolis(Vector3(0, 0, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Pose3 delta(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Start with a camera on x-axis looking at origin
 | 
					
						
							|  |  |  |   double radius = 30; | 
					
						
							|  |  |  |   const Point3 up(0, 0, 1), target(0, 0, 0); | 
					
						
							|  |  |  |   const Point3 position(radius, 0, 0); | 
					
						
							|  |  |  |   const SimpleCamera camera = SimpleCamera::Lookat(position, target, up); | 
					
						
							|  |  |  |   const auto pose_0 = camera.pose(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Now, create a constant-twist scenario that makes the camera orbit the
 | 
					
						
							|  |  |  |   // origin
 | 
					
						
							|  |  |  |   double angular_velocity = M_PI,  // rad/sec
 | 
					
						
							|  |  |  |       delta_t = 1.0 / 18;          // makes for 10 degrees per step
 | 
					
						
							|  |  |  |   Vector3 angular_velocity_vector(0, -angular_velocity, 0); | 
					
						
							|  |  |  |   Vector3 linear_velocity_vector(radius * angular_velocity, 0, 0); | 
					
						
							|  |  |  |   auto scenario = ConstantTwistScenario(angular_velocity_vector, | 
					
						
							|  |  |  |                                         linear_velocity_vector, pose_0); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create a factor graph
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   NonlinearFactorGraph newgraph; | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |   // Create (incremental) ISAM2 solver
 | 
					
						
							|  |  |  |   ISAM2 isam; | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create the initial estimate to the solution
 | 
					
						
							|  |  |  |   // Intentionally initialize the variables off from the ground truth
 | 
					
						
							|  |  |  |   Values initialEstimate, totalEstimate, result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Add a prior on pose x0. This indirectly specifies where the origin is.
 | 
					
						
							| 
									
										
										
										
											2018-10-22 19:31:12 +08:00
										 |  |  |   // 0.1 rad std on roll, pitch, yaw, 30cm std on x,y,z.
 | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |   auto noise = noiseModel::Diagonal::Sigmas( | 
					
						
							| 
									
										
										
										
											2018-10-22 19:31:12 +08:00
										 |  |  |       (Vector(6) << Vector3::Constant(0.1), Vector3::Constant(0.3)).finished()); | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   newgraph.push_back(PriorFactor<Pose3>(X(0), pose_0, noise)); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Add imu priors
 | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |   Key biasKey = Symbol('b', 0); | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |   auto biasnoise = noiseModel::Diagonal::Sigmas(Vector6::Constant(0.1)); | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |   PriorFactor<imuBias::ConstantBias> biasprior(biasKey, imuBias::ConstantBias(), | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |                                                biasnoise); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |   newgraph.push_back(biasprior); | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |   initialEstimate.insert(biasKey, imuBias::ConstantBias()); | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |   auto velnoise = noiseModel::Diagonal::Sigmas(Vector3(0.1, 0.1, 0.1)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   Vector n_velocity(3); | 
					
						
							|  |  |  |   n_velocity << 0, angular_velocity * radius, 0; | 
					
						
							|  |  |  |   PriorFactor<Vector> velprior(V(0), n_velocity, velnoise); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |   newgraph.push_back(velprior); | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   initialEstimate.insert(V(0), n_velocity); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |   // IMU preintegrator
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   PreintegratedImuMeasurements accum(params); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Simulate poses and imu measurements, adding them to the factor graph
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   for (size_t i = 0; i < 36; ++i) { | 
					
						
							|  |  |  |     double t = i * delta_t; | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |     if (i == 0) {  // First time add two poses
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |       auto pose_1 = scenario.pose(delta_t); | 
					
						
							|  |  |  |       initialEstimate.insert(X(0), pose_0.compose(delta)); | 
					
						
							|  |  |  |       initialEstimate.insert(X(1), pose_1.compose(delta)); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |     } else if (i >= 2) {  // Add more poses as necessary
 | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |       auto pose_i = scenario.pose(t); | 
					
						
							|  |  |  |       initialEstimate.insert(X(i), pose_i.compose(delta)); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (i > 0) { | 
					
						
							|  |  |  |       // Add Bias variables periodically
 | 
					
						
							|  |  |  |       if (i % 5 == 0) { | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |         biasKey++; | 
					
						
							|  |  |  |         Symbol b1 = biasKey - 1; | 
					
						
							|  |  |  |         Symbol b2 = biasKey; | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |         Vector6 covvec; | 
					
						
							|  |  |  |         covvec << 0.1, 0.1, 0.1, 0.1, 0.1, 0.1; | 
					
						
							| 
									
										
										
										
											2018-10-14 04:25:58 +08:00
										 |  |  |         auto cov = noiseModel::Diagonal::Variances(covvec); | 
					
						
							|  |  |  |         auto f = boost::make_shared<BetweenFactor<imuBias::ConstantBias> >( | 
					
						
							|  |  |  |             b1, b2, imuBias::ConstantBias(), cov); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |         newgraph.add(f); | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |         initialEstimate.insert(biasKey, imuBias::ConstantBias()); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |       // Predict acceleration and gyro measurements in (actual) body frame
 | 
					
						
							|  |  |  |       auto measuredAcc = scenario.acceleration_b(t) - | 
					
						
							|  |  |  |                          scenario.rotation(t).transpose() * params->n_gravity; | 
					
						
							|  |  |  |       auto measuredOmega = scenario.omega_b(t); | 
					
						
							|  |  |  |       accum.integrateMeasurement(measuredAcc, measuredOmega, delta_t); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |       // Add Imu Factor
 | 
					
						
							| 
									
										
										
										
											2018-10-14 05:48:36 +08:00
										 |  |  |       ImuFactor imufac(X(i - 1), V(i - 1), X(i), V(i), biasKey, accum); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |       newgraph.add(imufac); | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // insert new velocity, which is wrong
 | 
					
						
							|  |  |  |       initialEstimate.insert(V(i), n_velocity); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |       accum.resetIntegration(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Incremental solution
 | 
					
						
							|  |  |  |     isam.update(newgraph, initialEstimate); | 
					
						
							|  |  |  |     result = isam.calculateEstimate(); | 
					
						
							|  |  |  |     newgraph = NonlinearFactorGraph(); | 
					
						
							|  |  |  |     initialEstimate.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-10-17 07:01:28 +08:00
										 |  |  |   GTSAM_PRINT(result); | 
					
						
							| 
									
										
										
										
											2018-10-14 03:29:07 +08:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* ************************************************************************* */ |