예제 #1
0
def build_measurements(param):
    output = []
    inputs = read_param(param)
    for inp in inputs:
        obj = messages_pb2.Measurement()
        output.append(obj)
        for dest, src in _measurement_fields.items():
            fld = inp.get(src)
            if (fld):
                if (isinstance(fld, list)):
                    getattr(obj, dest).extend(fld)
                else:
                    setattr(obj, dest, fld)

    return (output)
예제 #2
0
def plot(config,
         measurements,
         orbit_fit,
         interactive=False,
         output_file_path=None):
    cfg = read_param(config)
    inp = [
        x for x in read_param(measurements)
        if ("Station" in x or "Position" in x or "PositionVelocity" in x)
    ]
    out = [
        x for x in read_param(orbit_fit) if ("PreFit" in x and "PostFit" in x)
    ]

    key = list(cfg["Measurements"].keys())
    dmcrun = (cfg["Estimation"].get("DMCCorrTime", 0.0) > 0.0
              and cfg["Estimation"].get("DMCSigmaPert", 0.0) > 0.0)
    dmcidx = 6

    cd = cfg.get("Drag", {}).get("Coefficient", {}).get("Estimation", "")
    cr = cfg.get("RadiationPressure", {}).get("Creflection",
                                              {}).get("Estimation", "")
    if (cd == "Estimate"):
        dmcidx += 1
    if (cr == "Estimate"):
        dmcidx += 1

    parnames = []
    if (cd == "Estimate" or (cd == "Consider" and cr == "Consider")):
        parnames.extend([r"$C_D$", r"$C_R$"])
    else:
        parnames.extend([r"$C_R$", r"$C_D$"])

    for sk, sv in cfg.get("Stations", {}).items():
        if (sv.get("BiasEstimation", "") in ["Estimate", "Consider"]):
            for m in cfg.get("Measurements", {}).keys():
                parnames.append(sk + m)

    tstamp,prefit,posfit,inocov,params,estmacc,estmcov = [],[],[],[],[],[],[]
    for i, o in zip(inp, out):
        tstamp.append(dateutil.parser.isoparse(i["Time"]))
        if (key[0] == "Position" or key[0] == "PositionVelocity"):
            prefit.append(
                [ix - ox for ix, ox in zip(i[key[0]], o["PreFit"][key[0]])])
            posfit.append(
                [ix - ox for ix, ox in zip(i[key[0]], o["PostFit"][key[0]])])
        else:
            if (len(key) == 2):
                prefit.append([
                    i[key[0]] - o["PreFit"][key[0]][-1],
                    i[key[1]] - o["PreFit"][key[1]][-1]
                ])
                posfit.append([
                    i[key[0]] - o["PostFit"][key[0]][-1],
                    i[key[1]] - o["PostFit"][key[1]][-1]
                ])
            else:
                prefit.append([i[key[0]] - o["PreFit"][key[0]][-1]])
                posfit.append([i[key[0]] - o["PostFit"][key[0]][-1]])

        p = []
        for m in range(len(o["InnovationCovariance"])):
            p.append(3.0 * numpy.sqrt(o["InnovationCovariance"][m][m]))
        inocov.append(p)

        if (len(o["EstimatedState"]) > 6):
            if (dmcrun):
                params.append(o["EstimatedState"][6:dmcidx] +
                              o["EstimatedState"][dmcidx + 3:])
            else:
                params.append(o["EstimatedState"][6:])

        if (dmcrun):
            r = numpy.array(o["EstimatedState"][:3])
            r /= norm(r)
            v = numpy.array(o["EstimatedState"][3:6])
            v /= norm(v)
            h = numpy.cross(r, v)
            rot = numpy.vstack((r, numpy.cross(h, r), h))
            estmacc.append(rot.dot(o["EstimatedState"][dmcidx:dmcidx + 3]))

    pre = numpy.array(prefit)
    pos = numpy.array(posfit)
    cov = numpy.array(inocov)
    par = numpy.array(params)
    estmacc = numpy.array(estmacc)
    start = tstamp[0] if (tstamp[0] < tstamp[-1]) else tstamp[-1]
    tim = [(t - start).total_seconds() / 3600 for t in tstamp]

    angles = ["Azimuth", "Elevation", "RightAscension", "Declination"]
    if (key[0] in angles and key[1] in angles):
        pre *= 648000.0 / math.pi
        pos *= 648000.0 / math.pi
        cov *= 648000.0 / math.pi
        units = ["arcsec", "arcsec"]
    else:
        if ("Position" in key):
            units = ["m", "m", "m"]
        elif ("PositionVelocity" in key):
            units = ["m", "m", "m", "m/s", "m/s", "m/s"]
        else:
            units = ["m", "m/s"]

    if ("Position" in key):
        ylabs = [r"$\Delta x$", r"$\Delta y$", r"$\Delta z$"]
        order = [1, 2, 3]
    elif ("PositionVelocity" in key):
        ylabs = [
            r"$\Delta x$", r"$\Delta y$", r"$\Delta z$", r"$\Delta v_x$",
            r"$\Delta v_y$", r"$\Delta v_z$"
        ]
        order = [1, 3, 5, 2, 4, 6]
    else:
        ylabs = key

    outfiles = []
    plt.figure(0)
    plt.suptitle("Pre-fit residuals")
    for i in range(pre.shape[-1]):
        if ("Position" in key):
            plt.subplot(3, 1, order[i])
        elif ("PositionVelocity" in key):
            plt.subplot(3, 2, order[i])
        else:
            plt.subplot(pre.shape[-1], 1, i + 1)
        plt.semilogx(tim, pre[:, i], "ob")
        plt.xlabel("Time [hr]")
        plt.ylabel("%s [%s]" % (ylabs[i], units[i]))

    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_prefit.png")
        plt.savefig(outfiles[-1], format="png")

    plt.figure(1)
    plt.suptitle("Post-fit residuals")
    for i in range(pre.shape[-1]):
        if ("Position" in key):
            plt.subplot(3, 1, order[i])
        elif ("PositionVelocity" in key):
            plt.subplot(3, 2, order[i])
        else:
            plt.subplot(pre.shape[-1], 1, i + 1)
        plt.semilogx(tim, pos[:, i], "ob")
        plt.semilogx(tim, -cov[:, i], "-r")
        plt.semilogx(tim, cov[:, i], "-r", label=r"Innov. 3$\sigma$")
        plt.xlabel("Time [hr]")
        plt.ylabel("%s [%s]" % (ylabs[i], units[i]))
        if ("Position" not in key and "PositionVelocity" not in key):
            plt.ylim(-cov[i, 0], cov[i, 0])

    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_postfit.png")
        plt.savefig(outfiles[-1], format="png")

    for i in range(par.shape[-1]):
        if (i == 0):
            plt.figure(2)
            plt.suptitle("Estimated parameters")

        plt.subplot(par.shape[1], 1, i + 1)
        plt.semilogx(tim, par[:, i], "ob")
        plt.xlabel("Time [hr]")
        plt.ylabel(parnames[i])

    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_estpar.png")
        plt.savefig(outfiles[-1], format="png")

    if (dmcrun):
        lab = [
            r"Radial [$\frac{m}{s^2}$]", r"In track [$\frac{m}{s^2}$]",
            r"Cross track [$\frac{m}{s^2}$]"
        ]
        plt.figure(3)
        plt.suptitle("DMC estimated accelerations")
        for i in range(3):
            plt.subplot(3, 1, i + 1)
            plt.semilogx(tim, estmacc[:, i], "-b")
            plt.xlabel("Time [hr]")
            plt.ylabel(lab[i])

        plt.tight_layout(rect=[0, 0.03, 1, 0.95])
        if (output_file_path is not None):
            outfiles.append(output_file_path + "_estacc.png")
            plt.savefig(outfiles[-1], format="png")

    if (interactive):
        plt.show()
    plt.close("all")
    return (outfiles)
