pull/1/head^2
bert hubert 2019-09-03 20:05:40 +02:00
parent 4cd49b000f
commit 1a69de074e
12 changed files with 279 additions and 99 deletions

View File

@ -17,13 +17,13 @@ clean:
H2OPP=ext/powerblog/h2o-pp.o
SIMPLESOCKETS=ext/powerblog/ext/simplesocket/swrappers.o ext/powerblog/ext/simplesocket/sclasses.o ext/powerblog/ext/simplesocket/comboaddress.o
navparse: navparse.o ext/fmt-5.2.1/src/format.o $(H2OPP) $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o
navparse: navparse.o ext/fmt-5.2.1/src/format.o $(H2OPP) $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o navmon.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -L/usr/local/opt/openssl/lib/ -lh2o-evloop -lssl -lcrypto -lz -lcurl -lprotobuf # -lwslay
navdump: navdump.o ext/fmt-5.2.1/src/format.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o navmon.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -lprotobuf
navdisplay: navdisplay.o ext/fmt-5.2.1/src/format.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o
navdisplay: navdisplay.o ext/fmt-5.2.1/src/format.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o ephemeris.o navmon.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -lprotobuf -lncurses
@ -39,7 +39,7 @@ tlecatch: tlecatch.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc))
navmon.pb.cc: navmon.proto
protoc --cpp_out=./ navmon.proto
ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-5.2.1/src/format.o galileo.o gps.o beidou.o navmon.o
ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-5.2.1/src/format.o galileo.o gps.o beidou.o navmon.o ephemeris.o
$(CXX) -std=gnu++17 $^ -o $@ -lprotobuf
testrunner: navmon.pb.o testrunner.o ubx.o bits.o ext/fmt-5.2.1/src/format.o galileo.o gps.o beidou.o ephemeris.o

View File

@ -1,6 +1,7 @@
#include "beidou.hh"
#include "bits.hh"
#include <iostream>
using namespace std;
// with immense gratitude to https://stackoverflow.com/questions/24612436/how-to-check-a-bch15-11-1-code-checksum-for-bds-beidou-satellite-system
@ -72,3 +73,54 @@ int beidouBitconv(int their)
return their - (1 + 4 + (wordcount -1)*8);
}
bool processBeidouAlmanac(const BeidouMessage& bm, struct BeidouAlmanacEntry& bae)
{
bae.alma = bm.alma;
int pageno = bm.alma.pageno;
if(bm.fraid == 5 && pageno >= 11 && pageno <= 23) {
/*
cout<<" AmEpID "<< bm.alma.AmEpID;
cout << " AmID "<<bm.alma.AmID; */
if(bm.alma.AmEpID != 3) {
// cout<<" skipping page because AmEpID tells us to "<<endl;
return false;
}
}
if(ephAge(bm.sow, bm.alma.getT0e()) < 0) {
// cout <<" almanac too old t0a "<<bm.alma.getT0e()<<" sow "<<bm.sow << " days " << 1.0*(bm.alma.getT0e()-bm.sow)/86400<< endl;
return false;
}
if(bm.alma.sqrtA == 0) {
// cout<<"sqrtA==0 - likely not a present satellite "<<endl;
return false;
}
Point sat;
if(bm.fraid ==4 && pageno <= 5)
bae.alma.geo=true;
else
bae.alma.geo=false;
int offset = 0;
if(bm.fraid == 4)
offset = 0;
else if(bm.fraid == 5 && pageno <=6)
offset = 24;
else if(bm.fraid == 5 && bm.alma.AmID ==1)
offset = 20;
else if(bm.fraid == 5 && bm.alma.AmID ==2)
offset = 34;
else if(bm.fraid == 5 && bm.alma.AmID ==3)
offset = 46;
bae.sv = pageno+offset;
// cout<<" eff-id "<<bae.sv;
if(bae.sv == 59)
bae.alma.geo = true;
return true;
}

View File

