예제 #1
0
 def test_shortest_arc(self):
     v1 = np.array([1., 0., 0.])
     v2 = np.array([0., 1., 0.])
     arc = math_utils.shortest_arc(v1, v2)
     rotated = arc * quaternion.x * arc.inverse()
     np.testing.assert_almost_equal((quaternion.y - rotated).norm(), 0.0)
     np.testing.assert_almost_equal(rotated.norm(), 1.0)
예제 #2
0
    def pid(self):
        """x_d is relative target position"""
        if not self.takeoff:
            return
        if self.x is None:
            print(
                "PID controller: Failed to get state estimate, skipping frame")
            return
        x, xdot, xddot, body_orientation = self.x, self.xdot, self.xddot, self.q_b
        roll, pitch, yaw = self.rpy(body_orientation)
        g_vec = np.array([0.0, 0.0, -9.81])
        unit_z = np.array([0.0, 0.0, 1.0])

        x_d = self.x_d
        # Position controller
        self.px_pid.setpoint = x_d[0]
        self.py_pid.setpoint = x_d[1]
        self.pz_pid.setpoint = x_d[2]
        v_d = np.array([0.0, 0.0, 0.0])
        v_d[0] = self.px_pid(0.0)
        v_d[1] = self.py_pid(0.0)
        v_d[2] = self.pz_pid(0.0)

        # Velocity controller
        self.vx_pid.setpoint = v_d[0]
        self.vy_pid.setpoint = v_d[1]
        self.vz_pid.setpoint = v_d[2]
        a_d = np.array([0.0, 0.0, 0.0])
        a_d[0] = self.vx_pid(xdot[0])
        a_d[1] = self.vy_pid(xdot[1])
        a_d[2] = self.vz_pid(xdot[2])

        a_db = self.world_to_body(body_orientation, a_d - g_vec)

        # Find desired attitude correction using shortest arc algorithm
        q_theta = math_utils.shortest_arc(unit_z, a_db)
        roll_d, pitch_d, _ = self.rpy(q_theta)
        _, _, yaw_d = self.rpy(self.q_d)

        yaw_diff = self._compute_yaw_diff(yaw, yaw_d)

        # Apply attitude corrections using attitude PID
        self.thetax_pid.setpoint = roll_d
        self.thetay_pid.setpoint = pitch_d
        self.thetaz_pid.setpoint = yaw_diff
        omega_d = np.array([0.0, 0.0, 0.0])
        omega_d[0] = self.thetax_pid(
            0.0)  # 0 because a correction quantity is being tracked
        omega_d[1] = self.thetay_pid(0.0)
        omega_d[2] = self.thetaz_pid(0.0)

        # Send command
        c = np.linalg.norm(
            a_db)  # Desired thrust is norm of desired acceleration
        self.command(c, omega_d)
예제 #3
0
 def test_shortest_arc_same(self):
     v1 = np.array([1, 0, 0]) * 2.0
     v2 = np.array([1., 0., 0.])
     arc = math_utils.shortest_arc(v1, v2)
     rotated = arc * quaternion.x * arc.inverse()
     np.testing.assert_almost_equal(rotated, quaternion.x)
예제 #4
0
 def _orientation_quaternion(self, x):
     # The low level controller will use only the yaw angle.
     # Returns the quaternion which will rotate the x-axis to
     # point towards the next gate.
     gaze_direction = self._gaze_direction(x)
     return math_utils.shortest_arc(np.array([1., 0., 0.]), gaze_direction)
예제 #5
0
def solve_for_orientation(f, a):
    # Gravity is subtracted
    a_without_thrust = (a - f)
    return math_utils.shortest_arc(a_without_thrust, gravity_vector)