Пример #1
0
    def test_F(self):
        w_hat = np.array([1.0, 2.0, 3.0])
        q_hat = np.array([0.0, 0.0, 0.0, 1.0])
        a_hat = np.array([1.0, 2.0, 3.0])
        w_G = np.array([0.1, 0.1, 0.1])

        F = self.imu_state.F(w_hat, q_hat, a_hat, w_G)

        # -- First row --
        self.assertTrue(np_equal(F[0:3, 0:3], -skew(w_hat)))
        self.assertTrue(np_equal(F[0:3, 3:6], -np.eye(3)))
        # -- Third Row --
        self.assertTrue(np_equal(F[6:9, 0:3], dot(-C(q_hat).T, skew(a_hat))))
        self.assertTrue(np_equal(F[6:9, 6:9], -2.0 * skew(w_G)))
        self.assertTrue(np_equal(F[6:9, 9:12], -C(q_hat).T))
        self.assertTrue(np_equal(F[6:9, 12:15], -skewsq(w_G)))
        # -- Fifth Row --
        # self.assertTrue(np_equal(F[12:15, 6:9], np.eye(3)))

        # Plot matrix
        # debug = True
        debug = False
        if debug:
            ax = plt.subplot(111)
            ax.matshow(F)
            plt.show()
Пример #2
0
    def test_J(self):
        # Setup
        cam_q_CI = np.array([0.0, 0.0, 0.0, 1.0])
        cam_p_IC = np.array([1.0, 1.0, 1.0])
        q_hat_IG = np.array([0.0, 0.0, 0.0, 1.0])
        N = 1
        J = self.imu_state.J(cam_q_CI, cam_p_IC, q_hat_IG, N)

        # Assert
        C_CI = C(cam_q_CI)
        C_IG = C(q_hat_IG)
        # -- First row --
        self.assertTrue(np_equal(J[0:3, 0:3], C_CI))
        # -- Second row --
        self.assertTrue(np_equal(J[3:6, 0:3], skew(dot(C_IG.T, cam_p_IC))))
        # -- Third row --
        self.assertTrue(np_equal(J[3:6, 12:15], I(3)))

        # Plot matrix
        # debug = True
        debug = False
        if debug:
            ax = plt.subplot(111)
            ax.matshow(J)
            plt.show()
Пример #3
0
def quatrcomp(q):
    """Quaternion right compound

    Source:

        Page 4.

        Trawny, Nikolas, and Stergios I. Roumeliotis. "Indirect Kalman filter
        for 3D attitude estimation." University of Minnesota, Dept. of Comp.
        Sci. & Eng., Tech. Rep 2 (2005): 2005.

    Parameters
    ----------
    q : np.array - 4x1
        Quaternion (x, y, z, w)

    Returns
    -------

    """
    q1, q2, q3, q4 = q.ravel()
    vector = np.array([[q1], [q2], [q3]])
    scalar = q4

    return np.block([[scalar * np.eye(3) + skew(vector), vector],
                     [-vector.T, scalar]])
Пример #4
0
    def J(self, cam_q_CI, cam_p_IC, q_hat_IG, N):
        """Jacobian J matrix

        Parameters
        ----------
        cam_q_CI : np.array
            Rotation from IMU to camera frame
            in quaternion (x, y, z, w)
        cam_p_IC : np.array
            Position of camera in IMU frame
        q_hat_IG : np.array
            Rotation from global to IMU frame
        N : float
            Number of camera states

        Returns
        -------
        J: np.array
            Jacobian matrix J

        """
        C_CI = C(cam_q_CI)
        C_IG = C(q_hat_IG)
        J = zeros((6, 15 + 6 * N))

        # -- First row --
        J[0:3, 0:3] = C_CI
        # -- Second row --
        J[3:6, 0:3] = skew(dot(C_IG.T, cam_p_IC))
        J[3:6, 12:15] = I(3)

        return J
Пример #5
0
    def test_skew(self):
        v = np.array([[1.0], [2.0], [3.0]])
        X = skew(v)
        X_expected = np.array([[0.0, -3.0, 2.0],
                               [3.0, 0.0, -1.0],
                               [-2.0, 1.0, 0.0]])

        self.assertTrue(np.array_equal(X, X_expected))
Пример #6
0
    def F(self, w_hat, q_hat, a_hat, w_G):
        """Transition Jacobian F matrix

        Predicition or transition matrix in an EKF

        Parameters
        ----------
        w_hat : np.array
            Estimated angular velocity
        q_hat : np.array
            Estimated quaternion (x, y, z, w)
        a_hat : np.array
            Estimated acceleration
        w_G : np.array
            Earth's angular velocity (i.e. Earth's rotation)

        Returns
        -------
        F : np.array - 15x15
            Transition jacobian matrix F

        """
        # F matrix
        F = zeros((15, 15))
        # -- First row --
        F[0:3, 0:3] = -skew(w_hat)
        F[0:3, 3:6] = -I(3)
        # -- Third Row --
        F[6:9, 0:3] = -dot(C(q_hat).T, skew(a_hat))
        F[6:9, 6:9] = -2.0 * skew(w_G)
        F[6:9, 9:12] = -C(q_hat).T
        F[6:9, 12:15] = -skewsq(w_G)
        # -- Fifth Row --
        F[12:15, 6:9] = np.ones(3)

        return F
