Example #1
0
 def addPrior(self, i: int, graph: gtsam.NonlinearFactorGraph):
     """Add a prior on the navigation state at time `i`."""
     state = self.scenario.navState(i)
     graph.push_back(
         gtsam.PriorFactorPose3(X(i), state.pose(), self.priorNoise))
     graph.push_back(
         gtsam.PriorFactorVector(V(i), state.velocity(), self.velNoise))
Example #2
0
    def test_PriorFactor(self):
        values = gtsam.Values()

        key = 5
        priorPose3 = gtsam.Pose3()
        model = gtsam.noiseModel_Unit.Create(6)
        factor = gtsam.PriorFactorPose3(key, priorPose3, model)
        values.insert(key, priorPose3)
        self.assertEqual(factor.error(values), 0)

        key = 3
        priorVector = np.array([0., 0., 0.])
        model = gtsam.noiseModel_Unit.Create(3)
        factor = gtsam.PriorFactorVector(key, priorVector, model)
        values.insert(key, priorVector)
        self.assertEqual(factor.error(values), 0)
    ###############################    Build the factor graph   ####################################

    factor_graph = gtsam.NonlinearFactorGraph()

    # A technical hack for defining variable names in GTSAM python bindings
    def symbol(letter, index):
        return int(gtsam.symbol(ord(letter), index))


    # Add a prior factor on the initial position
    factor_graph.push_back(
        gtsam.PriorFactorPose3(symbol('x', 0), params.initial_pose,
                               params.initial_pose_covariance))
    factor_graph.push_back(
        gtsam.PriorFactorVector(symbol('v', 0), params.initial_velocity,
                                params.initial_velocity_covariance))

    # Add IMU factors (or "motion model"/"transition" factors).
    # Ideally, we would add factors between every pair (xᵢ₋₁, xᵢ). But, to save computations,
    # we will add factors between pairs (x₀, xₖ), (xₖ, x₂ₖ) etc., and as an IMU "measurement"
    # between e.g. x₀ and xₖ we will use combined (pre-integrated) measurements `0, 1, ..., k-1`.
    # Below, `k == PREINTEGRATE_EVERY_STEPS`.
    PREINTEGRATE_EVERY_STEPS = 25

    # For code generalization, create pairs (0, k), (k, 2k), (2k, 3k), ..., (mk, N-1)
    preintegration_steps = list(
        range(0, len(imu_measurements), PREINTEGRATE_EVERY_STEPS))
    if preintegration_steps[-1] != len(
            imu_measurements) - 1:  # don't miss the last measurements
        preintegration_steps.append(len(imu_measurements) - 1)
    # An iterator over those pairs
Example #4
0
vv2.insert(4, np.array([4., 2., 1]))
vv2.print_(b"vv2:")
vv.print_(b"vv:")

vv.insert(4, np.array([1., 2., 4.]))
vv.print_(b"vv:")
vv3 = vv.add(vv2)

vv3.print_(b"vv3:")

values = gtsam.Values()
values.insert(1, gtsam.Point3())
values.insert(2, gtsam.Rot3())
values.print_(b"values:")

factor = gtsam.PriorFactorVector(1, np.array([1., 2., 3.]), diag)
print "Prior factor vector: ", factor

keys = gtsam.KeyVector()

keys.push_back(1)
keys.push_back(2)
print 'size: ', keys.size()
print keys.at(0)
print keys.at(1)