@ -172,7 +172,9 @@ struct BeidouMessage
int omega;
int M0;
int AmEpID;
int AmID;
int pageno;
double getMu() const { return 3.986004418 * pow(10.0, 14.0); } // m^3/s^2
double getOmegaE() const { return 7.2921150 * pow(10, -5); } // rad/s
@ -216,7 +218,8 @@ struct BeidouMessage
alma.omega = bbits(227, 24);
alma.M0 = bbits(259, 24);
alma.AmEpID = bbitu(291, 2);
return bbitu(44, 7);
alma.pageno = bbitu(44, 7);
return alma.pageno;
}
int a0gps, a1gps, a0gal, a1gal, a0glo, a1glo, a0utc, a1utc;
@ -224,8 +227,8 @@ struct BeidouMessage
int parse5(std::basic_string_view<uint8_t> cond)
{
int pageno = bbitu(44, 7);
if(pageno == 9) {
alma.pageno = bbitu(44, 7);
if(alma.pageno == 9) {
a0gps = bbits(97, 14);
a1gps = bbits(111, 16);
a0gal = bbits(135, 14);
@ -233,7 +236,7 @@ struct BeidouMessage
a0glo = bbits(181, 14);
a1glo = bbits(195, 16);
}
if(pageno == 10) {
if(alma.pageno == 10) {
a0utc = bbits(91, 32);
a1utc = bbits(131, 24);
deltaTLS = bbits(31+12+1+7, 8);
@ -251,11 +254,21 @@ struct BeidouMessage
alma.omega = bbits(227, 24);
alma.M0 = bbits(259, 24);
alma.AmEpID = bbitu(291, 2);
if(alma.pageno <=6)
alma.AmEpID = bbitu(291, 2);
else if(alma.pageno >= 11 && alma.pageno <= 23)
alma.AmID = bbitu(291, 2);
}
return pageno;
return alma.pageno;
}
};
struct BeidouAlmanacEntry
{
int sv;
BeidouMessage::Almanac alma;
};
bool processBeidouAlmanac(const BeidouMessage& bm, struct BeidouAlmanacEntry& bae);

View File

@ -14,22 +14,12 @@
// positive age = t0e in the past
int ephAge(int tow, int t0e)
{
unsigned int diff;
unsigned int halfweek = 0.5*7*86400;
if(t0e < tow) {
diff = tow - t0e;
if(diff < halfweek)
return diff;
else
return -(7*86400 - tow) - t0e;
}
else { // "t0e in future"
diff = 7*86400 - t0e + tow;
if(diff < halfweek)
return diff;
else
return tow - t0e; // in the future, negative age
}
int diff = tow - t0e;
if(diff > 3.5*86400)
diff -= 604800;
if(diff < -3.5*86400)
diff += 604800;
return diff;
}
// all axes start at earth center of gravity
@ -48,11 +38,13 @@ std::pair<double,double> getLongLat(double x, double y, double z)
Vector flat(core, proj);
Vector toLatLon0{core, LatLon0};
double longitude = acos( toLatLon0.inner(flat) / (toLatLon0.length() * flat.length()));
if(y < 0)
longitude *= -1;
Vector toUs{core, pos};
double latitude = acos( flat.inner(toUs) / (toUs.length() * flat.length()));
if(z < 0)
latitude *= -1;
return std::make_pair(longitude, latitude);
}

View File

