From a954bab1cedc52b961e6210a2f805f2f56840977 Mon Sep 17 00:00:00 2001 From: A-j-K Date: Mon, 10 Jul 2023 20:07:21 +0100 Subject: [PATCH] Add OMMDateTime object and UTs --- plugins/Satellites/src/CMakeLists.txt | 6 +- plugins/Satellites/src/OMMDateTime.cpp | 97 ++++++++++++ plugins/Satellites/src/OMMDateTime.hpp | 65 +++++++++ plugins/Satellites/src/omm.cpp | 138 ++++++++++-------- plugins/Satellites/src/omm.hpp | 26 ++-- plugins/Satellites/src/test/CMakeLists.txt | 9 +- plugins/Satellites/src/test/testOMM.cpp | 40 +++-- plugins/Satellites/src/test/testOMM.hpp | 5 +- .../Satellites/src/test/testOMMDateTime.cpp | 57 ++++++++ .../Satellites/src/test/testOMMDateTime.hpp | 35 +++++ 10 files changed, 388 insertions(+), 90 deletions(-) create mode 100644 plugins/Satellites/src/OMMDateTime.cpp create mode 100644 plugins/Satellites/src/OMMDateTime.hpp create mode 100644 plugins/Satellites/src/test/testOMMDateTime.cpp create mode 100644 plugins/Satellites/src/test/testOMMDateTime.hpp diff --git a/plugins/Satellites/src/CMakeLists.txt b/plugins/Satellites/src/CMakeLists.txt index 136396134d95a3..34fdce33b6b456 100644 --- a/plugins/Satellites/src/CMakeLists.txt +++ b/plugins/Satellites/src/CMakeLists.txt @@ -20,8 +20,10 @@ SET(Satellites_SRCS gsatellite/SGP4.h gsatellite/SGP4.cpp - omm.hpp - omm.cpp + OMM.hpp + OMM.cpp + OMMDateTime.hpp + OMMDateTime.cpp gSatWrapper.hpp gSatWrapper.cpp Satellite.hpp diff --git a/plugins/Satellites/src/OMMDateTime.cpp b/plugins/Satellites/src/OMMDateTime.cpp new file mode 100644 index 00000000000000..2c8f9e6bc194bc --- /dev/null +++ b/plugins/Satellites/src/OMMDateTime.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2023 Andy Kirkham + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +#include +#include +#include + +#include "OMMDateTime.hpp" + +OMMDateTime::OMMDateTime() +{} + +OMMDateTime::~OMMDateTime() +{} + +OMMDateTime::OMMDateTime(QString & s, Type t) +{ + switch(t) { + case STR_TLE: + ctorTle(s); + break; + case STR_ISO8601: + ctorISO(s); + break; + default: + break; + } +} + +// From SGP4.cpp +static void jday_SGP4(int year, int mon, int day, int hr, int minute, double sec, double & jd, double & jdFrac) +{ + jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) + floor(275 * mon / 9.0) + day + + 1721013.5; // use - 678987.0 to go to mjd directly + jdFrac = (sec + minute * 60.0 + hr * 3600.0) / 86400.0; + if (fabs(jdFrac) > 1.0) { + double dtt = floor(jdFrac); + jd = jd + dtt; + jdFrac = jdFrac - dtt; + } +} + +void OMMDateTime::ctorTle(const QString & s) +{ + int year = s.mid(0, 2).toInt(); + double day = s.mid(2).toDouble(); + int whole_day = std::floor(day); + double frac_day = day - whole_day; + + // Create a QDate. + year += (year < 57) ? 2000 : 1900; + QDate d(year, 1, 1); + d = d.addDays(whole_day - 1); // Minus 1 because we start on 1st Jan. + + // Create the time. + double seconds = (24 * 60 * 60) * frac_day; + int whole_hours = std::floor(seconds / 3600); + seconds -= whole_hours * 3600; + int whole_mins = std::floor(seconds / 60); + seconds -= whole_mins * 60; + + jday_SGP4(d.year(), d.month(), d.day(), whole_hours, whole_mins, seconds, m_epoch_jd, m_epoch_jd_frac); +} + +void OMMDateTime::ctorISO(const QString & s) +{ + QDateTime d = QDateTime::fromString(s, Qt::ISODate); + int year = d.date().year(); + int mon = d.date().month(); + int day = d.date().day(); + int hour = d.time().hour(); + int min = d.time().minute(); + double sec = d.time().second(); + auto decimal = s.indexOf(QChar('.')); + if(decimal > 0) { + auto frac_s = s.mid(decimal); + double frac_d = frac_s.toDouble(); + sec += frac_d; + } + jday_SGP4(year, mon, day, hour, min, sec, m_epoch_jd, m_epoch_jd_frac); +} + diff --git a/plugins/Satellites/src/OMMDateTime.hpp b/plugins/Satellites/src/OMMDateTime.hpp new file mode 100644 index 00000000000000..81230a516c609d --- /dev/null +++ b/plugins/Satellites/src/OMMDateTime.hpp @@ -0,0 +1,65 @@ +/* + * Stellarium + * Copyright (C) 2023 Andy Kirkham + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +/* + * The standard QDateTime type only stores to the millisecond but + * satellite propargation models use to microsecond timimg. + * For Stellarium display purposes millisecond accuracy is + * probably good enough. However, the Unit Tests source data + * expectations from common SGP4 models and therefore fail to + * agree to routines that do not account for microsecond timing. + * This class therefore is to allow for us timings. + * + * Epoch times are stored as JD and JDF. + */ + +#ifndef SATELLITES_OMMDATETIME_HPP +#define SATELLITES_OMMDATETIME_HPP + +#include +#include + +class OMMDateTime +{ +public: + enum Type { + STR_TLE, + STR_ISO8601 + }; + + OMMDateTime(); + ~OMMDateTime(); + + OMMDateTime(QString& s, Type t = STR_TLE); + + double getJulianDay() { return m_epoch_jd; } + + double getJulianFrac() { return m_epoch_jd_frac; } + + double getJulian() { return m_epoch_jd + m_epoch_jd_frac; } + +private: + void ctorTle(const QString & s); + void ctorISO(const QString & s); + + double m_epoch_jd{}; + double m_epoch_jd_frac{}; +}; + +#endif diff --git a/plugins/Satellites/src/omm.cpp b/plugins/Satellites/src/omm.cpp index cb9c6245cab97d..a7cb04f0986d66 100644 --- a/plugins/Satellites/src/omm.cpp +++ b/plugins/Satellites/src/omm.cpp @@ -16,42 +16,47 @@ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ +#include + +#include #include -#include "omm.hpp" +#include "OMM.hpp" namespace PluginSatellites { -omm::omm() +OMM::OMM() { m_source_type = SourceType::Invalid; } -omm::~omm() +OMM::~OMM() {} -omm::omm(QXmlStreamReader& r) +OMM::OMM(QXmlStreamReader& r) { m_source_type = SourceType::Invalid; setFromXML(r); } -omm::omm(QString & l1, QString & l2) +OMM::OMM(QString & l1, QString & l2) { m_source_type = SourceType::LegacyTle; m_line1 = l1; m_line2 = l2; + processTleLegacy(); } -omm::omm(QString& l0, QString& l1, QString& l2) +OMM::OMM(QString& l0, QString& l1, QString& l2) { m_source_type = SourceType::LegacyTle; m_line0 = l0; m_line1 = l1; m_line2 = l2; + processTleLegacy(); } -bool omm::hasValidLegacyTleData() +bool OMM::hasValidLegacyTleData() { if(m_source_type == SourceType::LegacyTle) { if(m_line1.startsWith('1') && m_line2.startsWith('2')) { @@ -61,28 +66,30 @@ bool omm::hasValidLegacyTleData() return false; } -bool omm::setFromXML(QXmlStreamReader & r) +bool OMM::setFromXML(QXmlStreamReader & r) { if (r.name().toString().toLower() == "omm") { bool collectChars = false; QString savedTag; QString savedVal; m_source_type = SourceType::Xml; - r.readNext(); // Advance past starting tag. + r.readNext(); // Advance past starting tag. while (!r.hasError() && !r.atEnd()) { QString tag = r.name().toString(); if (tag.toLower() == "omm") { - // Detected closing tag. + // Detected closing tag. return true; } if (r.isStartElement()) { collectChars = true; savedTag = tag.toUpper(); savedVal = ""; - } else if (collectChars) { + } + else if (collectChars) { if (r.isCharacters()) { savedVal += r.text(); - } else if (r.isEndElement()) { + } + else if (r.isEndElement()) { processXmlElement(savedTag, savedVal); collectChars = false; savedVal = ""; @@ -99,56 +106,71 @@ bool omm::setFromXML(QXmlStreamReader & r) return false; } -void omm::processXmlElement(const QString & tag, const QString & val) +void OMM::processXmlElement(const QString & tag, const QString & val) { - if (tag == "OBJECT_NAME") { - m_object_name = val; - } - else if (tag == "OBJECT_ID") { - m_object_id = val; - } - else if (tag == "EPOCH") { + if (tag == "EPOCH") { m_epoch_str = val; m_epoch = QDateTime::fromString(val, "yyyy-MM-ddThh:mm:ss.zzzzzz"); } - else if (tag == "MEAN_MOTION") { - m_mean_motion = val.toDouble(); - } - else if (tag == "ECCENTRICITY") { - m_eccentricity = val.toDouble(); - } - else if (tag == "INCLINATION") { - m_inclination = val.toDouble(); - } - else if (tag == "RA_OF_ASC_NODE") { - m_ascending_node = val.toDouble(); - } - else if (tag == "ARG_OF_PERICENTER") { - m_argument_perigee = val.toDouble(); - } - else if (tag == "MEAN_ANOMALY") { - m_mean_anomoly = val.toDouble(); - } - else if (tag == "CLASSIFICATION_TYPE") { - m_classification = val.at(0).toUpper(); - } - else if (tag == "NORAD_CAT_ID") { - m_norad_cat_id = val.toInt(); - } - else if (tag == "ELEMENT_SET_NO") { - m_element_set_no = val.toInt(); - } - else if (tag == "REV_AT_EPOCH") { - m_rev_at_epoch = val.toInt(); - } - else if (tag == "BSTAR") { - m_bstar = val.toDouble(); - } - else if (tag == "MEAN_MOTION_DOT") { - m_mean_motion_dot = val.toDouble(); - } - else if (tag == "MEAN_MOTION_DDOT") { - m_mean_motion_ddot = val.toDouble(); + else if (tag == "OBJECT_NAME") m_object_name = val; + else if (tag == "OBJECT_ID") m_object_id = val; + else if (tag == "MEAN_MOTION") m_mean_motion = val.toDouble(); + else if (tag == "ECCENTRICITY") m_eccentricity = val.toDouble(); + else if (tag == "INCLINATION") m_inclination = val.toDouble(); + else if (tag == "RA_OF_ASC_NODE") m_ascending_node = val.toDouble(); + else if (tag == "ARG_OF_PERICENTER") m_argument_perigee = val.toDouble(); + else if (tag == "MEAN_ANOMALY") m_mean_anomoly = val.toDouble(); + else if (tag == "CLASSIFICATION_TYPE") m_classification = val.at(0).toUpper(); + else if (tag == "NORAD_CAT_ID") m_norad_cat_id = val.toInt(); + else if (tag == "ELEMENT_SET_NO") m_element_set_no = val.toInt(); + else if (tag == "REV_AT_EPOCH") m_rev_at_epoch = val.toInt(); + else if (tag == "BSTAR") m_bstar = val.toDouble(); + else if (tag == "MEAN_MOTION_DOT") m_mean_motion_dot = val.toDouble(); + else if (tag == "MEAN_MOTION_DDOT") m_mean_motion_ddot = val.toDouble(); +} + +// Everything below here is for extracting the data from the two TLE lines. + +// J F M A M J J A S O N D +static int month_lens[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +// TLE Line1 field positions and lengths. +static QPair NORAD_CAT_ID(2,5); +static QPair CLASSIFICATION_TYPE(7,1); +static QPair OBJECT_ID(9, 8); +static QPair EPOCH_YEAR(18, 2); +static QPair EPOCH_DAY(20, 12); +static QPair MEAN_MOTION_DOT(33, 10); +static QPair MEAN_MOTION_DDOT(44, 8); +static QPair BSTAR(53, 8); + +// TLE Line2 field positions and lengths. +static QPair INCLINATION(8, 8); +static QPair RA_OF_ASC_NODE(17, 8); +static QPair ECCENTRICITY(26, 7); +static QPair ARG_OF_PERICENTER(34, 8); +static QPair MEAN_ANOMALY(43, 8); +static QPair MEAN_MOTION(52, 11); +static QPair REV_AT_EPOCH(63, 5); + +void OMM::processTleLegacy(void) +{ + if (m_line1.at(0) == '1') { + m_norad_cat_id = m_line1.mid(NORAD_CAT_ID.first, NORAD_CAT_ID.second).toInt(); + m_classification = m_line1.at(CLASSIFICATION_TYPE.first); + m_object_id = m_line1.mid(OBJECT_ID.first, OBJECT_ID.second).trimmed(); + int epoch_year = m_line1.mid(EPOCH_YEAR.first, EPOCH_YEAR.second).toInt(); + if (epoch_year < 57) epoch_year += 2000; + else epoch_year += 1900; + QDate year = QDate(epoch_year, 1, 1); + double epoch_day = m_line1.mid(EPOCH_DAY.first, EPOCH_DAY.second).toDouble(); + int day = std::floor(epoch_day); + + // 18-31 Epoch. Element Set Epoch (UTC) *Note: spaces are acceptable in columns 20 & 21 + m_mean_motion_dot = m_line1.mid(33, 10).toDouble(); + QString dec("."); + dec.append(m_line1.mid(44, 5)); + m_mean_motion_ddot = dec.toDouble(); } } diff --git a/plugins/Satellites/src/omm.hpp b/plugins/Satellites/src/omm.hpp index 99658912e9c109..4106bf937fbda1 100644 --- a/plugins/Satellites/src/omm.hpp +++ b/plugins/Satellites/src/omm.hpp @@ -23,33 +23,33 @@ #include #include #include +#include #include namespace PluginSatellites { -class omm +class OMM { -private: - omm(); // Make default constructor unavailable. - public: + typedef QSharedPointer ShPtr; + enum class SourceType { Invalid, LegacyTle, Xml }; - // Allowed constructors. - omm(QXmlStreamReader& r); - omm(QString &, QString &); - omm(QString&, QString&, QString&); + OMM(); + OMM(QXmlStreamReader& r); + OMM(QString&, QString&); + OMM(QString&, QString&, QString&); // Destructor. - virtual ~omm(); + virtual ~OMM(); - //virtual omm& setLine0(const QString& s) { m_line0 = s; return *this; } - //virtual omm& setLine1(const QString& s) { m_line1 = s; return *this; } - //virtual omm& setLine2(const QString& s) { m_line2 = s; return *this; } + virtual OMM& setLine0(const QString& s) { m_line0 = s; return *this; } + virtual OMM& setLine1(const QString& s) { m_line1 = s; return *this; } + virtual OMM& setLine2(const QString& s) { m_line2 = s; return *this; } virtual const QString& getLine0() { return m_line0; } virtual const QString& getLine1() { return m_line1; } @@ -82,7 +82,7 @@ class omm virtual const QString& getObjectId() { return m_object_id; } private: - + void processTleLegacy(void); void processXmlElement(const QString& tag, const QString& val); SourceType m_source_type; diff --git a/plugins/Satellites/src/test/CMakeLists.txt b/plugins/Satellites/src/test/CMakeLists.txt index 66c1329e750273..5208ce09386ef7 100644 --- a/plugins/Satellites/src/test/CMakeLists.txt +++ b/plugins/Satellites/src/test/CMakeLists.txt @@ -10,6 +10,11 @@ SET_TARGET_PROPERTIES(testSatellites PROPERTIES FOLDER "plugins/Satellites/test" ADD_EXECUTABLE(testOMM testOMM.cpp testOMM.hpp) TARGET_LINK_LIBRARIES(testOMM Qt${QT_VERSION_MAJOR}::Test Satellites-static stelMain) -ADD_TEST(NAME OMM COMMAND testOMM) +ADD_TEST(testOMM testOMM) SET_TARGET_PROPERTIES(testOMM PROPERTIES FOLDER "plugins/Satellites/test") -FILE(COPY "${CMAKE_SOURCE_DIR}/plugins/Satellites/src/test/test_data.xml" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file +FILE(COPY "${CMAKE_SOURCE_DIR}/plugins/Satellites/src/test/test_data.xml" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") + +ADD_EXECUTABLE(testOMMDateTime testOMMDateTime.cpp testOMMDateTime.hpp) +TARGET_LINK_LIBRARIES(testOMMDateTime Qt${QT_VERSION_MAJOR}::Test Satellites-static stelMain) +ADD_TEST(testOMMDateTime testOMMDateTime) +SET_TARGET_PROPERTIES(testOMMDateTime PROPERTIES FOLDER "plugins/Satellites/test") \ No newline at end of file diff --git a/plugins/Satellites/src/test/testOMM.cpp b/plugins/Satellites/src/test/testOMM.cpp index 2e20a8b7261b63..22586d0c92504f 100644 --- a/plugins/Satellites/src/test/testOMM.cpp +++ b/plugins/Satellites/src/test/testOMM.cpp @@ -27,14 +27,28 @@ QTEST_GUILESS_MAIN(TestOMM) void TestOMM::testLegacyTle() { QString l0("ISS (ZARYA)"); - QString l1("1 25544U 98067A 23190.18395514 .00010525 00000-0 19463-3 0 9990"); - QString l2("2 25544 51.6405 219.5048 0000226 85.5338 22.9089 15.49626907405204"); - PluginSatellites::omm dut(l0, l1, l2); - QVERIFY(dut.getSourceType() == PluginSatellites::omm::SourceType::LegacyTle); - QVERIFY(dut.hasValidLegacyTleData() == true); - QVERIFY(dut.getLine0() == l0); - QVERIFY(dut.getLine1() == l1); - QVERIFY(dut.getLine2() == l2); + QString l1("1 25544U 98067A 23187.34555919 .00007611 00000+0 14335-3 0 9995"); + QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764"); + PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(l0, l1, l2)); + QVERIFY(dut->getSourceType() == PluginSatellites::OMM::SourceType::LegacyTle); + QVERIFY(dut->hasValidLegacyTleData() == true); + QVERIFY(dut->getLine0() == l0); + QVERIFY(dut->getLine1() == l1); + QVERIFY(dut->getLine2() == l2); +} + +void TestOMM::testProcessTleLegacy() +{ + QString l0("ISS (ZARYA)"); + QString l1("1 25544U 98067A 23187.34555919 .00007611 00000+0 14335-3 0 9995"); + QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764"); + PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(l0, l1, l2)); + QVERIFY(dut->getNoradcatId() == 25544); + QVERIFY(dut->getClassification() == 'U'); + QCOMPARE(dut->getObjectId(), QString("98067A")); + // ToDo, Epoch + QCOMPARE(dut->getMeanMotionDot(), 0.00007611); + QCOMPARE(dut->getMeanMotionDDot(), 0.0); } void TestOMM::testXMLread() @@ -65,12 +79,12 @@ void TestOMM::testXMLread() while (testContinue && !r.atEnd()) { QString tag = r.name().toString(); if (r.isStartElement() && tag.toLower() == "omm") { - PluginSatellites::omm dut(r); - QVERIFY(dut.getObjectId() == expectOjectId[idx]); - QVERIFY(dut.getNoradcatId() == expectNorad[idx]); - QVERIFY(dut.getEpochStr() == expectEpoch[idx]); + PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(r)); + QVERIFY(dut->getObjectId() == expectOjectId[idx]); + QVERIFY(dut->getNoradcatId() == expectNorad[idx]); + QVERIFY(dut->getEpochStr() == expectEpoch[idx]); QDateTime ep = QDateTime::fromString(expectEpoch[idx]); - QVERIFY(dut.getEpoch() == ep); + QVERIFY(dut->getEpoch() == ep); idx++; } r.readNext(); diff --git a/plugins/Satellites/src/test/testOMM.hpp b/plugins/Satellites/src/test/testOMM.hpp index 6e0465df32a954..32744dfad4640b 100644 --- a/plugins/Satellites/src/test/testOMM.hpp +++ b/plugins/Satellites/src/test/testOMM.hpp @@ -21,14 +21,15 @@ #include -#include "omm.hpp" +#include "OMM.hpp" class TestOMM : public QObject { -Q_OBJECT + Q_OBJECT private slots: void testLegacyTle(); void testXMLread(); + void testProcessTleLegacy(); }; #endif // TESTOMM_HPP diff --git a/plugins/Satellites/src/test/testOMMDateTime.cpp b/plugins/Satellites/src/test/testOMMDateTime.cpp new file mode 100644 index 00000000000000..069a8fc5f3e05c --- /dev/null +++ b/plugins/Satellites/src/test/testOMMDateTime.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 Andy Kirkham + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +#include + +#include "testOMMDateTime.hpp" + +QTEST_GUILESS_MAIN(TestOMMDateTime) + +void TestOMMDateTime::testEpoch_DEFAULT() +{ + QString epoch("23191.40640406"); // 2023-07-10T09:45:13.310784 :: JD 2460135.90640406 + OMMDateTime dut(epoch); // Assume TLE formatted string for ctor. +#ifdef _DEBUG + qDebug() << "2023-07-10T09:45:13.310784"; + qDebug() << std::fixed << qSetRealNumberPrecision(16) << dut.getJulian(); +#endif + QVERIFY(dut.getJulian() == 2460135.90640406); +} + +void TestOMMDateTime::testEpoch_TLE() +{ + QString epoch("23191.40640406"); // 2023-07-10T09:45:13.310784 :: JD 2460135.90640406 + OMMDateTime dut(epoch, OMMDateTime::STR_TLE); +#ifdef _DEBUG + qDebug() << "2023-07-10T09:45:13.310784"; + qDebug() << std::fixed << qSetRealNumberPrecision(16) << dut.getJulian(); +#endif + QVERIFY(dut.getJulian() == 2460135.90640406); +} + +void TestOMMDateTime::testEpoch_ISO() +{ + QString epoch("2023-07-10T09:45:13.310784"); // JD 2460135.90640406 + OMMDateTime dut(epoch, OMMDateTime::STR_ISO8601); +#ifdef _DEBUG + qDebug() << "2023-07-10T09:45:13.310784"; + qDebug() << std::fixed << qSetRealNumberPrecision(16) << dut.getJulian(); +#endif + QVERIFY(dut.getJulian() == 2460135.90640406); +} + diff --git a/plugins/Satellites/src/test/testOMMDateTime.hpp b/plugins/Satellites/src/test/testOMMDateTime.hpp new file mode 100644 index 00000000000000..3874f2bfd9358a --- /dev/null +++ b/plugins/Satellites/src/test/testOMMDateTime.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 Andy Kirkham + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. + */ + +#ifndef TESTOMMDATETIME_HPP +#define TESTOMMDATETIME_HPP + +#include + +#include "OMMDateTime.hpp" + +class TestOMMDateTime : public QObject +{ + Q_OBJECT +private slots: + void testEpoch_DEFAULT(); + void testEpoch_TLE(); + void testEpoch_ISO(); +}; + +#endif // TESTDATETIME_HPP