forked from berthubert/galmon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tle.cc
118 lines (98 loc) · 3.13 KB
/
tle.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "tle.hh"
#include "SGP4.h"
#include <iostream>
#include <fstream>
using namespace std;
static void trim(std::string& str)
{
auto pos = str.find_first_of("\r\n");
if(pos != string::npos)
str.resize(pos);
pos = str.find_last_not_of(" \t");
if(pos != string::npos)
str.resize(pos+1);
}
void TLERepo::parseFile(std::string_view fname)
{
ifstream ifs(&fname[0]);
string name, line1, line2;
for(;;) {
if(!getline(ifs, name) || !getline(ifs, line1) || !getline(ifs, line2))
break;
trim(name);
trim(line1);
trim(line2);
Tle tle(line1, line2);
/*
cout<<"name: "<<name<<endl;
cout<<"line1: "<<line1<<endl;
cout<<"line2: "<<line2<<endl;
cout << tle.ToString() << endl;
*/
auto sgp4 = std::make_unique<std::tuple<SGP4, Tle>>(SGP4(tle), tle);
d_sgp4s[name] = std::move(sgp4);
}
}
TLERepo::TLERepo()
{}
TLERepo::~TLERepo()
{}
static TLERepo::Match makeMatch(const DateTime& d, const SGP4& sgp4, const Tle& tle, string name, double distance)
{
TLERepo::Match m;
m.name=name;
m.norad = tle.NoradNumber();
m.internat = tle.IntDesignator();
m.inclination = tle.Inclination(false);
m.ran = tle.RightAscendingNode(false);
m.e = tle.Eccentricity();
m.distance = distance;
auto eci = sgp4.FindPosition(d);
double theta = -eci.GetDateTime().ToGreenwichSiderealTime();
Vector rot = eci.Position();
m.eciX = 1000.0*rot.x;
m.eciY = 1000.0*rot.y;
m.eciZ = 1000.0*rot.z;
rot.x = eci.Position().x * cos(theta) - eci.Position().y * sin(theta);
rot.y = eci.Position().x * sin(theta) + eci.Position().y * cos(theta);
m.ecefX = 1000.0 * rot.x;
m.ecefY = 1000.0 * rot.y;
m.ecefZ = 1000.0 * rot.z;
auto geod = eci.ToGeodetic();
m.latitude = geod.latitude;
m.longitude = geod.longitude;
m.altitude = geod.altitude;
return m;
}
TLERepo::Match TLERepo::getBestMatch(time_t now, double x, double y, double z, TLERepo::Match* secondbest)
{
struct tm tm;
gmtime_r(&now, &tm);
DateTime d(1900 + tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
Vector sat(x/1000.0, y/1000.0, z/1000.0);
multimap<double, string> distances;
for(const auto& sgp4 : d_sgp4s) {
try {
auto eci = get<0>(*sgp4.second).FindPosition(d);
double theta = -eci.GetDateTime().ToGreenwichSiderealTime();
Vector rot = eci.Position();
rot.x = eci.Position().x * cos(theta) - eci.Position().y * sin(theta);
rot.y = eci.Position().x * sin(theta) + eci.Position().y * cos(theta);
distances.insert({1000.0*(rot - sat).Magnitude(),sgp4.first});
}
catch(SatelliteException& se) {
// cerr<<"TLE error: "<<se.what()<<endl;
continue;
}
}
if(distances.empty())
return TLERepo::Match();
if(secondbest) {
auto iter = distances.begin();
if(iter != distances.end()) {
++iter;
*secondbest = makeMatch(d, get<0>(*d_sgp4s[iter->second]), get<1>(*d_sgp4s[iter->second]), iter->second, iter->first);
}
}
return makeMatch(d, get<0>(*d_sgp4s[distances.begin()->second]), get<1>(*d_sgp4s[distances.begin()->second]), distances.begin()->second, distances.begin()->first);
}