noise = gtsam.noiseModel_Isotropic.Precision(2, 3.0)
noise.print_('noise:')
print 'noise print:', noise
f = gtsam.JacobianFactor(7, np.ones([2, 2]), model=noise, b=np.ones(2))
print 'JacobianFactor(7):\n', f
Example #5
0
def IMU_example():
    """Run iSAM 2 example with IMU factor."""

    # Start with a camera on x-axis looking at origin
    radius = 30
    up = gtsam.Point3(0, 0, 1)
    target = gtsam.Point3(0, 0, 0)
    position = gtsam.Point3(radius, 0, 0)
    camera = gtsam.SimpleCamera.Lookat(position, target, up, gtsam.Cal3_S2())
    pose_0 = camera.pose()

    # Create the set of ground-truth landmarks and poses
    angular_velocity = math.radians(180)  # rad/sec
    delta_t = 1.0/18  # makes for 10 degrees per step

    angular_velocity_vector = vector3(0, -angular_velocity, 0)
    linear_velocity_vector = vector3(radius * angular_velocity, 0, 0)
    scenario = gtsam.ConstantTwistScenario(
        angular_velocity_vector, linear_velocity_vector, pose_0)

    # Create a factor graph
    newgraph = gtsam.NonlinearFactorGraph()

    # Create (incremental) ISAM2 solver
    isam = gtsam.ISAM2()

    # Create the initial estimate to the solution
    # Intentionally initialize the variables off from the ground truth
    initialEstimate = gtsam.Values()

    # Add a prior on pose x0. This indirectly specifies where the origin is.
    # 30cm std on x,y,z 0.1 rad on roll,pitch,yaw
    noise = gtsam.noiseModel_Diagonal.Sigmas(
        np.array([0.3, 0.3, 0.3, 0.1, 0.1, 0.1]))
    newgraph.push_back(gtsam.PriorFactorPose3(X(0), pose_0, noise))

    # Add imu priors
    biasKey = gtsam.symbol(ord('b'), 0)
    biasnoise = gtsam.noiseModel_Isotropic.Sigma(6, 0.1)
    biasprior = gtsam.PriorFactorConstantBias(biasKey, gtsam.imuBias_ConstantBias(),
                                              biasnoise)
    newgraph.push_back(biasprior)
    initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())
    velnoise = gtsam.noiseModel_Isotropic.Sigma(3, 0.1)

    # Calculate with correct initial velocity
    n_velocity = vector3(0, angular_velocity * radius, 0)
    velprior = gtsam.PriorFactorVector(V(0), n_velocity, velnoise)
    newgraph.push_back(velprior)
    initialEstimate.insert(V(0), n_velocity)

    accum = gtsam.PreintegratedImuMeasurements(PARAMS)

    # Simulate poses and imu measurements, adding them to the factor graph
    for i in range(80):
        t = i * delta_t  # simulation time
        if i == 0:  # First time add two poses
            pose_1 = scenario.pose(delta_t)
            initialEstimate.insert(X(0), pose_0.compose(DELTA))
            initialEstimate.insert(X(1), pose_1.compose(DELTA))
        elif i >= 2:  # Add more poses as necessary
            pose_i = scenario.pose(t)
            initialEstimate.insert(X(i), pose_i.compose(DELTA))

        if i > 0:
            # Add Bias variables periodically
            if i % 5 == 0:
                biasKey += 1
                factor = gtsam.BetweenFactorConstantBias(
                    biasKey - 1, biasKey, gtsam.imuBias_ConstantBias(), BIAS_COVARIANCE)
                newgraph.add(factor)
                initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())

            # Predict acceleration and gyro measurements in (actual) body frame
            nRb = scenario.rotation(t).matrix()
            bRn = np.transpose(nRb)
            measuredAcc = scenario.acceleration_b(t) - np.dot(bRn, n_gravity)
            measuredOmega = scenario.omega_b(t)
            accum.integrateMeasurement(measuredAcc, measuredOmega, delta_t)

            # Add Imu Factor
            imufac = gtsam.ImuFactor(
                X(i - 1), V(i - 1), X(i), V(i), biasKey, accum)
            newgraph.add(imufac)

            # insert new velocity, which is wrong
            initialEstimate.insert(V(i), n_velocity)
            accum.resetIntegration()

        # Incremental solution
        isam.update(newgraph, initialEstimate)
        result = isam.calculateEstimate()
        ISAM2_plot(result)

        # reset
        newgraph = gtsam.NonlinearFactorGraph()
        initialEstimate.clear()
Example #6
0
 def addPrior(self, i, graph):
     state = self.scenario.navState(i)
     graph.push_back(gtsam.PriorFactorPose3(
         X(i), state.pose(), self.priorNoise))
     graph.push_back(gtsam.PriorFactorVector(
         V(i), state.velocity(), self.velNoise))
