示例#1
0
    def test_rotation(self):
        """Test that a quaternion and its converted matrix perform the same rotation."""
        quat_rotated = rowan.rotate(input1, vector_inputs)

        matrices = rowan.to_matrix(input1)
        matrix_rotated = np.einsum("ijk,ki->ij", matrices, vector_inputs.T)
        self.assertTrue(np.allclose(matrix_rotated, quat_rotated))
示例#2
0
	def __init__(self, J, mass, a_min, a_max):
		self.mass = mass
		self.J = J
		self.a_min = a_min
		self.a_max = a_max

		# desired state
		self.p_d = np.array([0,0,0])
		self.v_d = np.array([0,0,0])
		self.a_d = np.array([0,0,0 + 9.81])
		self.R_d = rowan.to_matrix([1, 0, 0, 0])
		self.omega_d = np.array([0,0,0])

		# Gains
		self.Kpos_P = np.array([10,10,5])
		self.Kpos_D = np.array([5,5,2.5])

		self.lambda_a = np.array([20,20,8])
		self.K_att = np.array([0.003, 0.003, 0.003])
		self.kq = 0

		# state
		self.omega_r_last = None

		self.q = []
		self.qr = []
		self.omega = []
		self.omegar = []
示例#3
0
    def testfun(points, rotation):
        vertices = tet.vertices + points
        shape = ConvexPolyhedron(vertices)
        rotated_shape = ConvexPolyhedron(rowan.rotate(rotation, vertices))

        mat = rowan.to_matrix(rotation)
        rotated_inertia = rotate_order2_tensor(mat, shape.inertia_tensor)

        assert np.allclose(rotated_inertia, rotated_shape.inertia_tensor)
示例#4
0
 def test_to_from_matrix(self):
     # The equality is only guaranteed up to a sign
     converted = rowan.from_matrix(rowan.to_matrix(input1))
     self.assertTrue(
         np.all(
             np.logical_or(
                 np.isclose(input1 - converted, 0),
                 np.isclose(input1 + converted, 0),
             )))
示例#5
0
 def test_to_from_matrix(self):
     """Test conversion from a quaternion to a matrix and back."""
     # The equality is only guaranteed up to a sign
     converted = rowan.from_matrix(rowan.to_matrix(input1))
     self.assertTrue(
         np.all(
             np.logical_or(
                 np.isclose(input1 - converted, 0),
                 np.isclose(input1 + converted, 0),
             )))
示例#6
0
def test_rotate_inertia(points):
    # Use the input as noise rather than the base points to avoid precision and
    # degenerate cases provided by hypothesis.
    tet = PlatonicFamily()("Tetrahedron")
    vertices = tet.vertices + points

    rotation = rowan.random.rand()
    shape = ConvexPolyhedron(vertices)
    rotated_shape = ConvexPolyhedron(rowan.rotate(rotation, vertices))

    mat = rowan.to_matrix(rotation)
    rotated_inertia = rotate_order2_tensor(mat, shape.inertia_tensor)

    assert np.allclose(rotated_inertia, rotated_shape.inertia_tensor)
示例#7
0
    def test_to_matrix(self):
        v = np.copy(zero)
        with self.assertRaises(ZeroDivisionError):
            rowan.to_matrix(v)

        v = 2 * np.ones(4)
        with self.assertRaises(ValueError):
            rowan.to_matrix(v)

        v = np.copy(one)
        self.assertTrue(np.all(rowan.to_matrix(v) == np.eye(3)))

        v = np.copy(half)
        self.assertTrue(
            np.allclose(rowan.to_matrix(v),
                        np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]])))

        v[3] *= -1
        self.assertTrue(
            np.allclose(rowan.to_matrix(v),
                        np.array([[0, 1, 0], [0, 0, -1], [-1, 0, 0]])))
