コード例 #1
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testGroupAction(self):
        for i in range(100):
            rot1 = Rotation.random().as_matrix()
            rot2 = Rotation.random().as_matrix()

            R1 = SO3(rot1)
            R2 = SO3(rot2)

            R3 = R1 * R2
            R3_true = rot1 @ rot2

            np.testing.assert_allclose(R3_true, R3.arr)
コード例 #2
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testInv(self):
        for i in range(100):
            mat = Rotation.random().as_matrix()
            R = SO3(mat)

            R_inv = R.inv()
            R_T = R.transpose()
            R_inv_true = np.linalg.inv(mat)

            np.testing.assert_allclose(R_inv_true, R_inv.R)
            np.testing.assert_allclose(R_inv_true, R_T.R)
コード例 #3
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testAdjoint(self):
        for i in range(100):
            delta = np.random.uniform(-np.pi, np.pi, size=3)
            rot = Rotation.random().as_matrix()
            R = SO3(rot)

            Adj_R = R.Adj

            T_true = R * SO3.Exp(delta)
            T = SO3.Exp(Adj_R @ delta) * R

            np.testing.assert_allclose(T_true.R, T.R)
コード例 #4
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testRotatingVector(self):
        for i in range(100):  #Active rotation
            rot1 = Rotation.random().as_matrix()

            R = SO3(rot1)
            pt = np.random.uniform(-5, 5, size=3)

            rot_pt = R.rota(pt)
            rot_pt_true = rot1 @ pt

            np.testing.assert_allclose(rot_pt_true, rot_pt)

        for i in range(100):
            rot1 = Rotation.random().as_matrix()

            R = SO3(rot1)
            pt = np.random.uniform(-5, 5, size=3)

            rot_pt = R.rotp(pt)
            rot_pt_true = rot1.T @ pt

            np.testing.assert_allclose(rot_pt_true, rot_pt)
コード例 #5
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testLog(self):  #This has issues sometimes. It is infrequent though
        for i in range(100):
            temp = Rotation.random().as_matrix()
            R = SO3(temp)

            logR = SO3.log(R)
            logR_true = sp.linalg.logm(temp)

            if np.linalg.norm(logR_true - logR, ord='fro') > 1e-3:
                Pdb().set_trace()
                debug = 1
                temp = SO3.log(R)

            np.testing.assert_allclose(logR_true, logR, atol=1e-10)
コード例 #6
0
ファイル: test_so3.py プロジェクト: b4sgren/pyManifold
    def testConstructor(self):
        for i in range(100):
            angles = np.random.uniform(-np.pi, np.pi, size=3)
            R_ex = SO3.fromRPY(angles)

            cp = np.cos(angles[0])
            sp = np.sin(angles[0])
            R1 = np.array([[1, 0, 0], [0, cp, -sp], [0, sp, cp]])

            ct = np.cos(angles[1])
            st = np.sin(angles[1])
            R2 = np.array([[ct, 0, st], [0, 1, 0], [-st, 0, ct]])

            cps = np.cos(angles[2])
            sps = np.sin(angles[2])
            R3 = np.array([[cps, -sps, 0], [sps, cps, 0], [0, 0, 1]])

            R_true = Rotation.from_euler(
                'ZYX', [angles[2], angles[1], angles[0]]).as_matrix()

            R_ex2 = SO3(R_true)

            np.testing.assert_allclose(R_true, R_ex.arr)
            np.testing.assert_allclose(R_true, R_ex2.arr)
