Exemple #1
0
    def test_clip(self):
        """
        Utilities:   Vector clipping
        """
        for i in range(10):
            x = 100. * (np.random.rand(100) - 0.5)
            x_limits = 50. * (np.random.rand(2) - 0.5)

            x_clipped = utils.clip(x, a_min=min(x_limits), a_max=max(x_limits))
            self.assertLessEqual(max(x_clipped), max(x_limits))
            self.assertGreaterEqual(min(x_clipped), min(x_limits))
Exemple #2
0
def vertical(s: np.ndarray,
             tgt_z: np.ndarray,
             ):

    e_z = np.array([s[2], s[9], 0., 0., 0., 0.]) - np.array([tgt_z, 0., 0., 0., 0., 0.])

    u = -K_Z @ e_z

    # scale by vertical component of orientation
    q_real = s[3]
    u = u / utils.clip(q_real, 0.3)

    return u
Exemple #3
0
def step(s: np.ndarray, u: np.ndarray, dt: float, r_scale_dist: float = 1.):

    v, n_body, g, dn_body, df_motor = calc_derivative(s, u, r_scale_dist)

    # euler integration
    s[:3] = s[:3] + v * dt + 0.5 * g * dt**2
    s[3:7] = quaternion.integrate(s[3:7], n_body, dt)
    s[7:10] = s[7:10] + g * dt
    s[10:13] = s[10:13] + dn_body * dt
    s[13:17] = utils.clip(s[13:17] + df_motor * dt,
                          a_min=0.,
                          a_max=f_motor_max)

    return s, g, dn_body
Exemple #4
0
def update(s: np.ndarray,
           tgt: np.ndarray,
           ):

    u_attitude = attitude(s, tgt[np.array([0, 1])])
    u_vertical = vertical(s, tgt[2])

    if max(u_attitude) - min(u_attitude) > f_motor_max:
        u = 0.5 * f_motor_max * np.ones(4) + u_attitude
    else:
        u = U_0 + u_vertical + u_attitude
        if max(u) > f_motor_max:
            u = u - (max(u) - f_motor_max)

    u = utils.clip(u, a_min=0., a_max=f_motor_max)

    return u
Exemple #5
0
def to_state(
    sensor_state: Sensor,
    filter_state: Filter,
    u: np.ndarray,
    dt: float,
):
    s_filter = filter_state.s

    if ORIENTATION_FILTER == "Kalman":
        q, n_body, p = kalman_orientation(sensor_state, filter_state, u, dt)
    elif ORIENTATION_FILTER == "Madgwick":
        q, n_body = madgwick(sensor_state, filter_state, dt)
        p = np.zeros((11, 11))
    else:
        q, n_body, p = np.zeros(4), np.zeros(3), np.zeros((11, 11))

    x, v, g = filter_translational(sensor_state, filter_state, u, dt)

    # calculate motor force
    df_motor = drone.calc_motor_derivative(filter_state.s, u)

    # update state vector
    s_filter[:3] = x
    s_filter[3:7] = q
    s_filter[7:10] = v
    s_filter[10:13] = n_body
    s_filter[13:17] = utils.clip(s_filter[13:17] + df_motor * dt,
                                 a_min=0.,
                                 a_max=f_motor_max)

    # update filter (can't _replace in numba)
    filter_state = Filter(
        s=s_filter,
        p=p,
        r_trans_sensor=filter_state.r_trans_sensor,
        r_madgwick_gain=filter_state.r_madgwick_gain,
        g=g,
    )

    return filter_state