예제 #1
0
def test_tle_export():
    """Check `export_tle()` round-trip using all the TLEs in the test file.

    This iterates through the satellites in "SGP4-VER.TLE",
    generates `Satrec` objects and exports the TLEs.  These exported
    TLEs are then compared to the original TLE, closing the loop (or
    the round-trip).

    """
    data = get_data(__name__, 'SGP4-VER.TLE')
    tle_lines = iter(data.decode('ascii').splitlines())

    # Skip these lines, known errors
    # Resulting TLEs are equivalent (same values in the Satrec object), but they are not the same
    # 25954: BSTAR = 0 results in a negative exp, not positive
    # 29141: BSTAR = 0.13519 results in a negative exp, not positive
    # 33333: Checksum error as expected on both lines
    # 33334: Checksum error as expected on line 1
    # 33335: Checksum error as expected on line 1
    expected_errs_line1 = set([25954, 29141, 33333, 33334, 33335])
    expected_errs_line2 = set([33333, 33335])

    if accelerated:
        # Non-standard: omits the ephemeris type integer.
        expected_errs_line1.add(11801)

    for line1 in tle_lines:

        if not line1.startswith('1'):
            continue

        line2 = next(tle_lines)

        # trim lines to normal TLE string size
        line1 = line1[:69]
        line2 = line2[:69]
        satrec = Satrec.twoline2rv(line1, line2)
        satrec_old = io.twoline2rv(line1, line2, wgs72)

        # Generate TLE from satrec
        out_line1, out_line2 = export_tle(satrec)
        out_line1_old, out_line2_old = export_tle(satrec_old)

        if satrec.satnum not in expected_errs_line1:
            assertEqual(out_line1, line1)
            assertEqual(out_line1_old, line1)
        if satrec.satnum not in expected_errs_line2:
            assertEqual(out_line2, line2)
            assertEqual(out_line2_old, line2)
예제 #2
0
파일: tle.py 프로젝트: turkmvc/satmad
    def export_tle(self):
        """
        Exports the TLE to line1 and line2.

        A sample output looks like this::

            line1 = "1 25544U 98067A   08264.51782528 -.00002182  00000-0 -11606-4 0  2927"
            line2 = "2 25544  51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537"

        Returns
        -------
        line1, line2 : (str, str)
            strings containing line 1, line 2
        """
        line1, line2 = export_tle(self._satrec)

        return line1, line2
예제 #3
0
파일: tle.py 프로젝트: turkmvc/satmad
    def __str__(self):
        """
        Exports the TLE as a Three-Line string, with name, line1 and line2.

        A sample output looks like this::

            ISS (ZARYA)
            1 25544U 98067A   08264.51782528 -.00002182  00000-0 -11606-4 0  2927
            2 25544  51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537

        Returns
        -------
        str
            string containing line 1, line 2 and name of the satellite
        """
        line1, line2 = export_tle(self._satrec)

        txt = ""
        if self._name is not None and self._name.strip():
            txt += self._name + "\n"

        txt += line1 + "\n" + line2 + "\n"

        return txt
