forked from FOSS/BangleApps
91 lines
1.9 KiB
TypeScript
91 lines
1.9 KiB
TypeScript
import { draw } from './display';
|
|
import { updateLog } from './log';
|
|
import { ActivityStatus, AppState } from './state';
|
|
|
|
declare var Bangle: any;
|
|
|
|
interface GpsEvent {
|
|
lat: number;
|
|
lon: number;
|
|
alt: number;
|
|
speed: number;
|
|
hdop: number;
|
|
fix: number;
|
|
}
|
|
|
|
const EARTH_RADIUS = 6371008.8;
|
|
|
|
function initGps(state: AppState): void {
|
|
Bangle.on('GPS', (gps: GpsEvent) => readGps(state, gps));
|
|
Bangle.setGPSPower(1);
|
|
}
|
|
|
|
function readGps(state: AppState, gps: GpsEvent): void {
|
|
state.lat = gps.lat;
|
|
state.lon = gps.lon;
|
|
state.alt = gps.alt;
|
|
state.vel = gps.speed / 3.6;
|
|
state.fix = gps.fix;
|
|
state.dop = gps.hdop;
|
|
state.gpsValid = state.fix > 0;
|
|
|
|
updateGps(state);
|
|
draw(state);
|
|
|
|
/* Only log GPS data every 5 secs if we
|
|
have a fix and we're running. */
|
|
if (state.gpsValid &&
|
|
state.status === ActivityStatus.Running &&
|
|
state.timeSinceLog > 5) {
|
|
state.timeSinceLog = 0;
|
|
updateLog(state);
|
|
}
|
|
}
|
|
|
|
function updateGps(state: AppState): void {
|
|
const t = Date.now();
|
|
let dt = (t - state.t) / 1000;
|
|
if (!isFinite(dt)) dt=0;
|
|
state.t = t;
|
|
state.timeSinceLog += dt;
|
|
|
|
if (state.status === ActivityStatus.Running) {
|
|
state.duration += dt;
|
|
}
|
|
|
|
if (!state.gpsValid) {
|
|
return;
|
|
}
|
|
|
|
const r = EARTH_RADIUS + state.alt;
|
|
const lat = state.lat * Math.PI / 180;
|
|
const lon = state.lon * Math.PI / 180;
|
|
const x = r * Math.cos(lat) * Math.cos(lon);
|
|
const y = r * Math.cos(lat) * Math.sin(lon);
|
|
const z = r * Math.sin(lat);
|
|
|
|
if (!state.x) {
|
|
state.x = x;
|
|
state.y = y;
|
|
state.z = z;
|
|
return;
|
|
}
|
|
|
|
const dx = x - state.x;
|
|
const dy = y - state.y;
|
|
const dz = z - state.z;
|
|
const dpMag = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
|
|
state.x = x;
|
|
state.y = y;
|
|
state.z = z;
|
|
|
|
if (state.status === ActivityStatus.Running) {
|
|
state.distance += dpMag;
|
|
state.speed = (state.distance / state.duration) || 0;
|
|
state.cadence = (60 * state.steps / state.duration) || 0;
|
|
}
|
|
}
|
|
|
|
export { initGps, readGps, updateGps };
|