コード例 #1
0
def process(data_file, error_apriori, units):
    '''
    Given a .csv data file in the format of (time, x, y, z) applies both filters, generates a filtered.csv data
    file, prints out the final keplerian elements computed from both Lamberts and Interpolation and finally plots
    the initial, filtered data set and the final orbit.

    Args:
        data_file (string): The name of the .csv file containing the positional data
        error_apriori (float): apriori estimation of the measurements error in km

    Returns:
        Runs the whole process of the program
    '''
    # First read the csv file called "orbit" with the positional data
    data = read_data.load_data(data_file)

    if (units == 'm'):
        # Transform m to km
        data[:, 1:4] = data[:, 1:4] / 1000

    print(
        "***********Choose filter(s) in desired order of application***********"
    )
    print(
        "(SPACE to toggle, UP/DOWN to navigate, RIGHT/LEFT to select/deselect and ENTER to submit)"
    )
    print(
        "*if nothing is selected, Triple Moving Average followed by Savitzky Golay will be applied"
    )
    questions = [
        inquirer.Checkbox(
            'filter',
            message="Select filter(s)",
            choices=['Savitzky Golay Filter', 'Triple Moving Average Filter'],
        ),
    ]
    choices = inquirer.prompt(questions)
    data_after_filter = data

    if (len(choices['filter']) == 0):
        print("Applying Triple Moving Average followed by Savitzky Golay...")
        # Apply the Triple moving average filter with window = 3
        data_after_filter = triple_moving_average.generate_filtered_data(
            data_after_filter, 3)

        # Use the golay_window.py script to find the window for the Savitzky Golay filter based on the error you input
        window = golay_window.window(error_apriori, data_after_filter)

        # Apply the Savitzky Golay filter with window = window (51 for orbit.csv) and polynomial order = 3
        data_after_filter = sav_golay.golay(data_after_filter, window, 3)
    else:
        for index, choice in enumerate(choices['filter']):
            if (choice == 'Savitzky Golay Filter'):
                print("Applying Savitzky Golay Filter...")
                # Use the golay_window.py script to find the window for the Savitzky Golay filter based on the error you input
                window = golay_window.window(error_apriori, data_after_filter)

                # Apply the Savitzky Golay filter with window = window (51 for orbit.csv) and polynomial order = 3
                data_after_filter = sav_golay.golay(data_after_filter, window,
                                                    3)
            else:
                print("Applying Triple Moving Average Filter...")
                # Apply the Triple moving average filter with window = 3
                data_after_filter = triple_moving_average.generate_filtered_data(
                    data_after_filter, 3)

    # Compute the residuals between filtered data and initial data and then the sum and mean values of each axis
    res = data_after_filter[:, 1:4] - data[:, 1:4]
    sums = np.sum(res, axis=0)
    print("\nDisplaying the sum of the residuals for each axis")
    print(sums, "\n")

    means = np.mean(res, axis=0)
    print("Displaying the mean of the residuals for each axis")
    print(means, "\n")

    # Save the filtered data into a new csv called "filtered"
    np.savetxt("filtered.csv", data_after_filter, delimiter=",")

    print("***********Choose Method(s) for Orbit Determination***********")
    print(
        "(SPACE to toggle, UP/DOWN to navigate, RIGHT/LEFT to select/deselect and ENTER to submit)"
    )
    print(
        "*if nothing is selected, Cubic Spline Interpolation will be used for Orbit Determination"
    )
    questions = [
        inquirer.Checkbox(
            'method',
            message="Select Method(s)",
            choices=[
                'Lamberts Kalman', 'Cubic Spline Interpolation',
                'Ellipse Best Fit', 'Gibbs 3 Vector'
            ],
        ),
    ]
    choices = inquirer.prompt(questions)
    kep_elements = {}

    if (len(choices['method']) == 0):
        # Apply the interpolation method
        kep_inter = interpolation.main(data_after_filter)
        # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
        # We set an estimate of measurement variance R = 0.01 ** 2
        kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
        kep_final_inter = np.transpose(kep_final_inter)
        kep_final_inter = np.resize(kep_final_inter, ((7, 1)))
        kep_final_inter[6, 0] = sgp4.rev_per_day(kep_final_inter[0, 0])
        kep_elements['Cubic Spline Interpolation'] = kep_final_inter
    else:
        for index, choice in enumerate(choices['method']):
            if (choice == 'Lamberts Kalman'):
                # Apply Lambert Kalman method for the filtered data set
                kep_lamb = lamberts_kalman.create_kep(data_after_filter)
                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_lamb = lamberts_kalman.kalman(kep_lamb, 0.01**2)
                kep_final_lamb = np.transpose(kep_final_lamb)
                kep_final_lamb = np.resize(kep_final_lamb, ((7, 1)))
                kep_final_lamb[6, 0] = sgp4.rev_per_day(kep_final_lamb[0, 0])
                kep_elements['Lamberts Kalman'] = kep_final_lamb
            elif (choice == 'Cubic Spline Interpolation'):
                # Apply the interpolation method
                kep_inter = interpolation.main(data_after_filter)
                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
                kep_final_inter = np.transpose(kep_final_inter)
                kep_final_inter = np.resize(kep_final_inter, ((7, 1)))
                kep_final_inter[6, 0] = sgp4.rev_per_day(kep_final_inter[0, 0])
                kep_elements['Cubic Spline Interpolation'] = kep_final_inter
            elif (choice == 'Ellipse Best Fit'):
                # Apply the ellipse best fit method
                kep_ellip = ellipse_fit.determine_kep(data_after_filter[:,
                                                                        1:])[0]
                kep_final_ellip = np.transpose(kep_ellip)
                kep_final_ellip = np.resize(kep_final_ellip, ((7, 1)))
                kep_final_ellip[6, 0] = sgp4.rev_per_day(kep_final_ellip[0, 0])
                kep_elements['Ellipse Best Fit'] = kep_final_ellip
            else:
                # Apply the Gibbs method
                kep_gibbs = gibbs_method.gibbs_get_kep(data_after_filter[:,
                                                                         1:])
                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_gibbs = lamberts_kalman.kalman(kep_gibbs, 0.01**2)
                kep_final_gibbs = np.transpose(kep_final_gibbs)
                kep_final_gibbs = np.resize(kep_final_gibbs, ((7, 1)))
                kep_final_gibbs[6, 0] = sgp4.rev_per_day(kep_final_gibbs[0, 0])
                kep_elements['Gibbs 3 Vector'] = kep_final_gibbs

    kep_final = np.zeros((7, len(kep_elements)))
    order = []
    for index, key in enumerate(kep_elements):
        kep_final[:, index] = np.ravel(kep_elements[key])
        order.append(str(key))

    # Print the final orbital elements for all solutions
    kep_elements = [
        "Semi major axis (a)(km)", "Eccentricity (e)", "Inclination (i)(deg)",
        "Argument of perigee (ω)(deg)",
        "Right acension of ascending node (Ω)(deg)", "True anomaly (v)(deg)",
        "Frequency (f)(rev/day)"
    ]
    for i in range(0, len(order)):
        print("\n******************Output for %s Method******************\n" %
              order[i])
        for j in range(0, 7):
            print("%s: %.16f" % (kep_elements[j], kep_final[j, i]))

    print("\nShow plots? [y/n]")
    user_input = input()

    if (user_input == "y" or user_input == "Y"):
        for j in range(0, len(order)):
            # Plot the initial data set, the filtered data set and the final orbit
            # First we transform the set of keplerian elements into a state vector
            state = kep_state.kep_state(np.resize(kep_final[:, j], (7, 1)))

            # Then we produce more state vectors at varius times using a Runge Kutta algorithm
            keep_state = np.zeros((6, 150))
            ti = 0.0
            tf = 1.0
            t_hold = np.zeros((150, 1))
            x = state
            h = 0.1
            tetol = 1e-04
            for i in range(0, 150):
                keep_state[:,
                           i] = np.ravel(rkf78.rkf78(6, ti, tf, h, tetol, x))
                t_hold[i, 0] = tf
                tf = tf + 1

            positions = keep_state[0:3, :]

            ## Finally we plot the graph
            mpl.rcParams['legend.fontsize'] = 10
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot(data[:, 1],
                    data[:, 2],
                    data[:, 3],
                    ".",
                    label='Initial data ')
            ax.plot(data_after_filter[:, 1],
                    data_after_filter[:, 2],
                    data_after_filter[:, 3],
                    "k",
                    linestyle='-',
                    label='Filtered data')
            ax.plot(positions[0, :],
                    positions[1, :],
                    positions[2, :],
                    "r-",
                    label='Orbit after %s method' % order[j])
            ax.legend()
            ax.can_zoom()
            ax.set_xlabel('x (km)')
            ax.set_ylabel('y (km)')
            ax.set_zlabel('z (km)')
            plt.show()