示例#8
0
	def policy(self, state):
		# current state
		p = state[0:3]
		v = state[3:6]
		q = state[6:10]
		omega = state[10:13]
		R = rowan.to_matrix(q)

		# position controller
		# p_tilde = p - self.p_d
		# v_tilde = v - self.v_d
		# v_r = self.v_d - self.lambda_p * p_tilde
		# v_r_dot = self.a_d - self.lambda_p * v_tilde
		# s_v = v - v_r
		# f_r = self.mass * v_r_dot \
		# 	- self.Kv * s_v \
		# 	- self.Kp * p_tilde

		# thrust = np.linalg.norm(f_r)

		# qr = mkvec(
  #       asinf((F_d.x * sinf(yaw) - F_d.y * cosf(yaw)) / control->thrustSI),
  #       atanf((F_d.x * cosf(yaw) + F_d.y * sinf(yaw)) / F_d.z),
  #       desiredYaw);

		# position controller
		pos_e = self.p_d - p
		vel_e = self.v_d - v
		F_d = self.mass * (self.a_d + self.Kpos_D * vel_e + self.Kpos_P * pos_e)
		print(F_d)

		thrust = np.linalg.norm(F_d)
		yaw = 0
		rpy_d = np.array([
			np.arcsin((F_d[0] * np.sin(yaw) - F_d[1] * np.cos(yaw)) / thrust),
			np.arctan((F_d[0] * np.cos(yaw) + F_d[1] * np.sin(yaw)) / F_d[2]),
			yaw])
		R_d = rowan.to_matrix(rowan.from_euler(*rpy_d))
		print(rpy_d)
		print(R_d)

		# attitude controller

		# rotation error
		Rtilde = self.R_d.T @ R
		qtilde_0 = 1/2 * np.sqrt(1 + np.trace(Rtilde))
		qtilde_v = 1 / (4 * qtilde_0) * veemap(Rtilde - Rtilde.T)

		omega_r = Rtilde.T @ self.omega_d - 2 * self.lambda_a * qtilde_v
		print(omega_r)

		if self.omega_r_last is not None:
			omega_r_dot = (omega_r - self.omega_r_last) / 0.01
		else:
			omega_r_dot = np.zeros(3)
		self.omega_r_last = omega_r

		s_omega = omega - omega_r
		torque = self.J * omega_r_dot \
				- np.cross(self.J * omega, omega_r) \
				- self.K_att * s_omega \
				- self.kq * qtilde_v

		# power distribution
		thrust_to_torque = 0.006
		arm_length = 0.046
		thrustpart = 0.25 * thrust
		yawpart = -0.25 * torque[2] / thrust_to_torque

		arm = 0.707106781 * arm_length
		rollpart = 0.25 / arm * torque[0]
		pitchpart = 0.25 / arm * torque[1]

		motorForce = np.array([
			thrustpart - rollpart - pitchpart + yawpart,
			thrustpart - rollpart + pitchpart - yawpart,
			thrustpart + rollpart + pitchpart + yawpart,
			thrustpart + rollpart - pitchpart - yawpart
		])
		motorForce = np.clip(motorForce, self.a_min, self.a_max)

		# logging
		self.qr.append(np.degrees(rpy_d))
		self.q.append(np.degrees(rowan.to_euler(q, 'xyz')))
		self.omegar.append(omega_r)
		self.omega.append(omega)

		return motorForce
示例#9
0
	def policy(self, state):
		# current state
		p = state[0:3]
		v = state[3:6]
		q = state[6:10]
		omega = state[10:13]
		R = rowan.to_matrix(q)

		# position controller
		pos_e = self.p_d - p
		vel_e = self.v_d - v
		F_d = self.mass * (self.a_d + self.Kpos_D * vel_e + self.Kpos_P * pos_e)
		print(F_d)

		thrust = np.linalg.norm(F_d)
		yaw = 0
		q_d = np.array([
			np.arcsin((F_d[0] * np.sin(yaw) - F_d[1] * np.cos(yaw)) / thrust),
			np.arctan((F_d[0] * np.cos(yaw) + F_d[1] * np.sin(yaw)) / F_d[2]),
			yaw])

		if self.q_d_last is not None:
			q_d_dot = (q_d - self.q_d_last) / 0.01
		else:
			q_d_dot = np.zeros(3)
		self.q_d_last = q_d

		# attitude controller
		q = rowan.to_euler(q, 'xyz')

		omega_r = Zinv(q) @ (q_d_dot +self.lambda_att * (q_d -q))
		if self.omega_r_last is not None:
			omega_r_dot = (omega_r - self.omega_r_last) / 0.01
		else:
			omega_r_dot = np.zeros(3)
		self.omega_r_last = omega_r

		torque = self.J * omega_r_dot \
				- np.cross(self.J * omega, omega_r) \
				- self.K_att * (omega - omega_r)

		# power distribution
		thrust_to_torque = 0.006
		arm_length = 0.046
		thrustpart = 0.25 * thrust
		yawpart = -0.25 * torque[2] / thrust_to_torque

		arm = 0.707106781 * arm_length
		rollpart = 0.25 / arm * torque[0]
		pitchpart = 0.25 / arm * torque[1]

		motorForce = np.array([
			thrustpart - rollpart - pitchpart + yawpart,
			thrustpart - rollpart + pitchpart - yawpart,
			thrustpart + rollpart + pitchpart + yawpart,
			thrustpart + rollpart - pitchpart - yawpart
		])
		motorForce = np.clip(motorForce, self.a_min, self.a_max)

		# logging
		self.qr.append(np.degrees(q_d))
		self.q.append(np.degrees(q))
		self.omegar.append(omega_r)
		self.omega.append(omega)

		return motorForce
示例#10
0
    def test_rotation(self):
        quat_rotated = rowan.rotate(input1, vector_inputs)

        matrices = rowan.to_matrix(input1)
        matrix_rotated = np.einsum('ijk,ki->ij', matrices, vector_inputs.T)
        self.assertTrue(np.allclose(matrix_rotated, quat_rotated))