예제 #1
0
def compute_quat(all_data,
                 len_sensor_list,
                 quat_cal_offset,
                 rot_inds,
                 num_sensors=5,
                 t_offset=0,
                 signals_per_sensor=6,
                 beta=0.2 * np.ones(5),
                 rate=60.0,
                 verbose=False,
                 beta_init=0.4):
    d2g = ahrs.common.DEG2RAD  # Constant to convert degrees to radians
    Qi = np.zeros((num_sensors, quat_cal_offset, 4))
    Q = np.zeros((num_sensors, all_data.shape[0] - quat_cal_offset, 4))
    Qi[:, 0, :] = np.array([0.7071, 0.7071, 0.0, 0.0])

    z_neg_90 = np.array([[0, 1.0, 0], [-1., 0, 0], [0, 0, 1.0]])
    y_180 = np.array([[-1.0, 0, 0], [0, 1.0, 0], [0, 0, -1.0]])
    z_180 = np.array([[-1.0, 0, 0], [0, -1.0, 0], [0, 0, 1.0]])
    y_neg_90 = np.array([[0, 0, -1.0], [0, 1.0, 0], [1.0, 0, 0]])
    y_pos_90 = np.array([[0, 0, 1.0], [0, 1.0, 0], [-1.0, 0, 0]])
    ankle_offset = -100. * d2g
    x_pos_ankle = np.array([[1.0, 0, 0],
                            [0, np.cos(ankle_offset), -np.sin(ankle_offset)],
                            [0, np.sin(ankle_offset),
                             np.cos(ankle_offset)]])
    hip_rot = np.matmul(y_neg_90, z_180)
    foot_rot = np.matmul(x_pos_ankle, hip_rot)
    r_leg_rot = z_neg_90
    l_leg_rot = np.matmul(z_neg_90, y_180)
    rot_mats = np.zeros((len_sensor_list, 3, 3))
    for i in range(len_sensor_list):  # define rotation type
        if rot_inds[i] == 0:  # hip, torso, head
            rot_mats[i, :, :] = hip_rot
        elif rot_inds[i] == 1:  # left side
            rot_mats[i, :, :] = l_leg_rot
        elif rot_inds[i] == 2:  # right side
            rot_mats[i, :, :] = r_leg_rot
        elif rot_inds[i] == 3:  # foot
            rot_mats[i, :, :] = foot_rot

    for i in range(
            len_sensor_list):  # processing quaternions one sensor at a time
        s_off = i * signals_per_sensor
        accel = np.matmul(all_data[:, s_off + t_offset:s_off + t_offset + 3],
                          rot_mats[i, :, :])
        gyro = np.matmul(
            all_data[:, s_off + t_offset + 3:s_off + t_offset + 6],
            rot_mats[i, :, :])
        #mag = np.matmul(all_data[:,s_off+t_offset+6:s_off+t_offset+9],rot_mats[i,:,:])

        # calibrating the initial quaternion with a large beta_init value
        madgwick_i = ahrs.filters.Mahony(frequency=float(rate))
        for t in range(1, quat_cal_offset):
            Qi[i, t, :] = madgwick_i.updateIMU(Qi[i, t - 1, :], gyro[0, :],
                                               accel[0, :])
    quat_ang = np.zeros(num_sensors)
    for i in range(len_sensor_list):
        quat_ang[i], _ = orientMat(
            q2R(np.array(Qi[i, -1, :]))
        )  # multiply rot_mats by the gyro correction angle to correct to same heading as pelvis? Then
    mean_ang = np.mean(quat_ang)
    return Qi[:, -1, :], mean_ang, rot_mats
예제 #2
0
 def h_mag(self, q):
     C = q2R(q).T
     return C @ self.m_ref
