| 1 | mocchiut | 1.1 | // | 
| 2 |  |  | // stdafx.h | 
| 3 |  |  | // | 
| 4 |  |  | #ifndef sgp4_h | 
| 5 |  |  | #define sgp4_h | 
| 6 |  |  |  | 
| 7 |  |  | //#define WIN32_LEAN_AND_MEAN   // Exclude rarely-used stuff from Windows headers | 
| 8 |  |  | #include <stdio.h> | 
| 9 |  |  | //#include <tchar.h> | 
| 10 | mocchiut | 1.2 | #include <ctype.h> | 
| 11 | mocchiut | 1.1 | #include <string> | 
| 12 |  |  | #include <map> | 
| 13 |  |  | #include <vector> | 
| 14 |  |  | #include <algorithm> | 
| 15 |  |  | #include <assert.h> | 
| 16 |  |  | #include <time.h> | 
| 17 |  |  | #include <math.h> | 
| 18 |  |  |  | 
| 19 |  |  | using namespace std; | 
| 20 |  |  | // | 
| 21 |  |  | // globals.h | 
| 22 |  |  | // | 
| 23 |  |  |  | 
| 24 |  |  | const double PI           = 3.141592653589793; | 
| 25 |  |  | const double TWOPI        = 2.0 * PI; | 
| 26 |  |  | const double RADS_PER_DEG = PI / 180.0; | 
| 27 |  |  |  | 
| 28 |  |  | const double GM           = 398601.2;   // Earth gravitational constant, km^3/sec^2 | 
| 29 |  |  | const double GEOSYNC_ALT  = 42241.892;  // km | 
| 30 |  |  | const double EARTH_DIA    = 12800.0;    // km | 
| 31 |  |  | const double DAY_SIDERAL  = (23 * 3600) + (56 * 60) + 4.09;  // sec | 
| 32 |  |  | const double DAY_24HR     = (24 * 3600);   // sec | 
| 33 |  |  |  | 
| 34 |  |  | const double AE           = 1.0; | 
| 35 |  |  | const double AU           = 149597870.0;  // Astronomical unit (km) (IAU 76) | 
| 36 |  |  | const double SR           = 696000.0;     // Solar radius (km)      (IAU 76) | 
| 37 |  |  | const double TWOTHRD      = 2.0 / 3.0; | 
| 38 |  |  | const double XKMPER_WGS72 = 6378.135;     // Earth equatorial radius - km (WGS '72) | 
| 39 |  |  | const double F            = 1.0 / 298.26; // Earth flattening (WGS '72) | 
| 40 |  |  | const double GE           = 398600.8;     // Earth gravitational constant (WGS '72) | 
| 41 |  |  | const double J2           = 1.0826158E-3; // J2 harmonic (WGS '72) | 
| 42 |  |  | const double J3           = -2.53881E-6;  // J3 harmonic (WGS '72) | 
| 43 |  |  | const double J4           = -1.65597E-6;  // J4 harmonic (WGS '72) | 
| 44 |  |  | const double CK2          = J2 / 2.0; | 
| 45 |  |  | const double CK4          = -3.0 * J4 / 8.0; | 
| 46 |  |  | const double XJ3          = J3; | 
| 47 |  |  | const double E6A          = 1.0e-06; | 
| 48 |  |  | const double QO           = AE + 120.0 / XKMPER_WGS72; | 
| 49 |  |  | const double S            = AE + 78.0  / XKMPER_WGS72; | 
| 50 |  |  | const double HR_PER_DAY   = 24.0;          // Hours per day   (solar) | 
| 51 |  |  | const double MIN_PER_DAY  = 1440.0;        // Minutes per day (solar) | 
| 52 |  |  | const double SEC_PER_DAY  = 86400.0;       // Seconds per day (solar) | 
| 53 |  |  | const double OMEGA_E      = 1.00273790934; // earth rotation per sideral day | 
| 54 |  |  | const double XKE          = sqrt(3600.0 * GE /           //sqrt(ge) ER^3/min^2 | 
| 55 |  |  | (XKMPER_WGS72 * XKMPER_WGS72 * XKMPER_WGS72)); | 
| 56 |  |  | const double QOMS2T       = pow((QO - S), 4);            //(QO - S)^4 ER^4 | 
| 57 |  |  |  | 
| 58 |  |  | // Utility functions | 
| 59 |  |  | double sqr   (const double x); | 
| 60 |  |  | double Fmod2p(const double arg); | 
| 61 |  |  | double AcTan (const double sinx, double cosx); | 
| 62 |  |  |  | 
| 63 |  |  | double rad2deg(const double); | 
| 64 |  |  | double deg2rad(const double); | 
| 65 |  |  | // | 
| 66 |  |  | // coord.h | 
| 67 |  |  | // | 
| 68 |  |  | // Copyright 2002-2003 Michael F. Henry | 
| 69 |  |  | // | 
| 70 |  |  | ////////////////////////////////////////////////////////////////////// | 
| 71 |  |  | // Geocentric coordinates. | 
| 72 |  |  | class cCoordGeo | 
| 73 |  |  | { | 
| 74 |  |  | public: | 
| 75 |  |  | cCoordGeo(); | 
| 76 |  |  | cCoordGeo(double lat, double lon, double alt) : | 
| 77 |  |  | m_Lat(lat), m_Lon(lon), m_Alt(alt) {} | 
| 78 |  |  | virtual ~cCoordGeo() {}; | 
| 79 |  |  |  | 
| 80 |  |  | double m_Lat;   // Latitude,  radians (negative south) | 
| 81 |  |  | double m_Lon;   // Longitude, radians (negative west) | 
| 82 |  |  | double m_Alt;   // Altitude,  km      (above mean sea level) | 
| 83 |  |  | }; | 
| 84 |  |  |  | 
| 85 |  |  | ////////////////////////////////////////////////////////////////////// | 
| 86 |  |  | // Topocentric-Horizon coordinates. | 
| 87 |  |  | class cCoordTopo | 
| 88 |  |  | { | 
| 89 |  |  | public: | 
| 90 |  |  | cCoordTopo(); | 
| 91 |  |  | cCoordTopo(double az, double el, double rng, double rate) : | 
| 92 |  |  | m_Az(az), m_El(el), m_Range(rng), m_RangeRate(rate) {} | 
| 93 |  |  | virtual ~cCoordTopo() {}; | 
| 94 |  |  |  | 
| 95 |  |  | double m_Az;         // Azimuth, radians | 
| 96 |  |  | double m_El;         // Elevation, radians | 
| 97 |  |  | double m_Range;      // Range, kilometers | 
| 98 |  |  | double m_RangeRate;  // Range rate of change, km/sec | 
| 99 |  |  | // Negative value means "towards observer" | 
| 100 |  |  | }; | 
| 101 |  |  |  | 
| 102 |  |  | // cVector.h: interface for the cVector class. | 
| 103 |  |  | // | 
| 104 |  |  | // Copyright 2003 (c) Michael F. Henry | 
| 105 |  |  | // | 
| 106 |  |  | ////////////////////////////////////////////////////////////////////// | 
| 107 |  |  |  | 
| 108 |  |  | class cVector | 
| 109 |  |  | { | 
| 110 |  |  | public: | 
| 111 |  |  | cVector(double x = 0.0, double y = 0.0, double z = 0.0, double w = 0.0) : | 
| 112 |  |  | m_x(x), m_y(y), m_z(z), m_w(w) {} | 
| 113 |  |  | virtual ~cVector() {}; | 
| 114 |  |  |  | 
| 115 |  |  | void Sub(const cVector&);     // subtraction | 
| 116 |  |  | void Mul(double factor);      // multiply each component by 'factor' | 
| 117 |  |  |  | 
| 118 |  |  | double Angle(const cVector&) const;    // angle between two vectors | 
| 119 |  |  | double Magnitude() const;              // vector magnitude | 
| 120 |  |  | double Dot(const cVector& vec) const;  // dot product | 
| 121 |  |  |  | 
| 122 |  |  | // protected: | 
| 123 |  |  | double m_x; | 
| 124 |  |  | double m_y; | 
| 125 |  |  | double m_z; | 
| 126 |  |  | double m_w; | 
| 127 |  |  | }; | 
| 128 |  |  | // | 
| 129 |  |  | // cTle.h | 
| 130 |  |  | // | 
| 131 |  |  | // This class will accept a single set of two-line elements and then allow | 
| 132 |  |  | // a client to request specific fields, such as epoch, mean motion, | 
| 133 |  |  | // etc., from the set. | 
| 134 |  |  | // | 
| 135 |  |  | // Copyright 1996-2003 Michael F. Henry | 
| 136 |  |  | // | 
| 137 |  |  | ///////////////////////////////////////////////////////////////////////////// | 
| 138 |  |  | class cTle | 
| 139 |  |  | { | 
| 140 |  |  | public: | 
| 141 |  |  | cTle(string&, string&, string&); | 
| 142 |  |  | cTle(const cTle &tle); | 
| 143 |  |  | ~cTle(); | 
| 144 |  |  |  | 
| 145 |  |  | enum eTleLine | 
| 146 |  |  | { | 
| 147 |  |  | LINE_ZERO, | 
| 148 |  |  | LINE_ONE, | 
| 149 |  |  | LINE_TWO | 
| 150 |  |  | }; | 
| 151 |  |  |  | 
| 152 |  |  | enum eField | 
| 153 |  |  | { | 
| 154 |  |  | FLD_FIRST, | 
| 155 |  |  | FLD_NORADNUM = FLD_FIRST, | 
| 156 |  |  | FLD_INTLDESC, | 
| 157 |  |  | FLD_SET,       // TLE set number | 
| 158 |  |  | FLD_EPOCHYEAR, // Epoch: Last two digits of year | 
| 159 |  |  | FLD_EPOCHDAY,  // Epoch: Fractional Julian Day of year | 
| 160 |  |  | FLD_ORBITNUM,  // Orbit at epoch | 
| 161 |  |  | FLD_I,         // Inclination | 
| 162 |  |  | FLD_RAAN,      // R.A. ascending node | 
| 163 |  |  | FLD_E,         // Eccentricity | 
| 164 |  |  | FLD_ARGPER,    // Argument of perigee | 
| 165 |  |  | FLD_M,         // Mean anomaly | 
| 166 |  |  | FLD_MMOTION,   // Mean motion | 
| 167 |  |  | FLD_MMOTIONDT, // First time derivative of mean motion | 
| 168 |  |  | FLD_MMOTIONDT2,// Second time derivative of mean motion | 
| 169 |  |  | FLD_BSTAR,     // BSTAR Drag | 
| 170 |  |  | FLD_LAST       // MUST be last | 
| 171 |  |  | }; | 
| 172 |  |  |  | 
| 173 |  |  | enum eUnits | 
| 174 |  |  | { | 
| 175 |  |  | U_FIRST, | 
| 176 |  |  | U_RAD = U_FIRST,  // radians | 
| 177 |  |  | U_DEG,            // degrees | 
| 178 |  |  | U_NATIVE,         // TLE format native units (no conversion) | 
| 179 |  |  | U_LAST            // MUST be last | 
| 180 |  |  | }; | 
| 181 |  |  |  | 
| 182 |  |  | void Initialize(); | 
| 183 |  |  |  | 
| 184 |  |  | static int    CheckSum(const string&); | 
| 185 |  |  | static bool   IsValidLine(string&, eTleLine); | 
| 186 |  |  | static string ExpToDecimal(const string&); | 
| 187 |  |  |  | 
| 188 |  |  | static void TrimLeft(string&); | 
| 189 |  |  | static void TrimRight(string&); | 
| 190 |  |  |  | 
| 191 |  |  | double getField(eField fld,               // which field to retrieve | 
| 192 |  |  | eUnits unit  = U_NATIVE,  // return units in rad, deg etc. | 
| 193 |  |  | string *pstr = NULL,      // return ptr for str value | 
| 194 |  |  | bool bStrUnits = false)   // 'true': append units to str val | 
| 195 |  |  | const; | 
| 196 |  |  | string getName()  const { return m_strName; } | 
| 197 |  |  | string getLine1() const { return m_strLine1;} | 
| 198 |  |  | string getLine2() const { return m_strLine2;} | 
| 199 |  |  |  | 
| 200 |  |  | protected: | 
| 201 |  |  | static double ConvertUnits(double val, eField fld, eUnits units); | 
| 202 |  |  |  | 
| 203 |  |  | private: | 
| 204 |  |  | string getUnits(eField) const; | 
| 205 |  |  | double getFieldNumeric(eField) const; | 
| 206 |  |  |  | 
| 207 |  |  | // Satellite name and two data lines | 
| 208 |  |  | string m_strName; | 
| 209 |  |  | string m_strLine1; | 
| 210 |  |  | string m_strLine2; | 
| 211 |  |  |  | 
| 212 |  |  | // Converted fields, in atof()-readable form | 
| 213 |  |  | string m_Field[FLD_LAST]; | 
| 214 |  |  |  | 
| 215 |  |  | // Cache of field values in "double" format | 
| 216 |  |  | typedef int FldKey; | 
| 217 |  |  | FldKey Key(eUnits u, eField f) const { return (u * 100) + f; } | 
| 218 |  |  | mutable map<FldKey, double>  m_mapCache; | 
| 219 |  |  | }; | 
| 220 |  |  |  | 
| 221 |  |  | /////////////////////////////////////////////////////////////////////////// | 
| 222 |  |  | // | 
| 223 |  |  | // TLE data format | 
| 224 |  |  | // | 
| 225 |  |  | // [Reference: T.S. Kelso] | 
| 226 |  |  | // | 
| 227 |  |  | // Two line element data consists of three lines in the following format: | 
| 228 |  |  | // | 
| 229 |  |  | //  AAAAAAAAAAAAAAAAAAAAAA | 
| 230 |  |  | //  1 NNNNNU NNNNNAAA NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN | 
| 231 |  |  | //  2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN | 
| 232 |  |  | // | 
| 233 |  |  | //  Line 0 is a twenty-two-character name. | 
| 234 |  |  | // | 
| 235 |  |  | //   Lines 1 and 2 are the standard Two-Line Orbital Element Set Format identical | 
| 236 |  |  | //   to that used by NORAD and NASA.  The format description is: | 
| 237 |  |  | // | 
| 238 |  |  | //     Line 1 | 
| 239 |  |  | //     Column    Description | 
| 240 |  |  | //     01-01     Line Number of Element Data | 
| 241 |  |  | //     03-07     Satellite Number | 
| 242 |  |  | //     10-11     International Designator (Last two digits of launch year) | 
| 243 |  |  | //     12-14     International Designator (Launch number of the year) | 
| 244 |  |  | //     15-17     International Designator (Piece of launch) | 
| 245 |  |  | //     19-20     Epoch Year (Last two digits of year) | 
| 246 |  |  | //     21-32     Epoch (Julian Day and fractional portion of the day) | 
| 247 |  |  | //     34-43     First Time Derivative of the Mean Motion | 
| 248 |  |  | //               or Ballistic Coefficient (Depending on ephemeris type) | 
| 249 |  |  | //     45-52     Second Time Derivative of Mean Motion (decimal point assumed; | 
| 250 |  |  | //               blank if N/A) | 
| 251 |  |  | //     54-61     BSTAR drag term if GP4 general perturbation theory was used. | 
| 252 |  |  | //               Otherwise, radiation pressure coefficient.  (Decimal point assumed) | 
| 253 |  |  | //     63-63     Ephemeris type | 
| 254 |  |  | //     65-68     Element number | 
| 255 |  |  | //     69-69     Check Sum (Modulo 10) | 
| 256 |  |  | //               (Letters, blanks, periods, plus signs = 0; minus signs = 1) | 
| 257 |  |  | // | 
| 258 |  |  | //     Line 2 | 
| 259 |  |  | //     Column    Description | 
| 260 |  |  | //     01-01     Line Number of Element Data | 
| 261 |  |  | //     03-07     Satellite Number | 
| 262 |  |  | //     09-16     Inclination [Degrees] | 
| 263 |  |  | //     18-25     Right Ascension of the Ascending Node [Degrees] | 
| 264 |  |  | //     27-33     Eccentricity (decimal point assumed) | 
| 265 |  |  | //     35-42     Argument of Perigee [Degrees] | 
| 266 |  |  | //     44-51     Mean Anomaly [Degrees] | 
| 267 |  |  | //     53-63     Mean Motion [Revs per day] | 
| 268 |  |  | //     64-68     Revolution number at epoch [Revs] | 
| 269 |  |  | //     69-69     Check Sum (Modulo 10) | 
| 270 |  |  | // | 
| 271 |  |  | //     All other columns are blank or fixed. | 
| 272 |  |  | // | 
| 273 |  |  | // Example: | 
| 274 |  |  | // | 
| 275 |  |  | // NOAA 6 | 
| 276 |  |  | // 1 11416U          86 50.28438588 0.00000140           67960-4 0  5293 | 
| 277 |  |  | // 2 11416  98.5105  69.3305 0012788  63.2828 296.9658 14.24899292346978 | 
| 278 |  |  |  | 
| 279 |  |  | // | 
| 280 |  |  | // cJulian.h | 
| 281 |  |  | // | 
| 282 |  |  | // Copyright (c) 2003 Michael F. Henry | 
| 283 |  |  | // | 
| 284 |  |  | // | 
| 285 |  |  | // See note in cJulian.cpp for information on this class and the epoch dates | 
| 286 |  |  | // | 
| 287 |  |  | const double EPOCH_JAN1_00H_1900 = 2415019.5; // Jan 1.0 1900 = Jan 1 1900 00h UTC | 
| 288 |  |  | const double EPOCH_JAN1_12H_1900 = 2415020.0; // Jan 1.5 1900 = Jan 1 1900 12h UTC | 
| 289 |  |  | const double EPOCH_JAN1_12H_2000 = 2451545.0; // Jan 1.5 2000 = Jan 1 2000 12h UTC | 
| 290 |  |  |  | 
| 291 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 292 |  |  | class cJulian | 
| 293 |  |  | { | 
| 294 |  |  | public: | 
| 295 |  |  | cJulian() { Initialize(2000, 1); } | 
| 296 |  |  | explicit cJulian(time_t t);              // Create from time_t | 
| 297 |  |  | explicit cJulian(int year, double day);  // Create from year, day of year | 
| 298 |  |  | explicit cJulian(int year,               // i.e., 2004 | 
| 299 |  |  | int mon,                // 1..12 | 
| 300 |  |  | int day,                // 1..31 | 
| 301 |  |  | int hour,               // 0..23 | 
| 302 |  |  | int min,                // 0..59 | 
| 303 |  |  | double sec = 0.0);      // 0..(59.999999...) | 
| 304 |  |  | ~cJulian() {}; | 
| 305 |  |  |  | 
| 306 |  |  | double toGMST() const;           // Greenwich Mean Sidereal Time | 
| 307 |  |  | double toLMST(double lon) const; // Local Mean Sideral Time | 
| 308 |  |  | time_t toTime() const;           // To time_t type - avoid using | 
| 309 |  |  |  | 
| 310 |  |  | double FromJan1_00h_1900() const { return m_Date - EPOCH_JAN1_00H_1900; } | 
| 311 |  |  | double FromJan1_12h_1900() const { return m_Date - EPOCH_JAN1_12H_1900; } | 
| 312 |  |  | double FromJan1_12h_2000() const { return m_Date - EPOCH_JAN1_12H_2000; } | 
| 313 |  |  |  | 
| 314 |  |  | void getComponent(int *pYear, int *pMon = NULL, double *pDOM = NULL) const; | 
| 315 |  |  | double getDate() const { return m_Date; } | 
| 316 |  |  |  | 
| 317 |  |  | void addDay (double day) { m_Date += day;                 } | 
| 318 |  |  | void addHour(double hr ) { m_Date += (hr  / HR_PER_DAY ); } | 
| 319 |  |  | void addMin (double min) { m_Date += (min / MIN_PER_DAY); } | 
| 320 |  |  | void addSec (double sec) { m_Date += (sec / SEC_PER_DAY); } | 
| 321 |  |  |  | 
| 322 |  |  | double spanDay (const cJulian& b) const { return m_Date - b.m_Date;        } | 
| 323 |  |  | double spanHour(const cJulian& b) const { return spanDay(b) * HR_PER_DAY;  } | 
| 324 |  |  | double spanMin (const cJulian& b) const { return spanDay(b) * MIN_PER_DAY; } | 
| 325 |  |  | double spanSec (const cJulian& b) const { return spanDay(b) * SEC_PER_DAY; } | 
| 326 |  |  |  | 
| 327 |  |  | static bool IsLeapYear(int y) | 
| 328 |  |  | { return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0); } | 
| 329 |  |  |  | 
| 330 |  |  | protected: | 
| 331 |  |  | void Initialize(int year, double day); | 
| 332 |  |  |  | 
| 333 |  |  | double m_Date; // Julian date | 
| 334 |  |  | }; | 
| 335 |  |  | // | 
| 336 |  |  | // cEci.h | 
| 337 |  |  | // | 
| 338 |  |  | // Copyright (c) 2003 Michael F. Henry | 
| 339 |  |  | // | 
| 340 |  |  | ////////////////////////////////////////////////////////////////////// | 
| 341 |  |  | // class cEci | 
| 342 |  |  | // Encapsulates an Earth-Centered Inertial position, velocity, and time. | 
| 343 |  |  | class cEci | 
| 344 |  |  | { | 
| 345 |  |  | public: | 
| 346 |  |  | cEci() { m_VecUnits = UNITS_NONE; } | 
| 347 |  |  | cEci(const cCoordGeo &geo, const cJulian &cJulian); | 
| 348 |  |  | cEci(const cVector &pos, const cVector &vel, | 
| 349 |  |  | const cJulian &date, bool IsAeUnits = true); | 
| 350 |  |  | virtual ~cEci() {}; | 
| 351 |  |  |  | 
| 352 |  |  | cCoordGeo toGeo(); | 
| 353 |  |  |  | 
| 354 |  |  | cVector getPos()  const { return m_pos;  } | 
| 355 |  |  | cVector getVel()  const { return m_vel;  } | 
| 356 |  |  | cJulian getDate() const { return m_date; } | 
| 357 |  |  |  | 
| 358 |  |  | void setUnitsAe() { m_VecUnits = UNITS_AE; } | 
| 359 |  |  | void setUnitsKm() { m_VecUnits = UNITS_KM; } | 
| 360 |  |  | bool UnitsAreAe() const { return m_VecUnits == UNITS_AE; } | 
| 361 |  |  | bool UnitsAreKm() const { return m_VecUnits == UNITS_KM; } | 
| 362 |  |  | void ae2km();  // Convert position, velocity vector units from AE to km | 
| 363 |  |  |  | 
| 364 |  |  | protected: | 
| 365 |  |  | void MulPos(double factor) { m_pos.Mul(factor); } | 
| 366 |  |  | void MulVel(double factor) { m_vel.Mul(factor); } | 
| 367 |  |  |  | 
| 368 |  |  | enum VecUnits | 
| 369 |  |  | { | 
| 370 |  |  | UNITS_NONE, // not initialized | 
| 371 |  |  | UNITS_AE, | 
| 372 |  |  | UNITS_KM, | 
| 373 |  |  | }; | 
| 374 |  |  |  | 
| 375 |  |  | cVector  m_pos; | 
| 376 |  |  | cVector  m_vel; | 
| 377 |  |  | cJulian  m_date; | 
| 378 |  |  | VecUnits m_VecUnits; | 
| 379 |  |  | }; | 
| 380 | mocchiut | 1.3 | // | 
| 381 |  |  | // cNoradBase.h | 
| 382 |  |  | // | 
| 383 |  |  | // This class provides a base class for the NORAD SGP4/SDP4 | 
| 384 |  |  | // orbit models. | 
| 385 |  |  | // | 
| 386 |  |  | // Copyright (c) 2003 Michael F. Henry | 
| 387 |  |  | // | 
| 388 |  |  | #pragma once | 
| 389 |  |  |  | 
| 390 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 391 |  |  |  | 
| 392 |  |  | class cEci; | 
| 393 |  |  | class cOrbit; | 
| 394 |  |  |  | 
| 395 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 396 |  |  |  | 
| 397 |  |  | class cNoradBase | 
| 398 |  |  | { | 
| 399 |  |  | public: | 
| 400 |  |  | cNoradBase(const cOrbit&); | 
| 401 |  |  | virtual ~cNoradBase() {}; | 
| 402 |  |  |  | 
| 403 |  |  | virtual bool getPosition(double tsince, cEci &eci) = 0; | 
| 404 |  |  |  | 
| 405 |  |  | protected: | 
| 406 |  |  | cNoradBase& operator=(const cNoradBase&); | 
| 407 |  |  |  | 
| 408 |  |  | void Initialize(); | 
| 409 |  |  | bool FinalPosition(double  incl, double omega,  double     e, | 
| 410 |  |  | double     a, double    xl,  double xnode, | 
| 411 |  |  | double    xn, double tsince, cEci &eci); | 
| 412 |  |  |  | 
| 413 |  |  | const cOrbit &m_Orbit; | 
| 414 |  |  |  | 
| 415 |  |  | // Orbital parameter variables which need only be calculated one | 
| 416 |  |  | // time for a given orbit (ECI position time-independent). | 
| 417 |  |  | double m_satInc;  // inclination | 
| 418 |  |  | double m_satEcc;  // eccentricity | 
| 419 |  |  |  | 
| 420 |  |  | double m_cosio;   double m_theta2;  double m_x3thm1;  double m_eosq; | 
| 421 |  |  | double m_betao2;  double m_betao;   double m_aodp;    double m_xnodp; | 
| 422 |  |  | double m_s4;      double m_qoms24;  double m_perigee; double m_tsi; | 
| 423 |  |  | double m_eta;     double m_etasq;   double m_eeta;    double m_coef; | 
| 424 |  |  | double m_coef1;   double m_c1;      double m_c2;      double m_c3; | 
| 425 |  |  | double m_c4;      double m_sinio;   double m_a3ovk2;  double m_x1mth2; | 
| 426 |  |  | double m_xmdot;   double m_omgdot;  double m_xhdot1;  double m_xnodot; | 
| 427 |  |  | double m_xnodcf;  double m_t2cof;   double m_xlcof;   double m_aycof; | 
| 428 |  |  | double m_x7thm1; | 
| 429 |  |  | }; | 
| 430 |  |  | // | 
| 431 |  |  | // cOrbit.h | 
| 432 |  |  | // | 
| 433 |  |  | // This is the header file for the class cOrbit. This class accepts a | 
| 434 |  |  | // single satellite's NORAD two-line element set and provides information | 
| 435 |  |  | // regarding the satellite's orbit such as period, axis length, | 
| 436 |  |  | // ECI coordinates/velocity, etc., using the SGP4/SDP4 orbital models. | 
| 437 |  |  | // | 
| 438 |  |  | // Copyright (c) 2002-2003 Michael F. Henry | 
| 439 |  |  | // | 
| 440 |  |  | #pragma once | 
| 441 |  |  |  | 
| 442 |  |  | #include "math.h" | 
| 443 |  |  |  | 
| 444 |  |  | using namespace std; | 
| 445 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 446 |  |  |  | 
| 447 |  |  | class cVector; | 
| 448 |  |  | class cGeoCoord; | 
| 449 |  |  | class cEci; | 
| 450 |  |  |  | 
| 451 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 452 |  |  | class cOrbit | 
| 453 |  |  | { | 
| 454 |  |  | public: | 
| 455 |  |  | cOrbit(const cTle &tle); | 
| 456 |  |  | virtual ~cOrbit(); | 
| 457 |  |  |  | 
| 458 |  |  | // Return satellite ECI data at given minutes since element's epoch. | 
| 459 |  |  | bool getPosition(double tsince, cEci *pEci) const; | 
| 460 |  |  |  | 
| 461 |  |  | double Inclination()  const { return radGet(cTle::FLD_I);                 } | 
| 462 |  |  | double Eccentricity() const { return m_tle.getField(cTle::FLD_E);         } | 
| 463 |  |  | double RAAN()         const { return radGet(cTle::FLD_RAAN);              } | 
| 464 |  |  | double ArgPerigee()   const { return radGet(cTle::FLD_ARGPER);            } | 
| 465 |  |  | double BStar()        const { return m_tle.getField(cTle::FLD_BSTAR) / AE;} | 
| 466 |  |  | double Drag()         const { return m_tle.getField(cTle::FLD_MMOTIONDT); } | 
| 467 |  |  | double mnMotion()     const { return m_tle.getField(cTle::FLD_MMOTION);   } | 
| 468 |  |  | double mnAnomaly()    const { return radGet(cTle::FLD_M);                 } | 
| 469 |  |  | double mnAnomaly(cJulian t) const;  // mean anomaly (in radians) at time t | 
| 470 |  |  |  | 
| 471 |  |  | cJulian Epoch() const { return m_jdEpoch; } | 
| 472 |  |  |  | 
| 473 |  |  | double TPlusEpoch(const cJulian &t) const;    // time span [t - epoch] in secs | 
| 474 |  |  |  | 
| 475 |  |  | string SatName(bool fAppendId = false) const; | 
| 476 |  |  |  | 
| 477 |  |  | // "Recovered" from the input elements | 
| 478 |  |  | double SemiMajor()   const { return m_aeAxisSemiMajorRec; } | 
| 479 |  |  | double SemiMinor()   const { return m_aeAxisSemiMinorRec; } | 
| 480 |  |  | double mnMotionRec() const { return m_mnMotionRec; }  // mn motion, rads/min | 
| 481 |  |  | double Major()   const { return 2.0 * SemiMajor(); }  // major axis in AE | 
| 482 |  |  | double Minor()   const { return 2.0 * SemiMinor(); }  // minor axis in AE | 
| 483 |  |  | double Perigee() const { return m_kmPerigeeRec;    }  // perigee in km | 
| 484 |  |  | double Apogee()  const { return m_kmApogeeRec;     }  // apogee in km | 
| 485 |  |  | double Period()  const;                               // period in seconds | 
| 486 |  |  |  | 
| 487 |  |  | protected: | 
| 488 |  |  | double radGet(cTle::eField fld) const | 
| 489 |  |  | { return m_tle.getField(fld, cTle::U_RAD); } | 
| 490 |  |  |  | 
| 491 |  |  | double degGet(cTle::eField fld) const | 
| 492 |  |  | { return m_tle.getField(fld, cTle::U_DEG); } | 
| 493 |  |  |  | 
| 494 |  |  | private: | 
| 495 |  |  | cTle        m_tle; | 
| 496 |  |  | cJulian     m_jdEpoch; | 
| 497 |  |  | cNoradBase *m_pNoradModel; | 
| 498 |  |  |  | 
| 499 |  |  | // Caching variables; note units are not necessarily the same as tle units | 
| 500 |  |  | mutable double m_secPeriod; | 
| 501 |  |  |  | 
| 502 |  |  | // Caching variables recovered from the input TLE elements | 
| 503 |  |  | double m_aeAxisSemiMinorRec;  // semi-minor axis, in AE units | 
| 504 |  |  | double m_aeAxisSemiMajorRec;  // semi-major axis, in AE units | 
| 505 |  |  | double m_mnMotionRec;         // radians per minute | 
| 506 |  |  | double m_kmPerigeeRec;        // perigee, in km | 
| 507 |  |  | double m_kmApogeeRec;         // apogee, in km | 
| 508 |  |  | }; | 
| 509 |  |  |  | 
| 510 |  |  | // | 
| 511 |  |  | // cNoradSGP4.h | 
| 512 |  |  | // | 
| 513 |  |  | // This class implements the NORAD Simple General Perturbation 4 orbit | 
| 514 |  |  | // model. This model provides the ECI coordiantes/velocity of satellites | 
| 515 |  |  | // with orbit periods less than 225 minutes. | 
| 516 |  |  | // | 
| 517 |  |  | // Copyright (c) 2003 Michael F. Henry | 
| 518 |  |  | // | 
| 519 |  |  | #pragma once | 
| 520 |  |  |  | 
| 521 |  |  | class cOrbit; | 
| 522 |  |  |  | 
| 523 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 524 |  |  | class cNoradSGP4 : public cNoradBase | 
| 525 |  |  | { | 
| 526 |  |  | public: | 
| 527 |  |  | cNoradSGP4(const cOrbit &orbit); | 
| 528 |  |  | virtual ~cNoradSGP4() {}; | 
| 529 |  |  |  | 
| 530 |  |  | virtual bool getPosition(double tsince, cEci &eci); | 
| 531 |  |  |  | 
| 532 |  |  | protected: | 
| 533 |  |  | double m_c5; | 
| 534 |  |  | double m_omgcof; | 
| 535 |  |  | double m_xmcof; | 
| 536 |  |  | double m_delmo; | 
| 537 |  |  | double m_sinmo; | 
| 538 |  |  | }; | 
| 539 |  |  |  | 
| 540 |  |  | // | 
| 541 |  |  | // cNoradSDP4.h | 
| 542 |  |  | // | 
| 543 |  |  | // This class implements the NORAD Simple Deep Perturbation 4 orbit | 
| 544 |  |  | // model. This model provides the ECI coordinates/velocity of satellites | 
| 545 |  |  | // with periods >= 225 minutes. | 
| 546 |  |  | // | 
| 547 |  |  | // Copyright (c) 2003 Michael F. Henry | 
| 548 |  |  | // | 
| 549 |  |  | #pragma once | 
| 550 |  |  |  | 
| 551 |  |  | class cOrbit; | 
| 552 |  |  |  | 
| 553 |  |  | ////////////////////////////////////////////////////////////////////////////// | 
| 554 |  |  | class cNoradSDP4 : public cNoradBase | 
| 555 |  |  | { | 
| 556 |  |  | public: | 
| 557 |  |  | cNoradSDP4(const cOrbit &orbit); | 
| 558 |  |  | virtual ~cNoradSDP4() {}; | 
| 559 |  |  |  | 
| 560 |  |  | virtual bool getPosition(double tsince, cEci &eci); | 
| 561 |  |  |  | 
| 562 |  |  | protected: | 
| 563 |  |  | bool DeepInit(double *eosq,    double *sinio,    double *cosio,  double *m_betao, | 
| 564 |  |  | double *m_aodp,  double *m_theta2, double *m_sing, double *m_cosg, | 
| 565 |  |  | double *m_betao2,double *xmdot,    double *omgdot, double *xnodott); | 
| 566 |  |  |  | 
| 567 |  |  | bool DeepSecular(double *xmdf,  double *omgadf,double *xnode, double *emm, | 
| 568 |  |  | double *xincc, double *xnn,   double *tsince); | 
| 569 |  |  | bool DeepCalcDotTerms  (double *pxndot, double *pxnddt, double *pxldot); | 
| 570 |  |  | void DeepCalcIntegrator(double *pxndot, double *pxnddt, double *pxldot, | 
| 571 |  |  | const double &delt); | 
| 572 |  |  | bool DeepPeriodics(double *e,     double *xincc,  double *omgadf, | 
| 573 |  |  | double *xnode, double *xmam); | 
| 574 |  |  | double m_sing; | 
| 575 |  |  | double m_cosg; | 
| 576 |  |  |  | 
| 577 |  |  | // Deep Initialization | 
| 578 |  |  | double eqsq;   double siniq;  double cosiq;  double rteqsq; double ao; | 
| 579 |  |  | double cosq2;  double sinomo; double cosomo; double bsq;    double xlldot; | 
| 580 |  |  | double omgdt;  double xnodot; | 
| 581 |  |  |  | 
| 582 |  |  | // Deep Secular, Periodic | 
| 583 |  |  | double xll;    double omgasm; double xnodes; double _em; | 
| 584 |  |  | double xinc;   double xn;     double t; | 
| 585 |  |  |  | 
| 586 |  |  | // Variables shared by "Deep" routines | 
| 587 |  |  | double dp_e3;     double dp_ee2;    double dp_savtsn; double dp_se2; | 
| 588 |  |  | double dp_se3;    double dp_sgh2;   double dp_sgh3;   double dp_sgh4; | 
| 589 |  |  | double dp_sghs;   double dp_sh2;    double dp_sh3;    double dp_si2; | 
| 590 |  |  | double dp_si3;    double dp_sl2;    double dp_sl3;    double dp_sl4; | 
| 591 |  |  | double dp_xgh2;   double dp_xgh3;   double dp_xgh4;   double dp_xh2; | 
| 592 |  |  | double dp_xh3;    double dp_xi2;    double dp_xi3;    double dp_xl2; | 
| 593 |  |  | double dp_xl3;    double dp_xl4;    double dp_xqncl;  double dp_zmol; | 
| 594 |  |  | double dp_zmos; | 
| 595 |  |  |  | 
| 596 |  |  | double dp_atime;  double dp_d2201;  double dp_d2211;  double dp_d3210; | 
| 597 |  |  | double dp_d3222;  double dp_d4410;  double dp_d4422;  double dp_d5220; | 
| 598 |  |  | double dp_d5232;  double dp_d5421;  double dp_d5433;  double dp_del1; | 
| 599 |  |  | double dp_del2;   double dp_del3;   double dp_fasx2;  double dp_fasx4; | 
| 600 |  |  | double dp_fasx6;  double dp_omegaq; double dp_sse;    double dp_ssg; | 
| 601 |  |  | double dp_ssh;    double dp_ssi;    double dp_ssl;    double dp_step2; | 
| 602 |  |  | double dp_stepn;  double dp_stepp;  double dp_thgr;   double dp_xfact; | 
| 603 |  |  | double dp_xlamo;  double dp_xli;    double dp_xni; | 
| 604 |  |  |  | 
| 605 |  |  | bool dp_iresfl; | 
| 606 |  |  | bool dp_isynfl; | 
| 607 |  |  |  | 
| 608 |  |  | // DeepInit vars that change with epoch | 
| 609 |  |  | double dpi_c;      double dpi_ctem;   double dpi_day;    double dpi_gam; | 
| 610 |  |  | double dpi_stem;   double dpi_xnodce; double dpi_zcosgl; double dpi_zcoshl; | 
| 611 |  |  | double dpi_zcosil; double dpi_zsingl; double dpi_zsinhl; double dpi_zsinil; | 
| 612 |  |  | double dpi_zx;     double dpi_zy; | 
| 613 |  |  |  | 
| 614 |  |  | }; | 
| 615 |  |  |  | 
| 616 | mocchiut | 1.1 | #endif |