From 40fdef46b929e007dd6b85db249e2550aa57b389 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 27 Nov 2024 21:45:54 +0100 Subject: [PATCH 1/6] spacer: first version, allow switching GPS systems --- apps/spacer/ChangeLog | 1 + apps/spacer/README.md | 4 + apps/spacer/app-icon.js | 2 + apps/spacer/app.png | Bin 0 -> 14889 bytes apps/spacer/metadata.json | 13 +++ apps/spacer/spacer.app.js | 210 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 230 insertions(+) create mode 100644 apps/spacer/ChangeLog create mode 100644 apps/spacer/README.md create mode 100644 apps/spacer/app-icon.js create mode 100644 apps/spacer/app.png create mode 100644 apps/spacer/metadata.json create mode 100644 apps/spacer/spacer.app.js diff --git a/apps/spacer/ChangeLog b/apps/spacer/ChangeLog new file mode 100644 index 000000000..263d4078d --- /dev/null +++ b/apps/spacer/ChangeLog @@ -0,0 +1 @@ +0.01: attempt to import diff --git a/apps/spacer/README.md b/apps/spacer/README.md new file mode 100644 index 000000000..e9f645320 --- /dev/null +++ b/apps/spacer/README.md @@ -0,0 +1,4 @@ +# Space Race + +Compare GPS with Baido and Glonass + diff --git a/apps/spacer/app-icon.js b/apps/spacer/app-icon.js new file mode 100644 index 000000000..903d14af5 --- /dev/null +++ b/apps/spacer/app-icon.js @@ -0,0 +1,2 @@ +require("heatshrink").decompress(atob("mEwgIQNgQFEj/gAof+jgECgeAAIIFBgwCBuACBhgCEjAOEAoQ6CmAhCDwItDoEB4AFCsEBFgUEkEDG4XEJYcL8gFCgUP+gxCAoP8DIIFBhfsiEIAoMJAogCBAoYlBiBMBAoUwrA0B////ALECI0QAocgAolgApVADolAHYnAAomAAoqdBAoKVBMoRvCOIQDCRIIFBYwKVBAoKqC4AFBVQVggTRDn0CYgQcBN4LpDV4T7IAooAJA=")) + diff --git a/apps/spacer/app.png b/apps/spacer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..ce7ac239fd0f72f3a1ab88ccfa91bcd21846caf4 GIT binary patch literal 14889 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

obkzBHHw)%!W~j@Fk!G)!@_9jb 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 oeUItr=y-W~? space race ! */ + +/* + +apps/assistedgps/custom.html + +https://github.com/espruino/EspruinoDocs/blob/master/info/Bangle.js2%20Technical.md#gps + +gsa mi rika 2d/3d fix, a taky pdop/vdop/hdop + +CFG-NAVX z CASIC_en -- umoznuje nastavit chodec / auto / letadlo + +MON-VER -- vrati version stringy + +CFG-PMS z gpssetup to zda se neumi? + +2.11.5 CFG-RATE (0x06 0x04) +*/ + +/* ui library 0.1.3 */ +let ui = { + display: 0, + numScreens: 2, + drawMsg: function(msg) { + g.reset().setFont("Vector", 35) + .setColor(1, 1, 1) + .fillRect(0, this.wi, this.w, this.y2) + .setColor(0, 0, 0) + .drawString(msg, 5, 30) + .flip(); + }, + drawBusy: function() { + this.drawMsg("\n.oO busy"); + }, + nextScreen: function() { + print("nextS"); + this.display = this.display + 1; + if (this.display == this.numScreens) + this.display = 0; + this.drawBusy(); + }, + prevScreen: function() { + print("prevS"); + this.display = this.display - 1; + if (this.display < 0) + this.display = this.numScreens - 1; + this.drawBusy(); + }, + onSwipe: function(dir) { + this.nextScreen(); + }, + wi: 24, + y2: 176, + h: 152, + w: 176, + last_b: 0, + topLeft: function() { this.drawMsg("Unimpl"); }, + topRight: function() { this.drawMsg("Unimpl"); }, + touchHandler: function(d) { + let x = Math.floor(d.x); + let y = Math.floor(d.y); + + if (d.b != 1 || this.last_b != 0) { + this.last_b = d.b; + return; + } + + print("touch", x, y, this.h, this.w); + + if ((xthis.w/2) && (ythis.y2/2)) { + print("prev"); + this.prevScreen(); + } + if ((x>this.w/2) && (y>this.y2/2)) { + print("next"); + this.nextScreen(); + } + }, + init: function() { + this.h = this.y2 - this.wi; + this.drawBusy(); + } +}; + +let graw = { + 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() { + 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); + }, + on_raw: function(msg, lost) { + let s = msg.split(","); + let cmd = s[0].slice(3); + //print("cmd", cmd); + if (cmd === "GGA") { + this.old_msg = this.msg; + this.msg = {}; + this.msg.time = s[1]; + this.msg.quality = s[6]; + this.msg.in_view = s[7]; + this.msg.hdop = s[8]; + this.msg.gp = {}; + this.msg.bd = {}; + this.msg.gl = {}; + print("-----------------------------------------------"); + print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]); + return; + } + if (cmd === "GLL") return; /* Position lat/lon */ + if (cmd === "GSA") { + /* + $GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04 + 0 1 2 15 16 17 18 + */ + /* Satelites used, fix type! INTERESTING */ + let sys = s[18]; + let add = {}; + add.d23 = s[2]; + add.pdop = s[15]; + add.hdop = s[16]; + add.vdop = s[17]; + /* FIXME -- should really add to the sentence */ + if (sys == 1) { this.msg.gp = add; } + else if (sys == 2) { this.msg.gl = add; } + else if (sys == 4) { this.msg.bd = add; } + else print("GSA Unknown system\n"); + + print(msg); + return; + } + if (s[0] === "$GPGSV") { + print("Have gps sentences", s[1], "/", s[2]); + this.msg.gp.sent = ""+s[2]; + return; + } + if (s[0] === "$BDGSV") { + print("Have baidu sentences", s[1], "/", s[2]); + this.msg.bd.sent = ""+s[2]; + return; + } + if (s[0] === "$GLGSV") { + print("Have glonass sentences", s[1], "/", s[2]); + this.msg.gl.sent = ""+s[2]; + return; + } + if (cmd === "RMC") return; /* Repeat of position/speed/course */ + if (cmd === "VTG") return; /* Speeds in knots/kph */ + if (cmd === "ZDA") return; /* Time + timezone */ + if (cmd === "TXT") { + this.msg.finished = 1; + return; /* Misc text? antena open */ + } + + print(msg); + }, + casic_cmd: function (cmd) { + var cs = 0; + for (var i=1;i 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 */ + +ui.init(); +ui.topLeft = () => graw.selectSpace(); +Bangle.on("drag", (b) => ui.touchHandler(b)); +start(); From 0df0d1acfb1a47927a67d0e0cf35ab11dac93abe Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 27 Nov 2024 22:16:55 +0100 Subject: [PATCH 2/6] spacer: Better documentation. --- apps/spacer/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/spacer/README.md b/apps/spacer/README.md index e9f645320..5a8725a96 100644 --- a/apps/spacer/README.md +++ b/apps/spacer/README.md @@ -2,3 +2,7 @@ Compare GPS with Baido and Glonass +This turns GNSS receiver into mode with all three systems enabled, and +displays debug info from all of them. Click into top left corner to +switch navigation systems. + From 2153a2b349e047bfef84d6701de953d4cab763be Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 27 Nov 2024 22:19:45 +0100 Subject: [PATCH 3/6] spacer: fix warning --- apps/spacer/spacer.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 66f6302b9..14c564e6c 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -183,7 +183,7 @@ let graw = { this.sys += 1; if (this.sys == 4) this.sys = 0; - val = 7; + let val = 7; if (this.sys) val = 1 << (this.sys - 1); this.casic_cmd("$PCAS04,"+val); From a311899f2a122625f07ff0b29235fc20867aef44 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 2 Dec 2024 19:52:55 +0100 Subject: [PATCH 4/6] 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 14c564e6c..e7f0f5178 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(); From c7a3c602e2442e8f1039f75262f533922d51f503 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 3 Dec 2024 23:57:43 +0100 Subject: [PATCH 5/6] spacer: display (no data) when data are not available. --- apps/spacer/spacer.app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index e7f0f5178..4bedaa598 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -197,7 +197,10 @@ let sky = { 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"; + if (sys.sent !== undefined && sys.d23 !== undefined) + return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; + else + return "(no data)\n"; }, display: function() { if (ui.display != 1) From 97911d7b7aabbb954ec843c7d5f3bb9bb9fd903c Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 11 Dec 2024 23:52:25 +0100 Subject: [PATCH 6/6] spacer: fix exception when sys is undefined --- apps/spacer/spacer.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 4bedaa598..13812b2a5 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -197,7 +197,7 @@ let sky = { msg: {}, tof: function(v) { let i = (1*v); return i.toFixed(0); }, fmtSys: function(sys) { - if (sys.sent !== undefined && sys.d23 !== undefined) + if (sys && sys.sent !== undefined && sys.d23 !== undefined) return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; else return "(no data)\n";