magnav: Outsource tilt compensation to library

pull/2523/head
Erik Andresen 2023-01-22 10:10:29 +01:00
parent 020919bfd7
commit d612937bb7
7 changed files with 66 additions and 70 deletions

View File

@ -2,6 +2,5 @@
0.02: Course marker 0.02: Course marker
0.03: Tilt compensation and calibration 0.03: Tilt compensation and calibration
0.04: Fix Font size 0.04: Fix Font size
0.05: Inital portable version 0.05: Initial portable version
0.06: Outsource tilt compensation to library

41
apps/magnav/lib.js Normal file
View File

@ -0,0 +1,41 @@
exports.calibrate = () => {
var max={x:-32000, y:-32000, z:-32000},
min={x:32000, y:32000, z:32000};
var ref = setInterval(()=>{
var m = Bangle.getCompass();
max.x = m.x>max.x?m.x:max.x;
max.y = m.y>max.y?m.y:max.y;
max.z = m.z>max.z?m.z:max.z;
min.x = m.x<min.x?m.x:min.x;
min.y = m.y<min.y?m.y:min.y;
min.z = m.z<min.z?m.z:min.z;
}, 100);
return new Promise((resolve) => {
setTimeout(()=>{
if(ref) clearInterval(ref);
var offset = {x:(max.x+min.x)/2,y:(max.y+min.y)/2,z:(max.z+min.z)/2};
var delta = {x:(max.x-min.x)/2,y:(max.y-min.y)/2,z:(max.z-min.z)/2};
var avg = (delta.x+delta.y+delta.z)/3;
var scale = {x:avg/delta.x, y:avg/delta.y, z:avg/delta.z};
resolve({offset:offset,scale:scale});
},20000);
});
}
exports.tiltfixread = (O,S) => {
"ram"
var m = Bangle.getCompass();
var g = Bangle.getAccel();
m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
if (d<0) d+=360;
var phi = Math.atan(-g.x/-g.z);
var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
var costheta = Math.cos(theta), sintheta = Math.sin(theta);
var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
var yh = m.dz*sinphi - m.dx*cosphi;
var psi = Math.atan2(yh,xh)*180/Math.PI;
if (psi<0) psi+=360;
return psi;
}

View File

