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)
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)
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)
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)