interim
parent
4cd49b000f
commit
1a69de074e
6
Makefile
6
Makefile
|
@ -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
|
||||
|
|
52
beidou.cc
52
beidou.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
27
beidou.hh
27
beidou.hh
|
@ -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);
|
||||
|
|
30
ephemeris.cc
30
ephemeris.cc
|
@ -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);
|
||||
}
|
||||
|
|
37
glonass.hh
37
glonass.hh
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
79
navdump.cc
79
navdump.cc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
121
navparse.cc
121
navparse.cc
|
@ -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 {
|
||||
|
|
|
@ -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
12
tle.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue