1
0
Fork 0

Merge pull request #645 from jabituyaben/master

New app & updates to Astral Clock
master
Gordon Williams 2021-01-26 15:00:44 +00:00 committed by GitHub
commit c389428147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 298 additions and 12 deletions

View File

@ -2585,7 +2585,7 @@
{ "id": "astral", { "id": "astral",
"name": "Astral Clock", "name": "Astral Clock",
"icon": "app-icon.png", "icon": "app-icon.png",
"version":"0.01", "version":"0.02",
"readme": "README.md", "readme": "README.md",
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.", "description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
"tags": "clock", "tags": "clock",
@ -2595,6 +2595,18 @@
{"name":"astral.img","url":"app-icon.js","evaluate":true} {"name":"astral.img","url":"app-icon.js","evaluate":true}
] ]
}, },
{ "id": "alpinenav",
"name": "Alpine Nav",
"icon": "app-icon.png",
"version":"0.01",
"readme": "README.md",
"description": "App that performs GPS monitoring to track and display position relative to a given origin in realtime",
"tags": "outdoors,gps",
"storage": [
{"name":"alpinenav.app.js","url":"app.js"},
{"name":"alpinenav.img","url":"app-icon.js","evaluate":true}
]
},
{ "id": "lifeclk", { "id": "lifeclk",
"name": "Game of Life Clock", "name": "Game of Life Clock",
"shortName":"Conway's Clock", "shortName":"Conway's Clock",

30
apps/alpinenav/README.md Normal file
View File

@ -0,0 +1,30 @@
Alpine Navigator
================
App that performs GPS monitoring to track and display position relative to a given origin in realtime.
![screenshot](./sample.png)
Functions
---------
Note if you've not used GPS yet I suggest using one of the GPS apps to get your first fix and confirm as I've found that helps initially.
The GPS and magnetometer will be turned on and after a few moments, when the watch buzzes and the dot turns from red to pink, that means the GPS is fixed. all your movements now will be displayed with a line drawn back to show your position relative to the start. New waypoints will be added based on checking every 10 seconds for at least 5 meters of movement. The map will scale to your distance travelled so the route will always remain within the window, the accelerometer/pedometer is not used - this is a purely GPS and compass solution so can be used for driving/cycling etc. A log file will be recorded that tracks upto 1000 waypoints, this isn't a big file and you could remove the limit but I've kept it fairly conservative here as it's not intended as a main feature, there's already good GPS recorders for the Bangle. The following other items are displayed:
1. altitude at origin, this is displayed left of the centre.
2. current altitude, displayed centre right
3. distance from origin, bottom left (meters)
4. distance travelled, bottom right (meters)
5. compass heading, at the top
For the display, the route is kept at a set resolution, so there's no risk of running into memory problems if you run this for long periods or any length of time because the waypoints will be reduced when it reaches a set threshold so you may see the path smooth out slightly at intervals.
If you get strange values or dashes for the compass, it just needs calibration so you need to move the watch around briefly for this each time, ideally 360 degrees around itself, which involves taking the watch off. If you don't want to do that you can also just wave your hand around for a few seconds like you're at a rave or Dr Strange making a Sling Ring but often just moving your wrist a bit is enough.
The buttons do the following:
BTN1: this will display an 'X' in the bottom of the screen and lock all the buttons, this is to prevent you accidentally pressing either of the below. Remember to press this again to unlock it! soft and hard reset will both still work.
BTN2: this removes all waypoints aside from the origin and your current location; sometimes during smaller journeys and walks, the GPS can give sporadic differences in locations because of the error margins of GPS and this can add noise to your route.
BTN3: this will pause the GPS and magnetometer, useful for saving power for situations where you don't necessarily need to track parts of your route e.g. you're going indoors/shelter for some time. You'll know it's paused because the compass won't update it's reading and all the metrics will be blacked out on the screen.
Things to do next
-----------------
There's a GPS widget that's been developed to leverage low-power mode capability on the sensor, will look to incorporate that.

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mUywkEIf4A/AHUBiAYWgcwDC0v+IYW///C6sC+c/kAYUj/xj/wDCgvBgfyVihhBAQQASh6TCMikvYoRkU/73CMicD+ZnFViJFBj5MBMiU/+IuBJoJkRCoUvfIPy/5kQVgM//7gBC4KCDFxSsDgTHCl8QWgaRKmBJBFIzmDSJXzYBECWobbJAAKNIMhYlBOoK/IMhZXCmYMLABAkCS4RkSXZoNJRBo/CgK6UBwTWBBIs/SJBAGl7UFegIXMaogHEehAAHj/yIYsfehAAGMQISFMRxbCiEDU4ZiQZY5iQZYpiSbQ8/cwzLOCiQA/AH4A1A"))

BIN
apps/alpinenav/app-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

237
apps/alpinenav/app.js Normal file
View File

@ -0,0 +1,237 @@
var background_colour = "#000000";
var foregound_colour = "#ccff99";
var position_colour = "#ff3329";
var log_limit = 1000;
var max_array_size = 50;
var pause_tracker = false;
var temp;
var file;
var d;
var origin_lat;
var origin_lon;
var current_lat;
var current_lon;
var current_speed;
var distance_from_origin = 0;
var distane_travelled = 0;
var log_size;
var waypoints = [];
var start_alt = 0;
var current_alt = 0;
var button_lock = false;
var display_waypoints = [];
var waypoint = {
lat: "",
lon: ""
};
var compass_heading = "---";
function calcCrow(lat1, lon1, lat2, lon2) {
var R = 6371e3;
var dLat = toRad(lat2 - lat1);
var dLon = toRad(lon2 - lon1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
function toRad(Value) {
return Value * Math.PI / 180;
}
function draw() {
if (pause_tracker)
g.setColor(background_colour);
else
g.setColor(foregound_colour);
g.setFont("6x8", 2);
g.setFontAlign(0, 1);
g.drawString(distance_from_origin.toFixed(0), 40, 220, true);
g.drawString(distane_travelled.toFixed(0), 200, 220, true);
g.setFont("6x8", 1);
g.drawString(start_alt.toFixed(0), 40, 120, true);
g.drawString(current_alt.toFixed(0), 200, 120, true);
if (button_lock) {
g.setFont("6x8", 2);
g.setFontAlign(0, 0);
g.drawString("X", 120, 220, true);
g.setFont("6x8", 1);
}
}
function cull_array() {
for (var i = 2; i <= waypoints.length; i += 2)
waypoints.splice(i, 1);
}
function process_and_display() {
g.setColor(background_colour);
g.fillRect(10, 65, 230, 230);
g.setColor(foregound_colour);
if (waypoints.length > max_array_size)
cull_array();
rescale();
if (display_waypoints.length > 0) {
for (let x = 0; x < display_waypoints.length - 1; x++) {
g.reset();
g.setColor(foregound_colour);
g.drawLine(display_waypoints[x].lon, display_waypoints[x].lat, display_waypoints[x + 1].lon, display_waypoints[x + 1].lat);
}
g.reset();
g.setColor(position_colour);
g.fillCircle(display_waypoints[display_waypoints.length - 1].lon, display_waypoints[display_waypoints.length - 1].lat, 3);
}
}
function process_GPS() {
if (waypoints.length > 0) {
//check distance
temp_distance = calcCrow(current_lat, current_lon, waypoints[waypoints.length - 1].lat, waypoints[waypoints.length - 1].lon);
if (temp_distance > 5) {
var temp = Object.create(waypoint);
temp.lat = current_lat;
temp.lon = current_lon;
waypoints.push(temp);
distane_travelled += temp_distance;
distance_from_origin = calcCrow(current_lat, current_lon, waypoints[0].lat, waypoints[0].lon);
process_and_display();
if (log_size < log_limit) {
var csv = [
d,
origin_lat - current_lat,
current_lon - origin_lon,
current_speed,
current_alt
];
file.write(csv.join(",") + "\n");
log_size += 1;
}
}
}
else {
g.setColor(position_colour);
g.fillCircle(120, 120, 3);
}
draw();
}
function rescale() {
var max_val = 0;
display_waypoints = [];
for (let x = 0; x < waypoints.length; x++) {
if (Math.abs(waypoints[x].lat) > max_val)
max_val = Math.abs(waypoints[x].lat);
if (Math.abs(waypoints[x].lon) > max_val)
max_val = Math.abs(waypoints[x].lon);
}
scaler = 60 / max_val;
for (let x = 0; x < waypoints.length; x++) {
temp = Object.create(waypoint);
temp.lat = 140 - Math.round(waypoints[x].lat * scaler);
temp.lon = 120 - Math.round(waypoints[x].lon * scaler);
display_waypoints.push(temp);
}
}
Bangle.setCompassPower(1);
Bangle.setGPSPower(1);
g.clear();
process_GPS();
var poll_GPS = setInterval(process_GPS, 9000);
setWatch(function () {
if (!button_lock) {
waypoints.splice(1);
process_GPS();
}
}, BTN2, { repeat: true, edge: "falling" });
setWatch(function () {
if (!button_lock) {
if (!pause_tracker) {
Bangle.setCompassPower(0);
Bangle.setGPSPower(0);
pause_tracker = true;
}
else {
Bangle.setCompassPower(1);
Bangle.setGPSPower(1);
pause_tracker = false;
}
}
}, BTN3, { repeat: true, edge: "falling" });
setWatch(function () {
if (button_lock) {
button_lock = false;
g.setFontAlign(0, 0);
g.drawString(" ", 120, 220, true);
}
else {
button_lock = true;
g.setFontAlign(0, 0);
g.drawString("X", 120, 220, true);
}
}, BTN1, { repeat: true, edge: "falling" });
Bangle.on('GPS', function (g) {
if (g.fix) {
if (waypoints.length == 0) {
file = require("Storage").open("alpine_log.csv", "w");
file.write("");
file = require("Storage").open("alpine_log.csv", "a");
Bangle.buzz();
position_colour = 0xF81F;
origin_lat = g.lat;
origin_lon = g.lon;
start_alt = g.alt;
current_speed = g.speed;
sat_count = g.satellites;
var csv = [
d,
origin_lat,
origin_lon,
current_speed,
current_alt
];
file.write(csv.join(",") + "\n");
var temp = Object.create(waypoint);
temp.lat = 0;
temp.lon = 0;
process_GPS();
waypoints.push(temp);
}
else {
current_lat = g.lat - origin_lat;
current_lon = origin_lon - g.lon;
current_speed = g.speed;
sat_count = g.satellites;
current_alt = g.alt;
gps_time = g.time;
}
}
});
Bangle.on('mag', function (m) {
if (isNaN(m.heading))
compass_heading = "---";
else
compass_heading = 360 - Math.round(m.heading);
current_colour = g.getColor();
g.reset();
g.setColor(background_colour);
g.fillRect(140, 30, 190, 55);
g.setColor(foregound_colour);
g.setFont("6x8", 2);
if(compass_heading<100)
compass_heading = " " + compass_heading.toString();
g.drawString(compass_heading, 150, 15, true);
});

BIN
apps/alpinenav/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 KiB

2
apps/astral/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: Create astral clock app
0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget

View File

@ -32,14 +32,14 @@ if (test_file !== undefined) {
if (astral_settings === undefined) { if (astral_settings === undefined) {
astral_settings = { astral_settings = {
version: 1, version: 1,
lat: 51.9492, lat: 51.5074,
lon: 0.2834, lon: 0.1278,
astral_default: true, astral_default: true,
extras: [ extras: [
{ name: "Andromeda", ra: "004244", de: "411609", type: 3 }, { name: "Andromeda", ra: "004244", de: "411609", type: 3 },
{ name: "Cigar", ra: "095552", de: "694047", type: 3 }, { name: "Cigar", ra: "095552", de: "694047", type: 3 },
{ name: "Pinwheel", ra: "140313", de: "542057", type: 3 }, { name: "Pinwheel", ra: "140313", de: "542057", type: 3 },
{ name: "Whirlpool", ra: "1329553", de: "471143", type: 3 }, { name: "Whirlpool", ra: "132953", de: "471143", type: 3 },
{ name: "Orion", ra: "053517", de: "-052328", type: 2 }, { name: "Orion", ra: "053517", de: "-052328", type: 2 },
{ name: "Hercules", ra: "160515", de: "174455", type: 1 }, { name: "Hercules", ra: "160515", de: "174455", type: 1 },
{ name: "Beehive", ra: "084024", de: "195900", type: 1 }, { name: "Beehive", ra: "084024", de: "195900", type: 1 },
@ -662,12 +662,12 @@ function draw_moon(phase) {
if (phase == 5) { if (phase == 5) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
g.setColor("#000000"); g.setColor("#000000");
g.fillRect(220, 20, 240, 90); g.fillRect(220, 25, 240, 90);
} }
else if (phase == 6) { else if (phase == 6) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
g.setColor("#000000"); g.setColor("#000000");
g.fillRect(200, 20, 240, 90); g.fillRect(200, 25, 240, 90);
} }
else if (phase == 1) { else if (phase == 1) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
@ -679,12 +679,12 @@ function draw_moon(phase) {
else if (phase == 3) { else if (phase == 3) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
g.setColor("#000000"); g.setColor("#000000");
g.fillRect(160, 20, 180, 90); g.fillRect(160, 25, 180, 90);
} }
else if (phase == 2) { else if (phase == 2) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
g.setColor("#000000"); g.setColor("#000000");
g.fillRect(160, 20, 200, 90); g.fillRect(160, 25, 200, 90);
} }
else if (phase == 7) { else if (phase == 7) {
g.fillCircle(200, Yaxis, 30); g.fillCircle(200, Yaxis, 30);
@ -823,19 +823,23 @@ setWatch(function () {
display_colour = default_colour; display_colour = default_colour;
else else
display_colour = setupcomplete_colour; display_colour = setupcomplete_colour;
draw_moon(current_moonphase);
} }
}, BTN4, { repeat: true }); }, BTN4, { repeat: true });
//events //events
Bangle.on('mag', function (m) { Bangle.on('mag', function (m) {
g.setFont("6x8",2);
if (isNaN(m.heading)) if (isNaN(m.heading))
compass_heading = "--"; compass_heading = "---";
else else
compass_heading = 360 - Math.round(m.heading); compass_heading = 360 - Math.round(m.heading);
g.setColor("#000000"); // g.setColor("#000000");
g.fillRect(100, 10, 140, 20); // g.fillRect(160, 10, 160, 20);
g.setColor(display_colour); g.setColor(display_colour);
g.drawString(" " + (compass_heading) + " ", 130, 20, true /*clear background*/); if(compass_heading<100)
compass_heading = " " + compass_heading;
g.drawString(compass_heading, 150, 20, true /*clear background*/);
}); });
Bangle.on('GPS', function (g) { Bangle.on('GPS', function (g) {