Example #7
0
    def add_imu_measurements(self,
                             measured_poses,
                             measured_acc,
                             measured_omega,
                             measured_vel,
                             delta_t,
                             n_skip,
                             initial_poses=None):

        n_frames = measured_poses.shape[0]

        # Check if sizes are correct
        assert measured_poses.shape[0] == n_frames
        assert measured_acc.shape[0] == n_frames
        assert measured_vel.shape[0] == n_frames

        # Pose prior
        pose_key = X(0)
        pose_noise = gtsam.noiseModel.Diagonal.Sigmas(
            np.array([0.2, 0.2, 0.2, 0.2, 0.2, 0.2]))
        pose_0 = gtsam.Pose3(measured_poses[0])
        self.graph.push_back(
            gtsam.PriorFactorPose3(pose_key, pose_0, pose_noise))

        self.initial_estimate.insert(pose_key, gtsam.Pose3(measured_poses[0]))

        # IMU prior
        bias_key = B(0)
        bias_noise = gtsam.noiseModel.Isotropic.Sigma(6, 0.5)
        self.graph.push_back(
            gtsam.PriorFactorConstantBias(bias_key,
                                          gtsam.imuBias.ConstantBias(),
                                          bias_noise))

        self.initial_estimate.insert(bias_key, gtsam.imuBias.ConstantBias())

        # Velocity prior
        velocity_key = V(0)
        velocity_noise = gtsam.noiseModel.Isotropic.Sigma(3, .5)
        velocity_0 = measured_vel[0]
        self.graph.push_back(
            gtsam.PriorFactorVector(velocity_key, velocity_0, velocity_noise))

        self.initial_estimate.insert(velocity_key, velocity_0)

        # Preintegrator
        accum = gtsam.PreintegratedImuMeasurements(self.IMU_PARAMS)

        # Add measurements to factor graph
        for i in range(1, n_frames):
            accum.integrateMeasurement(measured_acc[i], measured_omega[i],
                                       delta_t[i - 1])
            if i % n_skip == 0:
                pose_key += 1
                DELTA = gtsam.Pose3(
                    gtsam.Rot3.Rodrigues(0, 0, 0.1 * np.random.randn()),
                    gtsam.Point3(4 * np.random.randn(), 4 * np.random.randn(),
                                 4 * np.random.randn()))
                self.initial_estimate.insert(
                    pose_key,
                    gtsam.Pose3(measured_poses[i]).compose(DELTA))

                velocity_key += 1
                self.initial_estimate.insert(velocity_key, measured_vel[i])

                bias_key += 1
                self.graph.add(
                    gtsam.BetweenFactorConstantBias(
                        bias_key - 1, bias_key, gtsam.imuBias.ConstantBias(),
                        self.BIAS_COVARIANCE))
                self.initial_estimate.insert(bias_key,
                                             gtsam.imuBias.ConstantBias())

                # Add IMU Factor
                self.graph.add(
                    gtsam.ImuFactor(pose_key - 1, velocity_key - 1, pose_key,
                                    velocity_key, bias_key, accum))

                # Reset preintegration
                accum.resetIntegration()
Example #8
0
            except StopIteration:
                pass

        # Accumulate the current measurement
        current_preintegrated_IMU.integrateMeasurement(measured_acceleration,
                                                       measured_angular_vel,
                                                       dt[i])

    # Add a prior factor on the initial state
    factor_graph.push_back(
        gtsam.PriorFactorPose3(symbol('x', preintegration_steps[0]),
                               params.initial_state.pose(),
                               params.initial_pose_covariance))
    factor_graph.push_back(
        gtsam.PriorFactorVector(symbol('v', preintegration_steps[0]),
                                params.initial_state.velocity(),
                                params.initial_velocity_covariance))
    factor_graph.push_back(
        gtsam.PriorFactorConstantBias(symbol('b', 0), params.IMU_bias,
                                      params.IMU_bias_covariance))

    if USE_VISUAL_FACTORS:
        factor_graph.push_back(
            gtsam.PriorFactorPoint3(symbol('m', 0), gtsam.Point3(1, 0, 0),
                                    gtsam.noiseModel_Isotropic.Sigma(3, 0.05)))

    # Other example priors, e.g. a constraint that the intial and the final states should be roughly identical:
    factor_graph.push_back(
        gtsam.PriorFactorPose3(symbol('x', preintegration_steps[-1]),
                               params.initial_state.pose(),
                               params.initial_pose_covariance))