@ -61,24 +61,7 @@ function newHeading(m,h){
var candraw = false; var candraw = false;
var CALIBDATA = require("Storage").readJSON("magnav.json",1)||null; var CALIBDATA = require("Storage").readJSON("magnav.json",1)||null;
const tiltfixread = require("magnav").tiltfixread;
function tiltfixread(O,S){
"ram"
var m = Bangle.getCompass();
var g = Bangle.getAccel();
m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
if (d<0) d+=360;
var phi = Math.atan(-g.x/-g.z);
var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
var costheta = Math.cos(theta), sintheta = Math.sin(theta);
var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
var yh = m.dz*sinphi - m.dx*cosphi;
var psi = Math.atan2(yh,xh)*180/Math.PI;
if (psi<0) psi+=360;
return psi;
}
// Note actual mag is 360-m, error in firmware // Note actual mag is 360-m, error in firmware
function reading() { function reading() {
@ -97,30 +80,6 @@ function reading() {
flip(buf,Yoff+80); flip(buf,Yoff+80);
} }
function calibrate(){
var max={x:-32000, y:-32000, z:-32000},
min={x:32000, y:32000, z:32000};
var ref = setInterval(()=>{
var m = Bangle.getCompass();
max.x = m.x>max.x?m.x:max.x;
max.y = m.y>max.y?m.y:max.y;
max.z = m.z>max.z?m.z:max.z;
min.x = m.x<min.x?m.x:min.x;
min.y = m.y<min.y?m.y:min.y;
min.z = m.z<min.z?m.z:min.z;
}, 100);
return new Promise((resolve) => {
setTimeout(()=>{
if(ref) clearInterval(ref);
var offset = {x:(max.x+min.x)/2,y:(max.y+min.y)/2,z:(max.z+min.z)/2};
var delta = {x:(max.x-min.x)/2,y:(max.y-min.y)/2,z:(max.z-min.z)/2};
var avg = (delta.x+delta.y+delta.z)/3;
var scale = {x:avg/delta.x, y:avg/delta.y, z:avg/delta.z};
resolve({offset:offset,scale:scale});
},20000);
});
}
var calibrating=false; var calibrating=false;
function docalibrate(first){ function docalibrate(first){
calibrating=true; calibrating=true;
@ -139,7 +98,7 @@ function docalibrate(first){
buf.drawString("Fig 8s to",120,0); buf.drawString("Fig 8s to",120,0);
buf.drawString("Calibrate",120,26); buf.drawString("Calibrate",120,26);
flip(buf,Yoff); flip(buf,Yoff);
calibrate().then((r)=>{ require("magnav").calibrate().then((r)=>{
CALIBDATA=r; CALIBDATA=r;
require("Storage").write("magnav.json",r); require("Storage").write("magnav.json",r);
restart() restart()

View File

@ -1,7 +1,7 @@
{ {
"id": "magnav", "id": "magnav",
"name": "Navigation Compass", "name": "Navigation Compass",
"version": "0.05", "version": "0.06",
"description": "Compass with linear display as for GPSNAV. Has Tilt compensation and remembers calibration.", "description": "Compass with linear display as for GPSNAV. Has Tilt compensation and remembers calibration.",
"screenshots": [{"url":"screenshot-b2.png"},{"url":"screenshot-light-b2.png"}], "screenshots": [{"url":"screenshot-b2.png"},{"url":"screenshot-light-b2.png"}],
"icon": "magnav.png", "icon": "magnav.png",
@ -11,6 +11,7 @@
"storage": [ "storage": [
{"name":"magnav.app.js","url":"magnav_b1.js","supports":["BANGLEJS"]}, {"name":"magnav.app.js","url":"magnav_b1.js","supports":["BANGLEJS"]},
{"name":"magnav.app.js","url":"magnav_b2.js","supports":["BANGLEJS2"]}, {"name":"magnav.app.js","url":"magnav_b2.js","supports":["BANGLEJS2"]},
{"name":"magnav","url":"lib.js"},
{"name":"magnav.img","url":"magnav-icon.js","evaluate":true} {"name":"magnav.img","url":"magnav-icon.js","evaluate":true}
], ],
"data": [{"name":"magnav.json"}] "data": [{"name":"magnav.json"}]

View File

@ -5,3 +5,4 @@
0.05: Fix not displaying of wpindex = 0 0.05: Fix not displaying of wpindex = 0
0.06: Added adjustment for Bangle.js magnetometer heading fix 0.06: Added adjustment for Bangle.js magnetometer heading fix
0.07: Add settings file with the option to disable the slow direction updates 0.07: Add settings file with the option to disable the slow direction updates
0.08: Use tilt compensation from new magnav library

View File

@ -85,31 +85,22 @@ function newHeading(m,h){
} }
var CALIBDATA = require("Storage").readJSON("magnav.json",1) || {}; var CALIBDATA = require("Storage").readJSON("magnav.json",1) || {};
let tiltfixread;
function tiltfixread(O,S){ try {
var m = Bangle.getCompass(); tiltfixread = require("magnav").tiltfixread;
if (O === undefined || S === undefined) { } catch(e) {
// no valid calibration from magnav, use built in // magnav not installed
return m.heading;
}
var g = Bangle.getAccel();
m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
if (d<0) d+=360;
var phi = Math.atan(-g.x/-g.z);
var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
var costheta = Math.cos(theta), sintheta = Math.sin(theta);
var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
var yh = m.dz*sinphi - m.dx*cosphi;
var psi = Math.atan2(yh,xh)*180/Math.PI;
if (psi<0) psi+=360;
return psi;
} }
// Note actual mag is 360-m, error in firmware // Note actual mag is 360-m, error in firmware
function read_compass() { function read_compass() {
var d = tiltfixread(CALIBDATA.offset,CALIBDATA.scale); let d;
if (tiltfixread === undefined || CALIBDATA.offset === undefined || CALIBDATA.scale === undefined) {
// magnav not installed or no valid calibration, use built in
d = Bangle.getCompass().heading;
} else {
d = tiltfixread(CALIBDATA.offset,CALIBDATA.scale);
}
if (isNaN(d)) return; // built in compass heading can return NaN when uncalibrated if (isNaN(d)) return; // built in compass heading can return NaN when uncalibrated
heading = newHeading(d,heading); heading = newHeading(d,heading);
direction = wp_bearing - heading; direction = wp_bearing - heading;
@ -278,6 +269,9 @@ function doselect(){
wp = waypoints[wpindex]; wp = waypoints[wpindex];
require("waypoints").save(waypoints); require("waypoints").save(waypoints);
} }
if (selected) {
Bangle.resetCompass(); // reset built in compass when a waypoint is selected
}
selected=!selected; selected=!selected;
drawN(); drawN();
} }
@ -294,6 +288,7 @@ Bangle.drawWidgets();
// load widgets can turn off GPS // load widgets can turn off GPS
Bangle.setGPSPower(1); Bangle.setGPSPower(1);
Bangle.setCompassPower(1); Bangle.setCompassPower(1);
Bangle.resetCompass() // reset built in compass on start in case we are not using tilt compensation
drawAll(); drawAll();
startTimers(); startTimers();
Bangle.on('GPS', onGPS); Bangle.on('GPS', onGPS);

View File

@ -1,12 +1,12 @@
{ {
"id": "waypointer", "id": "waypointer",
"name": "Way Pointer", "name": "Way Pointer",
"version": "0.07", "version": "0.08",
"description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation", "description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
"icon": "waypointer.png", "icon": "waypointer.png",
"tags": "tool,outdoors,gps", "tags": "tool,outdoors,gps",
"supports": ["BANGLEJS", "BANGLEJS2"], "supports": ["BANGLEJS", "BANGLEJS2"],
"dependencies" : { "waypoints":"type" }, "dependencies" : { "waypoints":"type", "magnav" : "app" },
"readme": "README.md", "readme": "README.md",
"storage": [ "storage": [
{"name":"waypointer.app.js","url":"app.js"}, {"name":"waypointer.app.js","url":"app.js"},