コード例 #7
0
    def update(self, state, des):
        p = state[0:3]
        v = state[3:6]
        R_bi = Quat2Rotation(state[6:10])
        om_b = state[10:]

        e3 = np.array([[0., 0., 1.]]).T

        p_err = p - des.pd
        pdot_err = v - des.pd_dot

        self.p_err_int += self.ts / 2.0 * (p_err + self.p_err_prev)
        self.p_err_prev = p_err

        et = np.vstack([p_err, pdot_err, self.p_err_int])

        # et = np.vstack([p_err, pdot_err])

        if not self.clipped_props:
            psid = des.psid
            psid_dot = des.psid_dot
        else:
            euler = Quat2Euler(state[6:10])
            psid = euler.item(2)
            psid_dot = om_b[-1]

        sd = np.array([[np.cos(psid)], [np.sin(psid)], [0]])
        sd_dot = psid_dot * np.array([[-np.sin(psid)], [np.cos(psid)], [0]])

        f = -self.Kt @ et + self.m * (self.g * e3 - des.pd_ddot)

        # T = -np.dot(f.T, R_bi.T@e3).item(0)
        T = np.linalg.norm(f)

        k_d = f / np.linalg.norm(f)
        kxs = cross(k_d, sd)
        j_d = kxs / np.linalg.norm(kxs)
        i_d = cross(j_d, k_d)

        R_di = np.hstack([i_d, j_d, k_d])

        k_d_dot = proj(k_d) / np.linalg.norm(f) @ (
            -self.m * des.pd_dddot -
            self.Kt @ (self.At - self.Bt @ self.Kt) @ et)
        j_d_dot = proj(j_d) / np.linalg.norm(kxs) @ (cross(k_d, sd_dot) +
                                                     cross(k_d_dot, sd))
        i_d_dot = cross(j_d, k_d_dot) + cross(j_d_dot, k_d)

        R_di_dot = np.hstack([i_d_dot, j_d_dot, k_d_dot])

        om_d = vee(R_di.T @ R_di_dot)

        #have to numerically differentiate because analytical derivative is nasty
        self.om_d_dot = (
            (2 * self.sig - self.ts) /
            (2 * self.sig + self.ts)) * self.om_d_dot + (
                2 / (2 * self.sig + self.ts)) * (om_d - self.om_d_prev)
        self.om_d_prev = om_d

        R_db = R_bi.T @ R_di
        om_err = R_db @ om_d - om_b
        r_err = np.array([SO3(R_db).Log().tolist()]).T

        om_db_dot = -cross(om_b, R_db @ om_d) + R_db @ self.om_d_dot

        if self.control_type == "lee1":
            tau = cross(
                om_b, self.J @ om_b) + self.J @ om_db_dot + self.kr_lee1 * vee(
                    skew_sym(R_db)) + self.Kom @ om_err  #this uses trace error

        elif self.control_type == "lee2":
            tau = cross(
                R_db @ om_d, self.J @ R_db @ om_d
            ) + self.J @ R_db @ self.om_d_dot + self.kr_lee2 * vee(
                skew_sym(R_db)) / np.sqrt(1.0 + np.trace(
                    R_db)) + self.Kom @ om_err  #this uses wierd trace error

        elif self.control_type == "lee3":
            r_1d = R_di[:, [0]]
            r_2d = R_di[:, [1]]
            r_3d = R_di[:, [2]]
            r_1b = R_bi[:, [0]]
            r_2b = R_bi[:, [1]]
            e_r1 = cross(R_bi.T @ r_1d, np.array([[1, 0, 0]]).T)
            e_r2 = cross(R_bi.T @ r_2d, np.array([[0, 1, 0]]).T)

            Psi_n1 = 1 - (r_1b.T @ r_1d).item(0)
            Psi_n2 = 1 - (r_2b.T @ r_2d).item(0)
            Psi_e1 = self.alpha_lee3 + self.beta_lee3 * (r_1b.T @ r_3d).item(0)
            Psi_e2 = self.alpha_lee3 + self.beta_lee3 * (r_2b.T @ r_3d).item(0)
            Psi_1 = self.kr1_lee3 * Psi_n1 + self.kr2_lee3 * Psi_n2
            Psi_2 = self.kr1_lee3 * Psi_n1 + self.kr2_lee3 * Psi_e2
            Psi_3 = self.kr1_lee3 * Psi_e1 + self.kr2_lee3 * Psi_n2
            Psi_choices = [Psi_1, Psi_2, Psi_3]
            Psi_min = np.argmin(Psi_choices)
            rho = Psi_choices[Psi_min]
            if Psi_choices[
                    self.m_lee3] - rho >= self.delta_lee3 and np.linalg.norm(
                        om_err) < self.om_lim_lee3:
                self.m_lee3 = Psi_min

            e_h1 = e_r1 if self.m_lee3 != 2 else -self.beta_lee3 * cross(
                R_bi.T @ r_3d,
                np.array([[1, 0, 0]]).T)
            e_h2 = e_r2 if self.m_lee3 != 1 else -self.beta_lee3 * cross(
                R_bi.T @ r_3d,
                np.array([[0, 1, 0]]).T)
            e_h = self.kr1_lee3 * e_h1 + self.kr2_lee3 * e_h2
            tau = cross(
                R_db @ om_d, self.J @ R_db @ om_d
            ) + self.J @ R_db @ self.om_d_dot - e_h + self.Kom_lee3 @ om_err  # this uses the overly complicated global hybrid controller

        elif self.control_type == "ours":
            tau = cross(om_b, self.J @ om_b) + self.J @ om_db_dot + SO3.Jl_inv(
                r_err
            ).T @ self.kr @ r_err + self.Kom @ om_err  #this uses log error

        commanded_state = np.vstack(
            [des.pd, des.pd_dot, Rotation2Quat(R_di), om_d])
        delta_unsat = self.mix_inv @ np.vstack([T, tau])

        return self.sat(delta_unsat), commanded_state
