| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  | function [ graph projectionFactorSeenBy] = covarianceAnalysisCreateFactorGraph( measurements, values, noiseModels, measurementNoise, options, metadata)
 | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  | % Create a factor graph based on provided measurements, values, and noises. | 
					
						
							|  |  |  | % Used for covariance analysis scripts. | 
					
						
							|  |  |  | % 'options' contains fields for including various factor types. | 
					
						
							|  |  |  | % 'metadata' is a storage variable for miscellaneous factor-specific values | 
					
						
							|  |  |  | % Authors: Luca Carlone, David Jensen | 
					
						
							|  |  |  | % Date: 2014/04/16 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import gtsam.*; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | graph = NonlinearFactorGraph; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  | % Iterate through the trajectory | 
					
						
							|  |  |  | for i=0:length(measurements) | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |   % Get the current pose | 
					
						
							|  |  |  |   currentPoseKey = symbol('x', i); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |   currentPose = values.at(currentPoseKey); | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |    | 
					
						
							|  |  |  |   if i==0 | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |     %% first time step, add priors | 
					
						
							| 
									
										
										
										
											2014-04-17 04:20:10 +08:00
										 |  |  |     % Pose prior (poses used for all factors) | 
					
						
							| 
									
										
										
										
											2014-05-16 03:57:22 +08:00
										 |  |  |     noisyInitialPoseVector = Pose3.Logmap(currentPose) + measurementNoise.poseNoiseVector .* randn(6,1);  | 
					
						
							| 
									
										
										
										
											2014-05-16 01:21:35 +08:00
										 |  |  |     initialPose = Pose3.Expmap(noisyInitialPoseVector); | 
					
						
							| 
									
										
										
										
											2014-04-17 04:20:10 +08:00
										 |  |  |     graph.add(PriorFactorPose3(currentPoseKey, initialPose, noiseModels.noisePose)); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     % IMU velocity and bias priors | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     if options.includeIMUFactors == 1 | 
					
						
							|  |  |  |       currentVelKey = symbol('v', 0); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       currentVel = values.at(currentVelKey).vector; | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |       graph.add(PriorFactorLieVector(currentVelKey, LieVector(currentVel), noiseModels.noiseVel)); | 
					
						
							| 
									
										
										
										
											2014-04-18 02:11:18 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       currentBiasKey = symbol('b', 0); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       currentBias = values.at(currentBiasKey); | 
					
						
							| 
									
										
										
										
											2014-04-18 02:11:18 +08:00
										 |  |  |       graph.add(PriorFactorConstantBias(currentBiasKey, currentBias, noiseModels.noisePriorBias)); | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |     %% Create a SmartProjectionFactor for each landmark | 
					
						
							| 
									
										
										
										
											2014-05-16 03:57:22 +08:00
										 |  |  |     projectionFactorSeenBy = []; | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     if options.includeCameraFactors == 1 | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |       for j=1:options.numberOfLandmarks | 
					
						
							| 
									
										
										
										
											2014-05-16 03:57:22 +08:00
										 |  |  |         SmartProjectionFactors(j) = SmartProjectionPose3Factor(0.01); | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |         % Use constructor with default values, but express the pose of the | 
					
						
							|  |  |  |         % camera as a 90 degree rotation about the X axis | 
					
						
							|  |  |  | %         SmartProjectionFactors(j) = SmartProjectionPose3Factor( ... | 
					
						
							|  |  |  | %             1, ...      % rankTol | 
					
						
							|  |  |  | %             -1, ...     % linThreshold | 
					
						
							|  |  |  | %             false, ...  % manageDegeneracy | 
					
						
							|  |  |  | %             false, ...  % enableEPI | 
					
						
							|  |  |  | %             metadata.camera.bodyPoseCamera);    % Pose of camera in body frame | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |       projectionFactorSeenBy = zeros(options.numberOfLandmarks,1); | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     %% Add Between factors | 
					
						
							|  |  |  |     if options.includeBetweenFactors == 1 | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       prevPoseKey = symbol('x', i-1); | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |       % Create the noisy pose estimate | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       deltaPose = Pose3.Expmap(measurements(i).deltaVector ... | 
					
						
							| 
									
										
										
										
											2014-04-17 04:20:10 +08:00
										 |  |  |         + (measurementNoise.poseNoiseVector .* randn(6,1)));  % added noise | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |       % Add the between factor to the graph | 
					
						
							|  |  |  |       graph.add(BetweenFactorPose3(prevPoseKey, currentPoseKey, deltaPose, noiseModels.noisePose)); | 
					
						
							|  |  |  |     end % end of Between pose factor creation | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     %% Add IMU factors | 
					
						
							|  |  |  |     if options.includeIMUFactors == 1 | 
					
						
							|  |  |  |       % Update keys | 
					
						
							|  |  |  |       currentVelKey = symbol('v', i);  % not used if includeIMUFactors is false | 
					
						
							|  |  |  |       currentBiasKey = symbol('b', i); % not used if includeIMUFactors is false | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       if options.imuFactorType == 1 | 
					
						
							| 
									
										
										
										
											2014-04-18 04:23:29 +08:00
										 |  |  |         use2ndOrderIntegration = true; | 
					
						
							| 
									
										
										
										
											2014-04-17 22:09:53 +08:00
										 |  |  |         % Initialize preintegration | 
					
						
							|  |  |  |         imuMeasurement = gtsam.ImuFactorPreintegratedMeasurements(... | 
					
						
							|  |  |  |           metadata.imu.zeroBias, ... | 
					
						
							|  |  |  |           metadata.imu.AccelerometerSigma.^2 * eye(3), ... | 
					
						
							|  |  |  |           metadata.imu.GyroscopeSigma.^2 * eye(3), ... | 
					
						
							| 
									
										
										
										
											2014-04-18 04:23:29 +08:00
										 |  |  |           metadata.imu.IntegrationSigma.^2 * eye(3), ... | 
					
						
							|  |  |  |           use2ndOrderIntegration); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |         % Generate IMU measurements with noise | 
					
						
							|  |  |  |         for j=1:length(measurements(i).imu) % all measurements to preintegrate | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |           accelNoise = (measurementNoise.imu.accelNoiseVector .* randn(3,1)); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |           imuAccel = measurements(i).imu(j).accel ... | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |             + accelNoise ...  % added noise | 
					
						
							| 
									
										
										
										
											2014-04-18 10:21:22 +08:00
										 |  |  |             + metadata.imu.accelConstantBiasVector;     % constant bias | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |          | 
					
						
							|  |  |  |           gyroNoise = (measurementNoise.imu.gyroNoiseVector .* randn(3,1)); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |           imuGyro = measurements(i).imu(j).gyro ... | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |             + gyroNoise ...   % added noise | 
					
						
							| 
									
										
										
										
											2014-04-18 10:21:22 +08:00
										 |  |  |             + metadata.imu.gyroConstantBiasVector;      % constant bias | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |            | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |           % Used for debugging | 
					
						
							|  |  |  |           %fprintf('  A: (meas)[%f %f %f] + (noise)[%f %f %f] + (bias)[%f %f %f] = [%f %f %f]\n', ... | 
					
						
							|  |  |  |           %    measurements(i).imu(j).accel(1), measurements(i).imu(j).accel(2), measurements(i).imu(j).accel(3), ... | 
					
						
							|  |  |  |           %    accelNoise(1), accelNoise(2), accelNoise(3), ... | 
					
						
							|  |  |  |           %    metadata.imu.accelConstantBiasVector(1), metadata.imu.accelConstantBiasVector(2), metadata.imu.accelConstantBiasVector(3), ... | 
					
						
							|  |  |  |           %    imuAccel(1), imuAccel(2), imuAccel(3)); | 
					
						
							|  |  |  |           %fprintf('  G: (meas)[%f %f %f] + (noise)[%f %f %f] + (bias)[%f %f %f] = [%f %f %f]\n', ... | 
					
						
							|  |  |  |           %    measurements(i).imu(j).gyro(1), measurements(i).imu(j).gyro(2), measurements(i).imu(j).gyro(3), ... | 
					
						
							|  |  |  |           %    gyroNoise(1), gyroNoise(2), gyroNoise(3), ... | 
					
						
							|  |  |  |           %    metadata.imu.gyroConstantBiasVector(1), metadata.imu.gyroConstantBiasVector(2), metadata.imu.gyroConstantBiasVector(3), ... | 
					
						
							|  |  |  |           %    imuGyro(1), imuGyro(2), imuGyro(3)); | 
					
						
							|  |  |  |            | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |           % Preintegrate | 
					
						
							|  |  |  |           imuMeasurement.integrateMeasurement(imuAccel, imuGyro, measurements(i).imu(j).deltaT); | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2014-04-18 04:00:18 +08:00
										 |  |  |         %imuMeasurement.print('imuMeasurement'); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         % Add Imu factor | 
					
						
							|  |  |  |         graph.add(ImuFactor(currentPoseKey-1, currentVelKey-1, currentPoseKey, currentVelKey, ... | 
					
						
							|  |  |  |           currentBiasKey-1, imuMeasurement, metadata.imu.g, metadata.imu.omegaCoriolis)); | 
					
						
							|  |  |  |         % Add between factor on biases | 
					
						
							|  |  |  |         graph.add(BetweenFactorConstantBias(currentBiasKey-1, currentBiasKey, metadata.imu.zeroBias, ... | 
					
						
							| 
									
										
										
										
											2014-04-25 05:01:08 +08:00
										 |  |  |           noiseModels.noiseBiasBetween)); | 
					
						
							| 
									
										
										
										
											2014-04-17 22:09:53 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-04-18 04:14:32 +08:00
										 |  |  |            | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       if options.imuFactorType == 2 | 
					
						
							| 
									
										
										
										
											2014-04-25 05:01:08 +08:00
										 |  |  |         use2ndOrderIntegration = true; | 
					
						
							| 
									
										
										
										
											2014-04-23 20:58:50 +08:00
										 |  |  |         % Initialize preintegration | 
					
						
							|  |  |  |         imuMeasurement = gtsam.CombinedImuFactorPreintegratedMeasurements(... | 
					
						
							|  |  |  |           metadata.imu.zeroBias, ... | 
					
						
							|  |  |  |           metadata.imu.AccelerometerSigma.^2 * eye(3), ... | 
					
						
							|  |  |  |           metadata.imu.GyroscopeSigma.^2 * eye(3), ... | 
					
						
							|  |  |  |           metadata.imu.IntegrationSigma.^2 * eye(3), ... | 
					
						
							| 
									
										
										
										
											2014-04-25 05:01:08 +08:00
										 |  |  |           metadata.imu.BiasAccelerometerSigma.^2 * eye(3), ...  % how bias changes over time | 
					
						
							|  |  |  |           metadata.imu.BiasGyroscopeSigma.^2 * eye(3), ...      % how bias changes over time | 
					
						
							|  |  |  |           diag(metadata.imu.BiasAccOmegaInit.^2), ...           % prior on bias | 
					
						
							|  |  |  |           use2ndOrderIntegration); | 
					
						
							| 
									
										
										
										
											2014-04-23 20:58:50 +08:00
										 |  |  |         % Generate IMU measurements with noise | 
					
						
							|  |  |  |         for j=1:length(measurements(i).imu) % all measurements to preintegrate | 
					
						
							|  |  |  |           imuAccel = measurements(i).imu(j).accel ... | 
					
						
							|  |  |  |             + (measurementNoise.imu.accelNoiseVector .* randn(3,1))...  % added noise | 
					
						
							|  |  |  |             + metadata.imu.accelConstantBiasVector;     % constant bias | 
					
						
							|  |  |  |           imuGyro = measurements(i).imu(j).gyro ... | 
					
						
							|  |  |  |             + (measurementNoise.imu.gyroNoiseVector .* randn(3,1))...   % added noise | 
					
						
							|  |  |  |             + metadata.imu.gyroConstantBiasVector;      % constant bias | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           % Preintegrate | 
					
						
							|  |  |  |           imuMeasurement.integrateMeasurement(imuAccel, imuGyro, measurements(i).imu(j).deltaT); | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2014-04-23 20:58:50 +08:00
										 |  |  |         % Add Imu factor | 
					
						
							|  |  |  |         graph.add(CombinedImuFactor( ... | 
					
						
							|  |  |  |           currentPoseKey-1, currentVelKey-1, ... | 
					
						
							|  |  |  |           currentPoseKey, currentVelKey, ... | 
					
						
							|  |  |  |           currentBiasKey-1, currentBiasKey, ... | 
					
						
							|  |  |  |           imuMeasurement, ... | 
					
						
							| 
									
										
										
										
											2014-04-30 03:46:43 +08:00
										 |  |  |           metadata.imu.g, metadata.imu.omegaCoriolis)); | 
					
						
							| 
									
										
										
										
											2014-04-18 03:23:01 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |     end % end of IMU factor creation | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |     %% Build Camera Factors | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |     if options.includeCameraFactors == 1         | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |       for j = 1:length(measurements(i).landmarks) | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |         cameraMeasurmentNoise = measurementNoise.cameraNoiseVector .* randn(2,1); | 
					
						
							|  |  |  |         cameraPixelMeasurement = measurements(i).landmarks(j).vector; | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |         % Only add the measurement if it is in the image frame (based on calibration) | 
					
						
							|  |  |  |         if(cameraPixelMeasurement(1) > 0 && cameraPixelMeasurement(2) > 0 ... | 
					
						
							|  |  |  |              && cameraPixelMeasurement(1) < 2*metadata.camera.calibration.px ... | 
					
						
							|  |  |  |              && cameraPixelMeasurement(2) < 2*metadata.camera.calibration.py) | 
					
						
							| 
									
										
										
										
											2014-05-09 03:27:32 +08:00
										 |  |  |           cameraPixelMeasurement = cameraPixelMeasurement + cameraMeasurmentNoise; | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |           SmartProjectionFactors(j).add( ... | 
					
						
							|  |  |  |              Point2(cameraPixelMeasurement), ... | 
					
						
							|  |  |  |              currentPoseKey, noiseModels.noiseCamera, ... | 
					
						
							|  |  |  |              metadata.camera.calibration); | 
					
						
							|  |  |  |            projectionFactorSeenBy(j) = projectionFactorSeenBy(j)+1; | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end % end of Camera factor creation | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2014-04-24 00:39:47 +08:00
										 |  |  |     %% Add GPS factors | 
					
						
							| 
									
										
										
										
											2014-04-24 04:06:03 +08:00
										 |  |  |     if options.includeGPSFactors == 1 && i >= options.gpsStartPose | 
					
						
							| 
									
										
										
										
											2014-04-24 02:45:17 +08:00
										 |  |  |       gpsPosition = measurements(i).gpsPositionVector ... | 
					
						
							|  |  |  |           + measurementNoise.gpsNoiseVector .* randn(3,1); | 
					
						
							|  |  |  |       graph.add(PriorFactorPose3(currentPoseKey, ... | 
					
						
							|  |  |  |           Pose3(currentPose.rotation, Point3(gpsPosition)), ... | 
					
						
							|  |  |  |           noiseModels.noiseGPS));  | 
					
						
							| 
									
										
										
										
											2014-04-24 00:39:47 +08:00
										 |  |  |     end % end of GPS factor creation | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2014-04-18 02:11:18 +08:00
										 |  |  |   end % end of else (i=0) | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  |    | 
					
						
							|  |  |  | end % end of for over trajectory | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  | %% Add Camera Factors to the graph | 
					
						
							| 
									
										
										
										
											2014-05-16 01:21:35 +08:00
										 |  |  | % Only factors for landmarks that have been viewed at least once are added | 
					
						
							|  |  |  | % to the graph | 
					
						
							| 
									
										
										
										
											2014-05-16 03:57:22 +08:00
										 |  |  | %[find(projectionFactorSeenBy ~= 0) projectionFactorSeenBy(find(projectionFactorSeenBy ~= 0))] | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  | if options.includeCameraFactors == 1 | 
					
						
							|  |  |  |   for j = 1:options.numberOfLandmarks | 
					
						
							| 
									
										
										
										
											2014-05-16 01:21:35 +08:00
										 |  |  |     if projectionFactorSeenBy(j) > 0 | 
					
						
							| 
									
										
										
										
											2014-05-15 22:01:53 +08:00
										 |  |  |       graph.add(SmartProjectionFactors(j)); | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-18 02:11:18 +08:00
										 |  |  | end % end of function | 
					
						
							| 
									
										
										
										
											2014-04-17 03:01:12 +08:00
										 |  |  | 
 |