renamed ImuFactorExample2 to ImuFactorISAM2Example
							parent
							
								
									d79ddb6858
								
							
						
					
					
						commit
						bfbb6cb28d
					
				| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
iSAM2 example with ImuFactor.
 | 
					iSAM2 example with ImuFactor.
 | 
				
			||||||
Author: Robert Truax (C++), Frank Dellaert (Python)
 | 
					Author: Frank Dellaert, Varun Agrawal
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
# pylint: disable=invalid-name, E1101
 | 
					# pylint: disable=invalid-name, E1101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,11 @@ from __future__ import print_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import math
 | 
					import math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import gtsam
 | 
					 | 
				
			||||||
import gtsam.utils.plot as gtsam_plot
 | 
					 | 
				
			||||||
import matplotlib.pyplot as plt
 | 
					import matplotlib.pyplot as plt
 | 
				
			||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
 | 
					from mpl_toolkits.mplot3d import Axes3D  # pylint: disable=W0611
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import gtsam
 | 
				
			||||||
from gtsam import (ISAM2, BetweenFactorConstantBias, Cal3_S2,
 | 
					from gtsam import (ISAM2, BetweenFactorConstantBias, Cal3_S2,
 | 
				
			||||||
                   ConstantTwistScenario, ImuFactor, NonlinearFactorGraph,
 | 
					                   ConstantTwistScenario, ImuFactor, NonlinearFactorGraph,
 | 
				
			||||||
                   PinholeCameraCal3_S2, Point3, Pose3,
 | 
					                   PinholeCameraCal3_S2, Point3, Pose3,
 | 
				
			||||||
| 
						 | 
					@ -20,7 +21,7 @@ from gtsam import (ISAM2, BetweenFactorConstantBias, Cal3_S2,
 | 
				
			||||||
from gtsam import symbol_shorthand_B as B
 | 
					from gtsam import symbol_shorthand_B as B
 | 
				
			||||||
from gtsam import symbol_shorthand_V as V
 | 
					from gtsam import symbol_shorthand_V as V
 | 
				
			||||||
from gtsam import symbol_shorthand_X as X
 | 
					from gtsam import symbol_shorthand_X as X
 | 
				
			||||||
from mpl_toolkits.mplot3d import Axes3D  # pylint: disable=W0611
 | 
					from gtsam.utils import plot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def vector3(x, y, z):
 | 
					def vector3(x, y, z):
 | 
				
			||||||
| 
						 | 
					@ -28,46 +29,46 @@ def vector3(x, y, z):
 | 
				
			||||||
    return np.array([x, y, z], dtype=np.float)
 | 
					    return np.array([x, y, z], dtype=np.float)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def ISAM2_plot(values, fignum=0):
 | 
					 | 
				
			||||||
    """Plot poses."""
 | 
					 | 
				
			||||||
    fig = plt.figure(fignum)
 | 
					 | 
				
			||||||
    axes = fig.gca(projection='3d')
 | 
					 | 
				
			||||||
    plt.cla()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    i = 0
 | 
					 | 
				
			||||||
    min_bounds = 0, 0, 0
 | 
					 | 
				
			||||||
    max_bounds = 0, 0, 0
 | 
					 | 
				
			||||||
    while values.exists(X(i)):
 | 
					 | 
				
			||||||
        pose_i = values.atPose3(X(i))
 | 
					 | 
				
			||||||
        gtsam_plot.plot_pose3(fignum, pose_i, 10)
 | 
					 | 
				
			||||||
        position = pose_i.translation().vector()
 | 
					 | 
				
			||||||
        min_bounds = [min(v1, v2) for (v1, v2) in zip(position, min_bounds)]
 | 
					 | 
				
			||||||
        max_bounds = [max(v1, v2) for (v1, v2) in zip(position, max_bounds)]
 | 
					 | 
				
			||||||
        # max_bounds = min(pose_i.x(), max_bounds[0]), 0, 0
 | 
					 | 
				
			||||||
        i += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # draw
 | 
					 | 
				
			||||||
    axes.set_xlim3d(min_bounds[0]-1, max_bounds[0]+1)
 | 
					 | 
				
			||||||
    axes.set_ylim3d(min_bounds[1]-1, max_bounds[1]+1)
 | 
					 | 
				
			||||||
    axes.set_zlim3d(min_bounds[2]-1, max_bounds[2]+1)
 | 
					 | 
				
			||||||
    plt.pause(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IMU preintegration parameters
 | 
					 | 
				
			||||||
# Default Params for a Z-up navigation frame, such as ENU: gravity points along negative Z-axis
 | 
					 | 
				
			||||||
g = 9.81
 | 
					g = 9.81
 | 
				
			||||||
n_gravity = vector3(0, 0, -g)
 | 
					kGravity = vector3(0, 0, -g)
 | 
				
			||||||
PARAMS = gtsam.PreintegrationParams.MakeSharedU(g)
 | 
					 | 
				
			||||||
I = np.eye(3)
 | 
					 | 
				
			||||||
PARAMS.setAccelerometerCovariance(I * 0.1)
 | 
					 | 
				
			||||||
PARAMS.setGyroscopeCovariance(I * 0.1)
 | 
					 | 
				
			||||||
PARAMS.setIntegrationCovariance(I * 0.1)
 | 
					 | 
				
			||||||
PARAMS.setUse2ndOrderCoriolis(False)
 | 
					 | 
				
			||||||
PARAMS.setOmegaCoriolis(vector3(0, 0, 0))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
BIAS_COVARIANCE = gtsam.noiseModel_Isotropic.Variance(6, 0.1)
 | 
					
 | 
				
			||||||
DELTA = Pose3(Rot3.Rodrigues(0, 0, 0),
 | 
					def preintegration_parameters():
 | 
				
			||||||
              Point3(0.05, -0.10, 0.20))
 | 
					    # IMU preintegration parameters
 | 
				
			||||||
 | 
					    # Default Params for a Z-up navigation frame, such as ENU: gravity points along negative Z-axis
 | 
				
			||||||
 | 
					    PARAMS = gtsam.PreintegrationParams.MakeSharedU(g)
 | 
				
			||||||
 | 
					    I = np.eye(3)
 | 
				
			||||||
 | 
					    PARAMS.setAccelerometerCovariance(I * 0.1)
 | 
				
			||||||
 | 
					    PARAMS.setGyroscopeCovariance(I * 0.1)
 | 
				
			||||||
 | 
					    PARAMS.setIntegrationCovariance(I * 0.1)
 | 
				
			||||||
 | 
					    PARAMS.setUse2ndOrderCoriolis(False)
 | 
				
			||||||
 | 
					    PARAMS.setOmegaCoriolis(vector3(0, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BIAS_COVARIANCE = gtsam.noiseModel_Isotropic.Variance(6, 0.1)
 | 
				
			||||||
 | 
					    DELTA = Pose3(Rot3.Rodrigues(0, 0, 0),
 | 
				
			||||||
 | 
					                  Point3(0.05, -0.10, 0.20))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return PARAMS, BIAS_COVARIANCE, DELTA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_camera(radius):
 | 
				
			||||||
 | 
					    up = Point3(0, 0, 1)
 | 
				
			||||||
 | 
					    target = Point3(0, 0, 0)
 | 
				
			||||||
 | 
					    position = Point3(radius, 0, 0)
 | 
				
			||||||
 | 
					    camera = PinholeCameraCal3_S2.Lookat(position, target, up, Cal3_S2())
 | 
				
			||||||
 | 
					    return camera
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_scenario(radius, pose_0, angular_velocity, delta_t):
 | 
				
			||||||
 | 
					    """Create the set of ground-truth landmarks and poses"""
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    angular_velocity_vector = vector3(0, -angular_velocity, 0)
 | 
				
			||||||
 | 
					    linear_velocity_vector = vector3(radius * angular_velocity, 0, 0)
 | 
				
			||||||
 | 
					    scenario = ConstantTwistScenario(
 | 
				
			||||||
 | 
					        angular_velocity_vector, linear_velocity_vector, pose_0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return scenario
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def IMU_example():
 | 
					def IMU_example():
 | 
				
			||||||
| 
						 | 
					@ -75,23 +76,17 @@ def IMU_example():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Start with a camera on x-axis looking at origin
 | 
					    # Start with a camera on x-axis looking at origin
 | 
				
			||||||
    radius = 30
 | 
					    radius = 30
 | 
				
			||||||
    up = Point3(0, 0, 1)
 | 
					    camera = get_camera(radius)
 | 
				
			||||||
    target = Point3(0, 0, 0)
 | 
					 | 
				
			||||||
    position = Point3(radius, 0, 0)
 | 
					 | 
				
			||||||
    camera = PinholeCameraCal3_S2.Lookat(position, target, up, Cal3_S2())
 | 
					 | 
				
			||||||
    pose_0 = camera.pose()
 | 
					    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
 | 
					    delta_t = 1.0/18  # makes for 10 degrees per step
 | 
				
			||||||
 | 
					    angular_velocity = math.radians(180)  # rad/sec
 | 
				
			||||||
 | 
					    scenario = get_scenario(radius, pose_0, angular_velocity, delta_t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    angular_velocity_vector = vector3(0, -angular_velocity, 0)
 | 
					    PARAMS, BIAS_COVARIANCE, DELTA = preintegration_parameters()
 | 
				
			||||||
    linear_velocity_vector = vector3(radius * angular_velocity, 0, 0)
 | 
					 | 
				
			||||||
    scenario = ConstantTwistScenario(
 | 
					 | 
				
			||||||
        angular_velocity_vector, linear_velocity_vector, pose_0)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Create a factor graph
 | 
					    # Create a factor graph
 | 
				
			||||||
    newgraph = NonlinearFactorGraph()
 | 
					    graph = NonlinearFactorGraph()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Create (incremental) ISAM2 solver
 | 
					    # Create (incremental) ISAM2 solver
 | 
				
			||||||
    isam = ISAM2()
 | 
					    isam = ISAM2()
 | 
				
			||||||
| 
						 | 
					@ -104,21 +99,21 @@ def IMU_example():
 | 
				
			||||||
    # 30cm std on x,y,z 0.1 rad on roll,pitch,yaw
 | 
					    # 30cm std on x,y,z 0.1 rad on roll,pitch,yaw
 | 
				
			||||||
    noise = gtsam.noiseModel_Diagonal.Sigmas(
 | 
					    noise = gtsam.noiseModel_Diagonal.Sigmas(
 | 
				
			||||||
        np.array([0.1, 0.1, 0.1, 0.3, 0.3, 0.3]))
 | 
					        np.array([0.1, 0.1, 0.1, 0.3, 0.3, 0.3]))
 | 
				
			||||||
    newgraph.push_back(PriorFactorPose3(X(0), pose_0, noise))
 | 
					    graph.push_back(PriorFactorPose3(X(0), pose_0, noise))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Add imu priors
 | 
					    # Add imu priors
 | 
				
			||||||
    biasKey = B(0)
 | 
					    biasKey = B(0)
 | 
				
			||||||
    biasnoise = gtsam.noiseModel_Isotropic.Sigma(6, 0.1)
 | 
					    biasnoise = gtsam.noiseModel_Isotropic.Sigma(6, 0.1)
 | 
				
			||||||
    biasprior = PriorFactorConstantBias(biasKey, gtsam.imuBias_ConstantBias(),
 | 
					    biasprior = PriorFactorConstantBias(biasKey, gtsam.imuBias_ConstantBias(),
 | 
				
			||||||
                                        biasnoise)
 | 
					                                        biasnoise)
 | 
				
			||||||
    newgraph.push_back(biasprior)
 | 
					    graph.push_back(biasprior)
 | 
				
			||||||
    initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())
 | 
					    initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())
 | 
				
			||||||
    velnoise = gtsam.noiseModel_Isotropic.Sigma(3, 0.1)
 | 
					    velnoise = gtsam.noiseModel_Isotropic.Sigma(3, 0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Calculate with correct initial velocity
 | 
					    # Calculate with correct initial velocity
 | 
				
			||||||
    n_velocity = vector3(0, angular_velocity * radius, 0)
 | 
					    n_velocity = vector3(0, angular_velocity * radius, 0)
 | 
				
			||||||
    velprior = PriorFactorVector(V(0), n_velocity, velnoise)
 | 
					    velprior = PriorFactorVector(V(0), n_velocity, velnoise)
 | 
				
			||||||
    newgraph.push_back(velprior)
 | 
					    graph.push_back(velprior)
 | 
				
			||||||
    initialEstimate.insert(V(0), n_velocity)
 | 
					    initialEstimate.insert(V(0), n_velocity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    accum = gtsam.PreintegratedImuMeasurements(PARAMS)
 | 
					    accum = gtsam.PreintegratedImuMeasurements(PARAMS)
 | 
				
			||||||
| 
						 | 
					@ -140,33 +135,36 @@ def IMU_example():
 | 
				
			||||||
                biasKey += 1
 | 
					                biasKey += 1
 | 
				
			||||||
                factor = BetweenFactorConstantBias(
 | 
					                factor = BetweenFactorConstantBias(
 | 
				
			||||||
                    biasKey - 1, biasKey, gtsam.imuBias_ConstantBias(), BIAS_COVARIANCE)
 | 
					                    biasKey - 1, biasKey, gtsam.imuBias_ConstantBias(), BIAS_COVARIANCE)
 | 
				
			||||||
                newgraph.add(factor)
 | 
					                graph.add(factor)
 | 
				
			||||||
                initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())
 | 
					                initialEstimate.insert(biasKey, gtsam.imuBias_ConstantBias())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Predict acceleration and gyro measurements in (actual) body frame
 | 
					            # Predict acceleration and gyro measurements in (actual) body frame
 | 
				
			||||||
            nRb = scenario.rotation(t).matrix()
 | 
					            nRb = scenario.rotation(t).matrix()
 | 
				
			||||||
            bRn = np.transpose(nRb)
 | 
					            bRn = np.transpose(nRb)
 | 
				
			||||||
            measuredAcc = scenario.acceleration_b(t) - np.dot(bRn, n_gravity)
 | 
					            measuredAcc = scenario.acceleration_b(t) - np.dot(bRn, kGravity)
 | 
				
			||||||
            measuredOmega = scenario.omega_b(t)
 | 
					            measuredOmega = scenario.omega_b(t)
 | 
				
			||||||
            accum.integrateMeasurement(measuredAcc, measuredOmega, delta_t)
 | 
					            accum.integrateMeasurement(measuredAcc, measuredOmega, delta_t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Add Imu Factor
 | 
					            # Add Imu Factor
 | 
				
			||||||
            imufac = ImuFactor(X(i - 1), V(i - 1), X(i), V(i), biasKey, accum)
 | 
					            imufac = ImuFactor(X(i - 1), V(i - 1), X(i), V(i), biasKey, accum)
 | 
				
			||||||
            newgraph.add(imufac)
 | 
					            graph.add(imufac)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # insert new velocity, which is wrong
 | 
					            # insert new velocity, which is wrong
 | 
				
			||||||
            initialEstimate.insert(V(i), n_velocity)
 | 
					            initialEstimate.insert(V(i), n_velocity)
 | 
				
			||||||
            accum.resetIntegration()
 | 
					            accum.resetIntegration()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Incremental solution
 | 
					        # Incremental solution
 | 
				
			||||||
        isam.update(newgraph, initialEstimate)
 | 
					        isam.update(graph, initialEstimate)
 | 
				
			||||||
        result = isam.calculateEstimate()
 | 
					        result = isam.calculateEstimate()
 | 
				
			||||||
        ISAM2_plot(result)
 | 
					        plot.plot_incremental_trajectory(0, result,
 | 
				
			||||||
 | 
					                                         start=i, scale=3, time_interval=0.01)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # reset
 | 
					        # reset
 | 
				
			||||||
        newgraph = NonlinearFactorGraph()
 | 
					        graph = NonlinearFactorGraph()
 | 
				
			||||||
        initialEstimate.clear()
 | 
					        initialEstimate.clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    plt.show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    IMU_example()
 | 
					    IMU_example()
 | 
				
			||||||
		Loading…
	
		Reference in New Issue