2020-09-23 10:18:20 +00:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<h2>Assisted GPS</h2>
|
|
|
|
<p>GPS can take a long time (~5 minutes) to get an accurate position the first time it is used.
|
|
|
|
AGPS uploads a few hints to the GPS receiver about satellite positions that allow it
|
|
|
|
to get a faster, more accurate fix - however they are only valid for a short period of time.</p>
|
2022-01-12 12:50:44 +00:00
|
|
|
<div id="banglejs1-info" style="display:none">
|
|
|
|
<p>You can upload data that covers a longer period of time, but the upload will take longer.</p>
|
|
|
|
<div class="form-group">
|
|
|
|
<label class="form-label">AGPS Validity time</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="agpsperiod" value="1d"><i class="form-icon"></i> 1 day (8kB)
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="agpsperiod" value="2d" checked><i class="form-icon"></i> 2 days (14kB)
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="agpsperiod" value="3d"><i class="form-icon"></i> 3 days (20kB)
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="agpsperiod" value="1wk"><i class="form-icon"></i> 1 week (46kB)
|
|
|
|
</label>
|
|
|
|
</div>
|
2020-09-23 10:18:20 +00:00
|
|
|
</div>
|
2022-01-12 12:50:44 +00:00
|
|
|
<div id="banglejs2-info" style="display:none">
|
2022-01-12 17:36:07 +00:00
|
|
|
<p>Using fewer GNSS systems may decrease the time to fix. (If unsure, select only GPS)</p>
|
|
|
|
<div class="form-group">
|
|
|
|
<label class="form-label">Select which GNSS system you want.</label>
|
|
|
|
<label class="form-radio">
|
2023-09-07 09:49:03 +00:00
|
|
|
<input type="radio" name="gnss_select" value="1" checked><i class="form-icon"></i> GPS (fastest to get a fix)
|
2022-01-12 17:36:07 +00:00
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="2"><i class="form-icon"></i> BDS
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="3"><i class="form-icon"></i> GPS+BDS
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="4"><i class="form-icon"></i> GLONASS
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="5"><i class="form-icon"></i> GPS+GLONASS
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="6"><i class="form-icon"></i> BDS+GLONASS
|
|
|
|
</label>
|
|
|
|
<label class="form-radio">
|
|
|
|
<input type="radio" name="gnss_select" value="6"><i class="form-icon"></i> GPS+BDS+GLONASS
|
|
|
|
</label>
|
|
|
|
</div>
|
2022-01-12 12:50:44 +00:00
|
|
|
</div>
|
|
|
|
<p id="upload-wrap" style="display:none">Click <button id="upload" class="btn btn-primary">Upload</button></p>
|
2020-09-23 10:18:20 +00:00
|
|
|
|
|
|
|
<script src="../../core/lib/customize.js"></script>
|
|
|
|
|
|
|
|
<script>
|
2022-01-12 12:50:44 +00:00
|
|
|
var isB1; // is Bangle.js 1?
|
|
|
|
var isB2; // is Bangle.js 2?
|
2024-10-28 12:21:08 +00:00
|
|
|
var currentPosition;
|
2022-01-12 12:50:44 +00:00
|
|
|
|
2020-09-23 10:18:20 +00:00
|
|
|
// When the 'upload' button is clicked...
|
|
|
|
document.getElementById("upload").addEventListener("click", function() {
|
2022-01-12 12:50:44 +00:00
|
|
|
var url;
|
|
|
|
if (isB1) {
|
|
|
|
var radios = document.getElementsByName('agpsperiod');
|
|
|
|
url = "https://www.espruino.com/agps/assistnow_1d.base64";
|
|
|
|
for (var i=0; i<radios.length; i++)
|
|
|
|
if (radios[i].checked)
|
|
|
|
url = "https://www.espruino.com/agps/assistnow_"+radios[i].value+".base64";
|
|
|
|
}
|
|
|
|
if (isB2) {
|
|
|
|
url = "https://www.espruino.com/agps/casic.base64";
|
|
|
|
}
|
2020-09-23 10:18:20 +00:00
|
|
|
console.log("Sending...");
|
|
|
|
//var text = document.getElementById("agpsperiod").value;
|
|
|
|
get(url, function(b64) {
|
|
|
|
var js = jsFromBase64(b64);
|
|
|
|
sendCustomizedApp({
|
|
|
|
storage:[
|
|
|
|
{name:"RAM", content:js},
|
|
|
|
]
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-01-12 12:50:44 +00:00
|
|
|
// =================================================== Bangle.js 1 UBLOX
|
|
|
|
|
2020-09-23 10:18:20 +00:00
|
|
|
function UBX_CMD(cmd) {
|
|
|
|
var d = [0xB5,0x62]; // sync chars
|
|
|
|
d = d.concat(cmd);
|
|
|
|
var a=0,b=0;
|
|
|
|
for (var i=2;i<d.length;i++) {
|
|
|
|
a += d[i];
|
|
|
|
b += a;
|
|
|
|
}
|
|
|
|
d.push(a&255,b&255);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
function UBX_MGA_INI_TIME_UTC() {
|
|
|
|
var a = new Uint8Array(4+24);
|
|
|
|
a.set([0x13,0x40,24,0]);
|
|
|
|
a.set([ 0x10, // 0: type
|
|
|
|
0, // 1: version
|
|
|
|
0, // 2: ref - none
|
|
|
|
0x80] ); // 3: leapsecs - unknown
|
|
|
|
var d = new Date();
|
|
|
|
d.setTime(d.getTime()+d.getTimezoneOffset()*60000); // get as UTC
|
|
|
|
var dv = new DataView(a.buffer, 4);
|
|
|
|
dv.setUint16(4, d.getFullYear());
|
|
|
|
dv.setUint8(6, d.getMonth()+1);
|
|
|
|
dv.setUint8(7, d.getDate());
|
|
|
|
dv.setUint8(8, d.getHours());
|
|
|
|
dv.setUint8(9, d.getMinutes());
|
|
|
|
dv.setUint8(10, d.getSeconds());
|
|
|
|
dv.setUint16(16, 10*60); // seconds part of accuracy - 10 minutes
|
|
|
|
return UBX_CMD([].slice.call(a));
|
|
|
|
}
|
|
|
|
|
2022-01-12 12:50:44 +00:00
|
|
|
// =================================================== Bangle.js 2 CASIC
|
2024-10-28 12:21:08 +00:00
|
|
|
// https://www.espruino.com/Bangle.js2+Technical#gps
|
2022-01-12 12:50:44 +00:00
|
|
|
|
|
|
|
function CASIC_CHECKSUM(cmd) {
|
|
|
|
var cs = 0;
|
|
|
|
for (var i=1;i<cmd.length;i++)
|
|
|
|
cs = cs ^ cmd.charCodeAt(i);
|
|
|
|
return cmd+"*"+cs.toString(16).toUpperCase().padStart(2, '0');
|
|
|
|
}
|
|
|
|
|
2024-10-28 12:21:08 +00:00
|
|
|
// Send a binary CASIC packet, eg: {classId:6, messageId:0, payload:[]}
|
|
|
|
function CASIC_PKT(pkt) {
|
|
|
|
pkt.payload = pkt.payload || [];
|
|
|
|
var plen = pkt.payload.length;
|
|
|
|
var msg = new Uint8Array(10+pkt.payload.length);
|
|
|
|
msg.set([0xBA,0xCE,
|
|
|
|
plen, // LENGTH
|
|
|
|
0x00,
|
|
|
|
pkt.classId, // CLASS ID
|
|
|
|
pkt.messageId]); // MESSAGE ID
|
|
|
|
msg.set(pkt.payload, 6);
|
|
|
|
var dv = new DataView(msg.buffer);
|
|
|
|
// checksum
|
|
|
|
var ckSum = 0;
|
|
|
|
for (i = -4; i < plen; i+=4)
|
|
|
|
ckSum = 0|(ckSum+dv.getUint32(6+i, true));
|
|
|
|
dv.setUint32(6+plen, ckSum, true);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send AID_INI message, {lat,lon,alt}
|
|
|
|
function AID_INI(pos) {
|
|
|
|
var msg = new Uint8Array(56);
|
|
|
|
var dv = new DataView(msg.buffer);
|
|
|
|
/*
|
|
|
|
double xOrLat, yOrLon, zOrAlt;
|
|
|
|
double tow; // 24
|
|
|
|
float df; // 32
|
|
|
|
float posAcc; // 36
|
|
|
|
float tAcc; // 40
|
|
|
|
float fAcc; // 44
|
|
|
|
unsigned int res; // 48
|
|
|
|
unsigned short int wn; // 52
|
|
|
|
unsigned char timeSource; // 54
|
|
|
|
unsigned char flags; // 55
|
|
|
|
*/
|
|
|
|
var ms = Date.now();
|
|
|
|
var wk = (ms-new Date("1980-01-06T00:00:00Z")) / 604800000;
|
|
|
|
var wn = Math.floor(wk); // week number
|
|
|
|
var tow = (wk-wn) * 604800; // seconds in week
|
|
|
|
dv.setFloat64(0, pos.lat, true); // xOrLat
|
|
|
|
dv.setFloat64(8, pos.lon, true); // yOrLon
|
|
|
|
dv.setFloat64(16, pos.alt, true); // zOrAlt
|
|
|
|
dv.setFloat64(24, tow, true); // tow
|
|
|
|
dv.setFloat32(32, 0, true); // df
|
|
|
|
dv.setFloat32(36, 0, true); // posAcc
|
|
|
|
dv.setFloat32(40, 0, true); // tAcc
|
|
|
|
dv.setFloat32(44, 0, true); // fAcc
|
|
|
|
dv.setUint32(48, 0, true); // res
|
|
|
|
dv.setUint16(52, wn, true); // wn
|
|
|
|
dv.setUint8(54,0); // timeSource
|
|
|
|
dv.setUint8(55, 0x23); // flags ( lat/lon and clock valid, no drift data )
|
|
|
|
return CASIC_PKT({classId:0x0B, messageId:0x01, payload:msg});
|
|
|
|
}
|
|
|
|
|
2022-01-12 12:50:44 +00:00
|
|
|
// ===================================================
|
|
|
|
|
2020-09-23 10:18:20 +00:00
|
|
|
function jsFromBase64(b64) {
|
|
|
|
var bin = atob(b64);
|
|
|
|
var chunkSize = 128;
|
2023-01-13 08:29:39 +00:00
|
|
|
var js = "\x10Bangle.setGPSPower(1,'agps');\n"; // turn GPS on
|
2022-01-12 12:50:44 +00:00
|
|
|
if (isB1) { // UBLOX
|
|
|
|
//js += `\x10Bangle.on('GPS-raw',function (d) { if (d.startsWith("\\xB5\\x62\\x05\\x01")) Terminal.println("GPS ACK"); else if (d.startsWith("\\xB5\\x62\\x05\\x00")) Terminal.println("GPS NACK"); })\n`;
|
|
|
|
//js += "\x10var t=getTime()+1;while(t>getTime());\n"; // wait 1 sec
|
|
|
|
js += `\x10Serial1.write(atob("${btoa(String.fromCharCode.apply(null,UBX_MGA_INI_TIME_UTC()))}"))\n`; // set GPS time
|
|
|
|
}
|
|
|
|
if (isB2) { // CASIC
|
2022-01-12 17:36:07 +00:00
|
|
|
// Select what GNSS System to use for decreased fix time.
|
|
|
|
var radios = document.getElementsByName('gnss_select');
|
|
|
|
var gnss_select="1";
|
|
|
|
for (var i=0; i<radios.length; i++)
|
|
|
|
if (radios[i].checked)
|
|
|
|
gnss_select=radios[i].value;
|
2023-05-05 13:29:53 +00:00
|
|
|
js += `\x10var t=getTime()+0.5;while (getTime()<t);\n`; // This is nasty - but we just wait here until the GPS has had time to boot
|
2022-01-12 17:36:07 +00:00
|
|
|
js += `\x10Serial1.println("${CASIC_CHECKSUM("$PCAS04,"+gnss_select)}")\n`; // set GNSS mode
|
2023-05-05 13:29:53 +00:00
|
|
|
js += `\x10Serial1.println("${CASIC_CHECKSUM("$PCAS03,1,0,0,1,1,0,0,0")}")\n`; // enable GGA,GSV,RMC packets (new Bangle.js 2 GPS firmwares don't include RMC by default!)
|
2024-10-28 12:21:08 +00:00
|
|
|
// If the browser let us have the current location, give it to the GPS chip to get a faster fix
|
|
|
|
if (currentPosition) {
|
|
|
|
js += `\x10Serial1.write([${AID_INI(currentPosition).join(",")}])\n`;
|
|
|
|
}
|
2023-05-05 13:29:53 +00:00
|
|
|
// Serial1.println("$PCAS06,0*1B") gets the current firmware version
|
2022-01-12 12:50:44 +00:00
|
|
|
}
|
2020-12-08 15:23:53 +00:00
|
|
|
|
2020-09-23 10:18:20 +00:00
|
|
|
for (var i=0;i<bin.length;i+=chunkSize) {
|
|
|
|
var chunk = bin.substr(i,chunkSize);
|
2020-12-08 15:23:53 +00:00
|
|
|
js += `\x10Serial1.write(atob("${btoa(chunk)}"))\n`;
|
2020-09-23 10:18:20 +00:00
|
|
|
}
|
2023-02-06 11:20:36 +00:00
|
|
|
js += "\x10setTimeout(() => Bangle.setGPSPower(0,'agps'), 1000);\n"; // turn GPS off after a delay
|
2020-09-23 10:18:20 +00:00
|
|
|
return js;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get(url,callback) {
|
|
|
|
console.log("Loading "+url);
|
|
|
|
var oReq = new XMLHttpRequest();
|
|
|
|
oReq.addEventListener("load", function() {
|
|
|
|
var b64 = this.responseText;
|
|
|
|
console.log("Response received...");
|
|
|
|
callback(b64);
|
|
|
|
});
|
|
|
|
oReq.open("GET", url);
|
|
|
|
oReq.send();
|
|
|
|
}
|
|
|
|
|
2022-01-12 12:50:44 +00:00
|
|
|
// Called when we know what device we're using
|
|
|
|
function onInit(device) {
|
|
|
|
isB2 = (device && device.id=="BANGLEJS2");
|
|
|
|
isB1 = !isB2;
|
|
|
|
document.getElementById("banglejs1-info").style = isB1?"":"display:none";
|
|
|
|
document.getElementById("banglejs2-info").style = isB2?"":"display:none";
|
|
|
|
document.getElementById("upload-wrap").style = "";
|
2024-10-28 12:21:08 +00:00
|
|
|
|
|
|
|
if (isB2) {
|
|
|
|
// get current position for AGPS improvement
|
|
|
|
navigator.geolocation.getCurrentPosition(function(position) {
|
|
|
|
currentPosition = {
|
|
|
|
lat : position.coords.latitude,
|
|
|
|
lon : position.coords.longitude,
|
|
|
|
alt : 0|position.coords.altitude
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2022-01-12 12:50:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-28 12:21:08 +00:00
|
|
|
|
2020-09-23 10:18:20 +00:00
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|