BangleApps/apps/speedalt/app.js

724 lines
18 KiB
JavaScript
Raw Normal View History

2021-01-21 02:42:19 +00:00
/*
Speed and Altitude [speedalt]
2021-01-26 22:33:16 +00:00
Mike Bennett mike[at]kereru.com
2021-03-09 04:53:50 +00:00
1.00 : Use new GPS settings module
1.01 : Third mode large clock display
2021-03-02 00:36:42 +00:00
1.02 : add smoothing with kalman filter
2021-01-21 02:42:19 +00:00
*/
2022-02-15 17:24:36 +00:00
//var v = '1.02g';
const BANGLEJS2 = process.env.HWVERSION==2;
const screenH = g.getHeight();
const screenH_Half = screenH / 2;
const screenH_Third = screenH / 3;
const screenH_TwoThirds = screenH * 2 / 3;
const screenW = g.getWidth();
const screenW_Half = screenW / 2;
const fontFactorB2 = 2/3;
/*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */
var KalmanFilter = (function () {
'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/**
* KalmanFilter
* @class
* @author Wouter Bulten
* @see {@link http://github.com/wouterbulten/kalmanjs}
* @version Version: 1.0.0-beta
* @copyright Copyright 2015-2018 Wouter Bulten
* @license MIT License
* @preserve
*/
var KalmanFilter =
/*#__PURE__*/
function () {
/**
* Create 1-dimensional kalman filter
* @param {Number} options.R Process noise
* @param {Number} options.Q Measurement noise
* @param {Number} options.A State vector
* @param {Number} options.B Control vector
* @param {Number} options.C Measurement vector
* @return {KalmanFilter}
*/
function KalmanFilter() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$R = _ref.R,
R = _ref$R === void 0 ? 1 : _ref$R,
_ref$Q = _ref.Q,
Q = _ref$Q === void 0 ? 1 : _ref$Q,
_ref$A = _ref.A,
A = _ref$A === void 0 ? 1 : _ref$A,
_ref$B = _ref.B,
B = _ref$B === void 0 ? 0 : _ref$B,
_ref$C = _ref.C,
C = _ref$C === void 0 ? 1 : _ref$C;
_classCallCheck(this, KalmanFilter);
this.R = R; // noise power desirable
this.Q = Q; // noise power estimated
this.A = A;
this.C = C;
this.B = B;
this.cov = NaN;
this.x = NaN; // estimated signal without noise
}
/**
* Filter a new value
* @param {Number} z Measurement
* @param {Number} u Control
* @return {Number}
*/
_createClass(KalmanFilter, [{
key: "filter",
value: function filter(z) {
var u = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (isNaN(this.x)) {
this.x = 1 / this.C * z;
this.cov = 1 / this.C * this.Q * (1 / this.C);
} else {
// Compute prediction
var predX = this.predict(u);
var predCov = this.uncertainty(); // Kalman gain
var K = predCov * this.C * (1 / (this.C * predCov * this.C + this.Q)); // Correction
this.x = predX + K * (z - this.C * predX);
this.cov = predCov - K * this.C * predCov;
}
return this.x;
}
/**
* Predict next value
* @param {Number} [u] Control
* @return {Number}
*/
}, {
key: "predict",
value: function predict() {
var u = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return this.A * this.x + this.B * u;
}
/**
* Return uncertainty of filter
* @return {Number}
*/
}, {
key: "uncertainty",
value: function uncertainty() {
return this.A * this.cov * this.A + this.R;
}
/**
* Return the last filtered measurement
* @return {Number}
*/
}, {
key: "lastMeasurement",
value: function lastMeasurement() {
return this.x;
}
/**
* Set measurement noise Q
* @param {Number} noise
*/
}, {
key: "setMeasurementNoise",
value: function setMeasurementNoise(noise) {
this.Q = noise;
}
/**
* Set the process noise R
* @param {Number} noise
*/
}, {
key: "setProcessNoise",
value: function setProcessNoise(noise) {
this.R = noise;
}
}]);
return KalmanFilter;
}();
return KalmanFilter;
}());
2021-01-21 02:42:19 +00:00
2022-02-15 17:24:36 +00:00
var buf = Graphics.createArrayBuffer(screenW,screenH_TwoThirds,2,{msb:true});
if (!BANGLEJS2)
require("Font7x11Numeric7Seg").add(Graphics); // Load fonts
2021-01-26 22:33:16 +00:00
2021-02-01 09:48:30 +00:00
var lf = {fix:0,satellites:0};
2021-01-26 22:33:16 +00:00
var showMax = 0; // 1 = display the max values. 0 = display the cur fix
2021-02-05 08:48:15 +00:00
var pwrSav = 1; // 1 = default power saving with watch screen off and GPS to PMOO mode. 0 = screen kept on.
2021-01-28 10:22:07 +00:00
var canDraw = 1;
2021-01-26 22:33:16 +00:00
var time = ''; // Last time string displayed. Re displayed in background colour to remove before drawing new time.
2021-02-05 00:22:00 +00:00
var tmrLP; // Timer for delay in switching to low power after screen turns off
2021-01-21 02:42:19 +00:00
2021-01-26 22:33:16 +00:00
var max = {};
max.spd = 0;
max.alt = 0;
2021-03-02 20:31:17 +00:00
max.n = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data.
2021-01-21 02:42:19 +00:00
2022-02-15 17:24:36 +00:00
var emulator = (process.env.BOARD=="EMSCRIPTEN" || process.env.BOARD=="EMSCRIPTEN2")?1:0; // 1 = running in emulator. Supplies test values;
2021-01-26 22:33:16 +00:00
var wp = {}; // Waypoint to use for distance from cur position.
2024-03-04 20:34:50 +00:00
//var SATinView = 0;
function nxtWp(inc){
2021-02-12 01:09:11 +00:00
cfg.wp+=inc;
loadWp();
}
function loadWp() {
var w = require("waypoints").load();
2021-02-12 01:09:11 +00:00
if (cfg.wp>=w.length) cfg.wp=0;
if (cfg.wp<0) cfg.wp = w.length-1;
2021-02-02 02:57:41 +00:00
savSettings();
2021-02-12 01:09:11 +00:00
wp = w[cfg.wp];
}
function radians(a) {
return a*Math.PI/180;
}
function distance(a,b){
var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2));
var y = radians(b.lat-a.lat);
2022-02-15 17:24:36 +00:00
// Distance in selected units
var d = Math.sqrt(x*x + y*y) * 6371000;
2021-02-12 01:09:11 +00:00
d = (d/parseFloat(cfg.dist)).toFixed(2);
if ( d >= 100 ) d = parseFloat(d).toFixed(1);
if ( d >= 1000 ) d = parseFloat(d).toFixed(0);
return d;
}
function drawFix(dat) {
2021-01-28 10:22:07 +00:00
if (!canDraw) return;
2021-01-26 22:33:16 +00:00
2021-01-28 10:22:07 +00:00
buf.clear();
2022-02-15 17:24:36 +00:00
var v = '';
2021-01-26 22:33:16 +00:00
var u='';
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
// Primary Display
v = (cfg.primSpd)?dat.speed.toString():dat.alt.toString();
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
// Primary Units
u = (cfg.primSpd)?cfg.spd_unit:dat.alt_units;
2021-01-26 22:33:16 +00:00
2021-02-04 04:03:44 +00:00
drawPrimary(v,u);
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
// Secondary Display
v = (cfg.primSpd)?dat.alt.toString():dat.speed.toString();
2021-01-26 22:33:16 +00:00
// Secondary Units
u = (cfg.primSpd)?dat.alt_units:cfg.spd_unit;
2022-02-15 17:24:36 +00:00
2021-02-04 04:03:44 +00:00
drawSecondary(v,u);
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
// Time
drawTime();
// Waypoint name
drawWP();
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
//Sats
if ( dat.age > 10 ) {
if ( dat.age > 90 ) dat.age = '>90';
drawSats('Age:'+dat.age);
2021-02-05 01:03:07 +00:00
}
else drawSats('Sats:'+dat.sats);
2022-02-15 17:24:36 +00:00
/* else if (!BANGLEJS2) {
drawSats('Sats:'+dat.sats);
} else {
if (lf.fix) {
if(emulator)console.log("fix "+lf.fix);
drawSats('Sats:'+dat.sats);
} else {
if(emulator)console.log("inView: "+SATinView);
drawSats('View:' + SATinView);
}
}
*/
2021-01-28 10:22:07 +00:00
g.reset();
g.drawImage(img,0,40);
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
}
2021-01-21 02:42:19 +00:00
function drawClock() {
if (!canDraw) return;
buf.clear();
drawTime();
drawWP();
g.reset();
g.drawImage(img,0,40);
}
2021-01-26 22:33:16 +00:00
function drawPrimary(n,u) {
2022-02-15 17:24:36 +00:00
if(emulator)console.log("drawPrimary: " + n +" "+ u);
2021-01-21 02:42:19 +00:00
// Primary Display
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
var s=40; // Font size
2021-02-04 04:03:44 +00:00
var l=n.length;
2022-02-15 17:24:36 +00:00
2021-02-04 04:03:44 +00:00
if ( l <= 7 ) s=48;
if ( l <= 6 ) s=55;
2021-02-21 21:07:54 +00:00
if ( l <= 5 ) s=66;
2021-02-04 04:03:44 +00:00
if ( l <= 4 ) s=85;
if ( l <= 3 ) s=110;
2022-02-15 17:24:36 +00:00
buf.setFontAlign(0,-1); //Centre
buf.setColor(1);
if (BANGLEJS2) s *= fontFactorB2;
2021-01-21 02:42:19 +00:00
buf.setFontVector(s);
2022-02-15 17:24:36 +00:00
buf.drawString(n,screenW_Half-10,0);
// Primary Units
s = 35; // Font size
2021-01-21 02:42:19 +00:00
buf.setFontAlign(1,-1,3); //right
2022-02-15 17:24:36 +00:00
buf.setColor(2);
if (BANGLEJS2) s = 20;
buf.setFontVector(s);
buf.drawString(u,screenW-30,0);
2021-01-26 22:33:16 +00:00
}
2021-01-21 02:42:19 +00:00
2021-01-26 22:33:16 +00:00
function drawSecondary(n,u) {
2022-02-15 17:24:36 +00:00
if(emulator)console.log("drawSecondary: " + n +" "+ u);
var xu = 180; // units X position
2021-02-04 04:03:44 +00:00
var l=n.length;
2022-02-15 17:24:36 +00:00
if ( l <= 5 ) xu = 155;
if ( l <= 4 ) xu = 125;
if ( l <= 3 ) xu = 100;
if ( l <= 2 ) xu = 65;
if ( l <= 1 ) xu = 35;
buf.setFontAlign(-1,1); //left, bottom
buf.setColor(1);
var s = 45; // Font size
if (BANGLEJS2) s *= fontFactorB2;
buf.setFontVector(s);
buf.drawString(n,5,screenH_TwoThirds-20);
2021-01-21 02:42:19 +00:00
// Secondary Units
buf.setFontAlign(-1,1); //left, bottom
2022-02-15 17:24:36 +00:00
buf.setColor(2);
s = 30; // Font size
if (BANGLEJS2) s *= fontFactorB2;
buf.setFontVector(s);
2022-03-12 11:12:51 +00:00
buf.drawString(u,xu - (BANGLEJS2*xu/5),screenH_TwoThirds-25);
2021-01-21 02:42:19 +00:00
}
2021-01-26 22:33:16 +00:00
function drawTime() {
var x, y;
2022-02-15 17:24:36 +00:00
if ( cfg.modeA == 2 ) {
2022-02-15 17:24:36 +00:00
x = screenW_Half;
y = 0;
buf.setFontAlign(0,-1);
buf.setFontVector(screenH_Third);
}
else {
x = 0;
2022-02-15 17:24:36 +00:00
y = screenH_TwoThirds;
buf.setFontAlign(-1,1);
2022-02-15 17:24:36 +00:00
if (!BANGLEJS2)
buf.setFont("7x11Numeric7Seg", 2);
2022-02-15 17:24:36 +00:00
else
buf.setFont("6x8", 2);
}
2021-01-21 02:42:19 +00:00
2021-01-26 22:33:16 +00:00
buf.setColor(0);
buf.drawString(time,x,y);
time = require("locale").time(new Date(),1);
2022-02-15 17:24:36 +00:00
buf.setColor(3);
2021-01-26 22:33:16 +00:00
buf.drawString(time,x,y);
}
2021-01-21 02:42:19 +00:00
2022-02-15 17:24:36 +00:00
function drawWP() { // from waypoints.json - see README.md
var nm = wp.name;
if ( nm == undefined || nm == 'NONE' || cfg.modeA ==1 ) nm = '';
2022-02-15 17:24:36 +00:00
if (emulator) nm="waypoint";
buf.setColor(2);
var s = 20; // Font size
if ( cfg.modeA == 0 ) { // dist mode
2022-02-15 17:24:36 +00:00
if(emulator)console.log("drawWP() 0: "+nm);
buf.setFontAlign(-1,1); //left, bottom
2022-02-15 17:24:36 +00:00
if (BANGLEJS2) s *= fontFactorB2;
buf.setFontVector(s);
2022-03-12 11:12:51 +00:00
buf.drawString(nm.substring(0,6),72,screenH_TwoThirds-(BANGLEJS2 * 15));
}
if ( cfg.modeA == 2 ) { // clock/large mode
2022-02-15 17:24:36 +00:00
if(emulator)console.log("drawWP() 2: "+nm);
s = 55; // Font size
buf.setFontAlign(0,1); //left, bottom
2022-02-15 17:24:36 +00:00
if (BANGLEJS2) s *= fontFactorB2;
buf.setFontVector(s);
2022-02-15 17:43:03 +00:00
buf.drawString(nm.substring(0,6),screenW_Half,screenH_TwoThirds-(BANGLEJS2 * 20));
}
2022-02-15 17:24:36 +00:00
}
2021-01-26 22:33:16 +00:00
function drawSats(sats) {
2021-02-01 06:40:37 +00:00
2022-02-15 17:24:36 +00:00
buf.setColor(3);
2021-02-01 06:40:37 +00:00
buf.setFont("6x8", 2);
buf.setFontAlign(1,1); //right, bottom
2022-02-15 17:24:36 +00:00
buf.drawString(sats,screenW,screenH_TwoThirds);
s = 30; // Font size
if (BANGLEJS2) s = 18;
buf.setFontVector(s);
buf.setColor(2);
2021-02-01 09:48:30 +00:00
if ( cfg.modeA == 1 ) {
2022-02-15 17:24:36 +00:00
buf.drawString('A',screenW,140-(BANGLEJS2 * 40));
if ( showMax ) {
buf.setFontAlign(0,1); //centre, bottom
2022-03-12 11:12:51 +00:00
buf.drawString('MAX',screenW_Half,screenH_TwoThirds + 4);
}
2021-02-01 09:48:30 +00:00
}
2022-02-15 17:24:36 +00:00
if ( cfg.modeA == 0 ) buf.drawString('D',screenW,140-(BANGLEJS2 * 40));
2021-01-26 22:33:16 +00:00
}
2021-01-21 02:42:19 +00:00
function onGPS(fix) {
2022-02-15 17:24:36 +00:00
2021-02-01 06:40:37 +00:00
if ( emulator ) {
2021-02-01 22:09:40 +00:00
fix.fix = 1;
fix.speed = 10 + (Math.random()*5);
fix.alt = 354 + (Math.random()*50);
2021-02-01 06:40:37 +00:00
fix.lat = -38.92;
2022-02-15 17:24:36 +00:00
fix.lon = 175.7613350;
2021-02-01 06:40:37 +00:00
fix.course = 245;
fix.satellites = 12;
fix.time = new Date();
fix.smoothed = 0;
2021-02-01 06:40:37 +00:00
}
2021-02-04 21:31:26 +00:00
2021-02-01 06:40:37 +00:00
var m;
2021-01-26 22:33:16 +00:00
2022-02-15 17:24:36 +00:00
var sp = '---';
2021-02-04 05:58:03 +00:00
var al = '---';
var di = '---';
2021-02-04 04:03:44 +00:00
var age = '---';
2021-02-04 21:31:26 +00:00
if (fix.fix) lf = fix;
if (lf.fix) {
2022-02-15 17:24:36 +00:00
// if (BANGLEJS2 && !emulator) Bangle.removeListener('GPS-raw', onGPSraw);
// Smooth data
if ( lf.smoothed !== 1 ) {
if ( cfg.spdFilt ) lf.speed = spdFilter.filter(lf.speed);
if ( cfg.altFilt ) lf.alt = altFilter.filter(lf.alt);
lf.smoothed = 1;
2021-03-02 20:31:17 +00:00
if ( max.n <= 15 ) max.n++;
}
2022-02-15 17:24:36 +00:00
2021-02-04 21:47:54 +00:00
// Speed
2021-02-12 01:09:11 +00:00
if ( cfg.spd == 0 ) {
2021-02-04 21:47:54 +00:00
m = require("locale").speed(lf.speed).match(/([0-9,\.]+)(.*)/); // regex splits numbers from units
sp = parseFloat(m[1]);
2021-02-12 01:09:11 +00:00
cfg.spd_unit = m[2];
2021-02-04 21:47:54 +00:00
}
2021-02-12 01:09:11 +00:00
else sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units
2022-02-15 17:24:36 +00:00
2021-02-04 21:47:54 +00:00
if ( sp < 10 ) sp = sp.toFixed(1);
else sp = Math.round(sp);
2021-03-02 20:31:17 +00:00
if (parseFloat(sp) > parseFloat(max.spd) && max.n > 15 ) max.spd = parseFloat(sp);
2021-02-04 21:47:54 +00:00
// Altitude
al = lf.alt;
2021-02-12 01:09:11 +00:00
al = Math.round(parseFloat(al)/parseFloat(cfg.alt));
2021-03-02 20:31:17 +00:00
if (parseFloat(al) > parseFloat(max.alt) && max.n > 15 ) max.alt = parseFloat(al);
2021-02-04 21:47:54 +00:00
// Distance to waypoint
di = distance(lf,wp);
if (isNaN(di)) di = 0;
// Age of last fix (secs)
2021-02-04 22:27:07 +00:00
age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000));
2021-02-04 22:14:34 +00:00
}
2022-02-15 17:24:36 +00:00
if ( cfg.modeA == 1 ) {
2022-02-15 17:24:36 +00:00
if ( showMax )
drawFix({
speed:max.spd,
sats:lf.satellites,
alt:max.alt,
alt_units:cfg.alt_unit,
age:age,
fix:lf.fix
}); // Speed and alt maximums
2022-02-15 17:24:36 +00:00
else
drawFix({
speed:sp,
sats:lf.satellites,
alt:al,
alt_units:cfg.alt_unit,
age:age,
fix:lf.fix
}); // Show speed/altitude
}
if ( cfg.modeA == 0 ) {
2021-02-04 21:47:54 +00:00
// Show speed/distance
2022-02-15 17:24:36 +00:00
if ( di <= 0 )
drawFix({
speed:sp,
sats:lf.satellites,
alt:'',
alt_units:'',
age:age,
fix:lf.fix
}); // No WP selected
2022-02-15 17:24:36 +00:00
else
drawFix({
speed:sp,
sats:lf.satellites,
alt:di,
alt_units:cfg.dist_unit,
age:age,
fix:lf.fix
});
2021-02-04 21:47:54 +00:00
}
if ( cfg.modeA == 2 ) {
// Large clock
drawClock();
}
2021-01-21 02:42:19 +00:00
2021-01-28 21:03:18 +00:00
}
2022-03-12 11:12:51 +00:00
function btn1press(longpress) {
if(emulator) console.log("Btn1, long="+longpress);
if ( cfg.modeA == 1 ) { // Spd+Alt mode - Switch between fix and MAX
if ( !longpress ) showMax = !showMax; // Short press toggle fix/max display
else { max.spd = 0; max.alt = 0; } // Long press resets max values.
2021-02-06 04:10:17 +00:00
}
2022-03-12 11:12:51 +00:00
else nxtWp(1); // Spd+Dist or Clock mode - Select next waypoint
2021-02-06 04:10:17 +00:00
onGPS(lf);
2022-03-12 11:12:51 +00:00
}
function btn2press(){
if(emulator) console.log("Btn2");
2022-02-15 17:24:36 +00:00
pwrSav=!pwrSav;
2021-02-12 00:53:08 +00:00
if ( pwrSav ) {
LED1.reset();
var s = require('Storage').readJSON('setting.json',1)||{};
var t = s.timeout||10;
Bangle.setLCDTimeout(t);
}
else {
Bangle.setLCDTimeout(0);
Bangle.setLCDPower(1);
LED1.set();
2021-02-06 07:31:31 +00:00
}
2022-03-12 11:12:51 +00:00
}
function btn3press(){
if(emulator) console.log("Btn3");
cfg.modeA = cfg.modeA+1;
if ( cfg.modeA > 2 ) cfg.modeA = 0;
2022-03-12 11:12:51 +00:00
if(emulator)console.log("cfg.modeA="+cfg.modeA);
2021-02-06 07:31:31 +00:00
savSettings();
2022-02-15 17:24:36 +00:00
onGPS(lf);
2022-03-12 11:12:51 +00:00
}
function btn4press(){
if(emulator) console.log("Btn4");
2021-02-12 01:09:11 +00:00
cfg.primSpd = !cfg.primSpd;
2021-02-06 07:31:31 +00:00
savSettings();
onGPS(lf); // Update display
2022-03-12 11:12:51 +00:00
}
function setButtons(){
if (!BANGLEJS2) { // Buttons for Bangle.js 1
setWatch(function(e) {
btn1press(( e.time - e.lastTime) > 2); // > 2 sec. is long press
}, BTN1, { edge:"falling",repeat:true});
// Power saving on/off (red dot visible if off)
setWatch(btn2press, BTN2, {repeat:true,edge:"falling"});
// Toggle between alt or dist
setWatch(btn3press, BTN3, {repeat:true,edge:"falling"});
// Touch left screen to toggle display
setWatch(btn4press, BTN4, {repeat:true,edge:"falling"});
2021-02-01 19:32:36 +00:00
2022-02-15 17:24:36 +00:00
} else { // Buttons for Bangle.js 2
2022-03-12 11:12:51 +00:00
setWatch(function(e) {
btn1press(( e.time - e.lastTime) > 0.4); // > 0.4 sec. is long press
}, BTN1, { edge:"falling",repeat:true});
2022-02-15 17:24:36 +00:00
2022-03-12 11:12:51 +00:00
Bangle.on('touch', function(btn_l_r, e) {
if(e.x < screenW_Half) btn4press();
2022-02-15 17:24:36 +00:00
else
2022-03-12 11:12:51 +00:00
if (e.y < screenH_Half)
btn2press();
else
btn3press();
2022-02-15 17:24:36 +00:00
});
}
2021-01-26 22:33:16 +00:00
}
2022-02-15 17:24:36 +00:00
2021-01-26 22:33:16 +00:00
function updateClock() {
2021-01-28 10:22:07 +00:00
if (!canDraw) return;
2022-02-15 17:24:36 +00:00
drawTime();
2021-01-26 22:33:16 +00:00
g.reset();
g.drawImage(img,0,40);
2021-02-04 04:03:44 +00:00
if ( emulator ) {max.spd++;max.alt++;}
2021-01-26 22:33:16 +00:00
}
2021-01-28 10:22:07 +00:00
function startDraw(){
canDraw=true;
2021-02-06 08:45:54 +00:00
setLpMode('SuperE'); // off
2021-01-28 10:22:07 +00:00
g.clear();
Bangle.drawWidgets();
2021-02-01 09:48:30 +00:00
onGPS(lf); // draw app screen
2021-01-28 10:22:07 +00:00
}
function stopDraw() {
canDraw=false;
2021-02-09 19:10:06 +00:00
if (!tmrLP) tmrLP=setInterval(function () {if (lf.fix) setLpMode('PSMOO');}, 10000); //Drop to low power in 10 secs. Keep lp mode off until we have a first fix.
2021-01-28 10:22:07 +00:00
}
2021-02-02 02:57:41 +00:00
function savSettings() {
2021-02-12 01:09:11 +00:00
require("Storage").write('speedalt.json',cfg);
2021-02-02 02:57:41 +00:00
}
2021-02-06 08:45:54 +00:00
function setLpMode(m) {
2021-02-05 00:54:04 +00:00
if (tmrLP) {clearInterval(tmrLP);tmrLP = false;} // Stop any scheduled drop to low power
2021-02-12 00:53:08 +00:00
if ( !gpssetup ) return;
2021-03-02 00:29:21 +00:00
gpssetup.setPowerMode({power_mode:m});
2021-02-06 08:45:54 +00:00
}
2021-02-01 09:20:48 +00:00
// =Main Prog
2021-01-28 10:22:07 +00:00
2022-02-15 17:24:36 +00:00
// Read settings.
2021-02-12 01:09:11 +00:00
let cfg = require('Storage').readJSON('speedalt.json',1)||{};
2021-01-28 10:22:07 +00:00
2021-02-12 01:09:11 +00:00
cfg.spd = cfg.spd||0; // Multiplier for speed unit conversions. 0 = use the locale values for speed
2022-02-15 17:24:36 +00:00
cfg.spd_unit = cfg.spd_unit||'km/h'; // Displayed speed unit
cfg.alt = cfg.alt||1;// Multiplier for altitude unit conversions. (feet:'0.3048')
cfg.alt_unit = cfg.alt_unit||'meter'; // Displayed altitude units ('feet')
2021-02-12 01:09:11 +00:00
cfg.dist = cfg.dist||1000;// Multiplier for distnce unit conversions.
cfg.dist_unit = cfg.dist_unit||'km'; // Displayed altitude units
cfg.colour = cfg.colour||0; // Colour scheme.
cfg.wp = cfg.wp||0; // Last selected waypoint for dist
2022-02-15 17:24:36 +00:00
cfg.modeA = cfg.modeA||1; // 0 = [D]ist, 1 = [A]ltitude, 2 = [C]lock
cfg.primSpd = cfg.primSpd||1; // 1 = Spd in primary, 0 = Spd in secondary
2021-02-02 02:57:41 +00:00
2022-02-15 17:24:36 +00:00
cfg.spdFilt = cfg.spdFilt==undefined?true:cfg.spdFilt;
cfg.altFilt = cfg.altFilt==undefined?true:cfg.altFilt;
if ( cfg.spdFilt ) var spdFilter = new KalmanFilter({R: 0.1 , Q: 1 });
if ( cfg.altFilt ) var altFilter = new KalmanFilter({R: 0.01, Q: 2 });
loadWp();
2021-01-26 22:33:16 +00:00
/*
Colour Pallet Idx
0 : Background (black)
1 : Speed/Alt
2 : Units
3 : Sats
*/
2022-02-15 17:24:36 +00:00
const background = 0; // g.theme.bg = 0xFFFF = gelb!?
2021-01-26 22:33:16 +00:00
var img = {
width:buf.getWidth(),
height:buf.getHeight(),
2021-02-01 09:48:30 +00:00
bpp:2,
2021-01-26 22:33:16 +00:00
buffer:buf.buffer,
2022-02-15 17:24:36 +00:00
palette:new Uint16Array([background,0x4FE0,0xEFE0,0x07DB]) // "Default"
2021-01-26 22:33:16 +00:00
};
2022-02-15 17:24:36 +00:00
if ( cfg.colour == 1 ) img.palette = new Uint16Array([background,0xFFFF,0xFFF6,0xDFFF]); // "Hi contrast"
if ( cfg.colour == 2 ) img.palette = new Uint16Array([background,0xFF800,0xFAE0,0xF813]); // "Night"
2021-01-26 22:33:16 +00:00
2021-01-28 10:22:07 +00:00
var SCREENACCESS = {
withApp:true,
2021-02-04 05:58:03 +00:00
request:function(){this.withApp=false;stopDraw();},
release:function(){this.withApp=true;startDraw();}
2022-02-15 17:24:36 +00:00
};
2021-01-26 22:33:16 +00:00
2021-01-28 10:22:07 +00:00
Bangle.on('lcdPower',function(on) {
if (!SCREENACCESS.withApp) return;
2022-02-15 17:24:36 +00:00
if (on) startDraw();
2021-02-04 05:58:03 +00:00
else stopDraw();
2021-01-28 10:22:07 +00:00
});
2021-01-26 22:33:16 +00:00
2022-02-15 17:24:36 +00:00
2021-02-12 00:53:08 +00:00
var gpssetup;
try {
2021-02-12 19:50:57 +00:00
gpssetup = require("gpssetup");
2021-02-12 00:53:08 +00:00
} catch(e) {
gpssetup = false;
}
2021-01-28 10:22:07 +00:00
// All set up. Lets go.
2021-01-26 22:33:16 +00:00
g.clear();
2021-02-01 09:48:30 +00:00
onGPS(lf);
2021-02-12 00:53:08 +00:00
Bangle.setGPSPower(1);
2021-02-05 20:26:41 +00:00
2021-02-12 00:53:08 +00:00
if ( gpssetup ) {
gpssetup.setPowerMode({power_mode:"SuperE"}).then(function() { Bangle.setGPSPower(1); });
2021-02-05 20:17:33 +00:00
}
else {
Bangle.setGPSPower(1);
}
2021-02-05 20:26:41 +00:00
2021-02-12 00:53:08 +00:00
Bangle.on('GPS', onGPS);
2021-01-21 02:42:19 +00:00
setButtons();
2021-02-20 21:39:01 +00:00
setInterval(updateClock, 10000);
2022-02-15 17:24:36 +00:00
Bangle.loadWidgets();
Bangle.drawWidgets();