Пример #7
0
    def update(self, a_m, w_m, dt):
        """IMU state update

        Parameters
        ----------
        a_m : np.array
            Accelerometer measurement
        w_m : np.array
            Gyroscope measurement
        dt : float
            Time difference (s)

        Returns
        -------
        a: np.array
            Corrected accelerometer measurement
        w: np.array
            Corrected gyroscope measurement

        """
        # Calculate new accel and gyro estimates
        # a_hat = (a_m - self.b_a)
        # w_hat = (w_m - self.b_g - dot(C(self.q_IG), self.w_G))
        a_hat = a_m
        w_hat = w_m

        # Build the jacobians F and G
        F = self.F(w_hat, self.q_IG, a_hat, self.w_G)
        G = self.G(self.q_IG)

        # Propagate IMU states
        # -- Orientation
        self.q_IG += dot(0.5 * Omega(w_hat), self.q_IG) * dt
        # self.q_IG = quatnormalize(self.q_IG)
        # -- Velocity
        self.v_G += (dot(C(self.q_IG).T, a_hat) -
                     2 * dot(skew(self.w_G), self.v_G) -
                     dot(skewsq(self.w_G), self.p_G)) * dt
        # self.v_G = self.v_G + (dot(C(self.q_IG).T, a_hat) - 2 * dot(skew(self.w_G), self.v_G) - dot(skewsq(self.w_G), self.p_G) + self.g_G) * dt  # NOQA
        # -- Position
        self.p_G += self.v_G * dt

        # Update covariance
        Phi = I(self.size) + F * dt
        self.P = dot(Phi, dot(self.P, Phi.T)) + dot(G, dot(self.Q, G.T)) * dt
        self.P = enforce_psd(self.P)

        return self.P, Phi
Пример #8
0
def Omega(w):
    """Omega function

    Parameters
    ----------
    w : np.array
        Angular velocity

    Returns
    -------

        Differential form of an angular velocity (np.array)

    """
    w = w.reshape((3, 1))
    return np.block([[-skew(w), w], [-w.T, 0.0]])
Пример #9
0
    def H(self, track, track_cam_states, p_G_f):
        """Form the Jacobian measurement matrix

        - $H^{(j)}_x$ of j-th feature track with respect to state $X$
        - $H^{(j)}_f$ of j-th feature track with respect to feature position

        Parameters
        ----------
        track : FeatureTrack
            Feature track of length M
        track_cam_states : list of CameraState
            N Camera states
        p_G_f : np.array
            Feature position in global frame

        Returns
        -------
        H_x_j: np.matrix
            Measurement jacobian matrix w.r.t state (size: 2*M x (15+6)N)

        """
        x_imu_size = self.imu_state.size      # Size of imu state
        x_cam_size = self.cam_states[0].size  # Size of cam state

        N = self.N()    # Number of camera states
        M = track.tracked_length()  # Length of feature track

        # Measurement jacobian w.r.t feature
        H_f_j = zeros((2 * M, 3))

        # Measurement jacobian w.r.t state
        H_x_j = zeros((2 * M, x_imu_size + x_cam_size * N))

        # Pose index
        pose_idx = track.frame_start - self.cam_states[0].frame_id
        assert track_cam_states[0].frame_id == track.frame_start
        assert track_cam_states[-1].frame_id == track.frame_end

        # Form measurement jacobians
        for i in range(M):
            # Feature position in camera frame
            C_CG = C(track_cam_states[i].q_CG)
            p_G_C = track_cam_states[i].p_G
            p_C_f = dot(C_CG, (p_G_f - p_G_C))
            X, Y, Z = p_C_f.ravel()

            # dh / dg
            dhdg = (1.0 / Z) * np.array([[1.0, 0.0, -X / Z],
                                         [0.0, 1.0, -Y / Z]])

            # Row start and end index
            rs = 2 * i
            re = 2 * i + 2

            # Column start and end index
            cs_dhdq = x_imu_size + (x_cam_size * pose_idx)
            ce_dhdq = x_imu_size + (x_cam_size * pose_idx) + 3

            cs_dhdp = x_imu_size + (x_cam_size * pose_idx) + 3
            ce_dhdp = x_imu_size + (x_cam_size * pose_idx) + 6

            # H_f_j measurement jacobian w.r.t feature
            H_f_j[rs:re, :] = dot(dhdg, C_CG)

            # H_x_j measurement jacobian w.r.t state
            H_x_j[rs:re, cs_dhdq:ce_dhdq] = dot(dhdg, skew(p_C_f))
            H_x_j[rs:re, cs_dhdp:ce_dhdp] = dot(-dhdg, C_CG)

            # Update pose_idx
            pose_idx += 1

        return H_f_j, H_x_j