def calib_param(compute=False):
    """ Load or compute calibration parameters
    """
    if compute == True:
        [params_acc, params_mag, params_gyr] = \
            calib.compute(imuNumber=5 ,filepath=DATACALIBFILE, param = 3)
    else:
        [params_acc, params_mag, params_gyr] = \
            calib.load_param(CALIBFILE)

    return [params_acc, params_mag, params_gyr]
Example #2
0
def test_martin_ahrs():

    quat_dict = sio.loadmat('data/test_martin_ahrs/quaternion_martin.mat')
    quat_verif = quat_dict['quaternion']

    [_, params_mag, params_gyr] = \
        calib.load_param("data/test_martin_ahrs/CalibrationFileIMU6.txt")

    # Load the recording data
    [_, accx, accy, accz, mx, my, mz, gyrx, gyry, gyrz] = \
        load_foxcsvfile("data/test_martin_ahrs/1_IMU6_RIGHT_FOOT.csv")

    # Applies the Scale and Offset to data
    scale_mag = params_mag[1:4, :]
    bias_mag = params_mag[0, :]
    scale_gyr = params_gyr[1:4, :]
    bias_gyr = params_gyr[0, :]

    acc_imu = np.column_stack([accx, accy, accz])
    mag_imu = np.column_stack([mx, my, mz])
    gyr_imu = np.column_stack([gyrx, gyry, gyrz])

    observer = martin.martin_ahrs()

    quaternion = np.zeros((len(acc_imu), 4))
    quaternion_corr = np.zeros((len(acc_imu), 4))

    data_init = np.mean(np.hstack(
    [acc_imu[0:200, :], \
    mag_imu[0:200, :], \
    gyr_imu[0:200, :]]), 0) # mean of the first static 2 seconds

    quaternion[0, :] = observer.init_observer(data_init)

    for i in range(1, len(acc_imu)-1):
        mag_imu[i, :] = np.transpose(np.dot(
        scale_mag, np.transpose((mag_imu[i, :]-np.transpose(bias_mag)))))
        gyr_imu[i, :] = np.transpose(np.dot(
        scale_gyr, np.transpose((gyr_imu[i, :]-np.transpose(bias_gyr)))))
        quaternion[i+1] = observer.update(
        np.hstack([acc_imu[i, :], mag_imu[i, :], gyr_imu[i, :]]), 0.005)

    conj_q_init = nq.conjugate(quaternion[150, :])
    for i in range(1, len(acc_imu)-1):
        quaternion_corr[i+1] = nq.mult(conj_q_init, quaternion[i+1])


    yield assert_equal, quaternion_corr.all() == quat_verif.all(), "OK"
Example #3
0
def calib_param(compute=True):
    """ Load or compute calibration parameters
    """
    if compute == True:
        [params_acc, params_mag, params_gyr] = \
            calib.compute(imuNumber=5 ,filepath=DATACALIBFILE, param = 3)
        calib.save_param(CALIBFILE,
                         params_acc,
                         params_mag,
                         params_gyr,
                         comments="Expe Prima")
    else:
        [params_acc, params_mag, params_gyr] = \
            calib.load_param(CALIBFILE)

    return [params_acc, params_mag, params_gyr]
Example #4
0
def test_mahony_ahrs():

    quat_dict = sio.loadmat('data/test_mahony_ahrs/quaternion_mahony.mat')
    quat_verif = quat_dict['quaternion']

    [params_acc, params_mag, params_gyr] = \
        calib.load_param("data/test_mahony_ahrs/CalibrationFileIMU6.txt")

    # Load the recording data
    [_, accx, accy, accz, mx, my, mz, gyrx, gyry, gyrz] = \
        load_foxcsvfile("data/test_mahony_ahrs/1_IMU6_RIGHT_FOOT.csv")

    # Applies the Scale and Offset to data
    scale_acc = params_acc[1:4, :]
    bias_acc = params_acc[0, :]
    scale_mag = params_mag[1:4, :]
    bias_mag = params_mag[0, :]
    scale_gyr = params_gyr[1:4, :]
    bias_gyr = params_gyr[0, :]

    acc_imu = np.column_stack([accx, accy, accz])
    mag_imu = np.column_stack([mx, my, mz])
    gyr_imu = np.column_stack([gyrx, gyry, gyrz])

    quaternion = np.zeros((len(acc_imu), 4))

    quaternion[0, :] = [1, 0, 0, 0]

    for i in range(0, len(acc_imu) - 1):
        acc_imu[i, :] = np.transpose(
            np.dot(scale_acc,
                   np.transpose((acc_imu[i, :] - np.transpose(bias_acc)))))
        mag_imu[i, :] = np.transpose(
            np.dot(scale_mag,
                   np.transpose((mag_imu[i, :] - np.transpose(bias_mag)))))
        gyr_imu[i, :] = np.transpose(
            np.dot(scale_gyr,
                   np.transpose((gyr_imu[i, :] - np.transpose(bias_gyr)))))
        quaternion[i + 1] = mahony.update(
            quaternion[i],
            np.hstack([acc_imu[i, :], mag_imu[i, :], gyr_imu[i, :]]))

    yield assert_equal, quaternion.all() == quat_verif.all(), "OK"