Example #9
0
	def __init__(self, params):
		""" Initialize variables """
		self.imu_meas_predict = [] # IMU measurements for pose prediction
		self.imu_opt_meas = [] # IMU measurements for pose prediction between measurement updates
		self.imu_samples = [] # imu samples
		self.opt_meas = [] # optimizes measurements
		self.__opt_meas_buffer_time = params['opt_meas_buffer_time']

		""" IMU Preintegration """
		# IMU preintegration parameters
		self.imu_preint_params = gtsam.PreintegrationParams(np.asarray(params['g']))
		self.imu_preint_params.setAccelerometerCovariance(np.eye(3) * np.power(params['acc_nd_sigma'], 2))
		self.imu_preint_params.setGyroscopeCovariance(np.eye(3) * np.power(params['acc_nd_sigma'], 2))
		self.imu_preint_params.setIntegrationCovariance(np.eye(3) * params['int_cov_sigma']**2)
		self.imu_preint_params.setUse2ndOrderCoriolis(params['setUse2ndOrderCoriolis'])
		self.imu_preint_params.setOmegaCoriolis(np.array(params['omega_coriolis']))

		""" Initialize Parameters """
		# ISAM2 initialization
		isam2_params = gtsam.ISAM2Params()
		isam2_params.setRelinearizeThreshold(params['relinearize_th'])
		isam2_params.setRelinearizeSkip(params['relinearize_skip'])
		isam2_params.setFactorization(params['factorization'])
		# self.isam2 = gtsam.ISAM2(isam2_params)
		self.isam2 = gtsam.ISAM2()
		self.new_factors = gtsam.NonlinearFactorGraph()
		self.new_initial_ests = gtsam.Values()
		self.min_imu_sample = 2 # minimum imu sample count needed for integration
		# ISAM2 keys
		self.poseKey = gtsam.symbol(ord('x'), 0)
		self.velKey = gtsam.symbol(ord('v'), 0)
		self.biasKey = gtsam.symbol(ord('b'), 0)

		""" Set initial variables """
		# Initial state
		self.last_opt_time = self.current_time = 0
		self.current_global_pose = numpy_pose_to_gtsam(
			params['init_pos'], 
			params['init_ori'])
		self.current_global_vel = np.asarray(
			params['init_vel'])
		self.current_bias = gtsam.imuBias_ConstantBias(
			np.asarray(params['init_acc_bias']),
			np.asarray(params['init_gyr_bias']))
		self.imu_accum = gtsam.PreintegratedImuMeasurements(self.imu_preint_params)
		# uncertainty of the initial state
		self.init_pos_cov = gtsam.noiseModel_Isotropic.Sigmas(np.array([
			params['init_ori_cov'], params['init_ori_cov'], params['init_ori_cov'],
			params['init_pos_cov'], params['init_pos_cov'], params['init_pos_cov']]))
		self.init_vel_cov = gtsam.noiseModel_Isotropic.Sigmas(np.array([
			params['init_vel_cov'], params['init_vel_cov'], params['init_vel_cov']]))
		self.init_bias_cov = gtsam.noiseModel_Isotropic.Sigmas(np.array([
			params['init_acc_bias_cov'], params['init_acc_bias_cov'], params['init_acc_bias_cov'],
			params['init_gyr_bias_cov'], params['init_gyr_bias_cov'], params['init_gyr_bias_cov']]))
		# measurement noise
		self.dvl_cov = gtsam.noiseModel_Isotropic.Sigmas(np.asarray(
			params['dvl_cov']))
		self.bar_cov = gtsam.noiseModel_Isotropic.Sigmas(np.asarray(
			params['bar_cov']))
		self.bias_cov = gtsam.noiseModel_Isotropic.Sigmas(np.concatenate((
			params['sigma_acc_bias_evol'],
			params['sigma_gyr_bias_evol'])))

		""" Set initial state """
		# Initial factors
		prior_pose_factor = gtsam.PriorFactorPose3(
			self.poseKey,
			self.current_global_pose,
			self.init_pos_cov)
		self.new_factors.add(prior_pose_factor)
		prior_vel_factor = gtsam.PriorFactorVector(
			self.velKey,
			self.current_global_vel,
			self.init_vel_cov)
		self.new_factors.add(prior_vel_factor)
		prior_bias_factor = gtsam.PriorFactorConstantBias(
			self.biasKey,
			self.current_bias,
			self.init_bias_cov)
		self.new_factors.add(prior_bias_factor)
		# Initial estimates
		self.new_initial_ests.insert(self.poseKey, self.current_global_pose)
		self.new_initial_ests.insert(self.velKey, self.current_global_vel)
		self.new_initial_ests.insert(self.biasKey, self.current_bias)