skyspy: Update to newer library version

master
Pavel Machek 2025-01-13 14:01:00 +01:00
parent 01a241a3bb
commit ce04f8283e
1 changed files with 210 additions and 120 deletions

View File

@ -530,63 +530,22 @@ let quality = {
var qalt = 9999; /* global, altitude quality */ var qalt = 9999; /* global, altitude quality */
/* sky library v0.2.3
needs ui */
let fix = {}; /* Global for sky library */ let fix = {}; /* Global for sky library */
/* sky library v0.2.0 */ let skys = {
let sky = {
sats: [], sats: [],
snum: 0, snum: 0,
sats_used: 0, sats_used: 0,
sky_start: -1, sky_start: -1,
this_usable: 0,
drawGrid: function() { reset: function() {
g.setColor(0,0,0); this.snum = 0;
ui.radLine(0, 1, 0.5, 1); this.sats = [];
ui.radLine(0.25, 1, 0.75, 1); this.sats_used = 0;
ui.radCircle(0.5);
ui.radCircle(1.0);
}, },
/* 18.. don't get reliable fix in 40s */
snrLim: 22,
drawSat: function(s) {
let a = s.azi / 360;
let e = ((90 - s.ele) / 90);
let x = ui.radX(a, e);
let y = ui.radY(a, e);
if (s.snr == 0)
g.setColor(1, 0.25, 0.25);
else if (s.snr < this.snrLim)
g.setColor(0.25, 0.5, 0.25);
else
g.setColor(0, 0, 0);
g.drawString(s.id, x, y);
},
// Should correspond to view from below.
// https://in-the-sky.org//satmap_radar.php?year=2023&month=10&day=24&skin=1
decorate: function() {},
drawSats: function(sats) {
if (ui.display != 0)
return;
g.reset()
.setColor(1, 1, 1)
.fillRect(0, ui.wi, ui.w, ui.y2)
.setFont("Vector", 20)
.setFontAlign(0, 0);
this.drawGrid();
sats.forEach(s => this.drawSat(s));
if (fix && fix.fix && fix.lat) {
g.setColor(0, 0, 0)
.setFontAlign(-1, 1);
g.drawString(fix.satellites + "/" + fix.hdop, 5, ui.y2);
}
this.decorate();
},
parseSats: function(s) { parseSats: function(s) {
let view = 1 * s[3]; let view = 1 * s[3];
let k = Math.min(4, view - this.snum); let k = Math.min(4, view - this.snum);
@ -602,36 +561,13 @@ let sky = {
} }
}, },
old_msg: {},
msg: {},
tof: function(v) { let i = (1*v); return i.toFixed(0); },
fmtSys: function(sys) {
return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n";
},
display: function() {
/* unused on skyspy */
if (ui.display == 1)
return;
let m = this.old_msg;
let msg = "" + this.tof(m.time) + "\n" +
"q" + m.quality + " " + m.in_view + " " + m.hdop + "\n" +
"gp"+ this.fmtSys(m.gp) +
"bd" + this.fmtSys(m.bd) +
"gl" + this.fmtSys(m.gl);
if (this.msg.finished != 1)
msg += "!";
g.reset().clear().setFont("Vector", 30)
.setColor(0, 0, 0)
.setFontAlign(-1, -1)
.drawString(msg, 0, 0);
},
snrSort: function() { snrSort: function() {
return this.sats.slice(0, this.snum).sort((a, b) => b.snr - a.snr); return this.sats.slice(0, this.snum).sort((a, b) => b.snr - a.snr);
}, },
getSatSNR: function(n) { /* Get n-th strongest sat */ getSatSNR: function(n) { /* Get n-th strongest sat */
if (n <= 0 || n > this.sats.length) if (n <= 0 || n > this.sats.length)
return -1; return -1;
// Sort the satellites by snr in descending order // Sort the satellites by snr in descending order
let sortedSats = this.snrSort(); let sortedSats = this.snrSort();
@ -641,14 +577,14 @@ let sky = {
qualest: function() { qualest: function() {
// Sort the satellites by snr in descending order // Sort the satellites by snr in descending order
let sortedSats = this.snrSort(); let sortedSats = this.snrSort();
if (sortedSats[4].snr) { if (sortedSats[4] && sortedSats[4].snr) {
return "" + sortedSats[4].snr + "dB"; return "" + sortedSats[4].snr + "dB";
} }
for (i=4; i>=0; i--) { for (let i=4; i>=0; i--) {
if (sortedSats[i].snr) if (sortedSats[i] && sortedSats[i].snr)
return "S" + (i+1); return "S" + (i+1);
} }
return "nil"; return "U" + this.snum;
}, },
satVisibility: [], satVisibility: [],
trackSatelliteVisibility: function() { trackSatelliteVisibility: function() {
@ -663,7 +599,7 @@ let sky = {
if (!existingSat) { if (!existingSat) {
// New satellite starts visibility // New satellite starts visibility
newVisibility[sat.id] = { start: now, visible: true }; newVisibility[sat.id] = { start: now, visible: true };
} else } else
newVisibility[sat.id] = this.satVisibility[sat.id]; newVisibility[sat.id] = this.satVisibility[sat.id];
} }
} }
@ -686,60 +622,194 @@ let sky = {
goodest: function () { goodest: function () {
let s = this.getnthLowestStartTimeSat(5); let s = this.getnthLowestStartTimeSat(5);
if (s==-1) if (s==-1)
return "none"; return "";
let t = getTime() - s.start; let t = getTime() - s.start;
return "" + t; return "" + t + "s";
}, },
summary: function () {
let s = this.goodest();
if (s != "")
return s;
return this.qualest();
},
onEnd: function () {
this.trackSatelliteVisibility();
if (this.sats_used < 5)
this.sky_start = getTime();
this.reset();
},
};
function deepCopy(obj) {
if (obj === null || typeof obj !== "object") {
return obj; // Return primitive values as-is
}
if (Array.isArray(obj)) {
return obj.map(deepCopy); // Handle arrays recursively
}
const copy = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]); // Recursively copy properties
}
}
return copy;
}
let sky = {
this_usable: 0,
debug: 0,
all: skys, /* Sattelites from all systems */
split: 1,
init: function () {
if (this.split) {
this.s_gp = deepCopy(skys);
this.s_gl = deepCopy(skys);
this.s_bd = deepCopy(skys);
}
},
drawGrid: function() {
g.setColor(0,0,0);
ui.radLine(0, 1, 0.5, 1);
ui.radLine(0.25, 1, 0.75, 1);
ui.radCircle(0.5);
ui.radCircle(1.0);
},
/* 18.. don't get reliable fix in 40s */
snrLim: 22,
drawSat: function(s) {
let a = s.azi / 360;
let e = ((90 - s.ele) / 90);
let x = ui.radX(a, e);
let y = ui.radY(a, e);
if (s.snr == 0)
g.setColor(1, 0.25, 0.25);
else if (s.snr < this.snrLim)
g.setColor(0.25, 0.5, 0.25);
else
g.setColor(0, 0, 0);
g.drawString(s.id, x, y);
},
// Should correspond to view from below.
// https://in-the-sky.org//satmap_radar.php?year=2023&month=10&day=24&skin=1
decorate: function() {},
drawSats: function(sats) {
g.reset()
.setColor(1, 1, 1)
.fillRect(0, ui.wi, ui.w, ui.y2)
.setFont("Vector", 20)
.setFontAlign(0, 0);
this.drawGrid();
sats.forEach(s => this.drawSat(s));
if (fix && fix.fix && fix.lat) {
g.setColor(0, 0, 0)
.setFontAlign(-1, 1);
g.drawString(fix.satellites + "/" + fix.hdop, 5, ui.y2);
}
this.decorate();
},
old_msg: {},
msg: {},
tof: function(v, n) { let i = (1*v); return i.toFixed(n); },
tof0: function(v) { return this.tof(v, 0); },
tof1: function(v) { return this.tof(v, 1); },
fmtSys: function(sys, sats) {
if (!sys.sent)
return " off\n";
let r = sys.sent + " ";
// r+= sys.d23 + "D ";
if (sats)
// r += sats.sats_used + "/" + sats.snum;
r += sats.summary();
return r + "\n";
},
drawRace: function() {
let m = this.old_msg;
let msg = "gmt" + this.tof0(m.time) + "\n" +
"q" + m.quality + " S" + m.in_view + " h" + this.tof0(m.hdop) + "m\n" +
/* "v" + this.tof0(m.vdop) + "m " + "p" + this.tof0(m.pdop) + "m\n" + */
this.all.summary() + "\n" +
"gp"+ this.fmtSys(m.gp, this.s_gp) +
"bd" + this.fmtSys(m.bd, this.s_bd) +
"gl" + this.fmtSys(m.gl, this.s_gl);
if (this.msg.finished != 1)
msg += "!";
g.reset().clear().setFont("Vector", 30)
.setColor(0, 0, 0)
.setFontAlign(-1, -1)
.drawString(msg, 0, 0);
},
drawEstimates: function() {
/*
Performance Assessment of GNSS Signals in terms of Time to
First Fix for Cold, Warm and Hot Start Matteo Paonni, Marco Anghileri,
Stefan Wallner, José-Ángel Ávila-Rodríguez, Bernd Eissfeller Institute
of Geodesy and Navigation, University FAF Munich, Germany
=> 22 to 26 dB -- long time / no fix / ...
=> 26db + -- basically strength no longer matters
*/
let r = this.all.qualest();
let r1 = this.all.goodest();
print(r, r1, this.old_msg.hdop, this.old_msg.quality);
ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.all.sky_start));
},
onMessageEnd: function() {},
messageEnd: function() { messageEnd: function() {
this.old_msg = this.msg; this.old_msg = this.msg;
this.msg = {}; this.msg = {};
this.msg.gp = {}; this.msg.gp = {};
this.msg.bd = {}; this.msg.bd = {};
this.msg.gl = {}; this.msg.gl = {};
this.drawSats(this.sats); this.onMessageEnd();
let r = this.qualest();
let r1 = this.goodest();
print(r, r1, this.old_msg.hdop, this.old_msg.quality);
if (ui.display == 4)
ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start));
this.trackSatelliteVisibility();
//print(this.sats); //print(this.sats);
if (this.sats_used < 5) this.all.onEnd();
this.sky_start = getTime(); if (this.split) {
this.snum = 0; this.s_gp.onEnd();
this.sats = []; this.s_gl.onEnd();
this.sats_used = 0; this.s_bd.onEnd();
quality.updateGps(); /* FIXME */ }
}, },
parseRaw: function(msg, lost) { parseRaw: function(msg, lost) {
//print(msg);
if (lost) print("## data lost"); if (lost) print("## data lost");
let s = msg.split(","); let s = msg.split(",");
// print(getTime(), s[0]); // print(getTime(), s[0]);
//return; //return;
let cmd = s[0].slice(3); let cmd = s[0].slice(3);
//print("cmd", cmd); //print("cmd", cmd);
if (cmd === "TXT") { if (cmd === "RMC") {
/* Repeat of position/speed/course */
this.messageEnd(); this.messageEnd();
return; return;
} }
if (cmd === "GGA") { if (cmd === "GGA") {
this.msg.time = s[1]; this.msg.time = s[1];
this.msg.quality = s[6]; this.msg.quality = s[6];
this.msg.in_view = s[7]; this.msg.in_view = s[7];
this.msg.hdop = s[8]; this.msg.hdop = s[8];
if (debug > 0) { if (this.debug > 0) {
print("-----------------------------------------------"); print("-----------------------------------------------");
print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]); print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]);
} }
return; return;
} }
if (cmd === "GLL") return; /* Position lat/lon */ if (cmd === "GLL") return; /* Position lat/lon */
if (cmd === "GSA") { if (cmd === "GSA") {
/* /*
$GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04 $GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04
0 1 2 15 16 17 18 0 1 2 15 16 17 18
*/ */
/* Satelites used, fix type! INTERESTING */ /* Satelites used, fix type! INTERESTING */
let sys = s[18]; let sys = s[18];
let add = {}; let add = {};
@ -747,44 +817,48 @@ let sky = {
add.pdop = s[15]; add.pdop = s[15];
add.hdop = s[16]; add.hdop = s[16];
add.vdop = s[17]; add.vdop = s[17];
sys = sys[0];
/* FIXME -- should really add to the sentence */ /* FIXME -- should really add to the sentence */
if (sys == 1) { this.msg.gp = add; } if (sys == 1) { this.msg.gp = add; }
else if (sys == 2) { this.msg.gl = add; } else if (sys == 2) { this.msg.gl = add; }
else if (sys == 4) { this.msg.bd = add; } else if (sys == 4) { this.msg.bd = add; }
else print("GSA Unknown system\n"); else {
print("GSA Unknown system -- ", sys, "\n");
//print(msg); print(msg);
}
return; return;
} }
if (s[0] === "$GPGSV") { if (s[0] === "$GPGSV") {
if (debug > 0) if (this.debug > 0)
print("Have gps sentences", s[1], "/", s[2]); print("Have gps sentences", s[1], "/", s[2]);
this.parseSats(s); this.all.parseSats(s);
if (this.split)
this.s_gp.parseSats(s);
this.msg.gp.sent = ""+s[2]; this.msg.gp.sent = ""+s[2];
return; return;
} }
if (s[0] === "$BDGSV") { if (s[0] === "$BDGSV") {
if (debug > 0) if (this.debug > 0)
print("Have baidu sentences", s[1], "/", s[2]); print("Have baidu sentences", s[1], "/", s[2]);
this.parseSats(s); this.all.parseSats(s);
if (this.split)
this.s_bd.parseSats(s);
this.msg.bd.sent = ""+s[2]; this.msg.bd.sent = ""+s[2];
return; return;
} }
if (s[0] === "$GLGSV") { if (s[0] === "$GLGSV") {
if (debug > 0) if (this.debug > 0)
print("Have glonass sentences", s[1], "/", s[2]); print("Have glonass sentences", s[1], "/", s[2]);
this.parseSats(s); this.all.parseSats(s);
if (this.split)
this.s_gl.parseSats(s);
this.msg.gl.sent = ""+s[2]; this.msg.gl.sent = ""+s[2];
return; return;
} }
if (cmd === "RMC") return; /* Repeat of position/speed/course */
if (cmd === "VTG") return; /* Speeds in knots/kph */ if (cmd === "VTG") return; /* Speeds in knots/kph */
if (cmd === "ZDA") return; /* Time + timezone */ if (cmd === "ZDA") return; /* Time + timezone */
if (cmd === "TXT") { if (cmd === "TXT") return; /* Misc text? antena open */
this.msg.finished = 1;
return; /* Misc text? antena open */
}
print(msg); print(msg);
}, },
casic_cmd: function (cmd) { casic_cmd: function (cmd) {
@ -798,7 +872,7 @@ let sky = {
this.sys += 1; this.sys += 1;
if (this.sys == 4) if (this.sys == 4)
this.sys = 0; this.sys = 0;
val = 7; let val = 7;
if (this.sys) if (this.sys)
val = 1 << (this.sys - 1); val = 1 << (this.sys - 1);
this.casic_cmd("$PCAS04,"+val); this.casic_cmd("$PCAS04,"+val);
@ -811,6 +885,20 @@ function markGps() {
Bangle.on('GPS-raw', (msg, lost) => sky.parseRaw(msg, lost)); Bangle.on('GPS-raw', (msg, lost) => sky.parseRaw(msg, lost));
} }
function onMessage() {
quality.updateGps();
if (ui.display == 4)
sky.drawEstimates();
if (ui.display == 0)
sky.drawSats(sky.all.sats);
/*
if (ui.display == 1)
sky.drawRace();
*/
}
ui.init(); ui.init();
ui.numScreens = 5; ui.numScreens = 5;
/* 0.. sat drawing /* 0.. sat drawing
@ -822,6 +910,8 @@ ui.numScreens = 5;
gps.init(); gps.init();
quality.resetAlt(); quality.resetAlt();
fmt.init(); fmt.init();
sky.onMessageEnd = onMessage;
sky.init();
sky.decorate = () => { sky.decorate = () => {
let p = 15; let p = 15;