Example #5
0
def compass():

    # Compute
    #    [_, params_mag, _] = \
    #        calib.compute(imuNumber=5 ,filepath="data/1_IMU5_REGLE.csv", param = 3)

    [_, params_mag, _] = \
        calib.load_param("data/CalibrationFileIMU5.txt")

    # Load the recording data
    [time_imu, _, _, _, mx, my, mz, _, _, _] = \
        load_foxcsvfile("data/2_IMU5_REGLE.csv")

    # Applies the Scale and Offset to data
    scale_mag = params_mag[1:4, :]
    bias_mag = params_mag[0, :]

    mag_imu = np.column_stack([mx, my, mz])

    #######################
    # 3D objects init
    #######################

    scene.title = "VISU COMPASS"
    scene.autocenter = False
    scene.scale = (0.05, 0.05, 0.05)
    scene.background = (255, 255, 255)
    scene.width = 900
    scene.height = 600
    scene.forward = (0, 0, -1)
    scene.up = (1, 0, 0)

    north_frame = arrow(pos=(0, 0, 0),
                        axis=(10, 0, 0),
                        shaftwidth=1,
                        color=color.blue)
    west_frame = arrow(pos=(0, 0, 0),
                       axis=(0, 10, 0),
                       shaftwidth=1,
                       color=color.green)
    est_frame = arrow(pos=(0, 0, 0),
                      axis=(0, -10, 0),
                      shaftwidth=1,
                      color=color.magenta)
    south_frame = arrow(pos=(0, 0, 0),
                        axis=(-10, 0, 0),
                        shaftwidth=1,
                        color=color.yellow)

    ring(pos=(0, 0, 0),
         axis=(0, 0, -1),
         radius=10,
         thickness=0.6,
         color=color.red)

    IMU = box(pos=(0, 0, 0),
              axis=(8, 0, 0),
              height=5,
              width=3,
              color=color.black)

    angle_display = label(text='Rotation / North : 0 ' + u'°',
                          yoffset=0,
                          xoffset=0,
                          line=False,
                          box=False,
                          color=color.blue,
                          height=18,
                          pos=(12, 0, 0))

    #######################
    # 3D Animation
    #######################

    angle_north = np.zeros((len(mag_imu) - 1, 1))

    for i in range(0, len(mag_imu) - 1):
        mag_imu[i, :] = np.transpose(
            np.dot(scale_mag,
                   np.transpose((mag_imu[i, :] - np.transpose(bias_mag)))))
        angle_north[i] = np.arctan(mag_imu[i, 1] / mag_imu[i, 0]) + (
            0.76 * pi / 180)  # declination = 0.76° in Montpellier

    rot = np.diff(angle_north, axis=0)
    rot_cum = np.cumsum(rot)
    for k in range(0, len(rot)):
        rate(200)
        IMU.rotate(origin=(0, 0, 0), angle=rot[k], axis=(0, 0, 1))
        angle_display.text = 'Rotation / North : ' + '%0.2f' % (
            (rot_cum[k]) * 180 / pi) + ' ' + u'°'

    #######################
    # Plots
    #######################

    figure
    hold(True)
    plot(rot_cum * 180 / pi)
    legend(('Rot/North(°)'))
