#pragma once #include "minivec.hh" #include #include #include struct GPSLikeEphemeris { virtual double getMu() const = 0; virtual double getOmegaE() const = 0; virtual double getE() const = 0; virtual uint32_t getT0e() const = 0; virtual double getI0() const = 0; virtual double getOmegadot() const = 0; virtual double getSqrtA() const = 0; virtual double getOmega0() const = 0; virtual double getOmega() const = 0; virtual double getM0() const = 0; virtual double getIdot() const = 0; virtual double getCic() const = 0; virtual double getCis() const = 0; virtual double getCuc() const = 0; virtual double getCus() const = 0; virtual double getCrc() const = 0; virtual double getCrs() const = 0; virtual double getDeltan()const = 0; virtual int getIOD() const = 0; // maybe af0, af1, af2? // maybe getUTCOffset? getAtomicOffset etc }; // lat, lon, height (rad, rad, meters) std::tuple ecefToWGS84(double x, double y, double z); // lat, lon, height (deg, deg, meters) inline std::tuple ecefToWGS84Deg(double x, double y, double z) { auto ret = ecefToWGS84(x, y, z); std::get<0>(ret) /= (M_PI / 180); std::get<1>(ret) /= (M_PI / 180); return ret; } double ephAge(double tow, int t0e); template double getCoordinates(double tow, const T& iod, Point* p, bool quiet=true) { using namespace std; // here goes const double mu = iod.getMu(); const double omegaE = iod.getOmegaE(); const double sqrtA = iod.getSqrtA(); const double deltan = iod.getDeltan(); const double t0e = iod.getT0e(); const double m0 = iod.getM0(); const double e = iod.getE(); const double omega = iod.getOmega(); const double cuc = iod.getCuc(); const double cus = iod.getCus(); const double crc = iod.getCrc(); const double crs = iod.getCrs(); const double cic = iod.getCic(); const double cis = iod.getCis(); const double idot = iod.getIdot(); const double i0 = iod.getI0(); const double Omegadot = iod.getOmegadot(); const double Omega0 = iod.getOmega0(); // NO IOD BEYOND THIS POINT! if(!quiet) { auto todeg = [](double rad) { return 360 * rad/(2*M_PI); }; cerr << "sqrtA = "<< sqrtA << endl; cerr << "deltan = "<< deltan << endl; cerr << "t0e = "<< t0e << endl; cerr << "m0 = "<< m0 << " ("< E = M + e * sin(E) double nu2 = M + e*2*sin(M) + e *e * (5.0/4.0) * sin(2*M) - e*e*e * (0.25*sin(M) - (13.0/12.0)*sin(3*M)); double corr = e*e*e*e * (103*sin(4*M) - 44*sin(2*M)) / 96.0 + e*e*e*e*e * (1097*sin(5*M) - 645*sin(3*M) + 50 *sin(M))/960.0 + e*e*e*e*e*e * (1223*sin(6*M) - 902*sin(4*M) + 85 *sin(2*M))/960.0; if(!quiet) { double nu1 = atan( ((sqrt(1-e*e) * sin(E)) / (1 - e * cos(E)) ) / ((cos(E) - e)/ (1-e*cos(E))) ); double nu2A = atan( (sqrt(1-e*e) * sin(E)) / (cos(E) - e) ); double nu2B = atan2( (sqrt(1-e*e) * sin(E)) , (cos(E) - e) ); double nu3 = 2* atan( sqrt((1+e)/(1-e)) * tan(E/2)); cerr << "e: "<x = xprime * cos(Omega) - yprime * cos(i) * sin(Omega); p->y = xprime * sin(Omega) + yprime * cos(i) * cos(Omega); p->z = yprime * sin(i); if(!quiet) { Point core(0.0, .0, .0); Vector radius(core, *p); cerr << radius.length() << " calculated r "< void getSpeed(double tow, const T& eph, Vector* v) { Point a, b; getCoordinates(tow-0.5, eph, &a); getCoordinates(tow+0.5, eph, &b); *v = Vector(a, b); } template DopplerData doDoppler(double tow, const Point& us, const T& eph, double freq) { DopplerData ret; // be careful with time here - we need to evaluate at the timestamp of this RFDataType update // which might be newer than .tow in g_svstats getCoordinates(tow, eph, &ret.sat); Point core; Vector us2sat(us, ret.sat); getSpeed(tow, eph, &ret.speed); Vector core2us(core, us); Vector dx(us, ret.sat); // = x-ourx, dy = y-oury, dz = z-ourz; us2sat.norm(); ret.radvel=us2sat.inner(ret.speed); double c=299792458; ret.preddop = -freq * ret.radvel/c; // be careful with time here - ret.ephage = ephAge(tow, eph.getT0e()); // cout<<"Radial velocity: "<< radvel<<", predicted doppler: "<< preddop << ", measured doppler: "< getLongLat(double x, double y, double z); double getElevationDeg(const Point& sat, const Point& our); double getAzimuthDeg(const Point& sat, const Point& our);