this code is running, so it must be good

pull/114/head
bert hubert 2020-04-25 11:43:25 +02:00
parent 67da85d812
commit 3c565b815e
10 changed files with 90 additions and 17 deletions

View File

@ -80,6 +80,10 @@ navparse: navparse.o ext/fmt-6.1.2/src/format.o $(H2OPP) $(SIMPLESOCKETS) minicu
reporter: reporter.o ext/fmt-6.1.2/src/format.o $(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 coverage.o osen.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl
tracker: tracker.o ext/fmt-6.1.2/src/format.o $(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 coverage.o osen.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl
galmonmon: galmonmon.o ext/fmt-6.1.2/src/format.o $(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 coverage.o osen.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl

View File

@ -311,7 +311,7 @@ int main(int argc, char **argv)
auto healthchange = g_sk.reportState(fullName, "health", sv["healthissue"]!=0);
std::optional<string> tooOldChange;
if(gnssid == 2)
tooOldChange = g_sk.reportState(fullName, "eph-too-old", sv["eph-age-m"] > 180, fmt::sprintf("%.2f", (double)sv["eph-age-m"]));
tooOldChange = g_sk.reportState(fullName, "eph-too-old", sv["eph-age-m"] > 105, fmt::sprintf("%.2f", (double)sv["eph-age-m"]));
else
tooOldChange = g_sk.reportState(fullName, "eph-too-old", sv["eph-age-m"] > 140, fmt::sprintf("%.2f", (double)sv["eph-age-m"]));

View File

@ -14,7 +14,7 @@ function maketable(str, arr)
enter().
append("tr");
var columns = ["sv", "best-tle", "iod", "eph-age-m", "latest-disco", "time-disco", "sisa", "health", "alma-dist", "delta-utc", "sources", "hqsources", "db", "delta_hz_corr","prres", "elev", "last-seen-s"];
var columns = ["sv", "best-tle", "iod", "eph-age-m", "latest-disco", "time-disco", "sisa", "health", "alma-dist", "delta-utc", "sources", "hqsources", "db", "rtcm-eph-delta-cm","prres", "elev", "last-seen-s"];
// append the header row
thead.append("tr")
@ -25,6 +25,8 @@ function maketable(str, arr)
.html(function(column) {
if(column == "delta_hz_corr")
return "ΔHz";
if(column == "rtcm-eph-delta-cm")
return "Δrtcm";
if(column == "delta-gps")
return "ΔGPS ns";
if(column == "delta-utc")
@ -60,6 +62,12 @@ function maketable(str, arr)
// ret.value="";
ret.value += "&nbsp;<a href='sv.html?gnssid="+row.gnssid+"&sv="+row.svid+"&sigid="+row.sigid+"'>"+row.sv+"</a>";
}
else if(column == "rtcm-eph-delta-cm") {
if(row[column] != null)
ret.value = row[column].toFixed(1)+" cm";
else
ret.value="";
}
else if(column == "aodc/e") {
if(row["aodc"] != null && row["aode"] != null)
ret.value = row["aodc"]+"/"+row["aode"];
@ -306,11 +314,11 @@ function update()
d3.json("global.json", function(d) {
var str="Galileo-UTC offset: <b>"+d["gst-utc-offset-ns"].toFixed(2)+"</b> ns";
str += ", Galileo-GPS offset: <b>"+d["gst-gps-offset-ns"].toFixed(2)+"</b> ns";
str += " , GPS-UTC offset: <b>"+d["gps-utc-offset-ns"].toFixed(2)+" ns</b>";
str += " , BeiDou-UTC offset: <b>"+d["beidou-utc-offset-ns"].toFixed(2)+" ns</b>";
str += " , GLONASS-UTC offset: <b>"+d["glonass-utc-offset-ns"].toFixed(2)+" ns</b>";
str += " , GLONASS-GPS offset: <b>"+d["glonass-gps-offset-ns"].toFixed(2)+" ns</b>";
str += ", GPS-UTC offset: <b>"+d["beidou-utc-offset-ns"].toFixed(2)+" ns</b>, "+d["leap-seconds"]+"</b> leap seconds";
str += ", GPS-UTC offset: <b>"+d["gps-utc-offset-ns"].toFixed(2)+" ns</b>";
str += ", BeiDou-UTC offset: <b>"+d["beidou-utc-offset-ns"].toFixed(2)+" ns</b>";
str += ", GLONASS-UTC offset: <b>"+d["glonass-utc-offset-ns"].toFixed(2)+" ns</b>";
str += ", GLONASS-GPS offset: <b>"+d["glonass-gps-offset-ns"].toFixed(2)+" ns</b>";
str += ", "+d["leap-seconds"]+"</b> leap seconds (GPS/Galileo)";
d3.select('#facts').html(str);
lastseen = moment(1000*d["last-seen"]);

View File

@ -287,7 +287,9 @@ try
ofstream iodstream("iodstream.csv");
iodstream << "timestamp gnssid sv iodnav t0e age" << endl;
ofstream ephcsv("eph.csv");
ephcsv<<"timestamp gnssid sv old_iod new_iod age insta_age x y z lat lon h"<<endl;
ofstream csv("delta.csv");
csv <<"timestamp gnssid sv tow tle_distance alma_distance utc_dist x y z vx vy vz rad inclination e iod"<<endl;
@ -447,8 +449,8 @@ try
auto newAtomic = gm.getAtomicOffset(gm.tow);
cout<<" clock-jump "<<oldAtomic.first - newAtomic.first<<" ns ";
// doOrbitDump(2, sv, gm.wn, oldEph[sv], gm, gm.tow - 3*3600, gm.tow + 3*3600);
auto latlonh = ecefToWGS84(newPoint.x, newPoint.y, newPoint.z);
ephcsv<<nmm.localutcseconds()<<" "<< 2 <<" " << sv <<" " <<oldEph[sv].iodnav << " "<<gm.iodnav <<" "<< (gm.getT0e() - oldEph[sv].getT0e()) <<" "<<ephAge(gm.tow, gm.getT0e())/3600 << " " <<newPoint.x<<" " << newPoint.y <<" " <<newPoint.z<<" " << 180*get<0>(latlonh)/M_PI<<" " << 180*get<1>(latlonh)/M_PI <<" " <<get<2>(latlonh) << "\n";
oldEph[sv]=gm;
}
}

View File

@ -1245,6 +1245,19 @@ try
// item["t0c"] = s.second.liveIOD().getT0c();
if(s.second.rtcmEphDelta.id.gnss == s.first.gnss && s.second.rtcmEphDelta.id.sv == s.first.sv && s.second.rtcmEphDelta.iod == s.second.liveIOD().getIOD()
&& abs(s.second.rtcmEphDelta.sow - s.second.tow())<60) {
const auto& ed = s.second.rtcmEphDelta;
item["rtcm-eph-delta-cm"] = truncPrec(sqrt(ed.radial*ed.radial + ed.along*ed.along + ed.cross*ed.cross)/10.0, 2);
item["rtcm-eph-radial-cm"] = truncPrec(ed.radial/10.0, 2);
item["rtcm-eph-along-cm"] = truncPrec(ed.along/10.0, 2);
item["rtcm-eph-cross-cm"] = truncPrec(ed.cross/10.0, 2);
item["rtcm-eph-dradial-cm"] = truncPrec(ed.dradial/10.0, 2);
item["rtcm-eph-dalong-cm"] = truncPrec(ed.dalong/10.0, 2);
item["rtcm-eph-dcross-cm"] = truncPrec(ed.dcross/10.0, 2);
}
Point p;
Point core;
@ -2166,6 +2179,10 @@ try
rm.parse(nmm.rm().contents());
if(rm.type == 1057 || rm.type == 1240) {
for(const auto& ed : rm.d_ephs) {
auto iter = g_svstats.find(ed.id);
if(iter != g_svstats.end() && iter->second.completeIOD() && iter->second.liveIOD().getIOD() == ed.iod)
iter->second.rtcmEphDelta = ed;
idb.addValue(ed.id, "rtcm-eph-correction", {
{"iod", ed.iod},
{"radial", ed.radial},
@ -2328,7 +2345,7 @@ try
int strno = gm.parse(std::basic_string<uint8_t>((uint8_t*)nmm.gloi().contents().c_str(), nmm.gloi().contents().size()));
g_svstats[id].perrecv[nmm.sourceid()].t = nmm.localutcseconds();
if(strno == 1 && gm.n4 != 0 && gm.NT !=0) {
uint32_t glotime = gm.getGloTime(); // this starts GLONASS time at 31st of december 1995, 00:00 UTC
// uint32_t glotime = gm.getGloTime(); // this starts GLONASS time at 31st of december 1995, 00:00 UTC
// CONVERSION, possibly vital
// svstat.wn = glotime / (7*86400);
// svstat.tow = glotime % (7*86400);

View File

@ -8,6 +8,7 @@
#include "tle.hh"
#include "sbas.hh"
#include "ephemeris.hh"
#include "rtcm.hh"
using namespace std; // XXX
@ -59,6 +60,8 @@ struct SVStat
map<int, SBASCombo> sbas;
RTCMMessage::EphemerisDelta rtcmEphDelta;
const GPSLikeEphemeris& liveIOD() const;
const GPSLikeEphemeris& prevIOD() const;

View File

@ -1,5 +1,6 @@
#include <tuple>
#include <math.h>
#include "ephemeris.hh"
/* gratefully adopted from http://danceswithcode.net/engineeringnotes/geodetic_to_ecef/geodetic_to_ecef.html
which in turn is based on the excellent work from

View File

@ -38,6 +38,8 @@ struct IntervalStat
{
std::optional<int> unhealthy;
std::optional<int> sisa;
bool ripe{false};
bool expired{false};
};
@ -116,12 +118,34 @@ int main(int argc, char **argv)
}
}
res = mc.getURL(url + mc.urlEncode("select max(\"eph-age\") from ephemeris where "+period+" and sigid='"+to_string(sigid)+"' group by gnssid,sv,sigid,time(10m)"));
j = nlohmann::json::parse(res);
for(const auto& sv : j["results"][0]["series"]) {
const auto& tags=sv["tags"];
SatID id{(unsigned int)std::stoi((string)tags["gnssid"]), (unsigned int)std::stoi((string)tags["sv"]), (unsigned int)std::stoi((string)tags["sigid"])};
for(const auto& v : sv["values"]) {
if(v.size() > 1 && v[1] != nullptr) {
int seconds = (int)v[1];
if(seconds > 86400) { // probably wraparound
}
else if(seconds > 4*3600) {
g_stats[id][(int)v[0]].expired = 1;
cout<<makeSatIDName(id)<<": "<<humanTimeShort(v[0])<<" " << seconds<<endl;
}
else if(seconds > 2*3600)
g_stats[id][(int)v[0]].ripe = (int)v[1] > 7200;
}
}
}
g_stats.erase({2,14,1});
g_stats.erase({2,18,1});
g_stats.erase({2,14,5});
g_stats.erase({2,18,5});
//g_stats[{2,11,1}];
g_stats[{2,19,1}];
unsigned int maxintervals=0;
time_t start=time(0), stop=0;
@ -140,10 +164,16 @@ int main(int argc, char **argv)
cout<<"Report on "<<g_stats.size()<<" SVs from "<<humanTime(start) <<" to " <<humanTime(stop) << endl;
int totnapa=0, totunhealthy=0, tothealthy=0, tottesting=0;
int totunobserved=0;
int totripe = 0, totexpired = 0;
for(const auto& sv : g_stats) {
int napa=0, unhealthy=0, healthy=0, testing=0;
int napa=0, unhealthy=0, healthy=0, testing=0, ripe=0, expired=0;
for(const auto& i : sv.second) {
if(i.second.ripe)
ripe++;
if(i.second.expired)
expired++;
if(i.second.unhealthy) {
if(*i.second.unhealthy==1)
unhealthy++;
@ -169,24 +199,30 @@ int main(int argc, char **argv)
totunhealthy += unhealthy;
tottesting += testing;
tothealthy += healthy;
totripe += ripe;
totexpired += expired;
totunobserved += maxintervals-sv.second.size();
cout<<fmt::sprintf("E%02d: %6.2f%% unobserved, %6.2f%% unhealthy, %6.2f%% healthy, %6.2f%% testing, %6.2f%% napa",
cout<<fmt::sprintf("E%02d: %6.2f%% unobserved, %6.2f%% unhealthy, %6.2f%% healthy, %6.2f%% testing, %6.2f%% napa, %6.2f%% ripe, %6.2f%% expired",
sv.first.sv,
100.0*(maxintervals-sv.second.size())/maxintervals,
100.0*unhealthy/maxintervals,
100.0*healthy/maxintervals,
100.0*testing/maxintervals,
100.0*napa/maxintervals
100.0*napa/maxintervals,
100.0*ripe/maxintervals,
100.0*expired/maxintervals
)<<endl;
}
cout<<"------------------------------------------------------------------------------------------"<<endl;
cout<<fmt::sprintf("Tot: %6.2f%% unobserved, %6.2f%% unhealthy, %6.2f%% healthy, %6.2f%% testing, %6.2f%% napa",
cout<<fmt::sprintf("Tot: %6.2f%% unobserved, %6.2f%% unhealthy, %6.2f%% healthy, %6.2f%% testing, %6.2f%% napa, %6.2f%% ripe, %6.2f%% expired",
100.0*(totunobserved)/maxintervals/g_stats.size(),
100.0*totunhealthy/maxintervals/g_stats.size(),
100.0*tothealthy/maxintervals/g_stats.size(),
100.0*tottesting/maxintervals/g_stats.size(),
100.0*totnapa/maxintervals/g_stats.size()
100.0*totnapa/maxintervals/g_stats.size(),
100.0*totripe/maxintervals/g_stats.size(),
100.0*totexpired/maxintervals/g_stats.size()
)<<endl;
}

View File

@ -54,6 +54,7 @@ void RTCMMessage::parse(const std::string& str)
ed.dalong = gbs(off + iodlen + 89, 19) * 0.004;
ed.dcross = gbs(off + iodlen +108, 19) * 0.004;
ed.iod = gbu(off +6, iodlen);
ed.sow = sow;
if(type == 1057) {
ed.id.gnss = 0;
ed.id.sigid = 0;

View File

@ -34,6 +34,7 @@ struct RTCMMessage
double radial, along, cross;
double dradial, dalong, dcross;
int iod;
int sow;
};
struct ClockDelta
{