예제 #4
0
def generate_tles_from_scratch_with_sgp(filename_out, constellation_name,
                                        num_orbits, num_sats_per_orbit,
                                        phase_diff, inclination_degree,
                                        eccentricity, arg_of_perigee_degree,
                                        mean_motion_rev_per_day):

    with open(filename_out, "w+") as f_out:

        # First line:
        #
        # <number of orbits> <number of satellites per orbit>
        #
        f_out.write("%d %d\n" % (num_orbits, num_sats_per_orbit))

        # Each of the subsequent (number of orbits * number of satellites per orbit) blocks
        # define a satellite as follows:
        #
        # <constellation_name> <global satellite id>
        # <TLE line 1>
        # <TLE line 2>
        satellite_counter = 0
        for orbit in range(0, num_orbits):

            # Orbit-dependent
            raan_degree = orbit * 360.0 / num_orbits
            orbit_wise_shift = 0
            if orbit % 2 == 1:
                if phase_diff:
                    orbit_wise_shift = 360.0 / (num_sats_per_orbit * 2.0)

            # For each satellite in the orbit
            for n_sat in range(0, num_sats_per_orbit):
                mean_anomaly_degree = orbit_wise_shift + (n_sat * 360 /
                                                          num_sats_per_orbit)

                # Epoch is set to the year 2000
                # This conveniently in TLE format gives 00001.00000000
                # for the epoch year and Julian day fraction entry
                jd, fr = jday(2000, 1, 1, 0, 0, 0)

                # Use SGP-4 to generate TLE
                sat_sgp4 = Satrec()

                # Based on: https://pypi.org/project/sgp4/
                sat_sgp4.sgp4init(
                    WGS72,  # Gravity model [1]
                    'i',  # Operating mode (a = old AFPSC mode, i = improved mode)
                    satellite_counter + 1,  # satnum:  satellite number
                    (jd + fr) -
                    2433281.5,  # epoch:   days since 1949 December 31 00:00 UT [2]
                    0.0,  # bstar:   drag coefficient (kg/m2er)
                    0.0,  # ndot:    ballistic coefficient (revs/day)
                    0.0,  # nndot:   second derivative of mean motion (revs/day^3)
                    eccentricity,  # ecco:    eccentricity
                    math.radians(arg_of_perigee_degree
                                 ),  # argpo:   argument or perigee (radians)
                    math.radians(
                        inclination_degree),  # inclo:    inclination(radians)
                    math.radians(mean_anomaly_degree
                                 ),  # mo:       mean anomaly (radians)
                    mean_motion_rev_per_day * 60 /
                    13750.9870831397,  # no_kazai: mean motion (radians/minute) [3]
                    math.radians(raan_degree)  # nodeo:    right ascension of
                    #           ascending node (radians)
                )

                # Side notes:
                # [1] WGS72 is also used in the NS-3 model
                # [2] Due to a bug in sgp4init, the TLE below irrespective of the value here gives zeros.
                # [3] Conversion factor from:
                #     https://www.translatorscafe.com/unit-converter/en-US/ (continue on next line)
                #     velocity-angular/1-9/radian/second-revolution/day/
                #

                # Export TLE from the SGP-4 object
                line1, line2 = export_tle(sat_sgp4)

                # Line 1 has some problems: there are unknown characters entered for the international
                # designator, and the Julian date is not respected
                # As such, we set our own bogus international designator 00000ABC
                # and we set our own epoch date as 1 January, 2000
                # Why it's 00001.00000000: https://www.celestrak.com/columns/v04n03/#FAQ04
                tle_line1 = line1[:7] + "U 00000ABC 00001.00000000 " + line1[
                    33:]
                tle_line1 = tle_line1[:68] + str(
                    calculate_tle_line_checksum(tle_line1[:68]))
                tle_line2 = line2

                # Check that the checksum is correct
                if len(tle_line1) != 69 or calculate_tle_line_checksum(
                        tle_line1[:68]) != int(tle_line1[68]):
                    raise ValueError("TLE line 1 checksum failed")
                if len(tle_line2) != 69 or calculate_tle_line_checksum(
                        tle_line2[:68]) != int(tle_line2[68]):
                    raise ValueError("TLE line 2 checksum failed")

                # Write TLE to file
                f_out.write(constellation_name + " " +
                            str(orbit * num_sats_per_orbit + n_sat) + "\n")
                f_out.write(tle_line1 + "\n")
                f_out.write(tle_line2 + "\n")

                # One more satellite there
                satellite_counter += 1