def VPython_quaternion_3D():

    # Compute
    #    [params_acc, params_mag, params_gyr] = \
    #        calib.compute(imuNumber=6 ,filepath="data/CALIB.csv", param = 3)

    [params_acc, params_mag, params_gyr] = \
        calib.load_param("data/CalibrationFileIMU6.txt")

    # Load the recording data
    [time_imu, accx, accy, accz, mx, my, mz, gyrx, gyry, gyrz] = \
        load_foxcsvfile("data/1_IMU6_RIGHT_FOOT.csv")

    # Applies the Scale and Offset to data
    scale_acc = params_acc[1:4, :]
    bias_acc = params_acc[0, :]
    scale_mag = params_mag[1:4, :]
    bias_mag = params_mag[0, :]
    scale_gyr = params_gyr[1:4, :]
    bias_gyr = params_gyr[0, :]

    acc_imu = np.column_stack([accx, accy, accz])
    mag_imu = np.column_stack([mx, my, mz])
    gyr_imu = np.column_stack([gyrx, gyry, gyrz])

    quaternion = np.zeros((len(acc_imu), 4))
    euler = np.zeros((len(acc_imu), 3))

    quaternion[0, :] = [1, 0, 0, 0]

    for i in range(0, len(acc_imu) - 1):
        acc_imu[i, :] = np.transpose(
            np.dot(scale_acc,
                   np.transpose((acc_imu[i, :] - np.transpose(bias_acc)))))
        mag_imu[i, :] = np.transpose(
            np.dot(scale_mag,
                   np.transpose((mag_imu[i, :] - np.transpose(bias_mag)))))
        gyr_imu[i, :] = np.transpose(
            np.dot(scale_gyr,
                   np.transpose((gyr_imu[i, :] - np.transpose(bias_gyr)))))
        quaternion[i + 1] = madgwick.update(
            quaternion[i],
            np.hstack([acc_imu[i, :], mag_imu[i, :], gyr_imu[i, :]]))
        euler[i] = quat2euler(quaternion[i + 1])

    #######################
    # Plots
    #######################
    dataVicon = np.loadtxt('data/RIGHT_FOOT.txt', skiprows=4)
    time_vicon = dataVicon[:, 0]
    euler_vicon = np.zeros((len(time_vicon), 3))
    quat_offset = np.hstack(
        [dataVicon[0, 7], dataVicon[0, 4], dataVicon[0, 5], dataVicon[0, 6]])
    for i in range(1, len(time_vicon) - 1):
        quat_vicon = np.hstack([
            dataVicon[i, 7], dataVicon[i, 4], dataVicon[i, 5], dataVicon[i, 6]
        ])
        euler_vicon[i] = quat2euler(
            nq.mult(nq.conjugate(quat_offset), quat_vicon))

    #Z
    plt.figure()
    plt.hold(True)
    plt.plot(time_imu - (0.2), euler[:, 0] * 180 / pi)
    plt.plot(time_vicon, euler_vicon[:, 0] * 180 / pi)
    plt.legend(('z_imu', 'z_vicon'))
    xlabel('time (s)')
    ylabel('angle (deg)')
    #Y
    plt.figure()
    plt.hold(True)
    plt.plot(time_imu - (0.2), euler[:, 1] * 180 / pi)
    plt.plot(time_vicon, euler_vicon[:, 1] * 180 / pi)
    plt.legend(('y_imu', 'y_vicon'))
    xlabel('time (s)')
    ylabel('angle (deg)')
    plt.show()
    #X
    plt.figure()
    plt.hold(True)
    plt.plot(time_imu - (0.2), euler[:, 2] * 180 / pi)
    plt.plot(time_vicon, euler_vicon[:, 2] * 180 / pi)
    plt.legend(('x_imu', 'x_vicon'))
    xlabel('time (s)')
    ylabel('angle (deg)')
    plt.show()

    quat_dict = {}
    quat_dict['quaternion'] = quaternion
    sio.savemat('quaternion_madgwick.mat', quat_dict)
Example #7
0
def compute_attitude(datafile, calibfile, anglefile, plotting=True):
    """ compute attitude IMU sensor
    """
    # Load calibration parameters
    [params_acc, params_mag, params_gyr] = calib.load_param(calibfile)
    # Load the recording data
    [time_sens, accx, accy, accz, magx, magy, magz, gyrx, gyry, gyrz] = \
        load_foxcsvfile(datafile)
    # Find motionless begin periods
    freqs = 200
    start, end = find_static_periods(gyrz, 2 * np.pi / 180, 3 * freqs)
    static_duration = time_sens[end[0]] - time_sens[start[0]]
    if static_duration < 5.0:
        print "Warning: static duration too low"

    time_imu = time_sens
    acc_imu = np.column_stack([accx, accy, accz])
    mag_imu = np.column_stack([magx, magy, magz])
    gyr_imu = np.column_stack([gyrx, gyry, gyrz])
    # Init output
    quat = np.zeros((len(acc_imu), 4))
    euler = np.zeros((len(acc_imu), 3))
    observer = martin_ahrs.martin_ahrs()
    # Initialization loop
    quat_offset = [1, 0, 0, 0]
    for i in range(0, end[0]):
        # Applies the Scale and Offset to data
        acc_imu[i, :] = normalize_data(acc_imu[i, :], params_acc)
        mag_imu[i, :] = normalize_data(mag_imu[i, :], params_mag)
        gyr_imu[i, :] = normalize_data(gyr_imu[i, :], params_gyr)
        # Filter call
        if i == 0:
            quat[0] = observer.init_observer(
                np.hstack([acc_imu[0, :], mag_imu[0, :], gyr_imu[0, :]]))
        else:
            quat[i] = observer.update(
                np.hstack([acc_imu[i, :], mag_imu[i, :], gyr_imu[i, :]]),
                0.005)
    quat_offset = nq.conjugate(quat[end - 1][0])
    print "Quaternion init", quat_offset

    # Computation loop
    for i in range(end[0], len(acc_imu)):
        # Applies the Scale and Offset to data
        acc_imu[i, :] = normalize_data(acc_imu[i, :], params_acc)
        mag_imu[i, :] = normalize_data(mag_imu[i, :], params_mag)
        gyr_imu[i, :] = normalize_data(gyr_imu[i, :], params_gyr)
        # Filter call
        quat[i] = observer.update(
            np.hstack([acc_imu[i, :], mag_imu[i, :], gyr_imu[i, :]]), 0.005)
        quat[i] = nq.mult(quat_offset, quat[i])
        euler[i] = quat2euler(quat[i])

    # Plot results
    if plotting is True:
        plot_quat("Expe Prima ", time_imu, quat[:, 0], quat[:, 1], quat[:, 2],
                  quat[:, 3])
        plot_euler("Expe Prima ", time_imu, euler[:, 2], euler[:, 1], euler[:,
                                                                            0])
    # Save results
    save_ahrs_csvfile(anglefile, time_imu, quat, euler)