Removed array of values from Tle
parent
7f70992717
commit
1d1aac3f5c
16
SGDP4.cpp
16
SGDP4.cpp
|
@ -51,14 +51,14 @@ void SGDP4::SetTle(const Tle& tle) {
|
||||||
/*
|
/*
|
||||||
* extract and format tle data
|
* extract and format tle data
|
||||||
*/
|
*/
|
||||||
mean_anomoly_ = tle.GetField(Tle::FLD_M, Tle::U_RAD);
|
mean_anomoly_ = tle.MeanAnomaly(false);
|
||||||
ascending_node_ = tle.GetField(Tle::FLD_RAAN, Tle::U_RAD);
|
ascending_node_ = tle.RightAscendingNode(false);
|
||||||
argument_perigee_ = tle.GetField(Tle::FLD_ARGPER, Tle::U_RAD);
|
argument_perigee_ = tle.ArgumentPerigee(false);
|
||||||
eccentricity_ = tle.GetField(Tle::FLD_E);
|
eccentricity_ = tle.Eccentricity();
|
||||||
inclination_ = tle.GetField(Tle::FLD_I, Tle::U_RAD);
|
inclination_ = tle.Inclination(false);
|
||||||
mean_motion_ = tle.GetField(Tle::FLD_MMOTION) * TWOPI / Globals::MIN_PER_DAY();
|
mean_motion_ = tle.MeanMotion() * TWOPI / Globals::MIN_PER_DAY();
|
||||||
bstar_ = tle.GetField(Tle::FLD_BSTAR);
|
bstar_ = tle.BStar();
|
||||||
epoch_ = tle.GetEpoch();
|
epoch_ = tle.Epoch();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* error checks
|
* error checks
|
||||||
|
|
348
Tle.cpp
348
Tle.cpp
|
@ -3,7 +3,17 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
Tle::Tle(const std::string& line_one, const std::string& line_two) {
|
||||||
|
|
||||||
|
name_.erase();
|
||||||
|
line_one_ = line_one;
|
||||||
|
line_two_ = line_two;
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
Tle::Tle(const std::string& name, const std::string& line_one, const std::string& line_two) {
|
Tle::Tle(const std::string& name, const std::string& line_one, const std::string& line_two) {
|
||||||
|
|
||||||
name_ = name;
|
name_ = name;
|
||||||
line_one_ = line_one;
|
line_one_ = line_one;
|
||||||
line_two_ = line_two;
|
line_two_ = line_two;
|
||||||
|
@ -12,105 +22,48 @@ Tle::Tle(const std::string& name, const std::string& line_one, const std::string
|
||||||
}
|
}
|
||||||
|
|
||||||
Tle::Tle(const Tle& tle) {
|
Tle::Tle(const Tle& tle) {
|
||||||
|
|
||||||
name_ = tle.name_;
|
name_ = tle.name_;
|
||||||
line_one_ = tle.line_one_;
|
line_one_ = tle.line_one_;
|
||||||
line_two_ = tle.line_two_;
|
line_two_ = tle.line_two_;
|
||||||
date_ = tle.date_;
|
|
||||||
|
|
||||||
for (int fld = FLD_FIRST; fld < FLD_LAST; fld++) {
|
norad_number_ = tle.norad_number_;
|
||||||
fields_[fld] = tle.fields_[fld];
|
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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tle::~Tle() {
|
Tle::~Tle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
double Tle::GetField(TleField fld, TleUnits units) const {
|
|
||||||
assert((FLD_FIRST <= fld) && (fld < FLD_LAST));
|
|
||||||
assert((U_FIRST <= units) && (units < U_LAST));
|
|
||||||
|
|
||||||
double value = fields_[fld].second;
|
|
||||||
double converted = 0.0;
|
|
||||||
|
|
||||||
switch (fld) {
|
|
||||||
case FLD_I:
|
|
||||||
case FLD_RAAN:
|
|
||||||
case FLD_ARGPER:
|
|
||||||
case FLD_M:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* native format is degrees
|
|
||||||
*/
|
|
||||||
if (units == U_RAD)
|
|
||||||
converted = Globals::Deg2Rad(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
converted = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return converted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get field represented as a string
|
* convert a tle raw string into an exponent string
|
||||||
*/
|
|
||||||
std::string Tle::GetFieldString(TleField fld, bool append_units) const {
|
|
||||||
assert((FLD_FIRST <= fld) && (fld < FLD_LAST));
|
|
||||||
|
|
||||||
std::string str = fields_[fld].first;
|
|
||||||
|
|
||||||
if (append_units)
|
|
||||||
str += GetUnits(fld);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get the units for a field
|
|
||||||
*/
|
|
||||||
std::string Tle::GetUnits(TleField field) const {
|
|
||||||
static const std::string strDegrees = " degrees";
|
|
||||||
static const std::string strRevsPerDay = " revs / day";
|
|
||||||
static const std::string strNull = "";
|
|
||||||
|
|
||||||
switch (field) {
|
|
||||||
case FLD_I:
|
|
||||||
case FLD_RAAN:
|
|
||||||
case FLD_ARGPER:
|
|
||||||
case FLD_M:
|
|
||||||
return strDegrees;
|
|
||||||
|
|
||||||
case FLD_MMOTION:
|
|
||||||
return strRevsPerDay;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return strNull;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* convert a raw string into an exponent string
|
|
||||||
*/
|
*/
|
||||||
std::string Tle::ExpToDecimal(const std::string& str) {
|
std::string Tle::ExpToDecimal(const std::string& str) {
|
||||||
static const int kColumnSign = 0;
|
|
||||||
static const int kLengthSign = 1;
|
static const int START_SIGN = 0;
|
||||||
static const int kColumnMantissa = 1;
|
static const int LENGTH_SIGN = 1;
|
||||||
static const int kLengthMantissa = 5;
|
static const int START_MANTISSA = 1;
|
||||||
static const int kColumnExp = 6;
|
static const int LENGTH_MANTISSA = 5;
|
||||||
static const int kLengthExp = 2;
|
static const int START_EXP = 6;
|
||||||
|
static const int LENGTH_EXP = 2;
|
||||||
|
|
||||||
assert(8 == str.length());
|
assert(8 == str.length());
|
||||||
|
|
||||||
std::string value;
|
std::string value = str.substr(START_SIGN, LENGTH_SIGN);
|
||||||
value = str.substr(kColumnSign, kLengthSign);
|
|
||||||
value += ".";
|
value += ".";
|
||||||
value += str.substr(kColumnMantissa, kLengthMantissa);
|
value += str.substr(START_MANTISSA, LENGTH_MANTISSA);
|
||||||
value += "e";
|
value += "e";
|
||||||
value += str.substr(kColumnExp, kLengthExp);
|
value += str.substr(START_EXP, LENGTH_EXP);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +72,12 @@ std::string Tle::ExpToDecimal(const std::string& str) {
|
||||||
* extract all variables
|
* extract all variables
|
||||||
*/
|
*/
|
||||||
void Tle::Initialize() {
|
void Tle::Initialize() {
|
||||||
|
|
||||||
|
std::string temp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* trim whitespace
|
||||||
|
*/
|
||||||
TrimLeft(name_);
|
TrimLeft(name_);
|
||||||
TrimRight(name_);
|
TrimRight(name_);
|
||||||
TrimLeft(line_one_);
|
TrimLeft(line_one_);
|
||||||
|
@ -126,104 +85,129 @@ void Tle::Initialize() {
|
||||||
TrimLeft(line_two_);
|
TrimLeft(line_two_);
|
||||||
TrimRight(line_two_);
|
TrimRight(line_two_);
|
||||||
|
|
||||||
assert(!name_.empty());
|
/*
|
||||||
assert(!line_one_.empty());
|
* check the two lines are valid
|
||||||
assert(!line_two_.empty());
|
*/
|
||||||
|
assert(IsValidPair(line_one_, line_two_));
|
||||||
assert(IsValidLine(line_one_, Tle::LINE_ONE));
|
|
||||||
assert(IsValidLine(line_two_, Tle::LINE_TWO));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* line 1
|
* line 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fields_[FLD_NORADNUM].first = line_one_.substr(TLE1_COL_SATNUM, TLE1_LEN_SATNUM);
|
temp = line_one_.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM).c_str();
|
||||||
fields_[FLD_INTLDESC].first = line_one_.substr(TLE1_COL_INTLDESC_A, TLE1_LEN_INTLDESC_A +
|
norad_number_ = atoi(temp.c_str());
|
||||||
TLE1_LEN_INTLDESC_B + TLE1_LEN_INTLDESC_C);
|
/*
|
||||||
fields_[FLD_EPOCHYEAR].first = line_one_.substr(TLE1_COL_EPOCH_A, TLE1_LEN_EPOCH_A);
|
* if blank use norad number
|
||||||
|
*/
|
||||||
|
if (name_.empty())
|
||||||
|
name_ = temp;
|
||||||
|
|
||||||
fields_[FLD_EPOCHDAY].first = line_one_.substr(TLE1_COL_EPOCH_B, TLE1_LEN_EPOCH_B);
|
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] == '-') {
|
if (line_one_[TLE1_COL_MEANMOTIONDT] == '-') {
|
||||||
// value is negative
|
temp = "-0";
|
||||||
fields_[FLD_MMOTIONDT].first = "-0";
|
|
||||||
} else
|
} else
|
||||||
fields_[FLD_MMOTIONDT].first = "0";
|
temp = "0";
|
||||||
|
temp += line_one_.substr(TLE1_COL_MEANMOTIONDT + 1, TLE1_LEN_MEANMOTIONDT);
|
||||||
|
mean_motion_dot_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_MMOTIONDT].first += line_one_.substr(TLE1_COL_MEANMOTIONDT + 1, TLE1_LEN_MEANMOTIONDT);
|
temp = ExpToDecimal(line_one_.substr(TLE1_COL_MEANMOTIONDT2, TLE1_LEN_MEANMOTIONDT2));
|
||||||
|
mean_motion_dot2_ = atof(temp.c_str());
|
||||||
|
|
||||||
// decimal point assumed; exponential notation
|
temp = ExpToDecimal(line_one_.substr(TLE1_COL_BSTAR, TLE1_LEN_BSTAR).c_str());
|
||||||
fields_[FLD_MMOTIONDT2].first = ExpToDecimal(line_one_.substr(TLE1_COL_MEANMOTIONDT2, TLE1_LEN_MEANMOTIONDT2));
|
bstar_ = atof(temp.c_str());
|
||||||
|
|
||||||
// decimal point assumed; exponential notation
|
|
||||||
fields_[FLD_BSTAR].first = ExpToDecimal(line_one_.substr(TLE1_COL_BSTAR, TLE1_LEN_BSTAR));
|
|
||||||
|
|
||||||
fields_[FLD_SET].first = line_one_.substr(TLE1_COL_ELNUM, TLE1_LEN_ELNUM);
|
|
||||||
TrimLeft(fields_[FLD_SET].first);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* line 2
|
* line 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fields_[FLD_I].first = line_two_.substr(TLE2_COL_INCLINATION, TLE2_LEN_INCLINATION);
|
temp = line_two_.substr(TLE2_COL_INCLINATION, TLE2_LEN_INCLINATION);
|
||||||
TrimLeft(fields_[FLD_I].first);
|
TrimLeft(temp);
|
||||||
|
inclination_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_RAAN].first = line_two_.substr(TLE2_COL_RAASCENDNODE, TLE2_LEN_RAASCENDNODE);
|
temp = line_two_.substr(TLE2_COL_RAASCENDNODE, TLE2_LEN_RAASCENDNODE);
|
||||||
TrimLeft(fields_[FLD_RAAN].first);
|
TrimLeft(temp);
|
||||||
|
right_ascending_node_ = atof(temp.c_str());
|
||||||
|
|
||||||
// decimal point is assumed
|
temp = "0.";
|
||||||
fields_[FLD_E].first = "0.";
|
temp += line_two_.substr(TLE2_COL_ECCENTRICITY, TLE2_LEN_ECCENTRICITY);
|
||||||
fields_[FLD_E].first += line_two_.substr(TLE2_COL_ECCENTRICITY, TLE2_LEN_ECCENTRICITY);
|
eccentricity_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_ARGPER].first = line_two_.substr(TLE2_COL_ARGPERIGEE, TLE2_LEN_ARGPERIGEE);
|
temp = line_two_.substr(TLE2_COL_ARGPERIGEE, TLE2_LEN_ARGPERIGEE);
|
||||||
TrimLeft(fields_[FLD_ARGPER].first);
|
TrimLeft(temp);
|
||||||
|
argument_perigee_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_M].first = line_two_.substr(TLE2_COL_MEANANOMALY, TLE2_LEN_MEANANOMALY);
|
temp = line_two_.substr(TLE2_COL_MEANANOMALY, TLE2_LEN_MEANANOMALY);
|
||||||
TrimLeft(fields_[FLD_M].first);
|
TrimLeft(temp);
|
||||||
|
mean_anomaly_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_MMOTION].first = line_two_.substr(TLE2_COL_MEANMOTION, TLE2_LEN_MEANMOTION);
|
temp = line_two_.substr(TLE2_COL_MEANMOTION, TLE2_LEN_MEANMOTION);
|
||||||
TrimLeft(fields_[FLD_MMOTION].first);
|
TrimLeft(temp);
|
||||||
|
mean_motion_ = atof(temp.c_str());
|
||||||
|
|
||||||
fields_[FLD_ORBITNUM].first = line_two_.substr(TLE2_COL_REVATEPOCH, TLE2_LEN_REVATEPOCH);
|
temp = line_two_.substr(TLE2_COL_REVATEPOCH, TLE2_LEN_REVATEPOCH);
|
||||||
TrimLeft(fields_[FLD_ORBITNUM].first);
|
TrimLeft(temp);
|
||||||
|
orbit_number_ = atoi(temp.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// update double variables
|
/*
|
||||||
for (int fld = FLD_FIRST; fld < FLD_LAST; fld++) {
|
* check the two lines have matching norad numbers
|
||||||
fields_[fld].second = atof(fields_[fld].first.c_str());
|
* and that the lines themselves are valid
|
||||||
}
|
*/
|
||||||
|
bool Tle::IsValidPair(const std::string& line1, const std::string& line2) {
|
||||||
|
|
||||||
int year = static_cast<int> (GetField(Tle::FLD_EPOCHYEAR));
|
if (atoi(line1.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM).c_str()) !=
|
||||||
if (year < 57)
|
atoi(line2.substr(TLE2_COL_NORADNUM, TLE2_LEN_NORADNUM).c_str()))
|
||||||
year += 2000;
|
return false;
|
||||||
else
|
|
||||||
year += 1900;
|
|
||||||
double day = GetField(Tle::FLD_EPOCHDAY);
|
|
||||||
|
|
||||||
date_ = Julian(year, day);
|
if (!IsValidLine(line1, 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!IsValidLine(line2, 2))
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* validate a line
|
* validate a line
|
||||||
*/
|
*/
|
||||||
bool Tle::IsValidLine(std::string& str, TleLine line) {
|
bool Tle::IsValidLine(const std::string& str, const unsigned char line_number) {
|
||||||
TrimLeft(str);
|
|
||||||
TrimRight(str);
|
|
||||||
|
|
||||||
const std::string line1_validation = "1 NNNNNC NNNNAAAA NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN";
|
static const std::string line1_pattern = "1 NNNNNC NNNNAAAA NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN";
|
||||||
const std::string line2_validation = "2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN";
|
static const std::string line2_pattern = "2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN";
|
||||||
|
|
||||||
if (Tle::LINE_ONE == line) {
|
/*
|
||||||
if (!ValidateLine(line1_validation, str))
|
* validate line against the pattern
|
||||||
|
*/
|
||||||
|
if (1 == line_number) {
|
||||||
|
if (!ValidateLine(str, line1_pattern))
|
||||||
return false;
|
return false;
|
||||||
} else if (Tle::LINE_TWO == line) {
|
} else if (2 == line_number) {
|
||||||
if (!ValidateLine(line2_validation, str))
|
if (!ValidateLine(str, line2_pattern))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last char in string must be checksum
|
/*
|
||||||
// int chk = CheckSum(str);
|
* last char in string is modulo 10 checksum
|
||||||
// if (chk != (str[TLE_LEN_LINE_DATA - 1] - '0'))
|
*/
|
||||||
// return false;
|
int chk = CheckSum(str);
|
||||||
|
if (chk != (str[TLE_LEN_LINE_DATA - 1] - '0'))
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -231,23 +215,49 @@ bool Tle::IsValidLine(std::string& str, TleLine line) {
|
||||||
/*
|
/*
|
||||||
* validate line given a pattern
|
* validate line given a pattern
|
||||||
*/
|
*/
|
||||||
bool Tle::ValidateLine(const std::string& pattern, const std::string& line) {
|
bool Tle::ValidateLine(const std::string& line, const std::string& pattern) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check length of lines match
|
||||||
|
*/
|
||||||
if (pattern.length() != line.length()) {
|
if (pattern.length() != line.length()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string::size_type pos = 0;
|
std::string::const_iterator pattern_itr = pattern.begin();
|
||||||
|
std::string::const_iterator line_itr = line.begin();
|
||||||
|
|
||||||
while (pos != line.length() - 1) {
|
while (pattern_itr != pattern.end()) {
|
||||||
if (isdigit(pattern[pos]) || pattern[pos] == ' ' || pattern[pos] == '.') {
|
|
||||||
if (pattern[pos] != line[pos])
|
if (isdigit(*pattern_itr) || *pattern_itr == ' ' ||
|
||||||
|
*pattern_itr == '.' || *pattern_itr == '-') {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* these characters should match exactly
|
||||||
|
*/
|
||||||
|
if (*pattern_itr != *line_itr)
|
||||||
return false;
|
return false;
|
||||||
} else if (pattern[pos] == 'N') {
|
|
||||||
if (!isdigit(line[pos]) && line[pos] != ' ')
|
} else if (*pattern_itr == 'N') {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if pattern value is 'N' then either a number or a ' '
|
||||||
|
*/
|
||||||
|
if (!isdigit(*line_itr) && *line_itr != ' ')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (*pattern_itr == '+') {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if pattern value is '+' then either a '+' or a ' '
|
||||||
|
*/
|
||||||
|
if (*line_itr != '+' && *line_itr != ' ')
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pos++;
|
|
||||||
|
pattern_itr++;
|
||||||
|
line_itr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -257,14 +267,19 @@ bool Tle::ValidateLine(const std::string& pattern, const std::string& line) {
|
||||||
* compute checksum
|
* compute checksum
|
||||||
*/
|
*/
|
||||||
int Tle::CheckSum(const std::string& str) {
|
int Tle::CheckSum(const std::string& str) {
|
||||||
|
|
||||||
size_t len = str.size() - 1;
|
size_t len = str.size() - 1;
|
||||||
int xsum = 0;
|
int xsum = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
|
||||||
char ch = str[i];
|
char ch = str[i];
|
||||||
|
|
||||||
if (isdigit(ch))
|
if (isdigit(ch))
|
||||||
xsum += (ch - '0');
|
xsum += (ch - '0');
|
||||||
else if (ch == '-')
|
else
|
||||||
|
|
||||||
|
if (ch == '-')
|
||||||
xsum++;
|
xsum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,28 +289,35 @@ int Tle::CheckSum(const std::string& str) {
|
||||||
/*
|
/*
|
||||||
* trim left of string
|
* trim left of string
|
||||||
*/
|
*/
|
||||||
void Tle::TrimLeft(std::string& s) {
|
void Tle::TrimLeft(std::string& str) {
|
||||||
if (!s.empty()) {
|
|
||||||
std::string::size_type pos = s.find_first_not_of(' ');
|
std::string whitespaces(" \t\f\n\r");
|
||||||
|
|
||||||
|
if (!str.empty()) {
|
||||||
|
std::string::size_type pos = str.find_first_not_of(whitespaces);
|
||||||
|
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
s.erase(0, pos);
|
str.erase(0, pos);
|
||||||
|
|
||||||
else
|
else
|
||||||
s.clear();
|
str.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* trim right of string
|
* trim right of string
|
||||||
*/
|
*/
|
||||||
void Tle::TrimRight(std::string& s) {
|
void Tle::TrimRight(std::string& str) {
|
||||||
if (!s.empty()) {
|
|
||||||
std::string::size_type pos = s.find_last_not_of(' ');
|
std::string whitespaces(" \t\f\n\r");
|
||||||
|
|
||||||
|
if (!str.empty()) {
|
||||||
|
std::string::size_type pos = str.find_last_not_of(whitespaces);
|
||||||
|
|
||||||
if (pos != std::string::npos)
|
if (pos != std::string::npos)
|
||||||
s.erase(pos + 1);
|
str.erase(pos + 1);
|
||||||
else
|
else
|
||||||
s.clear();
|
str.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
184
Tle.h
184
Tle.h
|
@ -8,73 +8,14 @@
|
||||||
|
|
||||||
class Tle {
|
class Tle {
|
||||||
public:
|
public:
|
||||||
|
Tle(const std::string& line_one, const std::string& line_two);
|
||||||
Tle(const std::string& name, const std::string& line_one, const std::string& line_two);
|
Tle(const std::string& name, const std::string& line_one, const std::string& line_two);
|
||||||
Tle(const Tle& tle);
|
Tle(const Tle& tle);
|
||||||
virtual ~Tle();
|
virtual ~Tle();
|
||||||
|
|
||||||
enum TleLine {
|
|
||||||
LINE_ZERO,
|
|
||||||
LINE_ONE,
|
|
||||||
LINE_TWO
|
|
||||||
};
|
|
||||||
|
|
||||||
enum TleField {
|
|
||||||
FLD_FIRST,
|
|
||||||
FLD_NORADNUM = FLD_FIRST,
|
|
||||||
FLD_INTLDESC,
|
|
||||||
FLD_SET, // Tle set number
|
|
||||||
FLD_EPOCHYEAR, // Epoch: Last two digits of year
|
|
||||||
FLD_EPOCHDAY, // Epoch: Fractional Julian Day of year
|
|
||||||
FLD_ORBITNUM, // Orbit at epoch
|
|
||||||
FLD_I, // Inclination
|
|
||||||
FLD_RAAN, // R.A. ascending node
|
|
||||||
FLD_E, // Eccentricity
|
|
||||||
FLD_ARGPER, // Argument of perigee
|
|
||||||
FLD_M, // Mean anomaly
|
|
||||||
FLD_MMOTION, // Mean motion
|
|
||||||
FLD_MMOTIONDT, // First time derivative of mean motion
|
|
||||||
FLD_MMOTIONDT2, // Second time derivative of mean motion
|
|
||||||
FLD_BSTAR, // BSTAR Drag
|
|
||||||
FLD_LAST // MUST be last
|
|
||||||
};
|
|
||||||
|
|
||||||
enum TleUnits {
|
|
||||||
U_FIRST,
|
|
||||||
U_RAD = U_FIRST, // radians
|
|
||||||
U_DEG, // degrees
|
|
||||||
U_NATIVE, // Tle format native units (no conversion)
|
|
||||||
U_LAST // MUST be last
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize from raw tle strings
|
* get raw strings
|
||||||
*/
|
*/
|
||||||
void Initialize();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get field represented as a double
|
|
||||||
*/
|
|
||||||
double GetField(TleField fld, TleUnits unit = U_NATIVE) const;
|
|
||||||
/*
|
|
||||||
* get field represented as a string
|
|
||||||
*/
|
|
||||||
std::string GetFieldString(TleField fld, bool append_units) const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get epoch of tle
|
|
||||||
*/
|
|
||||||
Julian GetEpoch() const {
|
|
||||||
return date_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* compute checksum
|
|
||||||
*/
|
|
||||||
static int CheckSum(const std::string& str);
|
|
||||||
static bool IsValidLine(std::string& str, TleLine line);
|
|
||||||
static void TrimLeft(std::string& str);
|
|
||||||
static void TrimRight(std::string& str);
|
|
||||||
|
|
||||||
std::string GetName() const {
|
std::string GetName() const {
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
@ -87,28 +28,100 @@ public:
|
||||||
return line_two_;
|
return line_two_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetNoradNumber() const {
|
/*
|
||||||
return GetField(Tle::FLD_NORADNUM);
|
* get tle values
|
||||||
|
*/
|
||||||
|
double 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(const bool in_degrees)const {
|
||||||
|
if (in_degrees)
|
||||||
|
return inclination_;
|
||||||
|
else
|
||||||
|
return Globals::Deg2Rad(inclination_);
|
||||||
|
}
|
||||||
|
|
||||||
|
double RightAscendingNode(const bool in_degrees)const {
|
||||||
|
if (in_degrees)
|
||||||
|
return right_ascending_node_;
|
||||||
|
else
|
||||||
|
return Globals::Deg2Rad(right_ascending_node_);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Eccentricity()const {
|
||||||
|
return eccentricity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ArgumentPerigee(const bool in_degrees)const {
|
||||||
|
if (in_degrees)
|
||||||
|
return argument_perigee_;
|
||||||
|
else
|
||||||
|
return Globals::Deg2Rad(argument_perigee_);
|
||||||
|
}
|
||||||
|
|
||||||
|
double MeanAnomaly(const bool in_degrees)const {
|
||||||
|
if (in_degrees)
|
||||||
|
return mean_anomaly_;
|
||||||
|
else
|
||||||
|
return Globals::Deg2Rad(mean_anomaly_);
|
||||||
|
}
|
||||||
|
|
||||||
|
double MeanMotion()const {
|
||||||
|
return mean_motion_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int OrbitNumber()const {
|
||||||
|
return orbit_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper / validation methods
|
||||||
|
*/
|
||||||
|
static bool IsValidPair(const std::string& line1, const std::string& line2);
|
||||||
|
static bool IsValidLine(const std::string& str, unsigned char line_number);
|
||||||
|
static void TrimLeft(std::string& str);
|
||||||
|
static void TrimRight(std::string& str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* get units for a field
|
* initialize from raw tle strings
|
||||||
*/
|
*/
|
||||||
std::string GetUnits(TleField field) const;
|
void Initialize();
|
||||||
/*
|
/*
|
||||||
* get raw value for a field
|
* format a raw string into an exponent string
|
||||||
*/
|
|
||||||
double GetFieldNumeric(TleField) const;
|
|
||||||
/*
|
|
||||||
* convert a raw string into an exponent string
|
|
||||||
*/
|
*/
|
||||||
static std::string ExpToDecimal(const std::string&);
|
static std::string ExpToDecimal(const std::string&);
|
||||||
/*
|
/*
|
||||||
* validate a line
|
* validate a line against a pattern
|
||||||
*/
|
*/
|
||||||
static bool ValidateLine(const std::string& pattern, const std::string& line);
|
static bool ValidateLine(const std::string& line, const std::string& pattern);
|
||||||
|
/*
|
||||||
|
* compute checksum
|
||||||
|
*/
|
||||||
|
static int CheckSum(const std::string& str);
|
||||||
|
|
||||||
|
private:
|
||||||
/*
|
/*
|
||||||
* raw tle data
|
* raw tle data
|
||||||
*/
|
*/
|
||||||
|
@ -117,12 +130,21 @@ private:
|
||||||
std::string line_two_;
|
std::string line_two_;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* epoch of tle
|
* extracted values all in native units
|
||||||
*/
|
*/
|
||||||
Julian date_;
|
double norad_number_;
|
||||||
|
std::string international_designator_;
|
||||||
// array of tle values in native string and double form
|
Julian epoch_;
|
||||||
std::pair<std::string, double> fields_[FLD_LAST];
|
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_;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* name line
|
* name line
|
||||||
|
@ -133,8 +155,8 @@ private:
|
||||||
/*
|
/*
|
||||||
* line 1
|
* line 1
|
||||||
*/
|
*/
|
||||||
static const unsigned int TLE1_COL_SATNUM = 2;
|
static const unsigned int TLE1_COL_NORADNUM = 2;
|
||||||
static const unsigned int TLE1_LEN_SATNUM = 5;
|
static const unsigned int TLE1_LEN_NORADNUM = 5;
|
||||||
static const unsigned int TLE1_COL_INTLDESC_A = 9;
|
static const unsigned int TLE1_COL_INTLDESC_A = 9;
|
||||||
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
|
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
|
||||||
static const unsigned int TLE1_COL_INTLDESC_B = 11;
|
static const unsigned int TLE1_COL_INTLDESC_B = 11;
|
||||||
|
@ -159,8 +181,8 @@ private:
|
||||||
/*
|
/*
|
||||||
* line 2
|
* line 2
|
||||||
*/
|
*/
|
||||||
static const unsigned int TLE2_COL_SATNUM = 2;
|
static const unsigned int TLE2_COL_NORADNUM = 2;
|
||||||
static const unsigned int TLE2_LEN_SATNUM = 5;
|
static const unsigned int TLE2_LEN_NORADNUM = 5;
|
||||||
static const unsigned int TLE2_COL_INCLINATION = 8;
|
static const unsigned int TLE2_COL_INCLINATION = 8;
|
||||||
static const unsigned int TLE2_LEN_INCLINATION = 8;
|
static const unsigned int TLE2_LEN_INCLINATION = 8;
|
||||||
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
|
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
|
||||||
|
|
Loading…
Reference in New Issue