예제 #3
0
def build_settings(param):
    inp = read_param(param)
    cfg = messages_pb2.Settings()
    for dest, src in _settings_fields.items():
        fld = inp
        for s in src[0]:
            fld = fld.get(s, src[1]) if s == src[0][-1] else fld.get(s)
            if (fld is None):
                fld = src[1]
                break
        if (fld is None):
            continue
        if (isinstance(fld, list)):
            getattr(cfg, dest).extend(fld)
        else:
            setattr(cfg, dest, fld)

    for f in inp.get("SpaceObject", {}).get("Facets", []):
        fac = messages_pb2.Facet(area=f["Area"])
        fac.normal.extend(f["Normal"])
        cfg.rso_facets.append(fac)

    coef = inp.get("Drag", {}).get("Coefficient", {})
    cfg.drag_coefficient.CopyFrom(
        messages_pb2.Parameter(name="Cd",
                               value=coef.get("Value", 2.0),
                               min=coef.get("Min", 1.0),
                               max=coef.get("Max", 3.0),
                               estimation=coef.get("Estimation", "Estimate")))
    for f in inp.get("Drag", {}).get("MSISEFlags", []):
        obj = messages_pb2.IntegerArray()
        obj.array.extend(f)
        cfg.drag_MSISE_flags.append(obj)

    coef = inp.get("RadiationPressure", {}).get("Creflection", {})
    cfg.rp_coeff_reflection.CopyFrom(
        messages_pb2.Parameter(name="Cr",
                               value=coef.get("Value", 1.5),
                               min=coef.get("Min", 1.0),
                               max=coef.get("Max", 2.0),
                               estimation=coef.get("Estimation", "Estimate")))

    for m in inp.get("Maneuvers", []):
        man = messages_pb2.Maneuver(time=m["Time"],
                                    trigger_event=m["TriggerEvent"],
                                    maneuver_type=m["ManeuverType"])
        if ("TriggerParams" in m):
            man.trigger_params.extend(m["TriggerParams"])
        if ("ManeuverParams" in m):
            man.maneuver_params.extend(m["ManeuverParams"])
        cfg.maneuvers.append(man)

    for k, v in inp.get("Stations", {}).items():
        sta = messages_pb2.Station(
            latitude=v["Latitude"],
            longitude=v["Longitude"],
            altitude=v["Altitude"],
            azimuth_bias=v.get("AzimuthBias", 0.0),
            elevation_bias=v.get("ElevationBias", 0.0),
            range_bias=v.get("RangeBias", 0.0),
            range_rate_bias=v.get("RangeRateBias", 0.0),
            right_ascension_bias=v.get("RightAscensionBias", 0.0),
            declination_bias=v.get("DeclinationBias", 0.0))
        sta.position_bias.extend(v.get("PositionBias", [0.0] * 3))
        sta.position_velocity_bias.extend(
            v.get("PositionVelocityBias", [0.0] * 6))
        cfg.stations[k].CopyFrom(sta)

    for k, v in inp.get("Measurements", {}).items():
        mea = messages_pb2.MeasurementSetting(two_way=v.get("TwoWay", True))
        mea.error.extend(v["Error"])
        cfg.measurements[k].CopyFrom(mea)

    coef = inp.get("Estimation", {}).get("DMCAcceleration", {})
    cfg.estm_DMC_acceleration.CopyFrom(
        messages_pb2.Parameter(name="",
                               value=coef.get("Value", 0.0),
                               min=coef.get("Min", -1.0E-3),
                               max=coef.get("Max", 1.0E-3),
                               estimation=coef.get("Estimation", "Estimate")))
    return (cfg)
예제 #4
0
def plot(config, sim_data, interactive=False, output_file_path=None):
    mu = 398600.4418
    cfg = read_param(config)
    out = read_param(sim_data)
    tstamp,hvec,hmag,ener,sma,ecc,inc,raan,argp,tran = [],[],[],[],[],[],[],[],[],[]
    for o in out:
        rv = [x / 1000.0 for x in o["TrueStateCartesian"][:6]]
        rn = norm(rv[:3])
        vn = norm(rv[3:])
        h = cross(rv[:3], rv[3:])
        hn = norm(h)
        a = 1.0 / (2.0 / rn - vn**2 / mu)
        e = cross(rv[3:], h) / mu - rv[:3] / rn
        en = norm(e)
        i = acos(h[2] / hn) * 180.0 / pi
        n = cross([0, 0, 1], h)
        nn = norm(n)
        O = acos(dot(n, [1, 0, 0]) / nn) * 180.0 / pi
        if (n[1] < 0.0):
            O = 360.0 - O
        w = acos(dot(n, e) / (nn * en)) * 180.0 / pi
        if (e[2] < 0.0):
            w = 360.0 - w
        theta = acos(dot(rv[:3], e) / (rn * en)) * 180.0 / pi
        if (dot(rv[:3], rv[3:]) < 0):
            theta = 360.0 - theta

        tstamp.append(dateutil.parser.isoparse(o["Time"]))
        hvec.append(h)
        hmag.append(hn)
        ener.append(0.5 * vn**2 - mu / rn)
        sma.append(a)
        ecc.append(en)
        inc.append(i)
        raan.append(O)
        argp.append(w)
        tran.append(theta)

    hvec = array(hvec)
    tim = [(t - tstamp[0]).total_seconds() / 3600 for t in tstamp]

    outfiles = []
    plt.figure(0)
    plt.subplot(611)
    plt.plot(tim, sma, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("SMA [km]")
    plt.subplot(612)
    plt.plot(tim, ecc, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("Eccentricity")
    plt.subplot(613)
    plt.plot(tim, inc, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("Inclination [deg]")
    plt.subplot(614)
    plt.plot(tim, raan, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("RAAN [deg]")
    plt.subplot(615)
    plt.plot(tim, argp, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("Perigee arg. [deg]")
    plt.subplot(616)
    plt.plot(tim, tran, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("True anom. [deg]")
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_elements.png")
        plt.savefig(outfiles[-1], format="png")

    plt.figure(1)
    plt.subplot(211)
    plt.plot(tim, hmag, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("Angular momentum")
    plt.subplot(212)
    plt.plot(tim, ener, "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("Specific energy")
    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_momentum_energy.png")
        plt.savefig(outfiles[-1], format="png")

    plt.figure(2)
    plt.subplot(311)
    plt.plot(tim, hvec[:, 0], "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("h(x)")
    plt.subplot(312)
    plt.plot(tim, hvec[:, 1], "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("h(y)")
    plt.subplot(313)
    plt.plot(tim, hvec[:, 2], "ob")
    plt.xlabel("Time [hr]")
    plt.ylabel("h(z)")
    plt.suptitle("Components of angular momentum")
    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    if (output_file_path is not None):
        outfiles.append(output_file_path + "_momentum_components.png")
        plt.savefig(outfiles[-1], format="png")

    if (interactive):
        plt.show()
    plt.close("all")
    return (outfiles)