From a311899f2a122625f07ff0b29235fc20867aef44 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 2 Dec 2024 19:52:55 +0100 Subject: [PATCH] spacer: merge satellite view --- apps/spacer/spacer.app.js | 140 +++++++++++++++++++++++++++++++++++--- 1 file changed, 130 insertions(+), 10 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 14c564e6c0..e7f0f5178a 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -1,7 +1,16 @@ -/* -> space race ! */ +/* Space race */ /* +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 + apps/assistedgps/custom.html https://github.com/espruino/EspruinoDocs/blob/master/info/Bangle.js2%20Technical.md#gps @@ -17,7 +26,7 @@ CFG-PMS z gpssetup to zda se neumi? 2.11.5 CFG-RATE (0x06 0x04) */ -/* ui library 0.1.3 */ +/* ui library 0.1.4 */ let ui = { display: 0, numScreens: 2, @@ -83,10 +92,107 @@ let ui = { init: function() { this.h = this.y2 - this.wi; this.drawBusy(); - } + }, + /* radial angle -- convert 0..1 to 0..2pi */ + radA: function(p) { return p*(Math.PI*2); }, + /* radial distance -- convert 0..1 to something that fits on screen */ + radD: function(d) { return d*(ui.h/2); }, + + /* given angle/distance, get X coordinate */ + radX: function(p, d) { + let a = this.radA(p); + return this.w/2 + Math.sin(a)*this.radD(d); + }, + /* given angle/distance, get Y coordinate */ + radY: function(p, d) { + let a = this.radA(p); + return this.h/2 - Math.cos(a)*this.radD(d) + this.wi; + }, + radLine: function(a1, d1, a2, d2) { + g.drawLine(this.radX(a1, d1), this.radY(a1, d1), this.radX(a2, d2), this.radY(a2, d2)); + }, + radCircle: function(d) { + g.drawCircle(this.radX(0, 0), this.radY(0, 0), this.radD(d)); + if (1) + return; + let step = 0.05; + for (let i = 0; i < 1; i += 0.05) { + this.radLine(i - step, d, i, d); + } + }, }; -let graw = { +let fix = {}; /* Global for sky library */ + +/* sky library v0.1.0 */ +let sky = { + sats: [], + snum: 0, + sats_used: 0, + sky_start: -1, + this_usable: 0, + + 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); + }, + + snrLim: 28, + 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) { + let view = 1 * s[3]; + let k = Math.min(4, view - this.snum); + for (let i = 4, j = 0; j < k; j++) { + let sat = { id: s[i++], ele: 1 * s[i++], azi: 1 * s[i++], snr: s[i++] }; + if (sat.snr === "") + sat.snr = 0; + if (sat.snr >= this.snrLim) { + this.sats_used++; + print(sat.id, sat.snr); + } + this.sats[this.snum++] = sat; + } + }, + old_msg: {}, msg: {}, tof: function(v) { let i = (1*v); return i.toFixed(0); }, @@ -94,6 +200,8 @@ let graw = { return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; }, display: function() { + 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" + @@ -107,7 +215,8 @@ let graw = { .setFontAlign(-1, -1) .drawString(msg, 0, 0); }, - on_raw: function(msg, lost) { + parseRaw: function(msg, lost) { + if (lost) print("## data lost"); let s = msg.split(","); let cmd = s[0].slice(3); //print("cmd", cmd); @@ -123,6 +232,12 @@ let graw = { this.msg.gl = {}; print("-----------------------------------------------"); print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]); + this.drawSats(this.sats); + if (this.sats_used < 5) + this.sky_start = getTime(); + this.snum = 0; + this.sats = []; + this.sats_used = 0; return; } if (cmd === "GLL") return; /* Position lat/lon */ @@ -149,16 +264,19 @@ let graw = { } if (s[0] === "$GPGSV") { print("Have gps sentences", s[1], "/", s[2]); + this.parseSats(s); this.msg.gp.sent = ""+s[2]; return; } if (s[0] === "$BDGSV") { print("Have baidu sentences", s[1], "/", s[2]); + this.parseSats(s); this.msg.bd.sent = ""+s[2]; return; } if (s[0] === "$GLGSV") { print("Have glonass sentences", s[1], "/", s[2]); + this.parseSats(s); this.msg.gl.sent = ""+s[2]; return; } @@ -193,18 +311,20 @@ let graw = { function start() { Bangle.setGPSPower(1); - Bangle.on('GPS-raw', function(a, b) { graw.on_raw(a, b); }); + Bangle.on('GPS-raw', function(a, b) { sky.parseRaw(a, b); }); setTimeout(function() { Bangle.removeAllListeners('GPS-raw'); }, 1000000); - setInterval(function() { graw.display(); }, 1000); + setInterval(function() { sky.display(); }, 1000); } // CASIC_CMD("$PCAS06,0"); /* Query product information */ -setTimeout(() => graw.casic_cmd("$PCAS04,7"), 1000); /* Enable gps + beidou + glonass */ -//setTimeout(() => graw.casic_cmd("$PCAS10,2"), 1200); /* 2: cold start, 1 warm start, 0: hot start */ +setTimeout(() => sky.casic_cmd("$PCAS04,7"), 1000); /* Enable gps + beidou + glonass */ +setTimeout(() => sky.casic_cmd("$PCAS03,1,1,1,1,1,1,1,1"), 1000); /* Enable gps + beidou + glonass */ + +//setTimeout(() => sky.casic_cmd("$PCAS10,2"), 1200); /* 2: cold start, 1 warm start, 0: hot start */ ui.init(); -ui.topLeft = () => graw.selectSpace(); +ui.topLeft = () => sky.selectSpace(); Bangle.on("drag", (b) => ui.touchHandler(b)); start();