@ -131,17 +131,34 @@ struct GlonassMessage
uint32_t getGloTime() const;
uint8_t n4{0}; // counting from 1996 ('n4=1'), this is the 4-year plan index we are currently in
uint16_t taugps;
int32_t taugps;
int32_t tauc;
void parse5(std::basic_string_view<uint8_t> gstr)
{
n4=getbitu(&gstr[0], 85-36, 5);
taugps = getbitsglonass(&gstr[0], 85-31, 22);
tauc = getbitsglonass(&gstr[0], 85-69, 32);
l_n = getbitu(&gstr[0], 85 - 9, 1);
}
double omegana; // 2^-15 semi-circles, at instantt of tlambdana
uint8_t hna;
uint32_t tlambdana; // 2^-5s time of ascending node passage, also: t0a, relative to MT midnight
int32_t deltatna; // 2^-9
double gettLambdaNa() const
{
return ldexp(tlambdana, -5);
}
void parse7_9_11_13_15(std::basic_string_view<uint8_t> gstr)
{
l_n = getbitu(&gstr[0], 85 - 9, 1);
omegana = getbitsglonass(&gstr[0], 85-80, 16);
hna = getbitu(&gstr[0], 85 - 14, 5); // this is always positive, but there is a translation table
tlambdana = getbitu(&gstr[0], 85 - 64, 21);
deltatna = getbitsglonass(&gstr[0], 85 - 43, 22);
}
@ -149,11 +166,23 @@ struct GlonassMessage
bool CnA;
int32_t lambdana; // 2^-20 semi-circles
int32_t deltaina; // 2^-20 semi-circles
double getLambdaNaDeg()
int32_t epsilonna; // 2^-20
int32_t tauna; // 2^-18
double getLambdaNaDeg() const
{
return ldexp(180.0*lambdana, -20);
}
double getE() const
{
return ldexp(epsilonna, -20);
}
double getI0() const
{
return M_PI*63.0/180 + ldexp(M_PI* deltaina, -20);
}
void parse6_8_10_12_14(std::basic_string_view<uint8_t> gstr)
{
@ -161,6 +190,8 @@ struct GlonassMessage
nA = getbitu(&gstr[0], 85-77, 5);
lambdana = getbitsglonass(&gstr[0], 85-62, 21);
deltaina = getbitsglonass(&gstr[0], 85-41, 18);
epsilonna = getbitu(&gstr[0], 85- 23, 15);
tauna = getbitsglonass(&gstr[0], 85 - 72, 10);
}
};

View File