コード例 #8
0
    def calcStep(self, t):
        w = np.pi/15.0
        g = 9.81
        if self._is_circle:
            # Complete a circle in 30s
            # Flat inputs
            x = 3 * np.cos(w*t)
            y = 3 * np.sin(w*t)
            z = -5.0
            psi = 0.0

            # World frames
            vx = -3 * w * np.sin(w*t)
            vy = 3 * w * np.cos(w*t)
            vz = 0

            # Accelerations in the world frame
            ax = -3 * w**2 * np.cos(w*t)
            ay = -3 * w**2 * np.sin(w*t)
            az = 0

            # Jerk
            jx = 3 * w**3 * np.sin(w*t)
            jy = -3 * w**3 * np.cos(w*t)
            jz = 0
            ad = np.array([jx, jy, jz])

            # Get rotation
            t = np.array([ax, ay, az + g])
            R_i_from_b = self.getRotation(t, psi)

            # Get angular rates
            u1 = self._quad_params.mass * np.linalg.norm(t)
            zB = R_i_from_b[:,-1]
            hw = self._quad_params.mass/u1 * (ad - (zB @ ad)*zB)
            p = -hw @ R_i_from_b[:,1]
            q = hw @ R_i_from_b[:,0]
            r = 0 # Because psi_dot is 0

        else:
            # Complete Figure 8 in 30s
            x = 3 * np.cos(w*t)
            y =  3 * np.cos(w*t) * np.sin(w*t)
            z = -5.0
            psi = 0.0

            vx = -3 * w * np.sin(w*t)
            vy = -3 * w  * (np.cos(w*t)**2 - np.sin(w*t)**2)
            vz = 0.0

            ax = -3 * w**2 * np.cos(w*t)
            ay = 12 * w**2 * np.cos(w*t) * np.sin(w*t)
            az = 0.0

            jx = 3 * w**3 * np.sin(w*t)
            jy = 12 * w**3 * (np.cos(w*t)**2 - np.sin(w*t)**2)
            jz = 0
            ad = np.array([jx, jy, jz])

            t = np.array([ax, ay, az+g])
            R_i_from_b = self.getRotation(t, psi)

            # Get angular rates
            u1 = self._quad_params.mass * np.linalg.norm(t)
            zB = R_i_from_b[:,-1]
            hw = self._quad_params.mass/u1 * (ad - (zB @ ad)*zB)
            p = -hw @ R_i_from_b[:,1]
            q = hw @ R_i_from_b[:,0]
            r = 0 # Because psi_dot is 0

        # return np.array([x, y, z]), np.array([vx, vy, vz]), [email protected]([ax, ay, az+g]), SO3(R_i_from_b), np.array([p, q, r])
        return np.array([x, y, z]), [email protected]([vx, vy, vz]), [email protected]([ax, ay, az+g]), SO3(R_i_from_b), np.array([p, q, r])