예제 #3
0
def do_gyro_integration(mag_data):
    global csv, timeArr, orientation, dt
    import ahrs.filters as filters
    import ahrs.common.orientation as orient

    if "wx_raw" in csv:
        gyro_data = np.array(
            [csv["wx_raw"] / 32.8, csv["wy_raw"] / 32.8,
             csv["wz_raw"] / 32.8]).T
        gyro_data = gyro_data * M_PI / 180.0  # deg/s to rad/s
    elif "imu1_gyro_x_real" in csv:
        gyro_data = np.array([
            -csv["imu1_gyro_x_real"], -csv["imu1_gyro_z_real"],
            csv["imu1_gyro_y_real"]
        ]).T / 4  # /4 for sensitivity bug fix
    else:
        gyro_data = np.array([csv["wx"], csv["wy"], csv["wz"]]).T
        gyro_data = gyro_data * M_PI / 180.0  # deg/s to rad/s

    # Crappy gyro cal -- subtract out the average of the first 10
    gyro_offset = [
        np.mean(gyro_data[:30, 0]),
        np.mean(gyro_data[:30]),
        np.mean(gyro_data[:30, 2])
    ]
    gyro_data = gyro_data - gyro_offset

    if "ax" in csv:
        acc_data = np.array(
            [-csv["ax"] * 9.81, -csv["az"] * 9.81, csv["ay"] * 9.81]).T
    else:
        acc_data = np.array([
            -csv["imu1_accel_x_real"], csv["imu1_accel_z_real"],
            -csv["imu1_accel_y_real"]
        ]).T

    # gyro_data = gyro_data[900:,:]
    if mag_data is not None:
        initial_tilt = orient.ecompass(acc_data[0],
                                       mag_data[0],
                                       frame='ENU',
                                       representation='quaternion')
    else:
        initial_tilt = orient.acc2q(acc_data[1, :])

    plt.figure()
    plt.plot(timeArr, gyro_data[:, 0], label="X")
    plt.plot(timeArr, gyro_data[:, 1], label="Y")
    plt.plot(timeArr, gyro_data[:, 2], label="Z")
    plt.plot(timeArr, acc_data[:, 0], label="aX")
    plt.plot(timeArr, acc_data[:, 1], label="aY")
    plt.plot(timeArr, acc_data[:, 2], label="aZ")
    plt.legend()

    rotM = orient.q2R(initial_tilt)
    newX = np.array([1, 0, 0]).T @ rotM
    angleBetween = newX @ np.array([1, 0, 0]).T
    print(f"Initial tilt: {initial_tilt} angle {acos(angleBetween) * RAD2DEG}")

    # orientation = filters.Mahony(gyr=gyro_data, acc=acc_data, frequency=1.0/np.mean(np.diff(timeArr)))
    # orientation = filters.Tilt(acc=acc_data)
    # orientation = filters.AngularRate(gyr=gyro_data[1000:,:], q0=initial_tilt, frequency=1/dt)
    orientation = filters.AngularRate(gyr=gyro_data,
                                      q0=initial_tilt,
                                      frequency=1 / dt)

    import RocketEKF
    from ahrs.utils.wmm import WMM
    # MDRA
    wmm = WMM(latitude=39.0785319, longitude=-75.87425944, height=0)

    # X is north, Y  is East, Z is down
    # So by default, it's NED
    # We want East-North-Up
    m_ref = np.array([wmm.Y, wmm.X, -wmm.Z]) / 1000
    print(f"Mag ref: {m_ref} microTesla")
    # o2 = RocketEKF.EKF(gyr=gyro_data, mag=mag_data, frequency=1/np.mean(np.diff(timeArr)), q0=initial_tilt, m_ref=m_ref, frame='ENU')
    # orientation = o2

    # np.savetxt('orient.mat', json.dumps(orientation.Q.tolist())

    bigarr = []
    i = 0
    for row in orientation.Q:
        # bigarr.append([row[0], row[1], row[2], row[3], csv["high_g_accel_x_real"][i], csv["high_g_accel_y_real"][i], csv["high_g_accel_z_real"][i], timeArr[i]])
        bigarr.append([row[0], row[1], row[2], row[3], timeArr[i]])
        i = i + 1
    bigarr = np.array(bigarr)
    print(bigarr.shape)

    json_dump = json.dumps(bigarr, cls=NumpyEncoder)
    # print(json_dump)
    with open("orient.json", "w") as txt:
        txt.write(json_dump)

    np.savetxt("orient.csv", bigarr)
예제 #4
0
 def h_both(self, q: np.ndarray) -> np.ndarray:
     C = q2R(q).T
     if len(self.z) < 4:
         return C @ self.a_ref
     return np.r_[C @ self.a_ref, C @ self.m_ref]