예제 #5
0
def find_orbit(nwalkers,
               ndim,
               pos,
               parameters,
               finding,
               loops,
               walks,
               counter,
               station,
               timestamp_min,
               timestamps,
               mode,
               measurements,
               orbit,
               meta=[[]],
               generated={}):

    # preparing the optimizer
    sampler = emcee.EnsembleSampler(nwalkers,
                                    ndim,
                                    log_probability,
                                    args=(parameters, finding, station,
                                          timestamp_min, timestamps, mode,
                                          measurements, orbit, meta))

    # preparing the storage of the best result of all loops
    results_min = []
    for i in range(ndim):
        results_min.append([])
    residual_min = []

    result_b4 = np.zeros(len(pos))
    b4 = 0
    b4_tle_line1 = ""
    b4_tle_line2 = ""
    b4_result = []

    # now we can run the loops at each iteration we have the EMCEE results
    for i in range(loops):
        #start the optimization with emcee
        pos, prob, state = sampler.run_mcmc(pos, walks, progress=True)

        # extracting the orbit parameters back from the resulting POS.
        # in this case, we just use the best result, which is argmax of POS
        r_p, r_a, AoP, inc, raan, tp, bstar, td = get_kepler_parameters(
            pos[np.argmax(prob)], parameters, finding, orbit)

        eccentricity = (r_a - r_p) / (r_a + r_p)
        h_angularmomentuum = np.sqrt(r_p * (1.0 + eccentricity * np.cos(0)) *
                                     mu)
        T_orbitperiod = 2.0 * np.pi / mu**2.0 * (
            h_angularmomentuum / np.sqrt(1.0 - eccentricity**2))**3

        me = tp * (2.0 * np.pi) / T_orbitperiod * 180.0 / np.pi
        me = zeroTo360(me)
        AoP = zeroTo360(AoP)
        raan = zeroTo360(raan)
        n = 24.0 * 3600.0 / T_orbitperiod

        satnum = 0
        epoch = timestamp_min
        ecco = eccentricity
        argpo = AoP
        inclo = inc
        mo = me
        no_kozai = n
        nodeo = raan
        ndot = 0.0
        satrec = get_satrec(satnum,
                            epoch,
                            ecco,
                            argpo,
                            inclo,
                            mo,
                            no_kozai,
                            nodeo,
                            bstar,
                            ndot,
                            nddot=0.0)
        tle_line1, tle_line2 = exporter.export_tle(satrec)

        if i == 0:
            b4 = np.max(prob)
            b4_tle_line1 = tle_line1
            b4_tle_line2 = tle_line2
            b4_result = pos[np.argmax(prob)]
        else:
            if np.max(prob) > b4:
                b4 = np.max(prob)
                b4_tle_line1 = tle_line1
                b4_tle_line2 = tle_line2
                b4_result = pos[np.argmax(prob)]

        #print("prob", np.max(prob), np.argmax(prob), b4)
        #print(pos[np.argmax(prob)])

        #save_progress(plotnames, counter, r_p, r_a, AoP, inc, raan, tp, bstar, td, np.max(prob), s1, t1, mode, filename_1)
        #save_progress_pos(plotnames, pos, prob, state)
        '''
        for ii in range(ndim):
            results_min[ii].append(pos[np.argmax(prob)][ii])
        residual_min.append(np.max(prob))
        plt.plot(np.abs(residual_min))
        plt.yscale("log")
        plt.grid()
        plt.savefig(plotnames+"_residual")
        plt.clf()
        plt.plot(results_min[0])
        plt.plot(results_min[1])
        plt.grid()
        plt.savefig(plotnames+"_radius")
        plt.clf()
        print(np.mean(results_min[0]), np.mean(results_min[1]))
        '''

        #get_state_plot(r_a, r_p, inc, raan, AoP, tp, bstar, td, station, timestamp_min, timestamps, mode, measurements)

        samples = sampler.chain[:, 0:, :].reshape((-1, ndim))

        result_percentile = np.percentile(samples, [16, 50, 84], axis=0)

        #import corner
        #import matplotlib.pyplot as plt
        #flat_samples = samples
        #fig = corner.corner(flat_samples)
        #plt.show()

        #print(samples.shape)
        #print(len(samples))
        #print(samples[:, 0])
        #print(samples[:, 1])
        #print(samples[:, 2])
        #print(samples[:, 3])
        #print(samples[:, 4])
        #print(samples[:, 5])

        #plt.plot(samples[:, 0])
        #plt.plot(samples[:, 1])
        #plt.show()
        #print(np.mean(samples[:, 0]))
        #print(np.mean(samples[:, 1]))

        for r in range(len(result_percentile[1])):

            for key in finding.keys():
                if finding[key] == r:
                    parameters_name = key

                #if finding[key].keys() > 1:
                #    for keykey in finding[key].keys():
                #        if finding[key][keykey] == r:
                #            parameters_name = r

            result_b4[r] = result_percentile[1][r]

        print("tle_line1:", b4_tle_line1)
        print("tle_line2:", b4_tle_line2)
        if "tle" in generated:
            print(
                "compare",
                compare(b4_tle_line1, b4_tle_line2, generated["tle"]["line1"],
                        generated["tle"]["line2"], timestamp_min, timestamps,
                        td))
        print("rp=", r_p, "ra=", r_a, "AoP=", AoP, "inc=", inc, "raan=", raan,
              "tp=", tp, "bstar=", bstar, "td=", td)
        print("overall", counter + 1, i + 1, "/", loops, "rms=", b4,
              "runtime=",
              time.time() - starttime)
        print("")

        # filtering the POS to change the values within their limits.
        # this shall help also with the percentiles and averages
        keys = list(finding.keys())
        for k in range(len(pos)):
            for l in range(len(pos[k])):

                if keys[l] == "AoP":
                    pos[k][l] = zeroTo360(pos[k][l])

                if keys[l] == "raan":
                    pos[k][l] = zeroTo360(pos[k][l])

                if keys[l] == "inc":
                    pos[k][l] = zeroTo180(pos[k][l])

        counter += 1
        sampler.reset()

    return b4_result, counter