コード例 #2
0
def process(data_file, error_apriori, name):
    ''' Perform filtering and orbit determination methods.
    Applies filters and orbit determination techniques on the input data and saves the 
    output in dst folder.
    
    Args:
        data_file (numpy array): Raw orbit data
        error_apriori (float): apriori estimation of the measurements error in km
        name (str): name of the file being processed
    '''
    # Get positional data
    data = data_file

    # Units is km by default

    # Apply the Triple moving average filter with window = 3
    data_after_filter = triple_moving_average.generate_filtered_data(data, 3)

    # Use the golay_window.py script to find the window for the savintzky golay filter based on the error you input
    window = golay_window.window(error_apriori, data_after_filter)

    # Apply the Savintzky - Golay filter with window = 31 and polynomail parameter = 6
    data_after_filter = sav_golay.golay(data_after_filter, window, 3)

    # Compute the residuals between filtered data and initial data and then the sum and mean values of each axis
    res = data_after_filter[:, 1:4] - data[:, 1:4]
    sums = np.sum(res, axis=0)
    print("Displaying the sum of the residuals for each axis")
    print(sums)
    print(" ")

    means = np.mean(res, axis=0)
    print("Displaying the mean of the residuals for each axis")
    print(means)
    print(" ")

    # Save the filtered data into a new csv called "filtered"
    np.savetxt(os.path.join(os.getcwd(), "example_data", "DestinationCSV",
                            "%s_filtered.csv" % (name)),
               data_after_filter,
               delimiter=",")

    # Apply Lambert's solution for the filtered data set
    kep_lamb = lamberts_kalman.create_kep(data_after_filter)

    # Apply the interpolation method
    kep_inter = interpolation.main(data_after_filter)

    # Apply the Gibbs method
    kep_gibbs = gibbsMethod.gibbs_get_kep(data_after_filter[:, 1:])

    # Apply the ellipse best fit method
    kep_ellip = ellipse_fit.determine_kep(data_after_filter[:, 1:])[0]

    # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
    # set we a estimate of measurement vatiance R = 0.01 ** 2
    kep_final_lamb = lamberts_kalman.kalman(kep_lamb, 0.01**2)
    kep_final_lamb = np.transpose(kep_final_lamb)
    kep_final_lamb = np.resize(kep_final_lamb, ((7, 1)))
    kep_final_lamb[6, 0] = sgp4.rev_per_day(kep_final_lamb[0, 0])

    kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
    kep_final_inter = np.transpose(kep_final_inter)
    kep_final_inter = np.resize(kep_final_inter, ((7, 1)))
    kep_final_inter[6, 0] = sgp4.rev_per_day(kep_final_inter[0, 0])

    kep_final_ellip = np.transpose(kep_ellip)
    kep_final_ellip = np.resize(kep_final_ellip, ((7, 1)))
    kep_final_ellip[6, 0] = sgp4.rev_per_day(kep_final_ellip[0, 0])

    kep_final_gibbs = lamberts_kalman.kalman(kep_gibbs, 0.01**2)
    kep_final_gibbs = np.transpose(kep_final_gibbs)
    kep_final_gibbs = np.resize(kep_final_gibbs, ((7, 1)))
    kep_final_gibbs[6, 0] = sgp4.rev_per_day(kep_final_gibbs[0, 0])

    kep_final = np.zeros((7, 4))
    kep_final[:, 0] = np.ravel(kep_final_lamb)
    kep_final[:, 1] = np.ravel(kep_final_inter)
    kep_final[:, 2] = np.ravel(kep_final_ellip)
    kep_final[:, 3] = np.ravel(kep_final_gibbs)

    # Print the final orbital elements for all solutions
    kep_elements = [
        "Semi major axis (a)(km)", "Eccentricity (e)", "Inclination (i)(deg)",
        "Argument of perigee (omega)(deg)",
        "Right acension of ascending node (Omega)(deg)",
        "True anomaly (v)(deg)", "Frequency (f)(rev/day)"
    ]
    det_methods = [
        "Lamberts Kalman", "Spline Interpolation", "Ellipse Best Fit",
        "Gibbs 3 Vector"
    ]
    method_name = ["lamb", "inter", "ellip", "gibb"]

    for i in range(0, 4):
        print("\n******************Output for %s Method******************\n" %
              det_methods[i])
        j = 0
        for j in range(0, 7):
            print("%s: %.16f\n" % (kep_elements[j], kep_final[j, i]))

    print("\nSave plots? [y/n]")
    user_input = input()

    if (user_input == "y" or user_input == "Y"):
        for j in range(0, 4):
            # Plot the initial data set, the filtered data set and the final orbit
            # First we transform the set of keplerian elements into a state vector
            state = kep_state.kep_state(np.resize(kep_final[:, j], (7, 1)))

            # Then we produce more state vectors at varius times using a Runge Kutta algorithm
            keep_state = np.zeros((6, 150))
            ti = 0.0
            tf = 1.0
            t_hold = np.zeros((150, 1))
            x = state
            h = 0.1
            tetol = 1e-04
            for i in range(0, 150):
                keep_state[:,
                           i] = np.ravel(rkf78.rkf78(6, ti, tf, h, tetol, x))
                t_hold[i, 0] = tf
                tf = tf + 1

            positions = keep_state[0:3, :]

            ## Finally we plot the graph
            mpl.rcParams['legend.fontsize'] = 10
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot(data[:, 1],
                    data[:, 2],
                    data[:, 3],
                    ".",
                    label='Initial data ')
            ax.plot(data_after_filter[:, 1],
                    data_after_filter[:, 2],
                    data_after_filter[:, 3],
                    "k",
                    linestyle='-',
                    label='Filtered data')
            ax.plot(positions[0, :],
                    positions[1, :],
                    positions[2, :],
                    "r-",
                    label='Orbit after %s method' % det_methods[j])
            ax.legend()
            ax.can_zoom()
            ax.set_xlabel('x (km)')
            ax.set_ylabel('y (km)')
            ax.set_zlabel('z (km)')
            plt.savefig(os.path.join(os.getcwd(), "example_data",
                                     "DestinationSVG",
                                     '%s_%s.svg' % (name, method_name[j])),
                        format="svg")
            print("saved %s_%s.svg" % (name, method_name[j]))
コード例 #3
0
    # Earth's mass parameter in appropriate units:
    mu_Earth = 398600.435436E9  # m^3/seg^2
    #Earth's radius in appropriate units:
    # R_Earth =  6378136.3 #m
    #minimal acceptable altitude for satellites (150 km)??
    #maximal acceptable altitude for satellites (150 km)??

    #write file name of data:
    fname = '../orbit.csv'

    # load observational data:
    data = np.loadtxt(fname, skiprows=1, usecols=(0, 1, 2, 3))
    # generate vector of initial guess of orbital elements:
    # values written below correspond to solution of ellipse_fit.py for the same file
    data0 = __read_file(fname)
    kep0, res0 = determine_kep(data0)

    a_ = kep0[0][0]  # m
    e_ = kep0[1][0]
    I_ = np.deg2rad(kep0[2][0])  #deg
    omega_ = np.deg2rad(kep0[3][0])  #deg
    Omega_ = np.deg2rad(kep0[4][0])  #deg
    f_ = np.deg2rad(kep0[5][0])  #deg

    #estimate time of pericenter passage from true anomaly at epoch
    E_ = truean2eccan(e_, f_)  #ecc. anomaly
    M_ = E_ - e_ * np.sin(E_)  #mean anomaly
    n_ = meanmotion(mu_Earth, a_)  #mean motion
    taup_ = data[0, 0] - M_ / n_  #time of pericenter passage

    # this is the vector of initial guess of orbital elements:
コード例 #4
0
def test_ellipse_fit():
    """Tests ellipse fit with 8 satellites:
       * NOAA-1
       * GPS-23
       * Cryosat-2
       * NOAA-15
       * NOAA-18
       * NOAA-19
       * MOLNIYA 2-10
       * ISS

       To add your own test copy the template, put the 2nd row of the TLE of the satellite
       in place of kep. In the rkf5 line put the final time and time step such that 700±200
       points are generated. Now, put the actual orbital parameters in the assert statements.

       Args:
           NIL

       Returns:
           NIL
    """

    #noaa-1
    tle = np.array(
        [101.7540, 195.7370, 0.0031531, 352.8640, 117.2610, 12.53984625169364])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 7200, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(7826.006538, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0031531, 0.01)  # ecc
    assert kep[2] == pytest.approx(101.7540, 0.1)  # inc
    assert kep[3] == pytest.approx(352.8640, 1.0)  # argp
    assert kep[4] == pytest.approx(195.7370, 0.1)  # raan
    assert kep[5] == pytest.approx(117.2610, 0.5)  # true_anom

    #gps-23
    tle = np.array(
        [54.4058, 84.8417, 0.0142955, 74.4543, 193.5934, 2.00565117179872])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 43080, 50, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(26560.21419, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0142955, 0.01)  # ecc
    assert kep[2] == pytest.approx(54.4058, 0.1)  # inc
    assert kep[3] == pytest.approx(74.4543, 1.0)  # argp
    assert kep[4] == pytest.approx(84.8417, 0.1)  # raan
    assert kep[5] == pytest.approx(193.5934, 0.5)  # true_anom

    #cryosat-2
    tle = np.array(
        [92.0287, 282.8216, 0.0005088, 298.0188, 62.0505, 14.52172969429489])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 5950, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(7096.69719, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0005088, 0.01)  # ecc
    assert kep[2] == pytest.approx(92.0287, 0.1)  # inc
    assert kep[3] == pytest.approx(298.0188, 1.0)  # argp
    assert kep[4] == pytest.approx(282.8216, 0.1)  # raan
    assert kep[5] == pytest.approx(62.0505, 0.5)  # true_anom

    #noaa-15
    tle = np.array(
        [98.7705, 158.2195, 0.0009478, 307.8085, 52.2235, 14.25852803])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 6120, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(7183.76381, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0009478, 0.01)  # ecc
    assert kep[2] == pytest.approx(98.7705, 0.1)  # inc
    assert kep[3] == pytest.approx(307.8085, 1.0)  # argp
    assert kep[4] == pytest.approx(158.2195, 0.1)  # raan
    assert kep[5] == pytest.approx(52.2235, 0.5)  # true_anom

    #noaa-18
    tle = np.array(
        [99.1472, 176.6654, 0.0014092, 197.4778, 162.5909, 14.12376102669957])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 6120, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(7229.38911, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0014092, 0.01)  # ecc
    assert kep[2] == pytest.approx(99.1472, 0.1)  # inc
    assert kep[3] == pytest.approx(197.4778, 1.0)  # argp
    assert kep[4] == pytest.approx(176.6654, 0.1)  # raan
    assert kep[5] == pytest.approx(162.5909, 0.5)  # true_anom

    #noaa-19
    tle = np.array(
        [99.1401, 119.3629, 0.0014753, 44.0001, 316.2341, 14.12279464478196])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 6120, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(7229.71889, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0014753, 0.01)  # ecc
    assert kep[2] == pytest.approx(99.1401, 0.1)  # inc
    assert kep[3] == pytest.approx(44.0001, 1.0)  # argp
    assert kep[4] == pytest.approx(119.3629, 0.1)  # raan
    assert kep[5] == pytest.approx(316.2341, 0.5)  # true_anom

    #molniya 2-10
    tle = np.array(
        [63.2749, 254.2968, 0.7151443, 294.4926, 9.2905, 2.01190064320534])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 43000, 50, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(26505.1836, 0.1)  # sma
    assert kep[1] == pytest.approx(0.7151443, 0.01)  # ecc
    assert kep[2] == pytest.approx(63.2749, 0.1)  # inc
    assert kep[3] == pytest.approx(294.4926, 1.0)  # argp
    assert kep[4] == pytest.approx(254.2968, 0.1)  # raan
    assert kep[5] == pytest.approx(65.56742, 0.5)  # true_anom

    #ISS
    tle = np.array(
        [51.6402, 150.4026, 0.0004084, 108.2140, 238.0528, 15.54082454114406])
    r = tle_to_state(tle)
    _, vecs = rkf5(0, 5560, 10, r)
    r = np.reshape(r, (1, 6))
    vecs = np.insert(vecs, 0, r, axis=0)
    vecs = vecs[:, 0:3]

    kep, _ = determine_kep(vecs)
    assert kep[0] == pytest.approx(6782.95812, 0.1)  # sma
    assert kep[1] == pytest.approx(0.0004084, 0.01)  # ecc
    assert kep[2] == pytest.approx(51.6402, 0.1)  # inc
    assert kep[3] == pytest.approx(108.2140, 1.0)  # argp
    assert kep[4] == pytest.approx(150.4026, 0.1)  # raan
    assert kep[5] == pytest.approx(238.0528, 0.5)  # true_anom
コード例 #5
0
ファイル: main.py プロジェクト: aakash525/orbitdeterminator
def process(data_file, error_apriori, units):
    '''
    Given a .csv data file in the format of (time, x, y, z) applies both filters, generates a filtered.csv data
    file, prints out the final keplerian elements computed from both Lamberts and Interpolation and finally plots
    the initial, filtered data set and the final orbit.

    Args:
        data_file (string): The name of the .csv file containing the positional data
        error_apriori (float): apriori estimation of the measurements error in km

    Returns:
        Runs the whole process of the program
    '''
    # First read the csv file called "orbit" with the positional data
    data = read_data.load_data(data_file)

    if (units == 'm'):
        # Transform m to km
        data[:, 1:4] = data[:, 1:4] / 1000

    print("Choose filter(s) in the order you want to apply them")
    print(
        "(SPACE to change, UP/DOWN to navigate, RIGHT/LEFT to Select/Deselect and ENTER to Submit)"
    )
    print("*if nothing is selected program will run without applying filters")
    questions = [
        inquirer.Checkbox(
            'filter',
            message="Select filters",
            choices=[
                'Savintzky Golay Filter', 'Tripple Moving Average Filter'
            ],
        ),
    ]
    choices = inquirer.prompt(questions)
    data_after_filter = data

    if (len(choices['filter']) == 0):
        print("No filter selected, continuing without applying filter")
    else:
        for index, choice in enumerate(choices['filter']):

            if (choice == 'Savintzky Golay Filter'):
                print("Applying Savintzky Golay Filter")
                # Use the golay_window.py script to find the window for the savintzky golay filter based on the error you input
                window = golay_window.window(error_apriori, data_after_filter)

                # Apply the Savintzky - Golay filter with window = 31 and polynomail parameter = 6
                data_after_filter = sav_golay.golay(data_after_filter, window,
                                                    3)
            else:
                print("Applying Triple Moving Average Filter")
                # Apply the Triple moving average filter with window = 3
                data_after_filter = triple_moving_average.generate_filtered_data(
                    data_after_filter, 3)

    # Compute the residuals between filtered data and initial data and then the sum and mean values of each axis
    res = data_after_filter[:, 1:4] - data[:, 1:4]
    sums = np.sum(res, axis=0)
    print("\nDisplaying the sum of the residuals for each axis")
    print(sums)

    means = np.mean(res, axis=0)
    print("Displaying the mean of the residuals for each axis")
    print(means, "\n")

    # Save the filtered data into a new csv called "filtered"
    np.savetxt("filtered.csv", data_after_filter, delimiter=",")

    print("Choose Methods for Orbit Determination")
    print(
        "(SPACE to change, UP/DOWN to navigate, RIGHT/LEFT to Select/Deselect and ENTER to Submit)"
    )
    print(
        "*if nothing is selected program will determine orbit using Cubic Spline Interpolation"
    )
    questions = [
        inquirer.Checkbox(
            'method',
            message="Select Methods",
            choices=[
                'Lamberts Kalman Solutions', 'Cubic Spline Interpolation',
                'Ellipse Best Fit'
            ],
        ),
    ]
    choices = inquirer.prompt(questions)
    kep_elements = {}

    if (len(choices['method']) == 0):
        # Apply the interpolation method
        kep_inter = interpolation.main(data_after_filter)
        # Apply Kalman filters, estimate of measurement variance R = 0.01 ** 2
        kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
        kep_elements['Interpolation'] = np.transpose(kep_final_inter)
    else:
        for index, choice in enumerate(choices['method']):
            if (choice == 'Lamberts Kalman Solutions'):
                # Apply Lambert's solution for the filtered data set
                kep_lamb = lamberts_kalman.create_kep(data_after_filter)
                # Apply Kalman filters, estimate of measurement variance R = 0.01 ** 2
                kep_final_lamb = lamberts_kalman.kalman(kep_lamb, 0.01**2)
                kep_elements['Lambert'] = np.transpose(kep_final_lamb)

            elif (choice == 'Cubic Spline Interpolation'):
                # Apply the interpolation method
                kep_inter = interpolation.main(data_after_filter)
                # Apply Kalman filters, estimate of measurement variance R = 0.01 ** 2
                kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
                kep_elements['Interpolation'] = np.transpose(kep_final_inter)
            elif (choice == 'Ellipse Best Fit'):
                # Fitting an ellipse on filtered data
                kep_elements['Ellipse-Fit'] = (ellipse_fit.determine_kep(
                    data_after_filter[:, 1:]))[0]

    kep_final = np.zeros((6, len(kep_elements)))
    order = []
    for index, key in enumerate(kep_elements):
        kep_final[:, index] = np.ravel(kep_elements[key])
        order.append(str(key))

    # Print the final orbital elements for both solutions
    print(
        "Displaying the final keplerian elements with methods in column order: {}"
        .format(", ".join(order)))
    print(kep_final)
    print("\n")

    # Plot the initial data set, the filtered data set and the final orbit

    # First we transform the set of keplerian elements into a state vector
    state = kep_state.kep_state(kep_elements[order[0]])

    # Then we produce more state vectors at varius times using a Runge Kutta algorithm
    keep_state = np.zeros((6, 150))
    ti = 0.0
    tf = 1.0
    t_hold = np.zeros((150, 1))
    x = state
    h = 0.1
    tetol = 1e-04
    for i in range(0, 150):
        keep_state[:, i] = np.ravel(rkf78.rkf78(6, ti, tf, h, tetol, x))
        t_hold[i, 0] = tf
        tf = tf + 1

    positions = keep_state[0:3, :]

    ## Finally we plot the graph
    mpl.rcParams['legend.fontsize'] = 10
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(data[:, 1], data[:, 2], data[:, 3], ".", label='Initial data ')
    ax.plot(data_after_filter[:, 1],
            data_after_filter[:, 2],
            data_after_filter[:, 3],
            "k",
            linestyle='-',
            label='Filtered data')
    ax.plot(positions[0, :],
            positions[1, :],
            positions[2, :],
            "r-",
            label='Orbit after {} method'.format(order[0]))
    ax.legend()
    ax.can_zoom()
    ax.set_xlabel('x (km)')
    ax.set_ylabel('y (km)')
    ax.set_zlabel('z (km)')
    plt.show()
