Changed Tle to used exceptions

feature/19
Daniel Warner 2011-05-31 12:06:22 +00:00
parent 1cf4c38d1a
commit e58928e887
7 changed files with 155 additions and 69 deletions

View File

@ -159,13 +159,13 @@ std::ostream & operator<<(std::ostream& stream, const Julian& julian) {
std::stringstream out;
struct Julian::DateTimeComponents datetime;
julian.ToGregorian(&datetime);
out << std::right << std::fixed << std::setprecision(7) << std::setfill('0');
out << std::right << std::fixed << std::setprecision(3) << std::setfill('0');
out << std::setw(4) << datetime.years << "-";
out << std::setw(2) << datetime.months << "-";
out << std::setw(2) << datetime.days << " ";
out << std::setw(2) << datetime.hours << ":";
out << std::setw(2) << datetime.minutes << ":";
out << std::setw(10) << datetime.seconds;
out << std::setw(6) << datetime.seconds << " UTC";
stream << out.str();
return stream;
}

View File

@ -58,8 +58,8 @@ void RunTle(Tle tle, double start, double end, double inc) {
std::cout.width(14);
std::cout << velocity.z << std::endl;
} catch (std::exception* ex) {
std::cout << ex->what() << std::endl;
} catch (SatelliteException& e) {
std::cout << e.what() << std::endl;
running = false;
}
if ((first_run && current == 0.0) || !first_run) {
@ -144,15 +144,15 @@ void RunTest(const char* infile) {
*/
if (!got_first_line) {
if (Tle::IsValidLine(line, 1)) {
try {
Tle::IsValidLine(line, 1);
/*
* store line and now read in second line
*/
got_first_line = true;
line1 = line;
} else {
std::cerr << "Error: Badly formatted first line:" << std::endl;
} catch (TleException& e) {
std::cerr << "Error: " << e.what() << std::endl;
std::cerr << line << std::endl;
}
} else {
@ -182,12 +182,13 @@ void RunTest(const char* infile) {
/*
* following line must be the second line
*/
if (Tle::IsValidLine(line2, 2)) {
try {
Tle::IsValidLine(line2, 2);
Tle tle("Test", line1, line2);
RunTle(tle, start, end, inc);
} else {
std::cerr << "Error: Badly formatted second line:" << std::endl;
std::cerr << line2 << std::endl;
} catch (TleException& e) {
std::cerr << "Error: " << e.what() << std::endl;
std::cerr << line << std::endl;
}
}
}

18
SGP4.cpp Normal file → Executable file
View File

@ -43,11 +43,11 @@ void SGP4::SetTle(const Tle& tle) {
* error checks
*/
if (eccentricity_ < 0.0 || eccentricity_ > 1.0 - 1.0e-3) {
throw new SatelliteException("Eccentricity out of range");
throw SatelliteException("Eccentricity out of range");
}
if (inclination_ < 0.0 || eccentricity_ > kPI) {
throw new SatelliteException("Inclination out of range");
throw SatelliteException("Inclination out of range");
}
Initialize();
@ -273,7 +273,7 @@ void SGP4::FindPositionSDP4(Eci* eci, double tsince) const {
DeepSpaceSecular(tsince, &xmdf, &omgadf, &xnode, &e, &xincl, &xn);
if (xn <= 0.0) {
throw new SatelliteException("Error: #2 (xn <= 0.0)");
throw SatelliteException("Error: #2 (xn <= 0.0)");
}
a = pow(kXKE / xn, kTWOTHIRD) * pow(tempa, 2.0);
@ -283,7 +283,7 @@ void SGP4::FindPositionSDP4(Eci* eci, double tsince) const {
* fix tolerance for error recognition
*/
if (e >= 1.0 || e < -0.001) {
throw new SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
}
/*
* fix tolerance to avoid a divide by zero
@ -318,7 +318,7 @@ void SGP4::FindPositionSDP4(Eci* eci, double tsince) const {
omega = omgadf;
if (e < 0.0 || e > 1.0) {
throw new SatelliteException("Error: #3 (e < 0.0 || e > 1.0)");
throw SatelliteException("Error: #3 (e < 0.0 || e > 1.0)");
}
/*
@ -402,14 +402,14 @@ void SGP4::FindPositionSGP4(Eci* eci, double tsince) const {
xl = xmp + omega + xnode + RecoveredMeanMotion() * templ;
if (xl <= 0.0) {
throw new SatelliteException("Error: #2 (xl <= 0.0)");
throw SatelliteException("Error: #2 (xl <= 0.0)");
}
/*
* fix tolerance for error recognition
*/
if (e >= 1.0 || e < -0.001) {
throw new SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
}
/*
* fix tolerance to avoid a divide by zero
@ -519,7 +519,7 @@ void SGP4::CalculateFinalPositionVelocity(Eci* eci, const double& tsince, const
const double pl = a * temp;
if (pl < 0.0) {
throw new SatelliteException("Error: #4 (pl < 0.0)");
throw SatelliteException("Error: #4 (pl < 0.0)");
}
const double r = a * (1.0 - ecose);
@ -549,7 +549,7 @@ void SGP4::CalculateFinalPositionVelocity(Eci* eci, const double& tsince, const
const double rfdotk = rfdot + xn * temp1 * (x1mth2 * cos2u + 1.5 * x3thm1);
if (rk < 1.0) {
throw new SatelliteException("Error: #6 Satellite decayed (rk < 1.0)");
throw SatelliteException("Error: #6 Satellite decayed (rk < 1.0)");
}
/*

1
SGP4.h Normal file → Executable file
View File

@ -3,6 +3,7 @@
#include "Tle.h"
#include "Eci.h"
#include "SatelliteException.h"
class SGP4 {
public:

144
Tle.cpp
View File

@ -5,7 +5,6 @@
Tle::Tle(const std::string& line_one, const std::string& line_two) {
name_.erase();
line_one_ = line_one;
line_two_ = line_two;
@ -57,7 +56,9 @@ std::string Tle::ExpToDecimal(const std::string& str) {
static const int START_EXP = 6;
static const int LENGTH_EXP = 2;
assert(8 == str.length());
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 += ".";
@ -88,16 +89,16 @@ void Tle::Initialize() {
/*
* check the two lines are valid
*/
assert(IsValidPair(line_one_, line_two_));
IsValidPair(line_one_, line_two_);
/*
* line 1
*/
temp = line_one_.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM).c_str();
temp = ExtractNoradNumber(line_one_, 1);
norad_number_ = atoi(temp.c_str());
/*
* if blank use norad number
* if blank use norad number for name
*/
if (name_.empty())
name_ = temp;
@ -113,7 +114,6 @@ void Tle::Initialize() {
year += 2000;
else
year += 1900;
epoch_ = Julian(year, day);
if (line_one_[TLE1_COL_MEANMOTIONDT] == '-') {
@ -164,43 +164,49 @@ void Tle::Initialize() {
/*
* check the two lines have matching norad numbers
* and that the lines themselves are valid
* and that the lines themselves are equal
*/
bool Tle::IsValidPair(const std::string& line1, const std::string& line2) {
void Tle::IsValidPair(const std::string& line1, const std::string& line2) {
if (!IsValidLine(line1, 1))
return false;
/*
* validate each line
*/
IsValidLine(line1, 1);
IsValidLine(line2, 2);
if (!IsValidLine(line2, 2))
return false;
/*
* extract norad numbers
*/
std::string norad_1 = ExtractNoradNumber(line1, 1);
std::string norad_2 = ExtractNoradNumber(line2, 2);
if (atoi(line1.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM).c_str()) !=
atoi(line2.substr(TLE2_COL_NORADNUM, TLE2_LEN_NORADNUM).c_str()))
return false;
return true;
/*
* make sure they match
*/
if (norad_1.compare(norad_2) != 0)
throw TleException("Norad numbers do not match.");
}
/*
* validate a line
*/
bool Tle::IsValidLine(const std::string& str, const unsigned char line_number) {
void Tle::IsValidLine(const std::string& str, const unsigned char line_number) {
static const std::string line1_pattern = "1 NNNNNC XXXXXXXX NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN";
/*
* 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) {
if (!ValidateLine(str, line1_pattern))
return false;
ValidateLine(str, line1_pattern);
} else if (2 == line_number) {
if (!ValidateLine(str, line2_pattern))
return false;
ValidateLine(str, line2_pattern);
} else {
return false;
throw TleException("Invalid line number to check.");
}
/*
@ -211,20 +217,23 @@ bool Tle::IsValidLine(const std::string& str, const unsigned char line_number) {
* if (chk != (str[TLE_LEN_LINE_DATA - 1] - '0'))
* return false;
*/
}
return true;
bool Tle::IsValidLineLength(const std::string& str) {
return str.length() == GetLineLength() ? true : false;
}
/*
* validate line given a pattern
*/
bool Tle::ValidateLine(const std::string& line, const std::string& pattern) {
void Tle::ValidateLine(const std::string& line, const std::string& pattern) {
/*
* check length of lines match
* check length of line
*/
if (line.length() < pattern.length()) {
return false;
if (!IsValidLineLength(line)) {
throw TleException("Invalid line length.");
}
std::string::const_iterator pattern_itr = pattern.begin();
@ -236,47 +245,67 @@ bool Tle::ValidateLine(const std::string& line, const std::string& pattern) {
*pattern_itr == '.') {
/*
* these characters should match exactly
* should match exactly
*/
if (*pattern_itr != *line_itr)
return false;
if (*pattern_itr != *line_itr) {
throw TleException("Invalid character.");
}
} else if (*pattern_itr == 'N') {
/*
* if pattern value is 'N' then either a number or a ' '
* 'N' = number or ' '
*/
if (!isdigit(*line_itr) && *line_itr != ' ')
return false;
if (!isdigit(*line_itr) && *line_itr != ' ') {
throw TleException("Invalid character.");
}
} else if (*pattern_itr == '+') {
/*
* if pattern value is '+' then either a '+' or '-' or ' ' or '0'
* '+' = '+' or '-' or ' ' or '0'
*/
if (*line_itr != '+' && *line_itr != '-' && *line_itr != ' ' && *line_itr != '0')
return false;
if (*line_itr != '+' && *line_itr != '-' && *line_itr != ' ' && *line_itr != '0') {
throw TleException("Invalid character.");
}
} else if (*pattern_itr == '-') {
/*
* if pattern value is '+' or '-'
* '-' = '+' or '-'
*/
if (*line_itr != '+' && *line_itr != '-')
return false;
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++;
}
return true;
}
/*
* compute checksum
*/
int Tle::CheckSum(const std::string& str) {
int Tle::CheckSum(const std::string & str) {
size_t len = str.size() - 1;
int xsum = 0;
@ -294,3 +323,28 @@ int Tle::CheckSum(const std::string& str) {
return (xsum % 10);
}
std::string Tle::ExtractNoradNumber(const std::string& str, const unsigned char 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;
}

11
Tle.h
View File

@ -3,6 +3,7 @@
#include "Globals.h"
#include "Julian.h"
#include "TleException.h"
#include <iostream>
@ -101,8 +102,8 @@ public:
static unsigned int GetLineLength() {
return TLE_LEN_LINE_DATA;
}
static bool IsValidPair(const std::string& line1, const std::string& line2);
static bool IsValidLine(const std::string& str, unsigned char line_number);
static void IsValidPair(const std::string& line1, const std::string& line2);
static void IsValidLine(const std::string& str, unsigned char line_number);
private:
/*
@ -116,12 +117,16 @@ private:
/*
* validate a line against a pattern
*/
static bool ValidateLine(const std::string& line, const std::string& 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, const unsigned char line_number);
static bool IsValidLineLength(const std::string& str);
private:
/*
* raw tle data

25
TleException.h Executable file
View File

@ -0,0 +1,25 @@
#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