Skip to content

Commit 880d8d0

Browse files
committed
Completed OMM and OMMDateTime objects
1 parent 1a4977a commit 880d8d0

File tree

8 files changed

+133
-70
lines changed

8 files changed

+133
-70
lines changed

plugins/Satellites/src/OMMDateTime.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ OMMDateTime::OMMDateTime()
2828
OMMDateTime::~OMMDateTime()
2929
{}
3030

31-
OMMDateTime::OMMDateTime(QString & s, Type t)
31+
OMMDateTime::OMMDateTime(const QString & s, Type t)
3232
{
3333
switch(t) {
3434
case STR_TLE:

plugins/Satellites/src/OMMDateTime.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@
3434

3535
#include <QString>
3636
#include <QDateTime>
37+
#include <QSharedPointer>
3738

3839
class OMMDateTime
3940
{
4041
public:
42+
typedef QSharedPointer<OMMDateTime> ShPtr;
43+
4144
enum Type {
4245
STR_TLE,
4346
STR_ISO8601
@@ -46,7 +49,7 @@ class OMMDateTime
4649
OMMDateTime();
4750
~OMMDateTime();
4851

49-
OMMDateTime(QString& s, Type t = STR_TLE);
52+
OMMDateTime(const QString& s, Type t = STR_TLE);
5053

5154
double getJulianDay() { return m_epoch_jd; }
5255

plugins/Satellites/src/omm.cpp

+52-31
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Stellarium
23
* Copyright (C) 2023 Andy Kirkham
34
*
45
* This program is free software; you can redistribute it and/or
@@ -23,8 +24,6 @@
2324

2425
#include "OMM.hpp"
2526

26-
namespace PluginSatellites {
27-
2827
OMM::OMM()
2928
{
3029
m_source_type = SourceType::Invalid;
@@ -44,7 +43,8 @@ OMM::OMM(QString & l1, QString & l2)
4443
m_source_type = SourceType::LegacyTle;
4544
m_line1 = l1;
4645
m_line2 = l2;
47-
processTleLegacy();
46+
processTleLegacyLine1();
47+
processTleLegacyLine2();
4848
}
4949

5050
OMM::OMM(QString& l0, QString& l1, QString& l2)
@@ -53,7 +53,9 @@ OMM::OMM(QString& l0, QString& l1, QString& l2)
5353
m_line0 = l0;
5454
m_line1 = l1;
5555
m_line2 = l2;
56-
processTleLegacy();
56+
processTleLegacyLine0();
57+
processTleLegacyLine1();
58+
processTleLegacyLine2();
5759
}
5860

5961
bool OMM::hasValidLegacyTleData()
@@ -108,10 +110,7 @@ bool OMM::setFromXML(QXmlStreamReader & r)
108110

109111
void OMM::processXmlElement(const QString & tag, const QString & val)
110112
{
111-
if (tag == "EPOCH") {
112-
m_epoch_str = val;
113-
m_epoch = QDateTime::fromString(val, "yyyy-MM-ddThh:mm:ss.zzzzzz");
114-
}
113+
if (tag == "EPOCH") m_sp_epoch = OMMDateTime::ShPtr(new OMMDateTime(val, OMMDateTime::STR_ISO8601));
115114
else if (tag == "OBJECT_NAME") m_object_name = val;
116115
else if (tag == "OBJECT_ID") m_object_id = val;
117116
else if (tag == "MEAN_MOTION") m_mean_motion = val.toDouble();
@@ -122,27 +121,56 @@ void OMM::processXmlElement(const QString & tag, const QString & val)
122121
else if (tag == "MEAN_ANOMALY") m_mean_anomoly = val.toDouble();
123122
else if (tag == "CLASSIFICATION_TYPE") m_classification = val.at(0).toUpper();
124123
else if (tag == "NORAD_CAT_ID") m_norad_cat_id = val.toInt();
125-
else if (tag == "ELEMENT_SET_NO") m_element_set_no = val.toInt();
124+
else if (tag == "ELEMENT_SET_NO") m_element_number = val.toInt();
126125
else if (tag == "REV_AT_EPOCH") m_rev_at_epoch = val.toInt();
127126
else if (tag == "BSTAR") m_bstar = val.toDouble();
128127
else if (tag == "MEAN_MOTION_DOT") m_mean_motion_dot = val.toDouble();
129128
else if (tag == "MEAN_MOTION_DDOT") m_mean_motion_ddot = val.toDouble();
130129
}
131130

132-
// Everything below here is for extracting the data from the two TLE lines.
131+
// Everything below here is for extracting the data from the legacy two line TLE format.
133132

134-
// J F M A M J J A S O N D
135-
static int month_lens[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
133+
void OMM::processTleLegacyLine0(void)
134+
{
135+
if (!m_line0.isEmpty()) {
136+
m_object_name = m_line0.trimmed();
137+
}
138+
}
136139

137140
// TLE Line1 field positions and lengths.
138141
static QPair<int, int> NORAD_CAT_ID(2,5);
139142
static QPair<int, int> CLASSIFICATION_TYPE(7,1);
140143
static QPair<int, int> OBJECT_ID(9, 8);
144+
static QPair<int, int> EPOCH(18, 14);
141145
static QPair<int, int> EPOCH_YEAR(18, 2);
142146
static QPair<int, int> EPOCH_DAY(20, 12);
143147
static QPair<int, int> MEAN_MOTION_DOT(33, 10);
144148
static QPair<int, int> MEAN_MOTION_DDOT(44, 8);
145149
static QPair<int, int> BSTAR(53, 8);
150+
static QPair<int, int> EPHEMERIS_TYPE(62, 1);
151+
static QPair<int, int> ELEMENT_NUMBER(64, 4);
152+
153+
void OMM::processTleLegacyLine1(void)
154+
{
155+
if (!m_line1.isEmpty() && m_line1.at(0) == '1') {
156+
auto epoch_str = m_line1.mid(EPOCH.first, EPOCH.second).trimmed();
157+
m_sp_epoch = OMMDateTime::ShPtr(new OMMDateTime(epoch_str));
158+
m_norad_cat_id = m_line1.mid(NORAD_CAT_ID.first, NORAD_CAT_ID.second).toInt();
159+
m_classification = m_line1.at(CLASSIFICATION_TYPE.first);
160+
m_object_id = m_line1.mid(OBJECT_ID.first, OBJECT_ID.second).trimmed();
161+
m_mean_motion_dot = m_line1.mid(33, 10).toDouble();
162+
QString ddot(".");
163+
ddot.append(m_line1.mid(44, 5));
164+
ddot.replace(QChar('-'), QString("e-"));
165+
m_mean_motion_ddot = ddot.toDouble();
166+
QString bstar(".");
167+
bstar.append(m_line1.mid(BSTAR.first, BSTAR.second).trimmed());
168+
bstar.replace(QChar('-'), QString("e-"));
169+
m_bstar = bstar.toDouble();
170+
m_ephermeris_type = m_line1.mid(EPHEMERIS_TYPE.first, EPHEMERIS_TYPE.second).trimmed().toInt();
171+
m_element_number = m_line1.mid(ELEMENT_NUMBER.first, ELEMENT_NUMBER.second).trimmed().toInt();
172+
}
173+
}
146174

147175
// TLE Line2 field positions and lengths.
148176
static QPair<int, int> INCLINATION(8, 8);
@@ -153,25 +181,18 @@ static QPair<int, int> MEAN_ANOMALY(43, 8);
153181
static QPair<int, int> MEAN_MOTION(52, 11);
154182
static QPair<int, int> REV_AT_EPOCH(63, 5);
155183

156-
void OMM::processTleLegacy(void)
184+
void OMM::processTleLegacyLine2(void)
157185
{
158-
if (m_line1.at(0) == '1') {
159-
m_norad_cat_id = m_line1.mid(NORAD_CAT_ID.first, NORAD_CAT_ID.second).toInt();
160-
m_classification = m_line1.at(CLASSIFICATION_TYPE.first);
161-
m_object_id = m_line1.mid(OBJECT_ID.first, OBJECT_ID.second).trimmed();
162-
int epoch_year = m_line1.mid(EPOCH_YEAR.first, EPOCH_YEAR.second).toInt();
163-
if (epoch_year < 57) epoch_year += 2000;
164-
else epoch_year += 1900;
165-
QDate year = QDate(epoch_year, 1, 1);
166-
double epoch_day = m_line1.mid(EPOCH_DAY.first, EPOCH_DAY.second).toDouble();
167-
int day = std::floor(epoch_day);
168-
169-
// 18-31 Epoch. Element Set Epoch (UTC) *Note: spaces are acceptable in columns 20 & 21
170-
m_mean_motion_dot = m_line1.mid(33, 10).toDouble();
171-
QString dec(".");
172-
dec.append(m_line1.mid(44, 5));
173-
m_mean_motion_ddot = dec.toDouble();
186+
if(!m_line2.isEmpty() && m_line2.at(0) == '2') {
187+
m_inclination = m_line2.mid(INCLINATION.first, INCLINATION.second).trimmed().toDouble();
188+
m_ascending_node = m_line2.mid(RA_OF_ASC_NODE.first, RA_OF_ASC_NODE.second).trimmed().toDouble();
189+
m_argument_perigee = m_line2.mid(ARG_OF_PERICENTER.first, ARG_OF_PERICENTER.second).trimmed().toDouble();
190+
QString ecc_s(".");
191+
ecc_s.append(m_line2.mid(ECCENTRICITY.first, ECCENTRICITY.second));
192+
m_eccentricity = ecc_s.trimmed().toDouble();
193+
m_mean_anomoly = m_line2.mid(MEAN_ANOMALY.first, MEAN_ANOMALY.second).trimmed().toDouble();
194+
m_mean_motion = m_line2.mid(MEAN_MOTION.first, MEAN_MOTION.second).trimmed().toDouble();
195+
m_rev_at_epoch = m_line2.mid(REV_AT_EPOCH.first, REV_AT_EPOCH.second).trimmed().toInt();
196+
174197
}
175198
}
176-
177-
} // end namespace PluginSatellites

plugins/Satellites/src/omm.hpp

+10-12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include <QSharedPointer>
2727
#include <QXmlStreamReader>
2828

29-
namespace PluginSatellites {
29+
#include "OMMDateTime.hpp"
3030

3131
class OMM
3232
{
@@ -61,18 +61,18 @@ class OMM
6161

6262
virtual SourceType getSourceType() { return m_source_type; }
6363

64-
virtual QDateTime getEpoch() { return m_epoch; }
65-
virtual const QString& getEpochStr() { return m_epoch_str; }
64+
virtual OMMDateTime::ShPtr getEpoch() { return m_sp_epoch; }
6665
virtual double getMeanMotion() { return m_mean_motion; }
6766
virtual double getEccentricity() { return m_eccentricity; }
6867
virtual double getInclination() { return m_inclination; }
6968
virtual double getAscendingNode() { return m_ascending_node; }
7069
virtual double getArgumentOfPerigee() { return m_argument_perigee; }
7170
virtual double getMeanAnomoly() { return m_mean_anomoly; }
71+
virtual int getEphermisType() { return m_ephermeris_type; }
72+
virtual int getElementNumber() { return m_element_number; }
7273

7374
virtual QChar getClassification() { return m_classification; }
7475
virtual int getNoradcatId() { return m_norad_cat_id; }
75-
virtual int getElementSetNo() { return m_element_set_no; }
7676
virtual int getRevAtEpoch() { return m_rev_at_epoch; }
7777
virtual double getBstar() { return m_bstar; }
7878
virtual double getMeanMotionDot() { return m_mean_motion_dot; }
@@ -82,7 +82,9 @@ class OMM
8282
virtual const QString& getObjectId() { return m_object_id; }
8383

8484
private:
85-
void processTleLegacy(void);
85+
void processTleLegacyLine0(void);
86+
void processTleLegacyLine1(void);
87+
void processTleLegacyLine2(void);
8688
void processXmlElement(const QString& tag, const QString& val);
8789

8890
SourceType m_source_type;
@@ -93,7 +95,7 @@ class OMM
9395
QString m_line2{};
9496

9597
// Mean elements.
96-
QDateTime m_epoch{};
98+
OMMDateTime::ShPtr m_sp_epoch{};
9799
double m_mean_motion{};
98100
double m_eccentricity{};
99101
double m_inclination{};
@@ -104,20 +106,16 @@ class OMM
104106
// TLE parameters.
105107
QChar m_classification{};
106108
int m_norad_cat_id{};
107-
int m_element_set_no{};
108109
int m_rev_at_epoch{};
109110
double m_bstar{};
110111
double m_mean_motion_dot{};
111112
double m_mean_motion_ddot{};
113+
int m_ephermeris_type{};
114+
int m_element_number{};
112115

113116
// Metadata
114117
QString m_object_name{};
115118
QString m_object_id{};
116-
117-
// Misc data.
118-
QString m_epoch_str;
119119
};
120120

121-
} // end namespace PluginSatellites
122-
123121
#endif

plugins/Satellites/src/test/testOMM.cpp

+52-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Stellarium
23
* Copyright (C) 2023 Andy Kirkham
34
*
45
* This program is free software; you can redistribute it and/or
@@ -27,28 +28,65 @@ QTEST_GUILESS_MAIN(TestOMM)
2728
void TestOMM::testLegacyTle()
2829
{
2930
QString l0("ISS (ZARYA)");
30-
QString l1("1 25544U 98067A 23187.34555919 .00007611 00000+0 14335-3 0 9995");
31+
// 1 2 3 4 5 6 7
32+
// 01234567890123456789012345678901234567890123456789012345678901234567890
33+
QString l1("1 25544U 98067A 23191.40640406 .00007611 00000+0 14335-3 0 9995");
3134
QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764");
32-
PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(l0, l1, l2));
33-
QVERIFY(dut->getSourceType() == PluginSatellites::OMM::SourceType::LegacyTle);
35+
OMM::ShPtr dut(new OMM(l0, l1, l2));
36+
QVERIFY(dut->getSourceType() == OMM::SourceType::LegacyTle);
3437
QVERIFY(dut->hasValidLegacyTleData() == true);
3538
QVERIFY(dut->getLine0() == l0);
3639
QVERIFY(dut->getLine1() == l1);
3740
QVERIFY(dut->getLine2() == l2);
3841
}
3942

40-
void TestOMM::testProcessTleLegacy()
43+
void TestOMM::testProcessTleLegacyLine0()
4144
{
4245
QString l0("ISS (ZARYA)");
43-
QString l1("1 25544U 98067A 23187.34555919 .00007611 00000+0 14335-3 0 9995");
46+
// 1 2 3 4 5 6 7
47+
// 01234567890123456789012345678901234567890123456789012345678901234567890
48+
QString l1("1 25544U 98067A 23191.40640406 .00007611 00000+0 14335-3 0 9995");
4449
QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764");
45-
PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(l0, l1, l2));
50+
OMM::ShPtr dut(new OMM(l0, l1, l2));
51+
QCOMPARE(dut->getObjectName(), "ISS (ZARYA)");
52+
}
53+
54+
void TestOMM::testProcessTleLegacyLine1()
55+
{
56+
QString l0("ISS (ZARYA)");
57+
// 1 2 3 4 5 6 7
58+
// 01234567890123456789012345678901234567890123456789012345678901234567890
59+
QString l1("1 25544U 98067A 23191.40640406 .00007611 00000+0 14335-3 0 9995");
60+
QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764");
61+
OMM::ShPtr dut(new OMM(l0, l1, l2));
4662
QVERIFY(dut->getNoradcatId() == 25544);
4763
QVERIFY(dut->getClassification() == 'U');
4864
QCOMPARE(dut->getObjectId(), QString("98067A"));
49-
// ToDo, Epoch
5065
QCOMPARE(dut->getMeanMotionDot(), 0.00007611);
5166
QCOMPARE(dut->getMeanMotionDDot(), 0.0);
67+
68+
auto jd_of_epoch = dut->getEpoch()->getJulian();
69+
QCOMPARE(jd_of_epoch, 2460135.906404059846);
70+
QCOMPARE(dut->getBstar(), 0.00014334999999999998785);
71+
QVERIFY(dut->getEphermisType() == 0);
72+
QVERIFY(dut->getElementNumber() == 999);
73+
}
74+
75+
void TestOMM::testProcessTleLegacyLine2()
76+
{
77+
QString l0("ISS (ZARYA)");
78+
// 1 2 3 4 5 6 7
79+
// 01234567890123456789012345678901234567890123456789012345678901234567890
80+
QString l1("1 25544U 98067A 23191.40640406 .00007611 00000+0 14335-3 0 9995");
81+
QString l2("2 25544 51.6398 233.5611 0000373 12.3897 91.4664 15.49560249404764");
82+
OMM::ShPtr dut(new OMM(l0, l1, l2));
83+
QCOMPARE(dut->getInclination(), 51.6398);
84+
QCOMPARE(dut->getAscendingNode(), 233.5611);
85+
QCOMPARE(dut->getArgumentOfPerigee(), 12.3897);
86+
QCOMPARE(dut->getEccentricity(), 0.0000373);
87+
QCOMPARE(dut->getMeanAnomoly(), 91.4664);
88+
QCOMPARE(dut->getMeanMotion(), 15.49560249);
89+
QCOMPARE(dut->getRevAtEpoch(), 40476);
5290
}
5391

5492
void TestOMM::testXMLread()
@@ -61,10 +99,10 @@ void TestOMM::testXMLread()
6199
QVector<int> expectNorad = {
62100
25544, 43557, 47853
63101
};
64-
QVector<QString> expectEpoch = {
65-
QString("2023-07-06T08:17:36.314016"),
66-
QString("2023-07-06T01:58:30.910944"),
67-
QString("2023-07-04T18:34:04.881504")
102+
QVector<double> expectEpoch = {
103+
2460135.906404059846,
104+
2460135.906404059846,
105+
2460135.906404059846
68106
};
69107
int idx = 0;
70108
bool testContinue = true;
@@ -79,12 +117,11 @@ void TestOMM::testXMLread()
79117
while (testContinue && !r.atEnd()) {
80118
QString tag = r.name().toString();
81119
if (r.isStartElement() && tag.toLower() == "omm") {
82-
PluginSatellites::OMM::ShPtr dut(new PluginSatellites::OMM(r));
120+
OMM::ShPtr dut(new OMM(r));
83121
QVERIFY(dut->getObjectId() == expectOjectId[idx]);
84122
QVERIFY(dut->getNoradcatId() == expectNorad[idx]);
85-
QVERIFY(dut->getEpochStr() == expectEpoch[idx]);
86-
QDateTime ep = QDateTime::fromString(expectEpoch[idx]);
87-
QVERIFY(dut->getEpoch() == ep);
123+
auto jd_of_epoch = dut->getEpoch()->getJulian();
124+
QCOMPARE(jd_of_epoch, expectEpoch[idx]);
88125
idx++;
89126
}
90127
r.readNext();

plugins/Satellites/src/test/testOMM.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Stellarium
23
* Copyright (C) 2023 Andy Kirkham
34
*
45
* This program is free software; you can redistribute it and/or
@@ -29,7 +30,9 @@ class TestOMM : public QObject
2930
private slots:
3031
void testLegacyTle();
3132
void testXMLread();
32-
void testProcessTleLegacy();
33+
void testProcessTleLegacyLine0();
34+
void testProcessTleLegacyLine1();
35+
void testProcessTleLegacyLine2();
3336
};
3437

3538
#endif // TESTOMM_HPP

0 commit comments

Comments
 (0)