コード例 #6
0
ファイル: main.py プロジェクト: subhayu99/orbitdeterminator
def process(data_file, error_apriori, units):
    '''
    Given a .csv data file in the format of (time, x, y, z) applies both filters, generates a filtered.csv data
    file, prints out the final keplerian elements computed from both Lamberts and Interpolation and finally plots
    the initial, filtered data set and the final orbit.

    Args:
        data_file (string): The name of the .csv file containing the positional data
        error_apriori (float): apriori estimation of the measurements error in km

    Returns:
        Runs the whole process of the program
    '''

    # First read the csv file called "orbit" with the positional data
    print("Imported file format is:",
          read_data.detect_file_format(data_file)["file"])
    print("")
    data = read_data.load_data(data_file)

    if (units == 'm'):
        # Transform m to km
        data[:, 1:4] = data[:, 1:4] / 1000

    print(
        "***********Choose filter(s) in desired order of application***********"
    )
    print(
        "(SPACE to toggle, UP/DOWN to navigate, RIGHT/LEFT to select/deselect and ENTER to submit)"
    )
    print(
        "*if nothing is selected, Triple Moving Average followed by Savitzky Golay will be applied"
    )
    questions = [
        inquirer.Checkbox(
            'filter',
            message="Select filter(s)",
            choices=[
                'None', 'Savitzky Golay Filter',
                'Triple Moving Average Filter', 'Wiener Filter'
            ],
        ),
    ]
    choices = inquirer.prompt(questions)
    data_after_filter = data

    if (len(choices['filter']) == 0):
        print("Applying Triple Moving Average followed by Savitzky Golay...")
        # Apply the Triple moving average filter with window = 3
        data_after_filter = triple_moving_average.generate_filtered_data(
            data_after_filter, 3)

        # Use the golay_window.py script to find the window for the Savitzky Golay filter based on the error you input
        window = golay_window.window(error_apriori, data_after_filter)

        polyorder = 3
        if polyorder < window:
            # Apply the Savitzky Golay filter with window = window (51 for example_data/orbit.csv) and polynomial order = 3
            data_after_filter = sav_golay.golay(data_after_filter, window,
                                                polyorder)

    else:
        for index, choice in enumerate(choices['filter']):
            if (choice == 'None'):
                print("Using the original data...")
                # no filter is applied
                data_after_filter = data_after_filter

            elif (choice == 'Savitzky Golay Filter'):
                print("Applying Savitzky Golay Filter...")
                # Use the golay_window.py script to find the window for the Savitzky Golay filter
                # based on the error you input
                window = golay_window.window(error_apriori, data_after_filter)

                polyorder = 3
                if polyorder < window:
                    # Apply the Savitzky Golay filter with window = window (51 for example_data/orbit.csv) and polynomial order = 3
                    data_after_filter = sav_golay.golay(
                        data_after_filter, window, polyorder)

            elif (choice == 'Wiener Filter'):
                print("Applying Wiener Filter...")
                # Apply the Wiener filter
                data_after_filter = wiener.wiener_new(data_after_filter, 3)

            else:
                print("Applying Triple Moving Average Filter...")
                # Apply the Triple moving average filter with window = 3
                data_after_filter = triple_moving_average.generate_filtered_data(
                    data_after_filter, 3)

    # Compute the residuals between filtered data and initial data and then the sum and mean values of each axis
    res = data_after_filter[:, 1:4] - data[:, 1:4]
    sums = np.sum(res, axis=0)
    print("\nDisplaying the sum of the residuals for each axis")
    print(sums, "\n")

    means = np.mean(res, axis=0)
    print("Displaying the mean of the residuals for each axis")
    print(means, "\n")

    # Save the filtered data into a new csv called "filtered"
    np.savetxt("filtered.csv", data_after_filter, delimiter=",")

    print("***********Choose Method(s) for Orbit Determination***********")
    print(
        "(SPACE to toggle, UP/DOWN to navigate, RIGHT/LEFT to select/deselect and ENTER to submit)"
    )
    print(
        "*if nothing is selected, Cubic Spline Interpolation will be used for Orbit Determination"
    )
    questions = [
        inquirer.Checkbox(
            'method',
            message="Select Method(s)",
            choices=[
                'Lamberts Kalman', 'Cubic Spline Interpolation',
                'Ellipse Best Fit', 'Gibbs 3 Vector', 'Gauss 3 Vector',
                'MCMC (exp.)'
            ],
        ),
    ]
    choices = inquirer.prompt(questions)
    kep_elements = {}

    if (len(choices['method']) == 0):
        # Apply the interpolation method
        kep_inter = interpolation.main(data_after_filter)
        # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
        # We set an estimate of measurement variance R = 0.01 ** 2
        kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
        kep_final_inter = np.transpose(kep_final_inter)
        kep_final_inter = np.resize(kep_final_inter, ((7, 1)))
        kep_final_inter[6, 0] = sgp4.rev_per_day(kep_final_inter[0, 0])
        kep_elements['Cubic Spline Interpolation'] = kep_final_inter

    else:
        for index, choice in enumerate(choices['method']):
            if (choice == 'Lamberts Kalman'):
                # Apply Lambert Kalman method for the filtered data set

                #previously, all data...
                #kep_lamb = lamberts_kalman.create_kep(data_after_filter)

                # only three (3) observations from half an orbit.
                # also just two (2) observations are fine for lamberts.
                data = np.array([
                    data_after_filter[:, :][0],
                    data_after_filter[:, :][len(data_after_filter) // 2],
                    data_after_filter[:, :][-1]
                ])

                kep_lamb = lamberts_kalman.create_kep(data)

                # Determination of orbit period
                semimajor_axis = kep_lamb[0][0]
                timestamps = data_after_filter[:, 0]

                index = get_timestamp_index_by_orbitperiod(
                    semimajor_axis, timestamps)

                # enough data for half orbit
                data = np.array([
                    data_after_filter[:, :][0],
                    data_after_filter[:, :][index // 2],
                    data_after_filter[:, :][index]
                ])

                kep_lamb = lamberts_kalman.create_kep(data)

                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_lamb = lamberts_kalman.kalman(kep_lamb, 0.01**2)
                kep_final_lamb = np.transpose(kep_final_lamb)
                kep_final_lamb = np.resize(kep_final_lamb, ((7, 1)))
                kep_final_lamb[6, 0] = sgp4.rev_per_day(kep_final_lamb[0, 0])
                kep_elements['Lamberts Kalman'] = kep_final_lamb

            elif (choice == 'Cubic Spline Interpolation'):
                # Apply the interpolation method
                kep_inter = interpolation.main(data_after_filter)
                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_inter = lamberts_kalman.kalman(kep_inter, 0.01**2)
                kep_final_inter = np.transpose(kep_final_inter)
                kep_final_inter = np.resize(kep_final_inter, ((7, 1)))
                kep_final_inter[6, 0] = sgp4.rev_per_day(kep_final_inter[0, 0])
                kep_elements['Cubic Spline Interpolation'] = kep_final_inter

            elif (choice == 'Ellipse Best Fit'):
                # Apply the ellipse best fit method
                kep_ellip = ellipse_fit.determine_kep(data_after_filter[:,
                                                                        1:])[0]
                kep_final_ellip = np.transpose(kep_ellip)
                kep_final_ellip = np.resize(kep_final_ellip, ((7, 1)))
                kep_final_ellip[6, 0] = sgp4.rev_per_day(kep_final_ellip[0, 0])
                kep_elements['Ellipse Best Fit'] = kep_final_ellip

            elif (choice == 'Gibbs 3 Vector'):
                # Apply the Gibbs method

                # first only with first, middle and last measurement
                R = np.array([
                    data_after_filter[:, 1:][0],
                    data_after_filter[:, 1:][len(data_after_filter) // 2],
                    data_after_filter[:, 1:][-1]
                ])

                kep_gibbs = gibbs_method.gibbs_get_kep(R)

                # Determination of orbit period
                semimajor_axis = kep_gibbs[0][0]
                timestamps = data_after_filter[:, 0]

                index = get_timestamp_index_by_orbitperiod(
                    semimajor_axis, timestamps)

                # enough data for half orbit
                R = np.array([
                    data_after_filter[:, 1:][0],
                    data_after_filter[:, 1:][index // 2],
                    data_after_filter[:, 1:][index]
                ])

                kep_gibbs = gibbs_method.gibbs_get_kep(R)

                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_gibbs = lamberts_kalman.kalman(kep_gibbs, 0.01**2)
                kep_final_gibbs = np.transpose(kep_final_gibbs)
                kep_final_gibbs = np.resize(kep_final_gibbs, ((7, 1)))
                kep_final_gibbs[6, 0] = sgp4.rev_per_day(kep_final_gibbs[0, 0])
                kep_elements['Gibbs 3 Vector'] = kep_final_gibbs

            elif (choice == 'Gauss 3 Vector'):
                # Apply the Gauss method

                # first only with first, middle and last measurement
                R = np.array([
                    data_after_filter[:, 1:][0],
                    data_after_filter[:, 1:][len(data_after_filter) // 2],
                    data_after_filter[:, 1:][-1]
                ])

                t1 = data_after_filter[:, 0][0]
                t2 = data_after_filter[:, 0][len(data_after_filter) // 2]
                t3 = data_after_filter[:, 0][-1]

                v2 = gauss_method.gauss_method_get_velocity(
                    R[0], R[1], R[2], t1, t2, t3)

                # Determination of orbit period
                semimajor_axis = oe.semimajor_axis(R[0], v2)
                timestamps = data_after_filter[:, 0]

                index = get_timestamp_index_by_orbitperiod(
                    semimajor_axis, timestamps)

                # enough data for half orbit
                R = np.array([
                    data_after_filter[:, 1:][0],
                    data_after_filter[:, 1:][index // 2],
                    data_after_filter[:, 1:][index]
                ])

                t1 = data_after_filter[:, 0][0]
                t2 = data_after_filter[:, 0][index // 2]
                t3 = data_after_filter[:, 0][index]

                v2 = gauss_method.gauss_method_get_velocity(
                    R[0], R[1], R[2], t1, t2, t3)

                semimajor_axis = oe.semimajor_axis(R[0], v2)
                ecc = oe.eccentricity_v(R[1], v2)
                ecc = np.linalg.norm(ecc)
                inc = oe.inclination(R[1], v2) * 180.0 / np.pi
                AoP = oe.AoP(R[1], v2) * 180.0 / np.pi
                raan = oe.raan(R[1], v2) * 180.0 / np.pi
                true_anomaly = oe.true_anomaly(R[1], v2) * 180.0 / np.pi
                T_orbitperiod = oe.T_orbitperiod(semimajor_axis=semimajor_axis)
                n_mean_motion_perday = oe.n_mean_motion_perday(T_orbitperiod)

                kep_gauss = np.array([[
                    semimajor_axis, ecc, inc, AoP, raan, true_anomaly,
                    n_mean_motion_perday
                ]])

                # Apply Kalman filters to find the best approximation of the keplerian elements for all solutions
                # We set an estimate of measurement variance R = 0.01 ** 2
                kep_final_gauss = lamberts_kalman.kalman(kep_gauss, 0.01**2)
                kep_final_gauss = np.transpose(kep_final_gauss)
                kep_final_gauss = np.resize(kep_final_gauss, ((7, 1)))
                kep_final_gauss[6, 0] = sgp4.rev_per_day(kep_final_gauss[0, 0])
                kep_elements['Gauss 3 Vector'] = kep_final_gauss

            else:
                # apply mcmc method, a real optimizer

                # all data
                timestamps = data_after_filter[:, 0]
                R = np.array(data_after_filter[:, 1:])

                # all data can make the MCMC very slow. so we just pick a few in random, but in order.
                timestamps_short = []
                R_short = []
                if len(timestamps) > 25:
                    print(
                        "Too many positions for MCMC. Just 25 positons are selected"
                    )

                    # pick randomly, but in order and no duplicates
                    l = list(
                        np.linspace(0,
                                    len(timestamps) - 1,
                                    num=len(timestamps)))
                    select_index = sorted(random.sample(list(l)[1:-1], k=23))
                    print(select_index)

                    timestamps_short.append(timestamps[0])
                    R_short.append(R[0])

                    for select in range(len(select_index)):
                        timestamps_short.append(timestamps[int(
                            select_index[select])])
                        R_short.append(R[int(select_index[select])])

                    timestamps_short.append(timestamps[-1])
                    R_short.append(R[-1])

                else:
                    timestamps_short = timestamps
                    R_short = R

                parameters = with_mcmc.fromposition(timestamps_short, R_short)

                r_a = parameters["r_a"]
                r_p = parameters["r_p"]
                AoP = parameters["AoP"]
                inc = parameters["inc"]
                raan = parameters["raan"]
                tp = parameters["tp"]

                semimajor_axis = (r_p + r_a) / 2.0
                ecc = (r_a - r_p) / (r_a + r_p)
                T_orbitperiod = oe.T_orbitperiod(semimajor_axis=semimajor_axis)
                true_anomaly = tp / T_orbitperiod * 360.0
                n_mean_motion_perday = oe.n_mean_motion_perday(T_orbitperiod)

                kep_mcmc = np.array([[
                    semimajor_axis, ecc, inc, AoP, raan, true_anomaly,
                    n_mean_motion_perday
                ]])

                kep_elements['MCMC (exp.)'] = kep_mcmc

    kep_final = np.zeros((7, len(kep_elements)))
    order = []
    for index, key in enumerate(kep_elements):
        kep_final[:, index] = np.ravel(kep_elements[key])
        order.append(str(key))

    # Print the final orbital elements for all solutions
    kep_elements = [
        "Semi major axis (a)(km)", "Eccentricity (e)", "Inclination (i)(deg)",
        "Argument of perigee (ω)(deg)",
        "Right acension of ascending node (Ω)(deg)", "True anomaly (v)(deg)",
        "Frequency (f)(rev/day)"
    ]

    for i in range(0, len(order)):
        print("\n******************Output for %s Method******************\n" %
              order[i])
        for j in range(0, 7):
            print("%s: %.16f" % (kep_elements[j], kep_final[j, i]))

    print("\nShow plots? [y/n]")
    user_input = input()

    if (user_input == "y" or user_input == "Y"):
        for j in range(0, len(order)):
            # Plot the initial data set, the filtered data set and the final orbit
            # First we transform the set of keplerian elements into a state vector
            state = kep_state.kep_state(np.resize(kep_final[:, j], (7, 1)))

            # Then we produce more state vectors at varius times using a Runge Kutta algorithm
            keep_state = np.zeros((6, 150))
            ti = 0.0
            tf = 1.0
            t_hold = np.zeros((150, 1))
            x = state
            h = 0.1
            tetol = 1e-04
            for i in range(0, 150):
                keep_state[:,
                           i] = np.ravel(rkf78.rkf78(6, ti, tf, h, tetol, x))
                t_hold[i, 0] = tf
                tf = tf + 1

            positions = keep_state[0:3, :]

            ## Finally we plot the graph
            mpl.rcParams['legend.fontsize'] = 10
            fig = plt.figure()
            ax = plt.axes(projection='3d')
            ax.plot(data[:, 1],
                    data[:, 2],
                    data[:, 3],
                    ".",
                    label='Initial data ')
            ax.plot(data_after_filter[:, 1],
                    data_after_filter[:, 2],
                    data_after_filter[:, 3],
                    "k",
                    linestyle='-',
                    label='Filtered data')
            ax.plot(positions[0, :],
                    positions[1, :],
                    positions[2, :],
                    "r-",
                    label='Orbit after %s method' % order[j])
            ax.legend()
            ax.can_zoom()
            ax.set_xlabel('x (km)')
            ax.set_ylabel('y (km)')
            ax.set_zlabel('z (km)')
            plt.show()