@ -12,6 +12,7 @@
#include "galileo.hh"
#include "navmon.pb.h"
#include <unistd.h>
#include "navmon.hh"
using namespace std;
@ -142,17 +143,17 @@ int main()
for(;;) {
char bert[4];
if(read(0, bert, 4) != 4 || bert[0]!='b' || bert[1]!='e' || bert[2] !='r' || bert[3]!='t') {
if(readn2(0, bert, 4) != 4 || bert[0]!='b' || bert[1]!='e' || bert[2] !='r' || bert[3]!='t') {
cerr<<"EOF or bad magic"<<endl;
break;
}
uint16_t len;
if(read(0, &len, 2) != 2)
if(readn2(0, &len, 2) != 2)
break;
len = htons(len);
char buffer[len];
if(read(0, buffer, len) != len)
if(readn2(0, buffer, len) != len)
break;
NavMonMessage nmm;

View File

@ -65,11 +65,15 @@ int main(int argc, char** argv)
try
{
TLERepo tles;
tles.parseFile("active.txt");
/* tles.parseFile("galileo.txt");
// tles.parseFile("active.txt");
tles.parseFile("galileo.txt");
tles.parseFile("glo-ops.txt");
tles.parseFile("gps-ops.txt");
tles.parseFile("beidou.txt");*/
tles.parseFile("beidou.txt");
ofstream almanac("almanac.txt");
ofstream iodstream("iodstream.csv");
iodstream << "timestamp gnssid sv iodnav t0e age" << endl;
for(;;) {
char bert[4];
@ -127,12 +131,18 @@ try
oldgm4s[nmm.gi().gnsssv()] = gm;
}
if(wtype == 1 || wtype == 2 || wtype == 3) {
iodstream << nmm.localutcseconds()<<" " << nmm.gi().gnssid() <<" "<< nmm.gi().gnsssv() << " " << gm.iodnav << " " << gm.t0e*60 <<" " << ephAge(gm.t0e*60, gm.tow);
if(wtype == 3)
iodstream<<endl;
else
iodstream<<"\n";
}
if(wtype == 0 || wtype == 5 || wtype == 6)
tow = gm.tow;
if(wtype < 7)
gm = GalileoMessage{};
// if(wtype < 7)
// gm = GalileoMessage{};
if(wtype >=7 && wtype<=10)
cout<<" ioda "<<gm.iodalmanac;
@ -225,53 +235,38 @@ try
else if((fraid == 4 && 1<= pageno && pageno <= 24) ||
(fraid == 5 && 1<= pageno && pageno <= 6) ||
(fraid == 5 && 11<= pageno && pageno <= 23) ) {
cout <<" pageno "<< (int) pageno<<" AmEpID "<< getbitu(&cond[0], beidouBitconv(291), 2);
Point sat;
if(fraid ==4 && pageno <= 5)
bm.alma.geo=true;
else
bm.alma.geo=false;
getCoordinates(0, bm.sow, bm.alma, &sat);
TLERepo::Match second;
auto match = tles.getBestMatch(nmm.localutcseconds(), sat.x, sat.y, sat.z, &second);
cout<<" alma best-tle-match "<<match.name <<" dist "<<match.distance /1000<<" km";
cout<<" norad " <<match.norad <<" int-desig " << match.internat;
cout<<" 2nd-match "<<second.name << " dist "<<second.distance/1000<<" km";
Point core{0,0,0};
cout<<" rad "<<Vector(core,sat).length() << " t0a " << bm.alma.getT0e() << " eph-age " <<ephAge(bm.sow, bm.alma.getT0e())<<endl;
int offset = 0;
if(fraid == 4)
offset = 0;
else if(fraid == 5 && pageno <=6)
offset = 24;
else if(fraid == 5 && bm.alma.AmEpID ==1)
offset = 20;
else if(fraid == 5 && bm.alma.AmEpID ==2)
offset = 34;
else if(fraid == 5 && bm.alma.AmEpID ==3)
offset = 46;
almanac << (int)pageno+offset <<" " << match.norad <<" " <<match.name<<" " << (int)(match.distance/1000)<<" " << (int)(Vector(core,sat).length()/1000000)<<" " << (int) fraid<<" " << (int) pageno <<" " <<(int)bm.alma.AmEpID<<" " <<(int)offset<<"\n";
}
else if(fraid == 5 && pageno==7) {
struct BeidouAlmanacEntry bae;
if(processBeidouAlmanac(bm, bae)) {
cout<<" alma-sv "<<bae.sv;
Point sat;
getCoordinates(0, bm.sow, bae.alma, &sat);
TLERepo::Match second;
auto match = tles.getBestMatch(nmm.localutcseconds(), sat.x, sat.y, sat.z, &second);
cout<<" best-tle-match "<<match.name <<" dist "<<match.distance /1000<<" km";
cout<<" norad " <<match.norad <<" int-desig " << match.internat;
cout<<" 2nd-match "<<second.name << " dist "<<second.distance/1000<<" km t0e "<<bm.alma.getT0e() << " t " <<nmm.localutcseconds();
}
else
cout <<" no valid alma";
}
else if(bm.fraid == 5 && pageno==7) {
for(int n=0; n<19; ++n)
cout<<" hea"<<(1+n)<<" " << getbitu(&cond[0], beidouBitconv(51+n*9), 9) << " ("<<beidouHealth(getbitu(&cond[0], beidouBitconv(51+n*9), 9)) <<")";
}
else if(fraid == 5 && pageno==8) {
else if(bm.fraid == 5 && pageno==8) {
for(int n=0; n<10; ++n)
cout<<" hea"<<(20+n)<<" " << getbitu(&cond[0], beidouBitconv(51+n*9), 9) << " ("<<beidouHealth(getbitu(&cond[0], beidouBitconv(51+n*9), 9))<<")";
cout<<" WNa "<<getbitu(&cond[0], beidouBitconv(190), 8)<<" t0a "<<getbitu(&cond[0], beidouBitconv(198), 8);
}
else if(fraid == 5 && pageno==24) {
else if(bm.fraid == 5 && pageno==24) {
int AmID= getbitu(&cond[0], beidouBitconv(216), 2);
cout<<" AmID "<< AmID;
for(int n=0; n<14; ++n)
cout<<" hea"<<(31+n)<<" (" << getbitu(&cond[0], beidouBitconv(51+n*9), 9) << " "<<beidouHealth(getbitu(&cond[0], beidouBitconv(51+n*9), 9))<<")";
}
cout<<endl;
}
else if(nmm.type() == NavMonMessage::BeidouInavTypeD2) {
int sv = nmm.bid2().gnsssv();
@ -320,11 +315,11 @@ try
}
else if(strno == 5)
cout<<", n4 "<< (int)gm.n4 << " l_n " << gm.l_n;
else if(strno == 7 || strno == 9 || strno == 11 || strno ==13 ||strno ==15) {
cout << " l_n "<< gm.l_n;
}
else if(strno == 6 || strno ==8 || strno == 10 || strno ==12 ||strno ==14) {
cout<<" nA "<< gm.nA <<" CnA " << gm.CnA <<" LambdaNaDeg "<< gm.getLambdaNaDeg();
cout<<" nA "<< gm.nA <<" CnA " << gm.CnA <<" LambdaNaDeg "<< gm.getLambdaNaDeg() << " e " <<gm.getE() << " i0 "<< 180.0*gm.getI0()/M_PI;
}
else if(strno == 7 || strno == 9 || strno == 11 || strno ==13 ||strno ==15) {
cout << " l_n "<< gm.l_n << " Tlambdana " <<gm.gettLambdaNa() <<" Hna " << (int)gm.hna;
}
cout<<endl;
}

View File

@ -61,7 +61,7 @@ try
cerr<<"New downstream client "<<client.toStringWithPort() << endl;
pair<uint64_t, uint64_t> start = {0,0};
start.first = time(0) - 4*3600; // 4 hours of backlog
start.first = time(0) - 24*3600; // 4 hours of backlog
// so we have a ton of files, and internally these are not ordered
map<string,uint32_t> fpos;

View File

@ -24,12 +24,15 @@
#include "galileo.hh"
#include "tle.hh"
#include <optional>
#include "navmon.hh"
#include <Tle.h>
using namespace std;
struct EofException{};
Point g_ourpos(3922.505 * 1000, 290.116 * 1000, 5004.189 * 1000);
map<int, BeidouAlmanacEntry> g_beidoualma;
map<int, pair<GlonassMessage, GlonassMessage>> g_glonassalma;
TLERepo g_tles;
struct GNSSReceiver
{
@ -232,6 +235,7 @@ struct SVStat
// Glonass
GlonassMessage glonassMessage;
pair<uint32_t, GlonassMessage> glonassAlmaEven;
map<uint64_t, SVPerRecv> perrecv;
pair<uint32_t, double> deltaHz;
@ -553,11 +557,13 @@ double getElevation(const Point& p)
int main(int argc, char** argv)
try
{
// g_tles.parseFile("active.txt");
// g_tles.parseFile("active.txt");
g_tles.parseFile("galileo.txt");
g_tles.parseFile("glo-ops.txt");
g_tles.parseFile("gps-ops.txt");
g_tles.parseFile("beidou.txt");
signal(SIGPIPE, SIG_IGN);
InfluxPusher idb(argc > 3 ? argv[3] : "galileo");
MiniCurl::init();
@ -633,6 +639,69 @@ try
return ret;
});
h2s.addHandler("/almanac", [](auto handler, auto req) {
nlohmann::json ret = nlohmann::json::object();
for(const auto& ae : g_beidoualma) {
nlohmann::json item = nlohmann::json::object();
if(ae.second.alma.getT0e() > 7*86400)
continue;
Point sat;
getCoordinates(0, latestTow(3), ae.second.alma, &sat);
item["eph-ecefX"]= sat.x/1000;
item["eph-ecefY"]= sat.y/1000;
item["eph-ecefZ"]= sat.z/1000;
auto longlat = getLongLat(sat.x, sat.y, sat.z);
item["eph-longitude"] = 180*longlat.first/M_PI;
item["eph-latitude"]= 180*longlat.second/M_PI;
item["t0e"] = ae.second.alma.getT0e();
item["t"]= ephAge(ae.second.alma.getT0e(), latestTow(3))/86400.0;
if(ephAge(ae.second.alma.getT0e(), latestTow(3)) < 0) {
auto match = g_tles.getBestMatch(nanoTime(3, latestWN(3), latestTow(3))/1000000000.0,
sat.x, sat.y, sat.z);
if(match.distance < 200000) {
item["best-tle"] = match.name;
item["best-tle-norad"] = match.norad;
item["best-tle-int-desig"] = match.internat;
item["best-tle-dist"] = match.distance/1000.0;
item["tle-ecefX"] = match.ecefX/1000;
item["tle-ecefY"] = match.ecefY/1000;
item["tle-ecefZ"] = match.ecefZ/1000;
item["tle-eciX"] = match.eciX/1000;
item["tle-eciY"] = match.eciY/1000;
item["tle-eciZ"] = match.eciZ/1000;
item["tle-latitude"] = 180*match.latitude/M_PI;
item["tle-longitude"] = 180*match.longitude/M_PI;
item["tle-altitude"] = match.altitude;
}
}
ret[fmt::sprintf("C%02d", ae.first)] = item;
}
for(const auto& ae : g_glonassalma) {
nlohmann::json item = nlohmann::json::object();
// ae.second.first -> even ae.second.sceond -> odd
item["e"] = ae.second.first.getE();
item["inclination"] = 180 * ae.second.first.getI0() /M_PI;
item["health"] = ae.second.first.CnA;
item["tlambdana"] = ae.second.second.gettLambdaNa();
item["lambdana"] = ae.second.second.getLambdaNaDeg();
item["hna"] = ae.second.second.hna;
ret[fmt::sprintf("R%02d", ae.first)] = item;
}
return ret;
});
@ -818,17 +887,17 @@ try
try {
for(;;) {
char bert[4];
if(read(0, bert, 4) != 4 || bert[0]!='b' || bert[1]!='e' || bert[2] !='r' || bert[3]!='t') {
if(readn2(0, bert, 4) != 4 || bert[0]!='b' || bert[1]!='e' || bert[2] !='r' || bert[3]!='t') {
cerr<<"EOF or bad magic"<<endl;
break;
}
uint16_t len;
if(read(0, &len, 2) != 2)
if(readn2(0, &len, 2) != 2)
break;
len = htons(len);
char buffer[len];
if(read(0, buffer, len) != len)
if(readn2(0, buffer, len) != len)
break;
NavMonMessage nmm;
@ -856,6 +925,9 @@ try
auto oldgm = svstat.galmsg;
unsigned int wtype = svstat.galmsg.parse(inav);
if(wtype == 1 || wtype == 2 || wtype == 3) {
idb.addValue(id, "iod-live", svstat.galmsg.iodnav);
}
if(1) {
// cout<<sv <<"\t" << wtype << "\t" << nmm.gi().gnsstow() << "\t"<< nmm.sourceid() << endl;
/* if(g_svstats[id].tow > nmm.gi().gnsstow()) {
@ -1146,7 +1218,6 @@ try
auto newOffset = bm.getAtomicOffset(bm.sow);
svstat.timeDisco = oldOffset.first - newOffset.first;
idb.addValue(id, "clock_jump_ns", svstat.timeDisco);
}
svstat.lastBeidouMessage1 = bm;
}
@ -1182,6 +1253,18 @@ try
if(bm.sqrtA) // only copy in if complete
svstat.oldBeidouMessage = bm;
}
else if((fraid == 4 && 1<= pageno && pageno <= 24) ||
(fraid == 5 && 1<= pageno && pageno <= 6) ||
(fraid == 5 && 11<= pageno && pageno <= 23) ) {
struct BeidouAlmanacEntry bae;
// bm.alma.AmEpID = svstat.oldBeidouMessage.alma.AmEpID; // this comes from older messages
if(processBeidouAlmanac(bm, bae)) {
g_beidoualma[bae.sv]=bae;
}
}
if(fraid==5 && pageno == 9) {
svstat.a0g = bm.a0gps;
svstat.a1g = bm.a1gps;
@ -1193,10 +1276,10 @@ try
g_dtLSBeidou = bm.deltaTLS;
// cout<<"Beidou leap seconds: "<<g_dtLSBeidou<<endl;
}
Point core, sat;
// Point core, sat;
getCoordinates(svstat.wn, svstat.tow, bm, &sat);
Vector l(core, sat);
// getCoordinates(svstat.wn, svstat.tow, bm, &sat);
// Vector l(core, sat);
// cout<<"C"<<id.second<< " "<<bm.sow<<" "<<(bm.sow % 30 )<<" FraID "<<fraid<<" "<<fmt::format("({0}, {1}, {2})", sat.x, sat.y, sat.z) <<", r: "<<l.length()<<" elev: "<<getElevation(sat)<<endl;
}
else if(nmm.type()== NavMonMessage::BeidouInavTypeD2) {
@ -1225,12 +1308,11 @@ try
uint32_t glotime = gm.getGloTime(); // this starts GLONASS time at 31st of december 1995, 00:00 UTC
svstat.wn = glotime / (7*86400);
svstat.tow = glotime % (7*86400);
}
if(strno == 2) {
else if(strno == 2) {
svstat.gpshealth = gm.Bn;
}
if(strno == 4) {
else if(strno == 4) {
svstat.aode = gm.En * 24;
idb.addValue(id, "glo_taun_ns", gm.getTaunNS());
idb.addValue(id, "ft", gm.FT);
@ -1240,20 +1322,27 @@ try
idb.addValue(id, "clock_jump_ns", svstat.timeDisco);
}
}
if(gm.x && gm.y && gm.z) {
time_t now = nmm.localutcseconds();
time_t now = nmm.localutcseconds() + 3*3600;
struct tm tm;
memset(&tm, 0, sizeof(tm));
gmtime_r(&now, &tm);
tm.tm_hour = (gm.Tb/4.0) - 3;
tm.tm_hour = (gm.Tb/4.0);
tm.tm_min = (gm.Tb % 4)*15;
tm.tm_sec = 0;
auto match = g_tles.getBestMatch(timegm(&tm), gm.getX(), gm.getY(), gm.getZ());
auto match = g_tles.getBestMatch(timegm(&tm)-3*3600, gm.getX(), gm.getY(), gm.getZ());
svstat.tleMatch = match;
}
}
else if(strno == 6 || strno == 8 || strno == 10 || strno == 12 || strno == 14) {
svstat.glonassAlmaEven = {nmm.localutcseconds(), gm};
}
else if(strno == 7 || strno == 9 || strno == 11 || strno == 13 || strno == 15) {
if(nmm.localutcseconds() - svstat.glonassAlmaEven.first < 4 && svstat.glonassAlmaEven.second.strtype == gm.strtype -1) {
g_glonassalma[svstat.glonassAlmaEven.second.nA] = make_pair(svstat.glonassAlmaEven.second, gm);
}
}
// cout<<"GLONASS R"<<id.second<<" str "<<strno<<endl;
}
else {

View File

@ -11,7 +11,8 @@ TEST_CASE("testing ephemeris age") {
CHECK(ephAge(0,3*86400) == -3*86400);
CHECK(ephAge(0, 3.49*86400) == -3.49*86400);
CHECK(ephAge(0, 3.51*86400) != -3.51*86400);
CHECK(ephAge(0, 3.51*86400) != -3.51*86400);
CHECK(ephAge(0, 3.6*86400) != -3.6*86400);
CHECK(ephAge(2*86400, 0) == 2*86400);

12
tle.cc
View File

@ -59,9 +59,9 @@ static TLERepo::Match makeMatch(const DateTime& d, const SGP4& sgp4, const Tle&
double theta = -eci.GetDateTime().ToGreenwichSiderealTime();
Vector rot = eci.Position();
m.eciX = rot.x;
m.eciY = rot.y;
m.eciZ = rot.z;
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);
@ -69,7 +69,11 @@ static TLERepo::Match makeMatch(const DateTime& d, const SGP4& sgp4, const Tle&
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;
}

2
tle.hh
View File

@ -25,6 +25,8 @@ public:
double eciX, eciY, eciZ; // m
double distance{-1}; // m
double latitude, longitude, altitude;
};
Match getBestMatch(time_t, double x, double y, double z, Match* secondbest=0);