Convert to unix files
parent
12297b37a1
commit
3926116d8e
224
CoordGeodetic.h
224
CoordGeodetic.h
|
@ -1,112 +1,112 @@
|
|||
#ifndef COORDGEODETIC_H_
|
||||
#define COORDGEODETIC_H_
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct CoordGeodetic
|
||||
{
|
||||
public:
|
||||
CoordGeodetic()
|
||||
: latitude(0.0), longitude(0.0), altitude(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* default is in degrees
|
||||
*/
|
||||
CoordGeodetic(double lat, double lon, double alt, bool radians = false)
|
||||
{
|
||||
if (radians)
|
||||
{
|
||||
latitude = lat;
|
||||
longitude = lon;
|
||||
}
|
||||
else
|
||||
{
|
||||
latitude = DegreesToRadians(lat);
|
||||
longitude = DegreesToRadians(lon);
|
||||
}
|
||||
altitude = alt;
|
||||
}
|
||||
|
||||
CoordGeodetic(const CoordGeodetic& g)
|
||||
{
|
||||
latitude = g.latitude;
|
||||
longitude = g.longitude;
|
||||
altitude = g.altitude;
|
||||
}
|
||||
|
||||
virtual ~CoordGeodetic()
|
||||
{
|
||||
}
|
||||
|
||||
CoordGeodetic& operator=(const CoordGeodetic& g)
|
||||
{
|
||||
if (this != &g)
|
||||
{
|
||||
latitude = g.latitude;
|
||||
longitude = g.longitude;
|
||||
altitude = g.altitude;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CoordGeodetic& g) const
|
||||
{
|
||||
return IsEqual(g);
|
||||
}
|
||||
|
||||
bool operator!=(const CoordGeodetic& g) const
|
||||
{
|
||||
return !IsEqual(g);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "Lat: " << std::setw(7) << RadiansToDegrees(latitude);
|
||||
ss << ", Lon: " << std::setw(7) << RadiansToDegrees(longitude);
|
||||
ss << ", Alt: " << std::setw(9) << altitude;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* radians (north positive, south negative)
|
||||
*/
|
||||
double latitude;
|
||||
/*
|
||||
* radians (east positive, west negative)
|
||||
*/
|
||||
double longitude;
|
||||
/*
|
||||
* kilometers
|
||||
*/
|
||||
double altitude;
|
||||
|
||||
protected:
|
||||
bool IsEqual(const CoordGeodetic& g) const
|
||||
{
|
||||
if (latitude == g.latitude && longitude == g.longitude &&
|
||||
altitude == g.altitude)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
|
||||
{
|
||||
return strm << g.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef COORDGEODETIC_H_
|
||||
#define COORDGEODETIC_H_
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct CoordGeodetic
|
||||
{
|
||||
public:
|
||||
CoordGeodetic()
|
||||
: latitude(0.0), longitude(0.0), altitude(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* default is in degrees
|
||||
*/
|
||||
CoordGeodetic(double lat, double lon, double alt, bool radians = false)
|
||||
{
|
||||
if (radians)
|
||||
{
|
||||
latitude = lat;
|
||||
longitude = lon;
|
||||
}
|
||||
else
|
||||
{
|
||||
latitude = DegreesToRadians(lat);
|
||||
longitude = DegreesToRadians(lon);
|
||||
}
|
||||
altitude = alt;
|
||||
}
|
||||
|
||||
CoordGeodetic(const CoordGeodetic& g)
|
||||
{
|
||||
latitude = g.latitude;
|
||||
longitude = g.longitude;
|
||||
altitude = g.altitude;
|
||||
}
|
||||
|
||||
virtual ~CoordGeodetic()
|
||||
{
|
||||
}
|
||||
|
||||
CoordGeodetic& operator=(const CoordGeodetic& g)
|
||||
{
|
||||
if (this != &g)
|
||||
{
|
||||
latitude = g.latitude;
|
||||
longitude = g.longitude;
|
||||
altitude = g.altitude;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CoordGeodetic& g) const
|
||||
{
|
||||
return IsEqual(g);
|
||||
}
|
||||
|
||||
bool operator!=(const CoordGeodetic& g) const
|
||||
{
|
||||
return !IsEqual(g);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "Lat: " << std::setw(7) << RadiansToDegrees(latitude);
|
||||
ss << ", Lon: " << std::setw(7) << RadiansToDegrees(longitude);
|
||||
ss << ", Alt: " << std::setw(9) << altitude;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* radians (north positive, south negative)
|
||||
*/
|
||||
double latitude;
|
||||
/*
|
||||
* radians (east positive, west negative)
|
||||
*/
|
||||
double longitude;
|
||||
/*
|
||||
* kilometers
|
||||
*/
|
||||
double altitude;
|
||||
|
||||
protected:
|
||||
bool IsEqual(const CoordGeodetic& g) const
|
||||
{
|
||||
if (latitude == g.latitude && longitude == g.longitude &&
|
||||
altitude == g.altitude)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
|
||||
{
|
||||
return strm << g.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,106 +1,106 @@
|
|||
#ifndef COORDTOPOGRAPHIC_H_
|
||||
#define COORDTOPOGRAPHIC_H_
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct CoordTopographic
|
||||
{
|
||||
public:
|
||||
CoordTopographic()
|
||||
: azimuth(0.0), elevation(0.0), range(0.0), range_rate(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
CoordTopographic(double az, double el, double rnge, double rnge_rate)
|
||||
: azimuth(az), elevation(el), range(rnge), range_rate(rnge_rate)
|
||||
{
|
||||
}
|
||||
|
||||
CoordTopographic(const CoordTopographic& t)
|
||||
{
|
||||
azimuth = t.azimuth;
|
||||
elevation = t.elevation;
|
||||
range = t.range;
|
||||
range_rate = t.range_rate;
|
||||
}
|
||||
|
||||
virtual ~CoordTopographic()
|
||||
{
|
||||
};
|
||||
|
||||
CoordTopographic& operator=(const CoordTopographic& t)
|
||||
{
|
||||
if (this != &t) {
|
||||
azimuth = t.azimuth;
|
||||
elevation = t.elevation;
|
||||
range = t.range;
|
||||
range_rate = t.range_rate;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CoordTopographic& t) const
|
||||
{
|
||||
return IsEqual(t);
|
||||
}
|
||||
|
||||
bool operator !=(const CoordTopographic& t) const
|
||||
{
|
||||
return !IsEqual(t);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "Az: " << std::setw(7) << RadiansToDegrees(azimuth);
|
||||
ss << ", El: " << std::setw(7) << RadiansToDegrees(elevation);
|
||||
ss << ", Rng: " << std::setw(9) << range;
|
||||
ss << ", Rng Rt: " << std::setw(6) << range_rate;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* radians
|
||||
*/
|
||||
double azimuth;
|
||||
/*
|
||||
* radians
|
||||
*/
|
||||
double elevation;
|
||||
/*
|
||||
* kilometers
|
||||
*/
|
||||
double range;
|
||||
/*
|
||||
* kilometers / second
|
||||
*/
|
||||
double range_rate;
|
||||
|
||||
protected:
|
||||
bool IsEqual(const CoordTopographic& t) const
|
||||
{
|
||||
if (azimuth == t.azimuth && elevation == t.elevation &&
|
||||
range == t.range && range_rate == t.range_rate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const CoordTopographic& t)
|
||||
{
|
||||
return strm << t.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef COORDTOPOGRAPHIC_H_
|
||||
#define COORDTOPOGRAPHIC_H_
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct CoordTopographic
|
||||
{
|
||||
public:
|
||||
CoordTopographic()
|
||||
: azimuth(0.0), elevation(0.0), range(0.0), range_rate(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
CoordTopographic(double az, double el, double rnge, double rnge_rate)
|
||||
: azimuth(az), elevation(el), range(rnge), range_rate(rnge_rate)
|
||||
{
|
||||
}
|
||||
|
||||
CoordTopographic(const CoordTopographic& t)
|
||||
{
|
||||
azimuth = t.azimuth;
|
||||
elevation = t.elevation;
|
||||
range = t.range;
|
||||
range_rate = t.range_rate;
|
||||
}
|
||||
|
||||
virtual ~CoordTopographic()
|
||||
{
|
||||
};
|
||||
|
||||
CoordTopographic& operator=(const CoordTopographic& t)
|
||||
{
|
||||
if (this != &t) {
|
||||
azimuth = t.azimuth;
|
||||
elevation = t.elevation;
|
||||
range = t.range;
|
||||
range_rate = t.range_rate;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CoordTopographic& t) const
|
||||
{
|
||||
return IsEqual(t);
|
||||
}
|
||||
|
||||
bool operator !=(const CoordTopographic& t) const
|
||||
{
|
||||
return !IsEqual(t);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "Az: " << std::setw(7) << RadiansToDegrees(azimuth);
|
||||
ss << ", El: " << std::setw(7) << RadiansToDegrees(elevation);
|
||||
ss << ", Rng: " << std::setw(9) << range;
|
||||
ss << ", Rng Rt: " << std::setw(6) << range_rate;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* radians
|
||||
*/
|
||||
double azimuth;
|
||||
/*
|
||||
* radians
|
||||
*/
|
||||
double elevation;
|
||||
/*
|
||||
* kilometers
|
||||
*/
|
||||
double range;
|
||||
/*
|
||||
* kilometers / second
|
||||
*/
|
||||
double range_rate;
|
||||
|
||||
protected:
|
||||
bool IsEqual(const CoordTopographic& t) const
|
||||
{
|
||||
if (azimuth == t.azimuth && elevation == t.elevation &&
|
||||
range == t.range && range_rate == t.range_rate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const CoordTopographic& t)
|
||||
{
|
||||
return strm << t.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
138
Eci.h
138
Eci.h
|
@ -1,69 +1,69 @@
|
|||
#ifndef ECI_H_
|
||||
#define ECI_H_
|
||||
|
||||
#include "CoordGeodetic.h"
|
||||
#include "Vector.h"
|
||||
#include "Julian.h"
|
||||
#include "Globals.h"
|
||||
|
||||
class Eci
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
* in degrees
|
||||
*/
|
||||
Eci(const Julian& date, double latitude, double longitude, double altitude)
|
||||
{
|
||||
ToEci(date, CoordGeodetic(latitude, longitude, altitude));
|
||||
}
|
||||
|
||||
Eci(const Julian& date, const CoordGeodetic& g)
|
||||
{
|
||||
ToEci(date, g);
|
||||
}
|
||||
|
||||
Eci(const Julian &date, const Vector &position)
|
||||
: date_(date), position_(position)
|
||||
{
|
||||
}
|
||||
|
||||
Eci(const Julian &date, const Vector &position, const Vector &velocity)
|
||||
: date_(date), position_(position), velocity_(velocity)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Eci()
|
||||
{
|
||||
}
|
||||
|
||||
Vector GetPosition() const
|
||||
{
|
||||
return position_;
|
||||
}
|
||||
|
||||
Vector GetVelocity() const
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
Julian GetDate() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
|
||||
CoordGeodetic ToGeodetic() const;
|
||||
|
||||
protected:
|
||||
void ToEci(const Julian& date, double latitude, double longitude,
|
||||
double altitude);
|
||||
void ToEci(const Julian& date, const CoordGeodetic& g);
|
||||
|
||||
private:
|
||||
Julian date_;
|
||||
Vector position_;
|
||||
Vector velocity_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef ECI_H_
|
||||
#define ECI_H_
|
||||
|
||||
#include "CoordGeodetic.h"
|
||||
#include "Vector.h"
|
||||
#include "Julian.h"
|
||||
#include "Globals.h"
|
||||
|
||||
class Eci
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
* in degrees
|
||||
*/
|
||||
Eci(const Julian& date, double latitude, double longitude, double altitude)
|
||||
{
|
||||
ToEci(date, CoordGeodetic(latitude, longitude, altitude));
|
||||
}
|
||||
|
||||
Eci(const Julian& date, const CoordGeodetic& g)
|
||||
{
|
||||
ToEci(date, g);
|
||||
}
|
||||
|
||||
Eci(const Julian &date, const Vector &position)
|
||||
: date_(date), position_(position)
|
||||
{
|
||||
}
|
||||
|
||||
Eci(const Julian &date, const Vector &position, const Vector &velocity)
|
||||
: date_(date), position_(position), velocity_(velocity)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Eci()
|
||||
{
|
||||
}
|
||||
|
||||
Vector GetPosition() const
|
||||
{
|
||||
return position_;
|
||||
}
|
||||
|
||||
Vector GetVelocity() const
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
Julian GetDate() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
|
||||
CoordGeodetic ToGeodetic() const;
|
||||
|
||||
protected:
|
||||
void ToEci(const Julian& date, double latitude, double longitude,
|
||||
double altitude);
|
||||
void ToEci(const Julian& date, const CoordGeodetic& g);
|
||||
|
||||
private:
|
||||
Julian date_;
|
||||
Vector position_;
|
||||
Vector velocity_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
212
Globals.h
212
Globals.h
|
@ -1,106 +1,106 @@
|
|||
#ifndef GLOBALS_H_
|
||||
#define GLOBALS_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
const double kAE = 1.0;
|
||||
const double kQ0 = 120.0;
|
||||
const double kS0 = 78.0;
|
||||
const double kMU = 398600.8;
|
||||
const double kXKMPER = 6378.135;
|
||||
const double kXJ2 = 1.082616e-3;
|
||||
const double kXJ3 = -2.53881e-6;
|
||||
const double kXJ4 = -1.65597e-6;
|
||||
|
||||
/*
|
||||
* alternative XKE
|
||||
* affects final results
|
||||
* aiaa-2006-6573
|
||||
* const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||
* dundee
|
||||
* const double kXKE = 7.43669161331734132e-2;
|
||||
*/
|
||||
const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||
const double kCK2 = 0.5 * kXJ2 * kAE * kAE;
|
||||
const double kCK4 = -0.375 * kXJ4 * kAE * kAE * kAE * kAE;
|
||||
|
||||
/*
|
||||
* alternative QOMS2T
|
||||
* affects final results
|
||||
* aiaa-2006-6573
|
||||
* #define QOMS2T (pow(((Q0 - S0) / XKMPER), 4.0))
|
||||
* dundee
|
||||
* #define QOMS2T (1.880279159015270643865e-9)
|
||||
*/
|
||||
const double kQOMS2T = pow(((kQ0 - kS0) / kXKMPER), 4.0);
|
||||
|
||||
const double kS = kAE * (1.0 + kS0 / kXKMPER);
|
||||
const double kPI = 3.14159265358979323846264338327950288419716939937510582;
|
||||
const double kTWOPI = 2.0 * kPI;
|
||||
const double kTWOTHIRD = 2.0 / 3.0;
|
||||
const double kTHDT = 4.37526908801129966e-3;
|
||||
/*
|
||||
* earth flattening
|
||||
*/
|
||||
const double kF = 1.0 / 298.26;
|
||||
/*
|
||||
* earth rotation per sideral day
|
||||
*/
|
||||
const double kOMEGA_E = 1.00273790934;
|
||||
const double kAU = 1.49597870691e8;
|
||||
|
||||
const double kSECONDS_PER_DAY = 86400.0;
|
||||
const double kMINUTES_PER_DAY = 1440.0;
|
||||
const double kHOURS_PER_DAY = 24.0;
|
||||
|
||||
|
||||
// Jan 1.0 1900 = Jan 1 1900 00h UTC
|
||||
const double kEPOCH_JAN1_00H_1900 = 2415019.5;
|
||||
|
||||
// Jan 1.5 1900 = Jan 1 1900 12h UTC
|
||||
const double kEPOCH_JAN1_12H_1900 = 2415020.0;
|
||||
|
||||
// Jan 1.5 2000 = Jan 1 2000 12h UTC
|
||||
const double kEPOCH_JAN1_12H_2000 = 2451545.0;
|
||||
|
||||
inline double Fmod2p(const double arg) {
|
||||
|
||||
double modu = fmod(arg, kTWOPI);
|
||||
if (modu < 0.0)
|
||||
modu += kTWOPI;
|
||||
|
||||
return modu;
|
||||
}
|
||||
|
||||
inline double DegreesToRadians(const double degrees) {
|
||||
|
||||
return degrees * kPI / 180.0;
|
||||
}
|
||||
|
||||
inline double RadiansToDegrees(const double radians) {
|
||||
|
||||
return radians * 180.0 / kPI;
|
||||
}
|
||||
|
||||
inline double AcTan(const double sinx, const double cosx) {
|
||||
|
||||
if (cosx == 0.0) {
|
||||
if (sinx > 0.0)
|
||||
return kPI / 2.0;
|
||||
else
|
||||
return 3.0 * kPI / 2.0;
|
||||
} else {
|
||||
if (cosx > 0.0)
|
||||
return atan(sinx / cosx);
|
||||
else
|
||||
return kPI + atan(sinx / cosx);
|
||||
}
|
||||
}
|
||||
|
||||
void TrimLeft(std::string& str);
|
||||
void TrimRight(std::string& str);
|
||||
void Trim(std::string& str);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef GLOBALS_H_
|
||||
#define GLOBALS_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
const double kAE = 1.0;
|
||||
const double kQ0 = 120.0;
|
||||
const double kS0 = 78.0;
|
||||
const double kMU = 398600.8;
|
||||
const double kXKMPER = 6378.135;
|
||||
const double kXJ2 = 1.082616e-3;
|
||||
const double kXJ3 = -2.53881e-6;
|
||||
const double kXJ4 = -1.65597e-6;
|
||||
|
||||
/*
|
||||
* alternative XKE
|
||||
* affects final results
|
||||
* aiaa-2006-6573
|
||||
* const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||
* dundee
|
||||
* const double kXKE = 7.43669161331734132e-2;
|
||||
*/
|
||||
const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
|
||||
const double kCK2 = 0.5 * kXJ2 * kAE * kAE;
|
||||
const double kCK4 = -0.375 * kXJ4 * kAE * kAE * kAE * kAE;
|
||||
|
||||
/*
|
||||
* alternative QOMS2T
|
||||
* affects final results
|
||||
* aiaa-2006-6573
|
||||
* #define QOMS2T (pow(((Q0 - S0) / XKMPER), 4.0))
|
||||
* dundee
|
||||
* #define QOMS2T (1.880279159015270643865e-9)
|
||||
*/
|
||||
const double kQOMS2T = pow(((kQ0 - kS0) / kXKMPER), 4.0);
|
||||
|
||||
const double kS = kAE * (1.0 + kS0 / kXKMPER);
|
||||
const double kPI = 3.14159265358979323846264338327950288419716939937510582;
|
||||
const double kTWOPI = 2.0 * kPI;
|
||||
const double kTWOTHIRD = 2.0 / 3.0;
|
||||
const double kTHDT = 4.37526908801129966e-3;
|
||||
/*
|
||||
* earth flattening
|
||||
*/
|
||||
const double kF = 1.0 / 298.26;
|
||||
/*
|
||||
* earth rotation per sideral day
|
||||
*/
|
||||
const double kOMEGA_E = 1.00273790934;
|
||||
const double kAU = 1.49597870691e8;
|
||||
|
||||
const double kSECONDS_PER_DAY = 86400.0;
|
||||
const double kMINUTES_PER_DAY = 1440.0;
|
||||
const double kHOURS_PER_DAY = 24.0;
|
||||
|
||||
|
||||
// Jan 1.0 1900 = Jan 1 1900 00h UTC
|
||||
const double kEPOCH_JAN1_00H_1900 = 2415019.5;
|
||||
|
||||
// Jan 1.5 1900 = Jan 1 1900 12h UTC
|
||||
const double kEPOCH_JAN1_12H_1900 = 2415020.0;
|
||||
|
||||
// Jan 1.5 2000 = Jan 1 2000 12h UTC
|
||||
const double kEPOCH_JAN1_12H_2000 = 2451545.0;
|
||||
|
||||
inline double Fmod2p(const double arg) {
|
||||
|
||||
double modu = fmod(arg, kTWOPI);
|
||||
if (modu < 0.0)
|
||||
modu += kTWOPI;
|
||||
|
||||
return modu;
|
||||
}
|
||||
|
||||
inline double DegreesToRadians(const double degrees) {
|
||||
|
||||
return degrees * kPI / 180.0;
|
||||
}
|
||||
|
||||
inline double RadiansToDegrees(const double radians) {
|
||||
|
||||
return radians * 180.0 / kPI;
|
||||
}
|
||||
|
||||
inline double AcTan(const double sinx, const double cosx) {
|
||||
|
||||
if (cosx == 0.0) {
|
||||
if (sinx > 0.0)
|
||||
return kPI / 2.0;
|
||||
else
|
||||
return 3.0 * kPI / 2.0;
|
||||
} else {
|
||||
if (cosx > 0.0)
|
||||
return atan(sinx / cosx);
|
||||
else
|
||||
return kPI + atan(sinx / cosx);
|
||||
}
|
||||
}
|
||||
|
||||
void TrimLeft(std::string& str);
|
||||
void TrimRight(std::string& str);
|
||||
void Trim(std::string& str);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
336
Julian.h
336
Julian.h
|
@ -1,168 +1,168 @@
|
|||
#ifndef JULIAN_H_
|
||||
#define JULIAN_H_
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Timespan.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
class Julian
|
||||
{
|
||||
public:
|
||||
Julian();
|
||||
|
||||
Julian(const Julian& jul)
|
||||
{
|
||||
date_ = jul.date_;
|
||||
}
|
||||
|
||||
Julian(const time_t t);
|
||||
|
||||
/*
|
||||
* create julian date from year and day of year
|
||||
*/
|
||||
Julian(int year, double day)
|
||||
{
|
||||
Initialize(year, day);
|
||||
}
|
||||
|
||||
/*
|
||||
* create julian date from individual components
|
||||
* year: 2004
|
||||
* mon: 1-12
|
||||
* day: 1-31
|
||||
* hour: 0-23
|
||||
* min: 0-59
|
||||
* sec: 0-59.99
|
||||
*/
|
||||
Julian(int year, int mon, int day, int hour, int min, double sec)
|
||||
{
|
||||
Initialize(year, mon, day, hour, min, sec);
|
||||
}
|
||||
|
||||
~Julian()
|
||||
{
|
||||
}
|
||||
|
||||
// comparison operators
|
||||
bool operator==(const Julian &date) const;
|
||||
bool operator!=(const Julian &date) const;
|
||||
bool operator>(const Julian &date) const;
|
||||
bool operator<(const Julian &date) const;
|
||||
bool operator>=(const Julian &date) const;
|
||||
bool operator<=(const Julian &date) const;
|
||||
|
||||
// assignment
|
||||
Julian& operator =(const Julian& b);
|
||||
Julian& operator =(const double b);
|
||||
// arithmetic
|
||||
Julian operator +(const Timespan& b) const;
|
||||
Julian operator -(const Timespan& b) const;
|
||||
Timespan operator -(const Julian& b) const;
|
||||
// compound assignment
|
||||
Julian & operator +=(const Timespan& b);
|
||||
Julian & operator -=(const Timespan& b);
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
struct DateTimeComponents dt;
|
||||
ToGregorian(&dt);
|
||||
ss << std::right << std::fixed;
|
||||
ss << std::setprecision(6) << std::setfill('0');
|
||||
ss << std::setw(4) << dt.years << "-";
|
||||
ss << std::setw(2) << dt.months << "-";
|
||||
ss << std::setw(2) << dt.days << " ";
|
||||
ss << std::setw(2) << dt.hours << ":";
|
||||
ss << std::setw(2) << dt.minutes << ":";
|
||||
ss << std::setw(9) << dt.seconds << " UTC";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
struct DateTimeComponents {
|
||||
|
||||
DateTimeComponents()
|
||||
: years(0), months(0), days(0),
|
||||
hours(0), minutes(0), seconds(0.0) {
|
||||
}
|
||||
|
||||
int years;
|
||||
int months;
|
||||
int days;
|
||||
int hours;
|
||||
int minutes;
|
||||
double seconds;
|
||||
};
|
||||
|
||||
void ToGregorian(struct DateTimeComponents* datetime) const;
|
||||
|
||||
time_t ToTime() const;
|
||||
double ToGreenwichSiderealTime() const;
|
||||
double ToLocalMeanSiderealTime(const double& lon) const;
|
||||
|
||||
double FromJan1_00h_1900() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_00H_1900;
|
||||
}
|
||||
|
||||
double FromJan1_12h_1900() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_12H_1900;
|
||||
}
|
||||
|
||||
double FromJan1_12h_2000() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_12H_2000;
|
||||
}
|
||||
|
||||
double GetDate() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
|
||||
void AddDay(double day)
|
||||
{
|
||||
date_ += day;
|
||||
}
|
||||
|
||||
void AddHour(double hr)
|
||||
{
|
||||
date_ += (hr / kHOURS_PER_DAY);
|
||||
}
|
||||
|
||||
void AddMin(double min)
|
||||
{
|
||||
date_ += (min / kMINUTES_PER_DAY);
|
||||
}
|
||||
|
||||
void AddSec(double sec)
|
||||
{
|
||||
date_ += (sec / kSECONDS_PER_DAY);
|
||||
}
|
||||
|
||||
static bool IsLeapYear(int y)
|
||||
{
|
||||
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Initialize(int year, double day);
|
||||
void Initialize(int year, int mon, int day, int hour, int min, double sec);
|
||||
|
||||
/*
|
||||
* the stored julian date
|
||||
*/
|
||||
double date_;
|
||||
};
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const Julian& j)
|
||||
{
|
||||
return strm << j.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef JULIAN_H_
|
||||
#define JULIAN_H_
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Timespan.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
class Julian
|
||||
{
|
||||
public:
|
||||
Julian();
|
||||
|
||||
Julian(const Julian& jul)
|
||||
{
|
||||
date_ = jul.date_;
|
||||
}
|
||||
|
||||
Julian(const time_t t);
|
||||
|
||||
/*
|
||||
* create julian date from year and day of year
|
||||
*/
|
||||
Julian(int year, double day)
|
||||
{
|
||||
Initialize(year, day);
|
||||
}
|
||||
|
||||
/*
|
||||
* create julian date from individual components
|
||||
* year: 2004
|
||||
* mon: 1-12
|
||||
* day: 1-31
|
||||
* hour: 0-23
|
||||
* min: 0-59
|
||||
* sec: 0-59.99
|
||||
*/
|
||||
Julian(int year, int mon, int day, int hour, int min, double sec)
|
||||
{
|
||||
Initialize(year, mon, day, hour, min, sec);
|
||||
}
|
||||
|
||||
~Julian()
|
||||
{
|
||||
}
|
||||
|
||||
// comparison operators
|
||||
bool operator==(const Julian &date) const;
|
||||
bool operator!=(const Julian &date) const;
|
||||
bool operator>(const Julian &date) const;
|
||||
bool operator<(const Julian &date) const;
|
||||
bool operator>=(const Julian &date) const;
|
||||
bool operator<=(const Julian &date) const;
|
||||
|
||||
// assignment
|
||||
Julian& operator =(const Julian& b);
|
||||
Julian& operator =(const double b);
|
||||
// arithmetic
|
||||
Julian operator +(const Timespan& b) const;
|
||||
Julian operator -(const Timespan& b) const;
|
||||
Timespan operator -(const Julian& b) const;
|
||||
// compound assignment
|
||||
Julian & operator +=(const Timespan& b);
|
||||
Julian & operator -=(const Timespan& b);
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
struct DateTimeComponents dt;
|
||||
ToGregorian(&dt);
|
||||
ss << std::right << std::fixed;
|
||||
ss << std::setprecision(6) << std::setfill('0');
|
||||
ss << std::setw(4) << dt.years << "-";
|
||||
ss << std::setw(2) << dt.months << "-";
|
||||
ss << std::setw(2) << dt.days << " ";
|
||||
ss << std::setw(2) << dt.hours << ":";
|
||||
ss << std::setw(2) << dt.minutes << ":";
|
||||
ss << std::setw(9) << dt.seconds << " UTC";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
struct DateTimeComponents {
|
||||
|
||||
DateTimeComponents()
|
||||
: years(0), months(0), days(0),
|
||||
hours(0), minutes(0), seconds(0.0) {
|
||||
}
|
||||
|
||||
int years;
|
||||
int months;
|
||||
int days;
|
||||
int hours;
|
||||
int minutes;
|
||||
double seconds;
|
||||
};
|
||||
|
||||
void ToGregorian(struct DateTimeComponents* datetime) const;
|
||||
|
||||
time_t ToTime() const;
|
||||
double ToGreenwichSiderealTime() const;
|
||||
double ToLocalMeanSiderealTime(const double& lon) const;
|
||||
|
||||
double FromJan1_00h_1900() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_00H_1900;
|
||||
}
|
||||
|
||||
double FromJan1_12h_1900() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_12H_1900;
|
||||
}
|
||||
|
||||
double FromJan1_12h_2000() const
|
||||
{
|
||||
return date_ - kEPOCH_JAN1_12H_2000;
|
||||
}
|
||||
|
||||
double GetDate() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
|
||||
void AddDay(double day)
|
||||
{
|
||||
date_ += day;
|
||||
}
|
||||
|
||||
void AddHour(double hr)
|
||||
{
|
||||
date_ += (hr / kHOURS_PER_DAY);
|
||||
}
|
||||
|
||||
void AddMin(double min)
|
||||
{
|
||||
date_ += (min / kMINUTES_PER_DAY);
|
||||
}
|
||||
|
||||
void AddSec(double sec)
|
||||
{
|
||||
date_ += (sec / kSECONDS_PER_DAY);
|
||||
}
|
||||
|
||||
static bool IsLeapYear(int y)
|
||||
{
|
||||
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Initialize(int year, double day);
|
||||
void Initialize(int year, int mon, int day, int hour, int min, double sec);
|
||||
|
||||
/*
|
||||
* the stored julian date
|
||||
*/
|
||||
double date_;
|
||||
};
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const Julian& j)
|
||||
{
|
||||
return strm << j.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
136
Observer.h
136
Observer.h
|
@ -1,68 +1,68 @@
|
|||
#ifndef OBSERVER_H_
|
||||
#define OBSERVER_H_
|
||||
|
||||
#include "CoordGeodetic.h"
|
||||
#include "CoordTopographic.h"
|
||||
#include "Julian.h"
|
||||
#include "Eci.h"
|
||||
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
Observer(double latitude, double longitude, double altitude)
|
||||
: geo_(latitude, longitude, altitude),
|
||||
observers_eci_(Julian(), geo_)
|
||||
{
|
||||
}
|
||||
|
||||
Observer(const CoordGeodetic &g)
|
||||
: geo_(g), observers_eci_(Julian(), geo_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Observer()
|
||||
{
|
||||
}
|
||||
|
||||
void SetLocation(const CoordGeodetic& g)
|
||||
{
|
||||
geo_ = g;
|
||||
observers_eci_ = Eci(observers_eci_.GetDate(), geo_);
|
||||
}
|
||||
|
||||
CoordGeodetic GetLocation() const
|
||||
{
|
||||
return geo_;
|
||||
}
|
||||
|
||||
Eci GetEciPosition(const Julian &date) const
|
||||
{
|
||||
return Eci(date, geo_);
|
||||
}
|
||||
|
||||
CoordTopographic GetLookAngle(const Eci &eci);
|
||||
|
||||
private:
|
||||
void UpdateObserversEci(const Julian &date)
|
||||
{
|
||||
/*
|
||||
* if date has changed, update for new date
|
||||
*/
|
||||
if (observers_eci_.GetDate() != date)
|
||||
{
|
||||
observers_eci_ = Eci(date, geo_);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the observers position
|
||||
*/
|
||||
CoordGeodetic geo_;
|
||||
/*
|
||||
* the observers eci for a particular time
|
||||
*/
|
||||
Eci observers_eci_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OBSERVER_H_
|
||||
#define OBSERVER_H_
|
||||
|
||||
#include "CoordGeodetic.h"
|
||||
#include "CoordTopographic.h"
|
||||
#include "Julian.h"
|
||||
#include "Eci.h"
|
||||
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
Observer(double latitude, double longitude, double altitude)
|
||||
: geo_(latitude, longitude, altitude),
|
||||
observers_eci_(Julian(), geo_)
|
||||
{
|
||||
}
|
||||
|
||||
Observer(const CoordGeodetic &g)
|
||||
: geo_(g), observers_eci_(Julian(), geo_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Observer()
|
||||
{
|
||||
}
|
||||
|
||||
void SetLocation(const CoordGeodetic& g)
|
||||
{
|
||||
geo_ = g;
|
||||
observers_eci_ = Eci(observers_eci_.GetDate(), geo_);
|
||||
}
|
||||
|
||||
CoordGeodetic GetLocation() const
|
||||
{
|
||||
return geo_;
|
||||
}
|
||||
|
||||
Eci GetEciPosition(const Julian &date) const
|
||||
{
|
||||
return Eci(date, geo_);
|
||||
}
|
||||
|
||||
CoordTopographic GetLookAngle(const Eci &eci);
|
||||
|
||||
private:
|
||||
void UpdateObserversEci(const Julian &date)
|
||||
{
|
||||
/*
|
||||
* if date has changed, update for new date
|
||||
*/
|
||||
if (observers_eci_.GetDate() != date)
|
||||
{
|
||||
observers_eci_ = Eci(date, geo_);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the observers position
|
||||
*/
|
||||
CoordGeodetic geo_;
|
||||
/*
|
||||
* the observers eci for a particular time
|
||||
*/
|
||||
Eci observers_eci_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,128 +1,128 @@
|
|||
#ifndef ORBITALELEMENTS_H_
|
||||
#define ORBITALELEMENTS_H_
|
||||
|
||||
#include "Tle.h"
|
||||
|
||||
class OrbitalElements
|
||||
{
|
||||
public:
|
||||
OrbitalElements(const Tle& tle);
|
||||
|
||||
virtual ~OrbitalElements()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* XMO
|
||||
*/
|
||||
double MeanAnomoly() const
|
||||
{
|
||||
return mean_anomoly_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNODEO
|
||||
*/
|
||||
double AscendingNode() const
|
||||
{
|
||||
return ascending_node_;
|
||||
}
|
||||
|
||||
/*
|
||||
* OMEGAO
|
||||
*/
|
||||
double ArgumentPerigee() const
|
||||
{
|
||||
return argument_perigee_;
|
||||
}
|
||||
|
||||
/*
|
||||
* EO
|
||||
*/
|
||||
double Eccentricity() const
|
||||
{
|
||||
return eccentricity_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XINCL
|
||||
*/
|
||||
double Inclination() const
|
||||
{
|
||||
return inclination_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNO
|
||||
*/
|
||||
double MeanMotion() const
|
||||
{
|
||||
return mean_motion_;
|
||||
}
|
||||
|
||||
/*
|
||||
* BSTAR
|
||||
*/
|
||||
double BStar() const
|
||||
{
|
||||
return bstar_;
|
||||
}
|
||||
|
||||
/*
|
||||
* AODP
|
||||
*/
|
||||
double RecoveredSemiMajorAxis() const
|
||||
{
|
||||
return recovered_semi_major_axis_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNODP
|
||||
*/
|
||||
double RecoveredMeanMotion() const
|
||||
{
|
||||
return recovered_mean_motion_;
|
||||
}
|
||||
|
||||
/*
|
||||
* PERIGE
|
||||
*/
|
||||
double Perigee() const
|
||||
{
|
||||
return perigee_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Period in minutes
|
||||
*/
|
||||
double Period() const
|
||||
{
|
||||
return period_;
|
||||
}
|
||||
|
||||
/*
|
||||
* EPOCH
|
||||
*/
|
||||
Julian Epoch() const
|
||||
{
|
||||
return epoch_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
double mean_anomoly_;
|
||||
double ascending_node_;
|
||||
double argument_perigee_;
|
||||
double eccentricity_;
|
||||
double inclination_;
|
||||
double mean_motion_;
|
||||
double bstar_;
|
||||
double recovered_semi_major_axis_;
|
||||
double recovered_mean_motion_;
|
||||
double perigee_;
|
||||
double period_;
|
||||
Julian epoch_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef ORBITALELEMENTS_H_
|
||||
#define ORBITALELEMENTS_H_
|
||||
|
||||
#include "Tle.h"
|
||||
|
||||
class OrbitalElements
|
||||
{
|
||||
public:
|
||||
OrbitalElements(const Tle& tle);
|
||||
|
||||
virtual ~OrbitalElements()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* XMO
|
||||
*/
|
||||
double MeanAnomoly() const
|
||||
{
|
||||
return mean_anomoly_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNODEO
|
||||
*/
|
||||
double AscendingNode() const
|
||||
{
|
||||
return ascending_node_;
|
||||
}
|
||||
|
||||
/*
|
||||
* OMEGAO
|
||||
*/
|
||||
double ArgumentPerigee() const
|
||||
{
|
||||
return argument_perigee_;
|
||||
}
|
||||
|
||||
/*
|
||||
* EO
|
||||
*/
|
||||
double Eccentricity() const
|
||||
{
|
||||
return eccentricity_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XINCL
|
||||
*/
|
||||
double Inclination() const
|
||||
{
|
||||
return inclination_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNO
|
||||
*/
|
||||
double MeanMotion() const
|
||||
{
|
||||
return mean_motion_;
|
||||
}
|
||||
|
||||
/*
|
||||
* BSTAR
|
||||
*/
|
||||
double BStar() const
|
||||
{
|
||||
return bstar_;
|
||||
}
|
||||
|
||||
/*
|
||||
* AODP
|
||||
*/
|
||||
double RecoveredSemiMajorAxis() const
|
||||
{
|
||||
return recovered_semi_major_axis_;
|
||||
}
|
||||
|
||||
/*
|
||||
* XNODP
|
||||
*/
|
||||
double RecoveredMeanMotion() const
|
||||
{
|
||||
return recovered_mean_motion_;
|
||||
}
|
||||
|
||||
/*
|
||||
* PERIGE
|
||||
*/
|
||||
double Perigee() const
|
||||
{
|
||||
return perigee_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Period in minutes
|
||||
*/
|
||||
double Period() const
|
||||
{
|
||||
return period_;
|
||||
}
|
||||
|
||||
/*
|
||||
* EPOCH
|
||||
*/
|
||||
Julian Epoch() const
|
||||
{
|
||||
return epoch_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
double mean_anomoly_;
|
||||
double ascending_node_;
|
||||
double argument_perigee_;
|
||||
double eccentricity_;
|
||||
double inclination_;
|
||||
double mean_motion_;
|
||||
double bstar_;
|
||||
double recovered_semi_major_axis_;
|
||||
double recovered_mean_motion_;
|
||||
double perigee_;
|
||||
double period_;
|
||||
Julian epoch_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
220
SGP4-VER.TLE
220
SGP4-VER.TLE
|
@ -1,110 +1,110 @@
|
|||
# ------------------ Verification test cases ----------------------
|
||||
# # TEME example
|
||||
1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753
|
||||
2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667 0.00 4320.0 360.00
|
||||
# ## fig show lyddane fix error with gsfc ver
|
||||
1 04632U 70093B 04031.91070959 -.00000084 00000-0 10000-3 0 9955
|
||||
2 04632 11.4628 273.1101 1450506 207.6000 143.9350 1.20231981 44145 -5184.0 -4896.0 120.00
|
||||
# DELTA 1 DEB # near earth normal drag equation
|
||||
# # perigee = 377.26km, so moderate drag case
|
||||
1 06251U 62025E 06176.82412014 .00008885 00000-0 12808-3 0 3985
|
||||
2 06251 58.0579 54.0425 0030035 139.1568 221.1854 15.56387291 6774 0.0 2880.0 120.00
|
||||
# MOLNIYA 2-14 # 12h resonant ecc in 0.65 to 0.7 range
|
||||
1 08195U 75081A 06176.33215444 .00000099 00000-0 11873-3 0 813
|
||||
2 08195 64.1586 279.0717 6877146 264.7651 20.2257 2.00491383225656 0.0 2880.0 120.00
|
||||
# MOLNIYA 1-36 ## fig 12h resonant ecc in 0.7 to 0.715 range
|
||||
1 09880U 77021A 06176.56157475 .00000421 00000-0 10000-3 0 9814
|
||||
2 09880 64.5968 349.3786 7069051 270.0229 16.3320 2.00813614112380 0.0 2880.0 120.00
|
||||
# SMS 1 AKM # show the integrator problem with gsfc ver
|
||||
1 09998U 74033F 05148.79417928 -.00000112 00000-0 00000+0 0 4480
|
||||
2 09998 9.4958 313.1750 0270971 327.5225 30.8097 1.16186785 45878 -1440.0 -720.00 60.0
|
||||
# # Original STR#3 SDP4 test
|
||||
1 11801U 80230.29629788 .01431103 00000-0 14311-1 13
|
||||
2 11801 46.7916 230.4354 7318036 47.4722 10.4117 2.28537848 13 0.0 1440.0 360.00
|
||||
# EUTELSAT 1-F1 (ECS1)## fig lyddane choice in GSFC at 2080 min
|
||||
1 14128U 83058A 06176.02844893 -.00000158 00000-0 10000-3 0 9627
|
||||
2 14128 11.4384 35.2134 0011562 26.4582 333.5652 0.98870114 46093 0.0 2880.0 120.00
|
||||
# SL-6 R/B(2) # Deep space, perigee = 82.48 (<98) for
|
||||
# # s4 > 20 mod
|
||||
1 16925U 86065D 06151.67415771 .02550794 -30915-6 18784-3 0 4486
|
||||
2 16925 62.0906 295.0239 5596327 245.1593 47.9690 4.88511875148616 0.0 1440.0 120.00
|
||||
# SL-12 R/B # Shows Lyddane choice at 1860 and 4700 min
|
||||
1 20413U 83020D 05363.79166667 .00000000 00000-0 00000+0 0 7041
|
||||
2 20413 12.3514 187.4253 7864447 196.3027 356.5478 0.24690082 7978 1440.0 4320.0 120.00
|
||||
# MOLNIYA 1-83 # 12h resonant, ecc > 0.715 (negative BSTAR)
|
||||
1 21897U 92011A 06176.02341244 -.00001273 00000-0 -13525-3 0 3044
|
||||
2 21897 62.1749 198.0096 7421690 253.0462 20.1561 2.01269994104880 0.0 2880.0 120.00
|
||||
# SL-6 R/B(2) # last tle given, decayed 2006-04-04, day 94
|
||||
1 22312U 93002D 06094.46235912 .99999999 81888-5 49949-3 0 3953
|
||||
2 22312 62.1486 77.4698 0308723 267.9229 88.7392 15.95744531 98783 54.2028672 1440.0 20.00
|
||||
# SL-6 R/B(2) # 12h resonant ecc in the > 0.715 range
|
||||
1 22674U 93035D 06176.55909107 .00002121 00000-0 29868-3 0 6569
|
||||
2 22674 63.5035 354.4452 7541712 253.3264 18.7754 1.96679808 93877 0.0 2880.0 120.00
|
||||
# ARIANE 44L+ R/B # Lyddane bug at <= 70 min for atan2(),
|
||||
# # no quadrant fix
|
||||
1 23177U 94040C 06175.45752052 .00000386 00000-0 76590-3 0 95
|
||||
2 23177 7.0496 179.8238 7258491 296.0482 8.3061 2.25906668 97438 0.0 1440.0 120.00
|
||||
# WIND # STR#3 Kepler failes past about 200 min
|
||||
1 23333U 94071A 94305.49999999 -.00172956 26967-3 10000-3 0 15
|
||||
2 23333 28.7490 2.3720 9728298 30.4360 1.3500 0.07309491 70 0.0 1600.0 120.00
|
||||
# ARIANE 42P+3 R/B ## fig Lyddane bug at > 280.5 min for AcTan()
|
||||
1 23599U 95029B 06171.76535463 .00085586 12891-6 12956-2 0 2905
|
||||
2 23599 6.9327 0.2849 5782022 274.4436 25.2425 4.47796565123555 0.0 720.0 20.00
|
||||
# ITALSAT 2 # 24h resonant GEO, inclination > 3 deg
|
||||
1 24208U 96044A 06177.04061740 -.00000094 00000-0 10000-3 0 1600
|
||||
2 24208 3.8536 80.0121 0026640 311.0977 48.3000 1.00778054 36119 0.0 1440.0 120.00
|
||||
# AMC-4 ## fig low incl, show incl shift with
|
||||
# ## gsfc version from 240 to 1440 min
|
||||
1 25954U 99060A 04039.68057285 -.00000108 00000-0 00000-0 0 6847
|
||||
2 25954 0.0004 243.8136 0001765 15.5294 22.7134 1.00271289 15615 -1440.0 1440.0 120.00
|
||||
# INTELSAT 902 # negative incl at 9313 min then
|
||||
# # 270 deg Lyddane bug at 37606 min
|
||||
1 26900U 01039A 06106.74503247 .00000045 00000-0 10000-3 0 8290
|
||||
2 26900 0.0164 266.5378 0003319 86.1794 182.2590 1.00273847 16981 9300.00 9400.00 60.00
|
||||
# COSMOS 1024 DEB # 12h resonant ecc in 0.5 to 0.65 range
|
||||
1 26975U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809
|
||||
2 26975 68.4714 236.1303 5602877 123.7484 302.5767 2.05657553 67521 0.0 2880.0 120.00
|
||||
# CBERS 2 # Near Earth, ecc = 8.84E-5 (< 1.0e-4)
|
||||
# # drop certain normal drag terms
|
||||
1 28057U 03049A 06177.78615833 .00000060 00000-0 35940-4 0 1836
|
||||
2 28057 98.4283 247.6961 0000884 88.1964 271.9322 14.35478080140550 0.0 2880.0 120.00
|
||||
# NAVSTAR 53 (USA 175)# 12h non-resonant GPS (ecc < 0.5 ecc)
|
||||
1 28129U 03058A 06175.57071136 -.00000104 00000-0 10000-3 0 459
|
||||
2 28129 54.7298 324.8098 0048506 266.2640 93.1663 2.00562768 18443 0.0 1440.0 120.00
|
||||
# COSMOS 2405 # Near Earth, perigee = 127.20 (< 156) s4 mod
|
||||
1 28350U 04020A 06167.21788666 .16154492 76267-5 18678-3 0 8894
|
||||
2 28350 64.9977 345.6130 0024870 260.7578 99.9590 16.47856722116490 0.0 2880.0 120.00
|
||||
# H-2 R/B # Deep space, perigee = 135.75 (<156) s4 mod
|
||||
1 28623U 05006B 06177.81079184 .00637644 69054-6 96390-3 0 6000
|
||||
2 28623 28.5200 114.9834 6249053 170.2550 212.8965 3.79477162 12753 0.0 1440.0 120.00
|
||||
# XM-3 # 24h resonant geo, incl < 3 deg goes
|
||||
# # negative around 1130 min
|
||||
1 28626U 05008A 06176.46683397 -.00000205 00000-0 10000-3 0 2190
|
||||
2 28626 0.0019 286.9433 0000335 13.7918 55.6504 1.00270176 4891 0.0 1440.0 120.00
|
||||
# MINOTAUR R/B # Sub-orbital case - Decayed 2005-11-29
|
||||
# #(perigee = -51km), lost in 50 minutes
|
||||
1 28872U 05037B 05333.02012661 .25992681 00000-0 24476-3 0 1534
|
||||
2 28872 96.4736 157.9986 0303955 244.0492 110.6523 16.46015938 10708 0.0 60.0 5.00
|
||||
# SL-14 DEB # Last stage of decay - lost in under 420 min
|
||||
1 29141U 85108AA 06170.26783845 .99999999 00000-0 13519-0 0 718
|
||||
2 29141 82.4288 273.4882 0015848 277.2124 83.9133 15.93343074 6828 0.0 440.0 20.00
|
||||
# SL-12 DEB # Near Earth, perigee = 212.24 < 220
|
||||
# # simplified drag eq
|
||||
1 29238U 06022G 06177.28732010 .00766286 10823-4 13334-2 0 101
|
||||
2 29238 51.5595 213.7903 0202579 95.2503 267.9010 15.73823839 1061 0.0 1440.0 120.00
|
||||
# # Original STR#3 SGP4 test
|
||||
1 88888U 80275.98708465 .00073094 13844-3 66816-4 0 87
|
||||
2 88888 72.8435 115.9689 0086731 52.6988 110.5714 16.05824518 1058 0.0 1440.0 120.00
|
||||
#
|
||||
# # check error code 4
|
||||
1 33333U 05037B 05333.02012661 .25992681 00000-0 24476-3 0 1534
|
||||
2 33333 96.4736 157.9986 9950000 244.0492 110.6523 4.00004038 10708 0.0 150.0 5.00
|
||||
# # try and check error code 2 but this
|
||||
1 33334U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809
|
||||
2 33334 68.4714 236.1303 5602877 123.7484 302.5767 0.00001000 67521 0.0 1440.0 1.00
|
||||
# # try to check error code 3 looks like ep never goes below zero, tied close to ecc
|
||||
1 33335U 05008A 06176.46683397 -.00000205 00000-0 10000-3 0 2190
|
||||
2 33335 0.0019 286.9433 0000004 13.7918 55.6504 1.00270176 4891 0.0 1440.0 20.00
|
||||
# SL-12 R/B # Shows Lyddane choice at 1860 and 4700 min
|
||||
1 20413U 83020D 05363.79166667 .00000000 00000-0 00000+0 0 7041
|
||||
2 20413 12.3514 187.4253 7864447 196.3027 356.5478 0.24690082 7978 1844000 1845100 5.00
|
||||
# ------------------ Verification test cases ----------------------
|
||||
# # TEME example
|
||||
1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753
|
||||
2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667 0.00 4320.0 360.00
|
||||
# ## fig show lyddane fix error with gsfc ver
|
||||
1 04632U 70093B 04031.91070959 -.00000084 00000-0 10000-3 0 9955
|
||||
2 04632 11.4628 273.1101 1450506 207.6000 143.9350 1.20231981 44145 -5184.0 -4896.0 120.00
|
||||
# DELTA 1 DEB # near earth normal drag equation
|
||||
# # perigee = 377.26km, so moderate drag case
|
||||
1 06251U 62025E 06176.82412014 .00008885 00000-0 12808-3 0 3985
|
||||
2 06251 58.0579 54.0425 0030035 139.1568 221.1854 15.56387291 6774 0.0 2880.0 120.00
|
||||
# MOLNIYA 2-14 # 12h resonant ecc in 0.65 to 0.7 range
|
||||
1 08195U 75081A 06176.33215444 .00000099 00000-0 11873-3 0 813
|
||||
2 08195 64.1586 279.0717 6877146 264.7651 20.2257 2.00491383225656 0.0 2880.0 120.00
|
||||
# MOLNIYA 1-36 ## fig 12h resonant ecc in 0.7 to 0.715 range
|
||||
1 09880U 77021A 06176.56157475 .00000421 00000-0 10000-3 0 9814
|
||||
2 09880 64.5968 349.3786 7069051 270.0229 16.3320 2.00813614112380 0.0 2880.0 120.00
|
||||
# SMS 1 AKM # show the integrator problem with gsfc ver
|
||||
1 09998U 74033F 05148.79417928 -.00000112 00000-0 00000+0 0 4480
|
||||
2 09998 9.4958 313.1750 0270971 327.5225 30.8097 1.16186785 45878 -1440.0 -720.00 60.0
|
||||
# # Original STR#3 SDP4 test
|
||||
1 11801U 80230.29629788 .01431103 00000-0 14311-1 13
|
||||
2 11801 46.7916 230.4354 7318036 47.4722 10.4117 2.28537848 13 0.0 1440.0 360.00
|
||||
# EUTELSAT 1-F1 (ECS1)## fig lyddane choice in GSFC at 2080 min
|
||||
1 14128U 83058A 06176.02844893 -.00000158 00000-0 10000-3 0 9627
|
||||
2 14128 11.4384 35.2134 0011562 26.4582 333.5652 0.98870114 46093 0.0 2880.0 120.00
|
||||
# SL-6 R/B(2) # Deep space, perigee = 82.48 (<98) for
|
||||
# # s4 > 20 mod
|
||||
1 16925U 86065D 06151.67415771 .02550794 -30915-6 18784-3 0 4486
|
||||
2 16925 62.0906 295.0239 5596327 245.1593 47.9690 4.88511875148616 0.0 1440.0 120.00
|
||||
# SL-12 R/B # Shows Lyddane choice at 1860 and 4700 min
|
||||
1 20413U 83020D 05363.79166667 .00000000 00000-0 00000+0 0 7041
|
||||
2 20413 12.3514 187.4253 7864447 196.3027 356.5478 0.24690082 7978 1440.0 4320.0 120.00
|
||||
# MOLNIYA 1-83 # 12h resonant, ecc > 0.715 (negative BSTAR)
|
||||
1 21897U 92011A 06176.02341244 -.00001273 00000-0 -13525-3 0 3044
|
||||
2 21897 62.1749 198.0096 7421690 253.0462 20.1561 2.01269994104880 0.0 2880.0 120.00
|
||||
# SL-6 R/B(2) # last tle given, decayed 2006-04-04, day 94
|
||||
1 22312U 93002D 06094.46235912 .99999999 81888-5 49949-3 0 3953
|
||||
2 22312 62.1486 77.4698 0308723 267.9229 88.7392 15.95744531 98783 54.2028672 1440.0 20.00
|
||||
# SL-6 R/B(2) # 12h resonant ecc in the > 0.715 range
|
||||
1 22674U 93035D 06176.55909107 .00002121 00000-0 29868-3 0 6569
|
||||
2 22674 63.5035 354.4452 7541712 253.3264 18.7754 1.96679808 93877 0.0 2880.0 120.00
|
||||
# ARIANE 44L+ R/B # Lyddane bug at <= 70 min for atan2(),
|
||||
# # no quadrant fix
|
||||
1 23177U 94040C 06175.45752052 .00000386 00000-0 76590-3 0 95
|
||||
2 23177 7.0496 179.8238 7258491 296.0482 8.3061 2.25906668 97438 0.0 1440.0 120.00
|
||||
# WIND # STR#3 Kepler failes past about 200 min
|
||||
1 23333U 94071A 94305.49999999 -.00172956 26967-3 10000-3 0 15
|
||||
2 23333 28.7490 2.3720 9728298 30.4360 1.3500 0.07309491 70 0.0 1600.0 120.00
|
||||
# ARIANE 42P+3 R/B ## fig Lyddane bug at > 280.5 min for AcTan()
|
||||
1 23599U 95029B 06171.76535463 .00085586 12891-6 12956-2 0 2905
|
||||
2 23599 6.9327 0.2849 5782022 274.4436 25.2425 4.47796565123555 0.0 720.0 20.00
|
||||
# ITALSAT 2 # 24h resonant GEO, inclination > 3 deg
|
||||
1 24208U 96044A 06177.04061740 -.00000094 00000-0 10000-3 0 1600
|
||||
2 24208 3.8536 80.0121 0026640 311.0977 48.3000 1.00778054 36119 0.0 1440.0 120.00
|
||||
# AMC-4 ## fig low incl, show incl shift with
|
||||
# ## gsfc version from 240 to 1440 min
|
||||
1 25954U 99060A 04039.68057285 -.00000108 00000-0 00000-0 0 6847
|
||||
2 25954 0.0004 243.8136 0001765 15.5294 22.7134 1.00271289 15615 -1440.0 1440.0 120.00
|
||||
# INTELSAT 902 # negative incl at 9313 min then
|
||||
# # 270 deg Lyddane bug at 37606 min
|
||||
1 26900U 01039A 06106.74503247 .00000045 00000-0 10000-3 0 8290
|
||||
2 26900 0.0164 266.5378 0003319 86.1794 182.2590 1.00273847 16981 9300.00 9400.00 60.00
|
||||
# COSMOS 1024 DEB # 12h resonant ecc in 0.5 to 0.65 range
|
||||
1 26975U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809
|
||||
2 26975 68.4714 236.1303 5602877 123.7484 302.5767 2.05657553 67521 0.0 2880.0 120.00
|
||||
# CBERS 2 # Near Earth, ecc = 8.84E-5 (< 1.0e-4)
|
||||
# # drop certain normal drag terms
|
||||
1 28057U 03049A 06177.78615833 .00000060 00000-0 35940-4 0 1836
|
||||
2 28057 98.4283 247.6961 0000884 88.1964 271.9322 14.35478080140550 0.0 2880.0 120.00
|
||||
# NAVSTAR 53 (USA 175)# 12h non-resonant GPS (ecc < 0.5 ecc)
|
||||
1 28129U 03058A 06175.57071136 -.00000104 00000-0 10000-3 0 459
|
||||
2 28129 54.7298 324.8098 0048506 266.2640 93.1663 2.00562768 18443 0.0 1440.0 120.00
|
||||
# COSMOS 2405 # Near Earth, perigee = 127.20 (< 156) s4 mod
|
||||
1 28350U 04020A 06167.21788666 .16154492 76267-5 18678-3 0 8894
|
||||
2 28350 64.9977 345.6130 0024870 260.7578 99.9590 16.47856722116490 0.0 2880.0 120.00
|
||||
# H-2 R/B # Deep space, perigee = 135.75 (<156) s4 mod
|
||||
1 28623U 05006B 06177.81079184 .00637644 69054-6 96390-3 0 6000
|
||||
2 28623 28.5200 114.9834 6249053 170.2550 212.8965 3.79477162 12753 0.0 1440.0 120.00
|
||||
# XM-3 # 24h resonant geo, incl < 3 deg goes
|
||||
# # negative around 1130 min
|
||||
1 28626U 05008A 06176.46683397 -.00000205 00000-0 10000-3 0 2190
|
||||
2 28626 0.0019 286.9433 0000335 13.7918 55.6504 1.00270176 4891 0.0 1440.0 120.00
|
||||
# MINOTAUR R/B # Sub-orbital case - Decayed 2005-11-29
|
||||
# #(perigee = -51km), lost in 50 minutes
|
||||
1 28872U 05037B 05333.02012661 .25992681 00000-0 24476-3 0 1534
|
||||
2 28872 96.4736 157.9986 0303955 244.0492 110.6523 16.46015938 10708 0.0 60.0 5.00
|
||||
# SL-14 DEB # Last stage of decay - lost in under 420 min
|
||||
1 29141U 85108AA 06170.26783845 .99999999 00000-0 13519-0 0 718
|
||||
2 29141 82.4288 273.4882 0015848 277.2124 83.9133 15.93343074 6828 0.0 440.0 20.00
|
||||
# SL-12 DEB # Near Earth, perigee = 212.24 < 220
|
||||
# # simplified drag eq
|
||||
1 29238U 06022G 06177.28732010 .00766286 10823-4 13334-2 0 101
|
||||
2 29238 51.5595 213.7903 0202579 95.2503 267.9010 15.73823839 1061 0.0 1440.0 120.00
|
||||
# # Original STR#3 SGP4 test
|
||||
1 88888U 80275.98708465 .00073094 13844-3 66816-4 0 87
|
||||
2 88888 72.8435 115.9689 0086731 52.6988 110.5714 16.05824518 1058 0.0 1440.0 120.00
|
||||
#
|
||||
# # check error code 4
|
||||
1 33333U 05037B 05333.02012661 .25992681 00000-0 24476-3 0 1534
|
||||
2 33333 96.4736 157.9986 9950000 244.0492 110.6523 4.00004038 10708 0.0 150.0 5.00
|
||||
# # try and check error code 2 but this
|
||||
1 33334U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809
|
||||
2 33334 68.4714 236.1303 5602877 123.7484 302.5767 0.00001000 67521 0.0 1440.0 1.00
|
||||
# # try to check error code 3 looks like ep never goes below zero, tied close to ecc
|
||||
1 33335U 05008A 06176.46683397 -.00000205 00000-0 10000-3 0 2190
|
||||
2 33335 0.0019 286.9433 0000004 13.7918 55.6504 1.00270176 4891 0.0 1440.0 20.00
|
||||
# SL-12 R/B # Shows Lyddane choice at 1860 and 4700 min
|
||||
1 20413U 83020D 05363.79166667 .00000000 00000-0 00000+0 0 7041
|
||||
2 20413 12.3514 187.4253 7864447 196.3027 356.5478 0.24690082 7978 1844000 1845100 5.00
|
||||
|
|
498
SGP4.h
498
SGP4.h
|
@ -1,249 +1,249 @@
|
|||
#ifndef SGP4_H_
|
||||
#define SGP4_H_
|
||||
|
||||
#include "Tle.h"
|
||||
#include "OrbitalElements.h"
|
||||
#include "Eci.h"
|
||||
#include "SatelliteException.h"
|
||||
|
||||
class SGP4
|
||||
{
|
||||
public:
|
||||
SGP4(const Tle& tle)
|
||||
: elements_(tle)
|
||||
{
|
||||
Initialise();
|
||||
}
|
||||
|
||||
virtual ~SGP4()
|
||||
{
|
||||
}
|
||||
|
||||
void SetTle(const Tle& tle);
|
||||
Eci FindPosition(double tsince) const;
|
||||
Eci FindPosition(const Julian& date) const;
|
||||
|
||||
struct CommonConstants
|
||||
{
|
||||
CommonConstants()
|
||||
: cosio(0.0), sinio(0.0), eta(0.0), t2cof(0.0), a3ovk2(0.0),
|
||||
x1mth2(0.0), x3thm1(0.0), x7thm1(0.0), aycof(0.0), xlcof(0.0),
|
||||
xnodcf(0.0), c1(0.0), c4(0.0), omgdot(0.0), xnodot(0.0), xmdot(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double cosio;
|
||||
double sinio;
|
||||
double eta;
|
||||
double t2cof;
|
||||
double a3ovk2;
|
||||
double x1mth2;
|
||||
double x3thm1;
|
||||
double x7thm1;
|
||||
double aycof;
|
||||
double xlcof;
|
||||
double xnodcf;
|
||||
double c1;
|
||||
double c4;
|
||||
double omgdot; // secular rate of omega (radians/sec)
|
||||
double xnodot; // secular rate of xnode (radians/sec)
|
||||
double xmdot; // secular rate of xmo (radians/sec)
|
||||
};
|
||||
|
||||
struct NearSpaceConstants
|
||||
{
|
||||
NearSpaceConstants()
|
||||
: c5(0.0), omgcof(0.0), xmcof(0.0), delmo(0.0), sinmo(0.0), d2(0.0),
|
||||
d3(0.0), d4(0.0), t3cof(0.0), t4cof(0.0), t5cof(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double c5;
|
||||
double omgcof;
|
||||
double xmcof;
|
||||
double delmo;
|
||||
double sinmo;
|
||||
double d2;
|
||||
double d3;
|
||||
double d4;
|
||||
double t3cof;
|
||||
double t4cof;
|
||||
double t5cof;
|
||||
};
|
||||
|
||||
struct DeepSpaceConstants
|
||||
{
|
||||
DeepSpaceConstants()
|
||||
: gsto(0.0), zmol(0.0), zmos(0.0), resonance_flag(false),
|
||||
synchronous_flag(false), sse(0.0), ssi(0.0), ssl(0.0), ssg(0.0),
|
||||
ssh(0.0), se2(0.0), si2(0.0), sl2(0.0), sgh2(0.0), sh2(0.0), se3(0.0),
|
||||
si3(0.0), sl3(0.0), sgh3(0.0), sh3(0.0), sl4(0.0), sgh4(0.0), ee2(0.0),
|
||||
e3(0.0), xi2(0.0), xi3(0.0), xl2(0.0), xl3(0.0), xl4(0.0), xgh2(0.0),
|
||||
xgh3(0.0), xgh4(0.0), xh2(0.0), xh3(0.0), d2201(0.0), d2211(0.0),
|
||||
d3210(0.0), d3222(0.0), d4410(0.0), d4422(0.0), d5220(0.0), d5232(0.0),
|
||||
d5421(0.0), d5433(0.0), del1(0.0), del2(0.0), del3(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double gsto;
|
||||
double zmol;
|
||||
double zmos;
|
||||
/*
|
||||
* whether the deep space orbit is
|
||||
* geopotential resonance for 12 hour orbits
|
||||
*/
|
||||
bool resonance_flag;
|
||||
/*
|
||||
* whether the deep space orbit is
|
||||
* 24h synchronous resonance
|
||||
*/
|
||||
bool synchronous_flag;
|
||||
/*
|
||||
* lunar / solar constants for epoch
|
||||
* applied during DeepSpaceSecular()
|
||||
*/
|
||||
double sse;
|
||||
double ssi;
|
||||
double ssl;
|
||||
double ssg;
|
||||
double ssh;
|
||||
/*
|
||||
* lunar / solar constants
|
||||
* used during DeepSpaceCalculateLunarSolarTerms()
|
||||
*/
|
||||
double se2;
|
||||
double si2;
|
||||
double sl2;
|
||||
double sgh2;
|
||||
double sh2;
|
||||
double se3;
|
||||
double si3;
|
||||
double sl3;
|
||||
double sgh3;
|
||||
double sh3;
|
||||
double sl4;
|
||||
double sgh4;
|
||||
double ee2;
|
||||
double e3;
|
||||
double xi2;
|
||||
double xi3;
|
||||
double xl2;
|
||||
double xl3;
|
||||
double xl4;
|
||||
double xgh2;
|
||||
double xgh3;
|
||||
double xgh4;
|
||||
double xh2;
|
||||
double xh3;
|
||||
/*
|
||||
* used during DeepSpaceCalcDotTerms()
|
||||
*/
|
||||
double d2201;
|
||||
double d2211;
|
||||
double d3210;
|
||||
double d3222;
|
||||
double d4410;
|
||||
double d4422;
|
||||
double d5220;
|
||||
double d5232;
|
||||
double d5421;
|
||||
double d5433;
|
||||
double del1;
|
||||
double del2;
|
||||
double del3;
|
||||
};
|
||||
|
||||
struct IntegratorValues
|
||||
{
|
||||
IntegratorValues() : xndot(0.0), xnddt(0.0), xldot(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double xndot;
|
||||
double xnddt;
|
||||
double xldot;
|
||||
};
|
||||
|
||||
struct IntegratorConstants
|
||||
{
|
||||
IntegratorConstants() : xfact(0.0), xlamo(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* integrator constants
|
||||
*/
|
||||
double xfact;
|
||||
double xlamo;
|
||||
|
||||
/*
|
||||
* integrator values for epoch
|
||||
*/
|
||||
struct IntegratorValues values_0;
|
||||
};
|
||||
|
||||
struct IntegratorParams
|
||||
{
|
||||
IntegratorParams() : xli(0.0), xni(0.0), atime(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* integrator values
|
||||
*/
|
||||
double xli;
|
||||
double xni;
|
||||
double atime;
|
||||
/*
|
||||
* itegrator values for current d_atime_
|
||||
*/
|
||||
struct IntegratorValues values_t;
|
||||
};
|
||||
|
||||
private:
|
||||
void Initialise();
|
||||
void DeepSpaceInitialise(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
||||
const double& theta2, const double& betao2,
|
||||
const double& xmdot, const double& omgdot, const double& xnodot);
|
||||
void DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
||||
double* pl, double* pgh, double* ph) const;
|
||||
void DeepSpacePeriodics(const double& t, double* em, double* xinc,
|
||||
double* omgasm, double* xnodes, double* xll) const;
|
||||
void DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||
double* xnodes, double* em, double* xinc, double* xn) const;
|
||||
Eci FindPositionSDP4(double tsince) const;
|
||||
Eci FindPositionSGP4(double tsince) const;
|
||||
Eci CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||
const double& a, const double& omega, const double& xl, const double& xnode,
|
||||
const double& xincl, const double& xlcof, const double& aycof,
|
||||
const double& x3thm1, const double& x1mth2, const double& x7thm1,
|
||||
const double& cosio, const double& sinio) const;
|
||||
void DeepSpaceCalcDotTerms(struct IntegratorValues *values) const;
|
||||
void DeepSpaceIntegrator(const double delt, const double step2,
|
||||
const struct IntegratorValues& values) const;
|
||||
void Reset();
|
||||
|
||||
/*
|
||||
* flags
|
||||
*/
|
||||
bool first_run_;
|
||||
bool use_simple_model_;
|
||||
bool use_deep_space_;
|
||||
|
||||
/*
|
||||
* the constants used
|
||||
*/
|
||||
struct CommonConstants common_consts_;
|
||||
struct NearSpaceConstants nearspace_consts_;
|
||||
struct DeepSpaceConstants deepspace_consts_;
|
||||
struct IntegratorConstants integrator_consts_;
|
||||
mutable struct IntegratorParams integrator_params_;
|
||||
|
||||
/*
|
||||
* the orbit data
|
||||
*/
|
||||
OrbitalElements elements_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SGP4_H_
|
||||
#define SGP4_H_
|
||||
|
||||
#include "Tle.h"
|
||||
#include "OrbitalElements.h"
|
||||
#include "Eci.h"
|
||||
#include "SatelliteException.h"
|
||||
|
||||
class SGP4
|
||||
{
|
||||
public:
|
||||
SGP4(const Tle& tle)
|
||||
: elements_(tle)
|
||||
{
|
||||
Initialise();
|
||||
}
|
||||
|
||||
virtual ~SGP4()
|
||||
{
|
||||
}
|
||||
|
||||
void SetTle(const Tle& tle);
|
||||
Eci FindPosition(double tsince) const;
|
||||
Eci FindPosition(const Julian& date) const;
|
||||
|
||||
struct CommonConstants
|
||||
{
|
||||
CommonConstants()
|
||||
: cosio(0.0), sinio(0.0), eta(0.0), t2cof(0.0), a3ovk2(0.0),
|
||||
x1mth2(0.0), x3thm1(0.0), x7thm1(0.0), aycof(0.0), xlcof(0.0),
|
||||
xnodcf(0.0), c1(0.0), c4(0.0), omgdot(0.0), xnodot(0.0), xmdot(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double cosio;
|
||||
double sinio;
|
||||
double eta;
|
||||
double t2cof;
|
||||
double a3ovk2;
|
||||
double x1mth2;
|
||||
double x3thm1;
|
||||
double x7thm1;
|
||||
double aycof;
|
||||
double xlcof;
|
||||
double xnodcf;
|
||||
double c1;
|
||||
double c4;
|
||||
double omgdot; // secular rate of omega (radians/sec)
|
||||
double xnodot; // secular rate of xnode (radians/sec)
|
||||
double xmdot; // secular rate of xmo (radians/sec)
|
||||
};
|
||||
|
||||
struct NearSpaceConstants
|
||||
{
|
||||
NearSpaceConstants()
|
||||
: c5(0.0), omgcof(0.0), xmcof(0.0), delmo(0.0), sinmo(0.0), d2(0.0),
|
||||
d3(0.0), d4(0.0), t3cof(0.0), t4cof(0.0), t5cof(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double c5;
|
||||
double omgcof;
|
||||
double xmcof;
|
||||
double delmo;
|
||||
double sinmo;
|
||||
double d2;
|
||||
double d3;
|
||||
double d4;
|
||||
double t3cof;
|
||||
double t4cof;
|
||||
double t5cof;
|
||||
};
|
||||
|
||||
struct DeepSpaceConstants
|
||||
{
|
||||
DeepSpaceConstants()
|
||||
: gsto(0.0), zmol(0.0), zmos(0.0), resonance_flag(false),
|
||||
synchronous_flag(false), sse(0.0), ssi(0.0), ssl(0.0), ssg(0.0),
|
||||
ssh(0.0), se2(0.0), si2(0.0), sl2(0.0), sgh2(0.0), sh2(0.0), se3(0.0),
|
||||
si3(0.0), sl3(0.0), sgh3(0.0), sh3(0.0), sl4(0.0), sgh4(0.0), ee2(0.0),
|
||||
e3(0.0), xi2(0.0), xi3(0.0), xl2(0.0), xl3(0.0), xl4(0.0), xgh2(0.0),
|
||||
xgh3(0.0), xgh4(0.0), xh2(0.0), xh3(0.0), d2201(0.0), d2211(0.0),
|
||||
d3210(0.0), d3222(0.0), d4410(0.0), d4422(0.0), d5220(0.0), d5232(0.0),
|
||||
d5421(0.0), d5433(0.0), del1(0.0), del2(0.0), del3(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double gsto;
|
||||
double zmol;
|
||||
double zmos;
|
||||
/*
|
||||
* whether the deep space orbit is
|
||||
* geopotential resonance for 12 hour orbits
|
||||
*/
|
||||
bool resonance_flag;
|
||||
/*
|
||||
* whether the deep space orbit is
|
||||
* 24h synchronous resonance
|
||||
*/
|
||||
bool synchronous_flag;
|
||||
/*
|
||||
* lunar / solar constants for epoch
|
||||
* applied during DeepSpaceSecular()
|
||||
*/
|
||||
double sse;
|
||||
double ssi;
|
||||
double ssl;
|
||||
double ssg;
|
||||
double ssh;
|
||||
/*
|
||||
* lunar / solar constants
|
||||
* used during DeepSpaceCalculateLunarSolarTerms()
|
||||
*/
|
||||
double se2;
|
||||
double si2;
|
||||
double sl2;
|
||||
double sgh2;
|
||||
double sh2;
|
||||
double se3;
|
||||
double si3;
|
||||
double sl3;
|
||||
double sgh3;
|
||||
double sh3;
|
||||
double sl4;
|
||||
double sgh4;
|
||||
double ee2;
|
||||
double e3;
|
||||
double xi2;
|
||||
double xi3;
|
||||
double xl2;
|
||||
double xl3;
|
||||
double xl4;
|
||||
double xgh2;
|
||||
double xgh3;
|
||||
double xgh4;
|
||||
double xh2;
|
||||
double xh3;
|
||||
/*
|
||||
* used during DeepSpaceCalcDotTerms()
|
||||
*/
|
||||
double d2201;
|
||||
double d2211;
|
||||
double d3210;
|
||||
double d3222;
|
||||
double d4410;
|
||||
double d4422;
|
||||
double d5220;
|
||||
double d5232;
|
||||
double d5421;
|
||||
double d5433;
|
||||
double del1;
|
||||
double del2;
|
||||
double del3;
|
||||
};
|
||||
|
||||
struct IntegratorValues
|
||||
{
|
||||
IntegratorValues() : xndot(0.0), xnddt(0.0), xldot(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
double xndot;
|
||||
double xnddt;
|
||||
double xldot;
|
||||
};
|
||||
|
||||
struct IntegratorConstants
|
||||
{
|
||||
IntegratorConstants() : xfact(0.0), xlamo(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* integrator constants
|
||||
*/
|
||||
double xfact;
|
||||
double xlamo;
|
||||
|
||||
/*
|
||||
* integrator values for epoch
|
||||
*/
|
||||
struct IntegratorValues values_0;
|
||||
};
|
||||
|
||||
struct IntegratorParams
|
||||
{
|
||||
IntegratorParams() : xli(0.0), xni(0.0), atime(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* integrator values
|
||||
*/
|
||||
double xli;
|
||||
double xni;
|
||||
double atime;
|
||||
/*
|
||||
* itegrator values for current d_atime_
|
||||
*/
|
||||
struct IntegratorValues values_t;
|
||||
};
|
||||
|
||||
private:
|
||||
void Initialise();
|
||||
void DeepSpaceInitialise(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
||||
const double& theta2, const double& betao2,
|
||||
const double& xmdot, const double& omgdot, const double& xnodot);
|
||||
void DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
||||
double* pl, double* pgh, double* ph) const;
|
||||
void DeepSpacePeriodics(const double& t, double* em, double* xinc,
|
||||
double* omgasm, double* xnodes, double* xll) const;
|
||||
void DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||
double* xnodes, double* em, double* xinc, double* xn) const;
|
||||
Eci FindPositionSDP4(double tsince) const;
|
||||
Eci FindPositionSGP4(double tsince) const;
|
||||
Eci CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||
const double& a, const double& omega, const double& xl, const double& xnode,
|
||||
const double& xincl, const double& xlcof, const double& aycof,
|
||||
const double& x3thm1, const double& x1mth2, const double& x7thm1,
|
||||
const double& cosio, const double& sinio) const;
|
||||
void DeepSpaceCalcDotTerms(struct IntegratorValues *values) const;
|
||||
void DeepSpaceIntegrator(const double delt, const double step2,
|
||||
const struct IntegratorValues& values) const;
|
||||
void Reset();
|
||||
|
||||
/*
|
||||
* flags
|
||||
*/
|
||||
bool first_run_;
|
||||
bool use_simple_model_;
|
||||
bool use_deep_space_;
|
||||
|
||||
/*
|
||||
* the constants used
|
||||
*/
|
||||
struct CommonConstants common_consts_;
|
||||
struct NearSpaceConstants nearspace_consts_;
|
||||
struct DeepSpaceConstants deepspace_consts_;
|
||||
struct IntegratorConstants integrator_consts_;
|
||||
mutable struct IntegratorParams integrator_params_;
|
||||
|
||||
/*
|
||||
* the orbit data
|
||||
*/
|
||||
OrbitalElements elements_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
#ifndef SATELLITEEXCEPTION_H_
|
||||
#define SATELLITEEXCEPTION_H_
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
class SatelliteException : public std::exception
|
||||
{
|
||||
public:
|
||||
SatelliteException(const char* message)
|
||||
: message_(message)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SatelliteException(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return message_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef SATELLITEEXCEPTION_H_
|
||||
#define SATELLITEEXCEPTION_H_
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
class SatelliteException : public std::exception
|
||||
{
|
||||
public:
|
||||
SatelliteException(const char* message)
|
||||
: message_(message)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SatelliteException(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return message_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
#ifndef SOLARPOSITION_H_
|
||||
#define SOLARPOSITION_H_
|
||||
|
||||
#include "Julian.h"
|
||||
#include "Eci.h"
|
||||
|
||||
class SolarPosition
|
||||
{
|
||||
public:
|
||||
SolarPosition()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SolarPosition()
|
||||
{
|
||||
}
|
||||
|
||||
Eci FindPosition(const Julian& j);
|
||||
|
||||
private:
|
||||
double Modulus(double arg1, double arg2) const;
|
||||
double Delta_ET(double year) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef SOLARPOSITION_H_
|
||||
#define SOLARPOSITION_H_
|
||||
|
||||
#include "Julian.h"
|
||||
#include "Eci.h"
|
||||
|
||||
class SolarPosition
|
||||
{
|
||||
public:
|
||||
SolarPosition()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SolarPosition()
|
||||
{
|
||||
}
|
||||
|
||||
Eci FindPosition(const Julian& j);
|
||||
|
||||
private:
|
||||
double Modulus(double arg1, double arg2) const;
|
||||
double Delta_ET(double year) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
114
Timespan.h
114
Timespan.h
|
@ -1,57 +1,57 @@
|
|||
#ifndef TIMESPAN_H_
|
||||
#define TIMESPAN_H_
|
||||
|
||||
class Timespan {
|
||||
public:
|
||||
Timespan();
|
||||
Timespan(const unsigned int days, const unsigned int hours,
|
||||
const unsigned int minutes, const double seconds);
|
||||
Timespan(const double b);
|
||||
Timespan(const Timespan& b);
|
||||
virtual ~Timespan(void);
|
||||
|
||||
void SetValue(const unsigned int days, const unsigned int hours,
|
||||
const unsigned int minutes, const double seconds);
|
||||
|
||||
void AddDays(const unsigned int days);
|
||||
void AddHours(const unsigned int hours);
|
||||
void AddMinutes(const unsigned int minutes);
|
||||
void AddSeconds(const double seconds);
|
||||
|
||||
double GetTotalDays() const;
|
||||
double GetTotalHours() const;
|
||||
double GetTotalMinutes() const;
|
||||
double GetTotalSeconds() const;
|
||||
|
||||
// assignment
|
||||
Timespan & operator=(const Timespan& b);
|
||||
// arithmetic
|
||||
Timespan operator+(const Timespan& b) const;
|
||||
Timespan operator-(const Timespan& b) const;
|
||||
Timespan operator/(const double b) const;
|
||||
Timespan operator*(const double b) const;
|
||||
// compound arithmetic
|
||||
Timespan & operator+=(const Timespan& b);
|
||||
Timespan & operator-=(const Timespan& b);
|
||||
Timespan & operator/=(const double b);
|
||||
Timespan & operator*=(const double b);
|
||||
// comparison
|
||||
bool operator==(const Timespan& b) const;
|
||||
bool operator!=(const Timespan& b) const;
|
||||
bool operator>(const Timespan& b) const;
|
||||
bool operator<(const Timespan& b) const;
|
||||
bool operator>=(const Timespan& b) const;
|
||||
bool operator<=(const Timespan& b) const;
|
||||
|
||||
friend double& operator +=(double& a, const Timespan& b);
|
||||
friend double& operator -=(double& a, const Timespan& b);
|
||||
|
||||
private:
|
||||
/*
|
||||
* stores value in minutes
|
||||
*/
|
||||
double time_span_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TIMESPAN_H_
|
||||
#define TIMESPAN_H_
|
||||
|
||||
class Timespan {
|
||||
public:
|
||||
Timespan();
|
||||
Timespan(const unsigned int days, const unsigned int hours,
|
||||
const unsigned int minutes, const double seconds);
|
||||
Timespan(const double b);
|
||||
Timespan(const Timespan& b);
|
||||
virtual ~Timespan(void);
|
||||
|
||||
void SetValue(const unsigned int days, const unsigned int hours,
|
||||
const unsigned int minutes, const double seconds);
|
||||
|
||||
void AddDays(const unsigned int days);
|
||||
void AddHours(const unsigned int hours);
|
||||
void AddMinutes(const unsigned int minutes);
|
||||
void AddSeconds(const double seconds);
|
||||
|
||||
double GetTotalDays() const;
|
||||
double GetTotalHours() const;
|
||||
double GetTotalMinutes() const;
|
||||
double GetTotalSeconds() const;
|
||||
|
||||
// assignment
|
||||
Timespan & operator=(const Timespan& b);
|
||||
// arithmetic
|
||||
Timespan operator+(const Timespan& b) const;
|
||||
Timespan operator-(const Timespan& b) const;
|
||||
Timespan operator/(const double b) const;
|
||||
Timespan operator*(const double b) const;
|
||||
// compound arithmetic
|
||||
Timespan & operator+=(const Timespan& b);
|
||||
Timespan & operator-=(const Timespan& b);
|
||||
Timespan & operator/=(const double b);
|
||||
Timespan & operator*=(const double b);
|
||||
// comparison
|
||||
bool operator==(const Timespan& b) const;
|
||||
bool operator!=(const Timespan& b) const;
|
||||
bool operator>(const Timespan& b) const;
|
||||
bool operator<(const Timespan& b) const;
|
||||
bool operator>=(const Timespan& b) const;
|
||||
bool operator<=(const Timespan& b) const;
|
||||
|
||||
friend double& operator +=(double& a, const Timespan& b);
|
||||
friend double& operator -=(double& a, const Timespan& b);
|
||||
|
||||
private:
|
||||
/*
|
||||
* stores value in minutes
|
||||
*/
|
||||
double time_span_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
832
Tle.cpp
832
Tle.cpp
|
@ -1,416 +1,416 @@
|
|||
#include "Tle.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace
|
||||
{
|
||||
/*
|
||||
* line 1
|
||||
*/
|
||||
static const unsigned int TLE1_COL_NORADNUM = 2;
|
||||
static const unsigned int TLE1_LEN_NORADNUM = 5;
|
||||
static const unsigned int TLE1_COL_INTLDESC_A = 9;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
|
||||
static const unsigned int TLE1_COL_INTLDESC_B = 11;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_B = 3;
|
||||
static const unsigned int TLE1_COL_INTLDESC_C = 14;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_C = 3;
|
||||
static const unsigned int TLE1_COL_EPOCH_A = 18;
|
||||
static const unsigned int TLE1_LEN_EPOCH_A = 2;
|
||||
static const unsigned int TLE1_COL_EPOCH_B = 20;
|
||||
static const unsigned int TLE1_LEN_EPOCH_B = 12;
|
||||
static const unsigned int TLE1_COL_MEANMOTIONDT = 33;
|
||||
static const unsigned int TLE1_LEN_MEANMOTIONDT = 10;
|
||||
static const unsigned int TLE1_COL_MEANMOTIONDT2 = 44;
|
||||
static const unsigned int TLE1_LEN_MEANMOTIONDT2 = 8;
|
||||
static const unsigned int TLE1_COL_BSTAR = 53;
|
||||
static const unsigned int TLE1_LEN_BSTAR = 8;
|
||||
static const unsigned int TLE1_COL_EPHEMTYPE = 62;
|
||||
static const unsigned int TLE1_LEN_EPHEMTYPE = 1;
|
||||
static const unsigned int TLE1_COL_ELNUM = 64;
|
||||
static const unsigned int TLE1_LEN_ELNUM = 4;
|
||||
|
||||
/*
|
||||
* line 2
|
||||
*/
|
||||
static const unsigned int TLE2_COL_NORADNUM = 2;
|
||||
static const unsigned int TLE2_LEN_NORADNUM = 5;
|
||||
static const unsigned int TLE2_COL_INCLINATION = 8;
|
||||
static const unsigned int TLE2_LEN_INCLINATION = 8;
|
||||
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
|
||||
static const unsigned int TLE2_LEN_RAASCENDNODE = 8;
|
||||
static const unsigned int TLE2_COL_ECCENTRICITY = 26;
|
||||
static const unsigned int TLE2_LEN_ECCENTRICITY = 7;
|
||||
static const unsigned int TLE2_COL_ARGPERIGEE = 34;
|
||||
static const unsigned int TLE2_LEN_ARGPERIGEE = 8;
|
||||
static const unsigned int TLE2_COL_MEANANOMALY = 43;
|
||||
static const unsigned int TLE2_LEN_MEANANOMALY = 8;
|
||||
static const unsigned int TLE2_COL_MEANMOTION = 52;
|
||||
static const unsigned int TLE2_LEN_MEANMOTION = 11;
|
||||
static const unsigned int TLE2_COL_REVATEPOCH = 63;
|
||||
static const unsigned int TLE2_LEN_REVATEPOCH = 5;
|
||||
|
||||
}
|
||||
|
||||
Tle::Tle(const Tle& tle)
|
||||
{
|
||||
name_ = tle.name_;
|
||||
line_one_ = tle.line_one_;
|
||||
line_two_ = tle.line_two_;
|
||||
|
||||
norad_number_ = tle.norad_number_;
|
||||
international_designator_ = tle.international_designator_;
|
||||
epoch_ = tle.epoch_;
|
||||
mean_motion_dot_ = tle.mean_motion_dot_;
|
||||
mean_motion_dot2_ = tle.mean_motion_dot2_;
|
||||
bstar_ = tle.bstar_;
|
||||
inclination_ = tle.inclination_;
|
||||
right_ascending_node_ = tle.right_ascending_node_;
|
||||
eccentricity_ = tle.eccentricity_;
|
||||
argument_perigee_ = tle.argument_perigee_;
|
||||
mean_anomaly_ = tle.mean_anomaly_;
|
||||
mean_motion_ = tle.mean_motion_;
|
||||
orbit_number_ = tle.orbit_number_;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert a tle raw string into an exponent string
|
||||
*/
|
||||
std::string Tle::ExpToDecimal(const std::string& str)
|
||||
{
|
||||
static const int START_SIGN = 0;
|
||||
static const int LENGTH_SIGN = 1;
|
||||
static const int START_MANTISSA = 1;
|
||||
static const int LENGTH_MANTISSA = 5;
|
||||
static const int START_EXP = 6;
|
||||
static const int LENGTH_EXP = 2;
|
||||
|
||||
if ((LENGTH_SIGN + LENGTH_MANTISSA + LENGTH_EXP) != str.length())
|
||||
{
|
||||
throw TleException("Invalid string length for exponential conversion.");
|
||||
}
|
||||
|
||||
std::string value = str.substr(START_SIGN, LENGTH_SIGN);
|
||||
value += ".";
|
||||
value += str.substr(START_MANTISSA, LENGTH_MANTISSA);
|
||||
value += "e";
|
||||
value += str.substr(START_EXP, LENGTH_EXP);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* extract all variables
|
||||
*/
|
||||
void Tle::Initialize()
|
||||
{
|
||||
std::string temp;
|
||||
|
||||
/*
|
||||
* trim whitespace
|
||||
*/
|
||||
TrimLeft(name_);
|
||||
TrimRight(name_);
|
||||
TrimLeft(line_one_);
|
||||
TrimRight(line_one_);
|
||||
TrimLeft(line_two_);
|
||||
TrimRight(line_two_);
|
||||
|
||||
/*
|
||||
* check the two lines are valid
|
||||
*/
|
||||
IsValidPair(line_one_, line_two_);
|
||||
|
||||
/*
|
||||
* line 1
|
||||
*/
|
||||
|
||||
temp = ExtractNoradNumber(line_one_, 1);
|
||||
norad_number_ = atoi(temp.c_str());
|
||||
/*
|
||||
* if blank use norad number for name
|
||||
*/
|
||||
if (name_.empty())
|
||||
{
|
||||
name_ = temp;
|
||||
}
|
||||
|
||||
international_designator_ = line_one_.substr(TLE1_COL_INTLDESC_A,
|
||||
TLE1_LEN_INTLDESC_A + TLE1_LEN_INTLDESC_B + TLE1_LEN_INTLDESC_C);
|
||||
|
||||
int year = atoi(line_one_.substr(TLE1_COL_EPOCH_A,
|
||||
TLE1_LEN_EPOCH_A).c_str());
|
||||
double day = atof(line_one_.substr(TLE1_COL_EPOCH_B,
|
||||
TLE1_LEN_EPOCH_B).c_str());
|
||||
/*
|
||||
* generate julian date for epoch
|
||||
*/
|
||||
if (year < 57)
|
||||
year += 2000;
|
||||
else
|
||||
year += 1900;
|
||||
epoch_ = Julian(year, day);
|
||||
|
||||
if (line_one_[TLE1_COL_MEANMOTIONDT] == '-') {
|
||||
temp = "-0";
|
||||
} else
|
||||
temp = "0";
|
||||
temp += line_one_.substr(TLE1_COL_MEANMOTIONDT + 1, TLE1_LEN_MEANMOTIONDT);
|
||||
mean_motion_dot_ = atof(temp.c_str());
|
||||
|
||||
temp = ExpToDecimal(line_one_.substr(TLE1_COL_MEANMOTIONDT2,
|
||||
TLE1_LEN_MEANMOTIONDT2));
|
||||
mean_motion_dot2_ = atof(temp.c_str());
|
||||
|
||||
temp = ExpToDecimal(line_one_.substr(TLE1_COL_BSTAR,
|
||||
TLE1_LEN_BSTAR).c_str());
|
||||
bstar_ = atof(temp.c_str());
|
||||
|
||||
/*
|
||||
* line 2
|
||||
*/
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_INCLINATION, TLE2_LEN_INCLINATION);
|
||||
TrimLeft(temp);
|
||||
inclination_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_RAASCENDNODE, TLE2_LEN_RAASCENDNODE);
|
||||
TrimLeft(temp);
|
||||
right_ascending_node_ = atof(temp.c_str());
|
||||
|
||||
temp = "0.";
|
||||
temp += line_two_.substr(TLE2_COL_ECCENTRICITY, TLE2_LEN_ECCENTRICITY);
|
||||
eccentricity_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_ARGPERIGEE, TLE2_LEN_ARGPERIGEE);
|
||||
TrimLeft(temp);
|
||||
argument_perigee_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_MEANANOMALY, TLE2_LEN_MEANANOMALY);
|
||||
TrimLeft(temp);
|
||||
mean_anomaly_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_MEANMOTION, TLE2_LEN_MEANMOTION);
|
||||
TrimLeft(temp);
|
||||
mean_motion_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_REVATEPOCH, TLE2_LEN_REVATEPOCH);
|
||||
TrimLeft(temp);
|
||||
orbit_number_ = atoi(temp.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* check the two lines have matching norad numbers
|
||||
* and that the lines themselves are equal
|
||||
*/
|
||||
void Tle::IsValidPair(const std::string& line1, const std::string& line2)
|
||||
{
|
||||
/*
|
||||
* validate each line
|
||||
*/
|
||||
IsValidLine(line1, 1);
|
||||
IsValidLine(line2, 2);
|
||||
|
||||
/*
|
||||
* extract norad numbers
|
||||
*/
|
||||
std::string norad_1 = ExtractNoradNumber(line1, 1);
|
||||
std::string norad_2 = ExtractNoradNumber(line2, 2);
|
||||
|
||||
/*
|
||||
* make sure they match
|
||||
*/
|
||||
if (norad_1.compare(norad_2) != 0)
|
||||
{
|
||||
throw TleException("Norad numbers do not match.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* validate a line
|
||||
*/
|
||||
void Tle::IsValidLine(const std::string& str, int line_number)
|
||||
{
|
||||
/*
|
||||
* validation patterns
|
||||
*/
|
||||
static const std::string line1_pattern = "1 NNNNNC NNNNNXXX NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN";
|
||||
static const std::string line2_pattern = "2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN";
|
||||
|
||||
/*
|
||||
* validate line against the pattern
|
||||
*/
|
||||
if (1 == line_number)
|
||||
{
|
||||
ValidateLine(str, line1_pattern);
|
||||
}
|
||||
else if (2 == line_number)
|
||||
{
|
||||
ValidateLine(str, line2_pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw TleException("Invalid line number to check.");
|
||||
}
|
||||
|
||||
/*
|
||||
* last char in string is modulo 10 checksum
|
||||
* edited out as checksum isnt consistent
|
||||
*
|
||||
* int chk = CheckSum(str);
|
||||
* if (chk != (str[TLE_LEN_LINE_DATA - 1] - '0'))
|
||||
* return false;
|
||||
*/
|
||||
}
|
||||
|
||||
bool Tle::IsValidLineLength(const std::string& str)
|
||||
{
|
||||
return str.length() == GetLineLength() ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* validate line given a pattern
|
||||
*/
|
||||
void Tle::ValidateLine(const std::string& line, const std::string& pattern)
|
||||
{
|
||||
/*
|
||||
* check length of line
|
||||
*/
|
||||
if (!IsValidLineLength(line))
|
||||
{
|
||||
throw TleException("Invalid line length.");
|
||||
}
|
||||
|
||||
std::string::const_iterator pattern_itr = pattern.begin();
|
||||
std::string::const_iterator line_itr = line.begin();
|
||||
|
||||
while (pattern_itr != pattern.end())
|
||||
{
|
||||
if (isdigit(*pattern_itr) || *pattern_itr == ' ' ||
|
||||
*pattern_itr == '.')
|
||||
{
|
||||
/*
|
||||
* should match exactly
|
||||
*/
|
||||
if (*pattern_itr != *line_itr)
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'N')
|
||||
{
|
||||
/*
|
||||
* 'N' = number or ' '
|
||||
*/
|
||||
if (!isdigit(*line_itr) && *line_itr != ' ')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == '+')
|
||||
{
|
||||
/*
|
||||
* '+' = '+' or '-' or ' ' or '0'
|
||||
*/
|
||||
if (*line_itr != '+' && *line_itr != '-' &&
|
||||
*line_itr != ' ' && *line_itr != '0')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == '-')
|
||||
{
|
||||
/*
|
||||
* '-' = '+' or '-'
|
||||
*/
|
||||
if (*line_itr != '+' && *line_itr != '-')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'C')
|
||||
{
|
||||
/*
|
||||
* 'C' = 'U' or 'S'
|
||||
*/
|
||||
if (*line_itr != 'U' && *line_itr != 'S')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'X')
|
||||
{
|
||||
/*
|
||||
* 'X' = A-Z or ' '
|
||||
*/
|
||||
if (!(*line_itr >= 'A' || *line_itr <= 'Z') && *line_itr != ' ')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
}
|
||||
|
||||
pattern_itr++;
|
||||
line_itr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compute checksum
|
||||
*/
|
||||
int Tle::CheckSum(const std::string & str)
|
||||
{
|
||||
size_t len = str.size() - 1;
|
||||
int xsum = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
char ch = str[i];
|
||||
|
||||
if (isdigit(ch))
|
||||
{
|
||||
xsum += (ch - '0');
|
||||
}
|
||||
else if (ch == '-')
|
||||
{
|
||||
xsum++;
|
||||
}
|
||||
}
|
||||
|
||||
return (xsum % 10);
|
||||
}
|
||||
|
||||
std::string Tle::ExtractNoradNumber(const std::string& str, int line_number)
|
||||
{
|
||||
std::string norad_number;
|
||||
|
||||
/*
|
||||
* check length
|
||||
*/
|
||||
if (!IsValidLineLength(str))
|
||||
{
|
||||
throw TleException("Invalid line length.");
|
||||
}
|
||||
|
||||
/*
|
||||
* extract string
|
||||
*/
|
||||
if (1 == line_number)
|
||||
{
|
||||
norad_number = str.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM);
|
||||
}
|
||||
else if (2 == line_number)
|
||||
{
|
||||
norad_number = str.substr(TLE2_COL_NORADNUM, TLE2_LEN_NORADNUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw TleException("Invalid line number to check.");
|
||||
}
|
||||
|
||||
return norad_number;
|
||||
}
|
||||
#include "Tle.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace
|
||||
{
|
||||
/*
|
||||
* line 1
|
||||
*/
|
||||
static const unsigned int TLE1_COL_NORADNUM = 2;
|
||||
static const unsigned int TLE1_LEN_NORADNUM = 5;
|
||||
static const unsigned int TLE1_COL_INTLDESC_A = 9;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
|
||||
static const unsigned int TLE1_COL_INTLDESC_B = 11;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_B = 3;
|
||||
static const unsigned int TLE1_COL_INTLDESC_C = 14;
|
||||
static const unsigned int TLE1_LEN_INTLDESC_C = 3;
|
||||
static const unsigned int TLE1_COL_EPOCH_A = 18;
|
||||
static const unsigned int TLE1_LEN_EPOCH_A = 2;
|
||||
static const unsigned int TLE1_COL_EPOCH_B = 20;
|
||||
static const unsigned int TLE1_LEN_EPOCH_B = 12;
|
||||
static const unsigned int TLE1_COL_MEANMOTIONDT = 33;
|
||||
static const unsigned int TLE1_LEN_MEANMOTIONDT = 10;
|
||||
static const unsigned int TLE1_COL_MEANMOTIONDT2 = 44;
|
||||
static const unsigned int TLE1_LEN_MEANMOTIONDT2 = 8;
|
||||
static const unsigned int TLE1_COL_BSTAR = 53;
|
||||
static const unsigned int TLE1_LEN_BSTAR = 8;
|
||||
static const unsigned int TLE1_COL_EPHEMTYPE = 62;
|
||||
static const unsigned int TLE1_LEN_EPHEMTYPE = 1;
|
||||
static const unsigned int TLE1_COL_ELNUM = 64;
|
||||
static const unsigned int TLE1_LEN_ELNUM = 4;
|
||||
|
||||
/*
|
||||
* line 2
|
||||
*/
|
||||
static const unsigned int TLE2_COL_NORADNUM = 2;
|
||||
static const unsigned int TLE2_LEN_NORADNUM = 5;
|
||||
static const unsigned int TLE2_COL_INCLINATION = 8;
|
||||
static const unsigned int TLE2_LEN_INCLINATION = 8;
|
||||
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
|
||||
static const unsigned int TLE2_LEN_RAASCENDNODE = 8;
|
||||
static const unsigned int TLE2_COL_ECCENTRICITY = 26;
|
||||
static const unsigned int TLE2_LEN_ECCENTRICITY = 7;
|
||||
static const unsigned int TLE2_COL_ARGPERIGEE = 34;
|
||||
static const unsigned int TLE2_LEN_ARGPERIGEE = 8;
|
||||
static const unsigned int TLE2_COL_MEANANOMALY = 43;
|
||||
static const unsigned int TLE2_LEN_MEANANOMALY = 8;
|
||||
static const unsigned int TLE2_COL_MEANMOTION = 52;
|
||||
static const unsigned int TLE2_LEN_MEANMOTION = 11;
|
||||
static const unsigned int TLE2_COL_REVATEPOCH = 63;
|
||||
static const unsigned int TLE2_LEN_REVATEPOCH = 5;
|
||||
|
||||
}
|
||||
|
||||
Tle::Tle(const Tle& tle)
|
||||
{
|
||||
name_ = tle.name_;
|
||||
line_one_ = tle.line_one_;
|
||||
line_two_ = tle.line_two_;
|
||||
|
||||
norad_number_ = tle.norad_number_;
|
||||
international_designator_ = tle.international_designator_;
|
||||
epoch_ = tle.epoch_;
|
||||
mean_motion_dot_ = tle.mean_motion_dot_;
|
||||
mean_motion_dot2_ = tle.mean_motion_dot2_;
|
||||
bstar_ = tle.bstar_;
|
||||
inclination_ = tle.inclination_;
|
||||
right_ascending_node_ = tle.right_ascending_node_;
|
||||
eccentricity_ = tle.eccentricity_;
|
||||
argument_perigee_ = tle.argument_perigee_;
|
||||
mean_anomaly_ = tle.mean_anomaly_;
|
||||
mean_motion_ = tle.mean_motion_;
|
||||
orbit_number_ = tle.orbit_number_;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert a tle raw string into an exponent string
|
||||
*/
|
||||
std::string Tle::ExpToDecimal(const std::string& str)
|
||||
{
|
||||
static const int START_SIGN = 0;
|
||||
static const int LENGTH_SIGN = 1;
|
||||
static const int START_MANTISSA = 1;
|
||||
static const int LENGTH_MANTISSA = 5;
|
||||
static const int START_EXP = 6;
|
||||
static const int LENGTH_EXP = 2;
|
||||
|
||||
if ((LENGTH_SIGN + LENGTH_MANTISSA + LENGTH_EXP) != str.length())
|
||||
{
|
||||
throw TleException("Invalid string length for exponential conversion.");
|
||||
}
|
||||
|
||||
std::string value = str.substr(START_SIGN, LENGTH_SIGN);
|
||||
value += ".";
|
||||
value += str.substr(START_MANTISSA, LENGTH_MANTISSA);
|
||||
value += "e";
|
||||
value += str.substr(START_EXP, LENGTH_EXP);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* extract all variables
|
||||
*/
|
||||
void Tle::Initialize()
|
||||
{
|
||||
std::string temp;
|
||||
|
||||
/*
|
||||
* trim whitespace
|
||||
*/
|
||||
TrimLeft(name_);
|
||||
TrimRight(name_);
|
||||
TrimLeft(line_one_);
|
||||
TrimRight(line_one_);
|
||||
TrimLeft(line_two_);
|
||||
TrimRight(line_two_);
|
||||
|
||||
/*
|
||||
* check the two lines are valid
|
||||
*/
|
||||
IsValidPair(line_one_, line_two_);
|
||||
|
||||
/*
|
||||
* line 1
|
||||
*/
|
||||
|
||||
temp = ExtractNoradNumber(line_one_, 1);
|
||||
norad_number_ = atoi(temp.c_str());
|
||||
/*
|
||||
* if blank use norad number for name
|
||||
*/
|
||||
if (name_.empty())
|
||||
{
|
||||
name_ = temp;
|
||||
}
|
||||
|
||||
international_designator_ = line_one_.substr(TLE1_COL_INTLDESC_A,
|
||||
TLE1_LEN_INTLDESC_A + TLE1_LEN_INTLDESC_B + TLE1_LEN_INTLDESC_C);
|
||||
|
||||
int year = atoi(line_one_.substr(TLE1_COL_EPOCH_A,
|
||||
TLE1_LEN_EPOCH_A).c_str());
|
||||
double day = atof(line_one_.substr(TLE1_COL_EPOCH_B,
|
||||
TLE1_LEN_EPOCH_B).c_str());
|
||||
/*
|
||||
* generate julian date for epoch
|
||||
*/
|
||||
if (year < 57)
|
||||
year += 2000;
|
||||
else
|
||||
year += 1900;
|
||||
epoch_ = Julian(year, day);
|
||||
|
||||
if (line_one_[TLE1_COL_MEANMOTIONDT] == '-') {
|
||||
temp = "-0";
|
||||
} else
|
||||
temp = "0";
|
||||
temp += line_one_.substr(TLE1_COL_MEANMOTIONDT + 1, TLE1_LEN_MEANMOTIONDT);
|
||||
mean_motion_dot_ = atof(temp.c_str());
|
||||
|
||||
temp = ExpToDecimal(line_one_.substr(TLE1_COL_MEANMOTIONDT2,
|
||||
TLE1_LEN_MEANMOTIONDT2));
|
||||
mean_motion_dot2_ = atof(temp.c_str());
|
||||
|
||||
temp = ExpToDecimal(line_one_.substr(TLE1_COL_BSTAR,
|
||||
TLE1_LEN_BSTAR).c_str());
|
||||
bstar_ = atof(temp.c_str());
|
||||
|
||||
/*
|
||||
* line 2
|
||||
*/
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_INCLINATION, TLE2_LEN_INCLINATION);
|
||||
TrimLeft(temp);
|
||||
inclination_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_RAASCENDNODE, TLE2_LEN_RAASCENDNODE);
|
||||
TrimLeft(temp);
|
||||
right_ascending_node_ = atof(temp.c_str());
|
||||
|
||||
temp = "0.";
|
||||
temp += line_two_.substr(TLE2_COL_ECCENTRICITY, TLE2_LEN_ECCENTRICITY);
|
||||
eccentricity_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_ARGPERIGEE, TLE2_LEN_ARGPERIGEE);
|
||||
TrimLeft(temp);
|
||||
argument_perigee_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_MEANANOMALY, TLE2_LEN_MEANANOMALY);
|
||||
TrimLeft(temp);
|
||||
mean_anomaly_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_MEANMOTION, TLE2_LEN_MEANMOTION);
|
||||
TrimLeft(temp);
|
||||
mean_motion_ = atof(temp.c_str());
|
||||
|
||||
temp = line_two_.substr(TLE2_COL_REVATEPOCH, TLE2_LEN_REVATEPOCH);
|
||||
TrimLeft(temp);
|
||||
orbit_number_ = atoi(temp.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* check the two lines have matching norad numbers
|
||||
* and that the lines themselves are equal
|
||||
*/
|
||||
void Tle::IsValidPair(const std::string& line1, const std::string& line2)
|
||||
{
|
||||
/*
|
||||
* validate each line
|
||||
*/
|
||||
IsValidLine(line1, 1);
|
||||
IsValidLine(line2, 2);
|
||||
|
||||
/*
|
||||
* extract norad numbers
|
||||
*/
|
||||
std::string norad_1 = ExtractNoradNumber(line1, 1);
|
||||
std::string norad_2 = ExtractNoradNumber(line2, 2);
|
||||
|
||||
/*
|
||||
* make sure they match
|
||||
*/
|
||||
if (norad_1.compare(norad_2) != 0)
|
||||
{
|
||||
throw TleException("Norad numbers do not match.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* validate a line
|
||||
*/
|
||||
void Tle::IsValidLine(const std::string& str, int line_number)
|
||||
{
|
||||
/*
|
||||
* validation patterns
|
||||
*/
|
||||
static const std::string line1_pattern = "1 NNNNNC NNNNNXXX NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN";
|
||||
static const std::string line2_pattern = "2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN";
|
||||
|
||||
/*
|
||||
* validate line against the pattern
|
||||
*/
|
||||
if (1 == line_number)
|
||||
{
|
||||
ValidateLine(str, line1_pattern);
|
||||
}
|
||||
else if (2 == line_number)
|
||||
{
|
||||
ValidateLine(str, line2_pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw TleException("Invalid line number to check.");
|
||||
}
|
||||
|
||||
/*
|
||||
* last char in string is modulo 10 checksum
|
||||
* edited out as checksum isnt consistent
|
||||
*
|
||||
* int chk = CheckSum(str);
|
||||
* if (chk != (str[TLE_LEN_LINE_DATA - 1] - '0'))
|
||||
* return false;
|
||||
*/
|
||||
}
|
||||
|
||||
bool Tle::IsValidLineLength(const std::string& str)
|
||||
{
|
||||
return str.length() == GetLineLength() ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* validate line given a pattern
|
||||
*/
|
||||
void Tle::ValidateLine(const std::string& line, const std::string& pattern)
|
||||
{
|
||||
/*
|
||||
* check length of line
|
||||
*/
|
||||
if (!IsValidLineLength(line))
|
||||
{
|
||||
throw TleException("Invalid line length.");
|
||||
}
|
||||
|
||||
std::string::const_iterator pattern_itr = pattern.begin();
|
||||
std::string::const_iterator line_itr = line.begin();
|
||||
|
||||
while (pattern_itr != pattern.end())
|
||||
{
|
||||
if (isdigit(*pattern_itr) || *pattern_itr == ' ' ||
|
||||
*pattern_itr == '.')
|
||||
{
|
||||
/*
|
||||
* should match exactly
|
||||
*/
|
||||
if (*pattern_itr != *line_itr)
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'N')
|
||||
{
|
||||
/*
|
||||
* 'N' = number or ' '
|
||||
*/
|
||||
if (!isdigit(*line_itr) && *line_itr != ' ')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == '+')
|
||||
{
|
||||
/*
|
||||
* '+' = '+' or '-' or ' ' or '0'
|
||||
*/
|
||||
if (*line_itr != '+' && *line_itr != '-' &&
|
||||
*line_itr != ' ' && *line_itr != '0')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == '-')
|
||||
{
|
||||
/*
|
||||
* '-' = '+' or '-'
|
||||
*/
|
||||
if (*line_itr != '+' && *line_itr != '-')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'C')
|
||||
{
|
||||
/*
|
||||
* 'C' = 'U' or 'S'
|
||||
*/
|
||||
if (*line_itr != 'U' && *line_itr != 'S')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (*pattern_itr == 'X')
|
||||
{
|
||||
/*
|
||||
* 'X' = A-Z or ' '
|
||||
*/
|
||||
if (!(*line_itr >= 'A' || *line_itr <= 'Z') && *line_itr != ' ')
|
||||
{
|
||||
throw TleException("Invalid character.");
|
||||
}
|
||||
}
|
||||
|
||||
pattern_itr++;
|
||||
line_itr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compute checksum
|
||||
*/
|
||||
int Tle::CheckSum(const std::string & str)
|
||||
{
|
||||
size_t len = str.size() - 1;
|
||||
int xsum = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
char ch = str[i];
|
||||
|
||||
if (isdigit(ch))
|
||||
{
|
||||
xsum += (ch - '0');
|
||||
}
|
||||
else if (ch == '-')
|
||||
{
|
||||
xsum++;
|
||||
}
|
||||
}
|
||||
|
||||
return (xsum % 10);
|
||||
}
|
||||
|
||||
std::string Tle::ExtractNoradNumber(const std::string& str, int line_number)
|
||||
{
|
||||
std::string norad_number;
|
||||
|
||||
/*
|
||||
* check length
|
||||
*/
|
||||
if (!IsValidLineLength(str))
|
||||
{
|
||||
throw TleException("Invalid line length.");
|
||||
}
|
||||
|
||||
/*
|
||||
* extract string
|
||||
*/
|
||||
if (1 == line_number)
|
||||
{
|
||||
norad_number = str.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM);
|
||||
}
|
||||
else if (2 == line_number)
|
||||
{
|
||||
norad_number = str.substr(TLE2_COL_NORADNUM, TLE2_LEN_NORADNUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw TleException("Invalid line number to check.");
|
||||
}
|
||||
|
||||
return norad_number;
|
||||
}
|
||||
|
|
430
Tle.h
430
Tle.h
|
@ -1,215 +1,215 @@
|
|||
#ifndef TLE_H_
|
||||
#define TLE_H_
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Julian.h"
|
||||
#include "TleException.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Tle
|
||||
{
|
||||
public:
|
||||
Tle(const std::string& line_one, const std::string& line_two)
|
||||
: line_one_(line_one), line_two_(line_two)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Tle(const std::string& name, const std::string& line_one,
|
||||
const std::string& line_two)
|
||||
: name_(name),line_one_(line_one), line_two_(line_two)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Tle(const Tle& tle);
|
||||
|
||||
virtual ~Tle()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* get raw strings
|
||||
*/
|
||||
std::string GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::string GetLine1() const
|
||||
{
|
||||
return line_one_;
|
||||
}
|
||||
|
||||
std::string GetLine2() const
|
||||
{
|
||||
return line_two_;
|
||||
}
|
||||
|
||||
/*
|
||||
* get tle values
|
||||
*/
|
||||
unsigned int NoradNumber() const
|
||||
{
|
||||
return norad_number_;
|
||||
}
|
||||
|
||||
std::string InternationlDesignator() const
|
||||
{
|
||||
return international_designator_;
|
||||
}
|
||||
|
||||
Julian Epoch() const
|
||||
{
|
||||
return epoch_;
|
||||
}
|
||||
|
||||
double MeanMotionDot() const
|
||||
{
|
||||
return mean_motion_dot_;
|
||||
}
|
||||
|
||||
double MeanMotionDot2() const
|
||||
{
|
||||
return mean_motion_dot2_;
|
||||
}
|
||||
|
||||
double BStar() const
|
||||
{
|
||||
return bstar_;
|
||||
}
|
||||
|
||||
double Inclination(bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return inclination_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(inclination_);
|
||||
}
|
||||
}
|
||||
|
||||
double RightAscendingNode(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return right_ascending_node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(right_ascending_node_);
|
||||
}
|
||||
}
|
||||
|
||||
double Eccentricity() const
|
||||
{
|
||||
return eccentricity_;
|
||||
}
|
||||
|
||||
double ArgumentPerigee(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return argument_perigee_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(argument_perigee_);
|
||||
}
|
||||
}
|
||||
|
||||
double MeanAnomaly(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return mean_anomaly_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(mean_anomaly_);
|
||||
}
|
||||
}
|
||||
|
||||
double MeanMotion() const
|
||||
{
|
||||
return mean_motion_;
|
||||
}
|
||||
|
||||
unsigned int OrbitNumber() const
|
||||
{
|
||||
return orbit_number_;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper / validation methods
|
||||
*/
|
||||
static unsigned int GetLineLength()
|
||||
{
|
||||
return TLE_LEN_LINE_DATA;
|
||||
}
|
||||
|
||||
static void IsValidPair(const std::string& line1, const std::string& line2);
|
||||
static void IsValidLine(const std::string& str, int line_number);
|
||||
|
||||
private:
|
||||
/*
|
||||
* initialize from raw tle strings
|
||||
*/
|
||||
void Initialize();
|
||||
/*
|
||||
* format a raw string into an exponent string
|
||||
*/
|
||||
static std::string ExpToDecimal(const std::string&);
|
||||
/*
|
||||
* validate a line against a pattern
|
||||
*/
|
||||
static void ValidateLine(const std::string& line,
|
||||
const std::string& pattern);
|
||||
/*
|
||||
* compute checksum
|
||||
*/
|
||||
static int CheckSum(const std::string& str);
|
||||
|
||||
static std::string ExtractNoradNumber(const std::string& str,
|
||||
int line_number);
|
||||
|
||||
static bool IsValidLineLength(const std::string& str);
|
||||
|
||||
private:
|
||||
/*
|
||||
* raw tle data
|
||||
*/
|
||||
std::string name_;
|
||||
std::string line_one_;
|
||||
std::string line_two_;
|
||||
|
||||
/*
|
||||
* extracted values all in native units
|
||||
*/
|
||||
unsigned int norad_number_;
|
||||
std::string international_designator_;
|
||||
Julian epoch_;
|
||||
double mean_motion_dot_;
|
||||
double mean_motion_dot2_;
|
||||
double bstar_;
|
||||
double inclination_;
|
||||
double right_ascending_node_;
|
||||
double eccentricity_;
|
||||
double argument_perigee_;
|
||||
double mean_anomaly_;
|
||||
double mean_motion_;
|
||||
unsigned int orbit_number_;
|
||||
|
||||
/*
|
||||
* line lengths
|
||||
*/
|
||||
static const unsigned int TLE_LEN_LINE_DATA = 69;
|
||||
static const unsigned int TLE_LEN_LINE_NAME = 22;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TLE_H_
|
||||
#define TLE_H_
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Julian.h"
|
||||
#include "TleException.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Tle
|
||||
{
|
||||
public:
|
||||
Tle(const std::string& line_one, const std::string& line_two)
|
||||
: line_one_(line_one), line_two_(line_two)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Tle(const std::string& name, const std::string& line_one,
|
||||
const std::string& line_two)
|
||||
: name_(name),line_one_(line_one), line_two_(line_two)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Tle(const Tle& tle);
|
||||
|
||||
virtual ~Tle()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* get raw strings
|
||||
*/
|
||||
std::string GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::string GetLine1() const
|
||||
{
|
||||
return line_one_;
|
||||
}
|
||||
|
||||
std::string GetLine2() const
|
||||
{
|
||||
return line_two_;
|
||||
}
|
||||
|
||||
/*
|
||||
* get tle values
|
||||
*/
|
||||
unsigned int NoradNumber() const
|
||||
{
|
||||
return norad_number_;
|
||||
}
|
||||
|
||||
std::string InternationlDesignator() const
|
||||
{
|
||||
return international_designator_;
|
||||
}
|
||||
|
||||
Julian Epoch() const
|
||||
{
|
||||
return epoch_;
|
||||
}
|
||||
|
||||
double MeanMotionDot() const
|
||||
{
|
||||
return mean_motion_dot_;
|
||||
}
|
||||
|
||||
double MeanMotionDot2() const
|
||||
{
|
||||
return mean_motion_dot2_;
|
||||
}
|
||||
|
||||
double BStar() const
|
||||
{
|
||||
return bstar_;
|
||||
}
|
||||
|
||||
double Inclination(bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return inclination_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(inclination_);
|
||||
}
|
||||
}
|
||||
|
||||
double RightAscendingNode(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return right_ascending_node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(right_ascending_node_);
|
||||
}
|
||||
}
|
||||
|
||||
double Eccentricity() const
|
||||
{
|
||||
return eccentricity_;
|
||||
}
|
||||
|
||||
double ArgumentPerigee(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return argument_perigee_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(argument_perigee_);
|
||||
}
|
||||
}
|
||||
|
||||
double MeanAnomaly(const bool in_degrees) const
|
||||
{
|
||||
if (in_degrees)
|
||||
{
|
||||
return mean_anomaly_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DegreesToRadians(mean_anomaly_);
|
||||
}
|
||||
}
|
||||
|
||||
double MeanMotion() const
|
||||
{
|
||||
return mean_motion_;
|
||||
}
|
||||
|
||||
unsigned int OrbitNumber() const
|
||||
{
|
||||
return orbit_number_;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper / validation methods
|
||||
*/
|
||||
static unsigned int GetLineLength()
|
||||
{
|
||||
return TLE_LEN_LINE_DATA;
|
||||
}
|
||||
|
||||
static void IsValidPair(const std::string& line1, const std::string& line2);
|
||||
static void IsValidLine(const std::string& str, int line_number);
|
||||
|
||||
private:
|
||||
/*
|
||||
* initialize from raw tle strings
|
||||
*/
|
||||
void Initialize();
|
||||
/*
|
||||
* format a raw string into an exponent string
|
||||
*/
|
||||
static std::string ExpToDecimal(const std::string&);
|
||||
/*
|
||||
* validate a line against a pattern
|
||||
*/
|
||||
static void ValidateLine(const std::string& line,
|
||||
const std::string& pattern);
|
||||
/*
|
||||
* compute checksum
|
||||
*/
|
||||
static int CheckSum(const std::string& str);
|
||||
|
||||
static std::string ExtractNoradNumber(const std::string& str,
|
||||
int line_number);
|
||||
|
||||
static bool IsValidLineLength(const std::string& str);
|
||||
|
||||
private:
|
||||
/*
|
||||
* raw tle data
|
||||
*/
|
||||
std::string name_;
|
||||
std::string line_one_;
|
||||
std::string line_two_;
|
||||
|
||||
/*
|
||||
* extracted values all in native units
|
||||
*/
|
||||
unsigned int norad_number_;
|
||||
std::string international_designator_;
|
||||
Julian epoch_;
|
||||
double mean_motion_dot_;
|
||||
double mean_motion_dot2_;
|
||||
double bstar_;
|
||||
double inclination_;
|
||||
double right_ascending_node_;
|
||||
double eccentricity_;
|
||||
double argument_perigee_;
|
||||
double mean_anomaly_;
|
||||
double mean_motion_;
|
||||
unsigned int orbit_number_;
|
||||
|
||||
/*
|
||||
* line lengths
|
||||
*/
|
||||
static const unsigned int TLE_LEN_LINE_DATA = 69;
|
||||
static const unsigned int TLE_LEN_LINE_NAME = 22;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
#ifndef TLEEXCEPTION_H_
|
||||
#define TLEEXCEPTION_H_
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
class TleException : public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
TleException(const char* message)
|
||||
: message_(message)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TleException(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return message_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef TLEEXCEPTION_H_
|
||||
#define TLEEXCEPTION_H_
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
class TleException : public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
TleException(const char* message)
|
||||
: message_(message)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TleException(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return message_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
196
Vector.h
196
Vector.h
|
@ -1,98 +1,98 @@
|
|||
#ifndef VECTOR_H_
|
||||
#define VECTOR_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct Vector
|
||||
{
|
||||
public:
|
||||
|
||||
Vector()
|
||||
: x(0.0), y(0.0), z(0.0), w(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(double xx, double yy, double zz)
|
||||
: x(xx), y(yy), z(zz), w(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(double xx, double yy, double zz, double ww)
|
||||
: x(xx), y(yy), z(zz), w(ww)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(const Vector& v)
|
||||
{
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
w = v.w;
|
||||
}
|
||||
|
||||
virtual ~Vector()
|
||||
{
|
||||
}
|
||||
|
||||
Vector& operator=(const Vector& v)
|
||||
{
|
||||
if (this != &v)
|
||||
{
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
w = v.w;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetMagnitude() const
|
||||
{
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
Vector Subtract(const Vector& v) const
|
||||
{
|
||||
/*
|
||||
* subtract (this) - (v)
|
||||
* and return result
|
||||
*/
|
||||
return Vector(x - v.x,
|
||||
y - v.y,
|
||||
z - v.z,
|
||||
0.0);
|
||||
}
|
||||
|
||||
double Dot(const Vector& vec) const
|
||||
{
|
||||
return (x * vec.x) +
|
||||
(y * vec.y) +
|
||||
(z * vec.z);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "X: " << std::setw(8) << x;
|
||||
ss << ", Y: " << std::setw(8) << y;
|
||||
ss << ", Z: " << std::setw(8) << z;
|
||||
ss << ", W: " << std::setw(8) << w;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
double w;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
|
||||
{
|
||||
return strm << v.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef VECTOR_H_
|
||||
#define VECTOR_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct Vector
|
||||
{
|
||||
public:
|
||||
|
||||
Vector()
|
||||
: x(0.0), y(0.0), z(0.0), w(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(double xx, double yy, double zz)
|
||||
: x(xx), y(yy), z(zz), w(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(double xx, double yy, double zz, double ww)
|
||||
: x(xx), y(yy), z(zz), w(ww)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(const Vector& v)
|
||||
{
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
w = v.w;
|
||||
}
|
||||
|
||||
virtual ~Vector()
|
||||
{
|
||||
}
|
||||
|
||||
Vector& operator=(const Vector& v)
|
||||
{
|
||||
if (this != &v)
|
||||
{
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
w = v.w;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetMagnitude() const
|
||||
{
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
Vector Subtract(const Vector& v) const
|
||||
{
|
||||
/*
|
||||
* subtract (this) - (v)
|
||||
* and return result
|
||||
*/
|
||||
return Vector(x - v.x,
|
||||
y - v.y,
|
||||
z - v.z,
|
||||
0.0);
|
||||
}
|
||||
|
||||
double Dot(const Vector& vec) const
|
||||
{
|
||||
return (x * vec.x) +
|
||||
(y * vec.y) +
|
||||
(z * vec.z);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::right << std::fixed << std::setprecision(2);
|
||||
ss << "X: " << std::setw(8) << x;
|
||||
ss << ", Y: " << std::setw(8) << y;
|
||||
ss << ", Z: " << std::setw(8) << z;
|
||||
ss << ", W: " << std::setw(8) << w;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
double w;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
|
||||
{
|
||||
return strm << v.ToString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue