using Toybox.Application as App; using Toybox.Application.Storage; using Toybox.Graphics as Gfx; using Toybox.Math; using Toybox.Position; using Toybox.System as Sys; using Toybox.Time; module C { // // Constants // public var WHITE = Gfx.COLOR_WHITE; public var BLACK = Gfx.COLOR_BLACK; public var RED = Gfx.COLOR_RED; public var GREEN = Gfx.COLOR_GREEN; public var BLUE = Gfx.COLOR_BLUE; public var YELLOW = Gfx.COLOR_YELLOW; public var TRANSPARENT = Gfx.COLOR_TRANSPARENT; public var NUM_VIEWS = 3; // // Page views // public var METER_ALT = 0; public var METER_SPEED = 1; public var METER_COMPASS = 2; public var METER_MAX = 3; // // Setting pages // public var MENU_IGNORE = 0; // Top level page public var MENU_POS = 1; public var MENU_UNITS = 2; public var MENU_DECL = 3; public var MENU_CEILING = 4; public var MENU_DEBUG = 5; public var MENU_DECL_AUTO = 6; public var MENU_DECL_SET = 7; public var MENU_UNIT_IMP = 8; public var MENU_UNIT_METRIC = 9; // // Units for numbers // public var UNITS_IMPERIAL = 0; public var UNITS_METRIC = 1; // // Compass heading sources // public var HEADING_MAG = 0; public var HEADING_TRUE = 1; public var HEADING_GPS = 2; public var HEADING_MAX = 3; // // Watch face dimensions // public var cx; public var cy; public var radius; // // Settings // public var units = 0; // 0 => imperial, 1 => metric public var ceiling = 0; // ceiling for low altitude warning public var mag_auto = false; // magnetic declination auto calculate (needs GPS) public var dbg_enable = false; // enable debug data public var dbg_speed = 0; // debug speec public var dbg_alt = 0; // debug altitude // // Compass display // public var meter_type; public var heading_type = HEADING_MAG; public var mag_gps = null; // magnetic declination, GPS computed public var mag_value = 0; // magnetic declination, user specified // // Raw position data // public var speed = null; // meters/sec public var alt = null; // meters public var heading = null; // degrees (GPS heading) public var aim = 0; // degrees (compass heading) public var lat = null; // degrees public var lon = null; // degress public var gps_timer = 0; // // Debug mode // (:debug) var debug = true; (:release) var debug = false; public function logger(s) { if (debug) { Sys.println("DDD:" + s); } } public function pr_memory(pre, suf) { var total, used, free; var scale; if (suf == null) { suf = 'u'; } switch (suf) { case 'k': case 'K': scale = 1000; break; case 'm': case 'M': scale = 1000*1000; break; case 'g': case 'G': scale = 1000*1000*1000; break; default: scale = 1; suf = ""; break; } var stats = Sys.getSystemStats(); total = stats.totalMemory / scale; used = stats.usedMemory / scale; free = stats.freeMemory / scale; logger(pre + ":" + total + suf + "=" + used + suf + "+" + free + suf); } public function pr_mem(pre) { pr_memory(pre, 'k'); } public function pr_xy(head, xy) { var v; logger(head); var len = xy.size(); for (var i = 0; i < len; i += 1) { v = xy[i]; logger("xy[" + i + "] = " + v[0].format("%.1f") + ", " + v[1].format("%.1f")); } } public function pr_gps(info) { var alt = info.altitude; var head = info.heading; var speed = info.speed; var ll = info.position.toDegrees(); logger("alt:" + alt.toNumber() + " m"); logger("head:" + head.toNumber() + " deg"); logger("speed:" + speed.toNumber() + " mps"); logger("lat/lon:" + ll[0].toNumber()+ "/" + ll[1].toNumber()); } function sh_pt(p) { return p[0].format("%.1f") + "x" + p[1].format("%.1f"); } function settings() { var app = App.getApp(); units = app.getProperty("units"); ceiling = app.getProperty("ceiling"); mag_auto = app.getProperty("mag_auto"); mag_value = app.getProperty("mag_value"); dbg_enable = app.getProperty("dbg_enable"); dbg_speed = app.getProperty("dbg_speed"); dbg_alt = app.getProperty("dbg_alt"); } function new_gps(info, wmm) { if (debug) { info.altitude = 1670; info.speed = 26.8; info.position = new Position.Location({ :latitude => 40, :longitude => -104, :format => :degrees }); } if (dbg_enable) { info.altitude = dbg_alt; info.heading = Math.PI/4; info.speed = dbg_speed; } speed = info.speed; alt = info.altitude; heading = C.rad2deg(info.heading); var ll = info.position.toDegrees(); lat = ll[0]; lon = ll[1]; if (mag_auto) { var d = wmm.E0000(info.position, Time.now()); if (d != mag_gps) { mag_gps = d; } Storage.setValue("mag_gps", d); } } function get_heading() { var dec = mag_auto ? mag_gps: mag_value; if (dec == null) { dec = 0; } switch (heading_type) { case HEADING_TRUE: return [ aim + dec, "true", null ]; case HEADING_MAG: return [ aim, "mag", dec ]; case HEADING_GPS: return (heading != null) ? [ heading, "gps", null ] : null; } return [ aim, "??", null ]; } function get_speed(s) { if (dbg_enable) { s = dbg_speed; } if (s == null) { return null; } switch (units) { case UNITS_IMPERIAL: return [ s * 2.3694, "mph" ]; case UNITS_METRIC: return [ s * 3.6 , "kph" ]; } return [ s, "m/s" ]; } function get_alt(a) { if (dbg_enable) { a = dbg_alt; } if (a == null) { return null; } return m2unit(a); } function m2unit(a) { switch (units) { case UNITS_IMPERIAL: return [ a * 3.28084, "ft" ]; case UNITS_METRIC: return [ a, "m" ]; } return [ a, "m" ]; } function new_compass(info) { if (info.heading != null) { aim = C.rad2deg(info.heading); } } function n2str(n, prec) { if (n == null) { return "--"; } return n.format("%." + prec + "f"); } function meter_select(type) { if (type == METER_COMPASS) { heading_type = (heading_type + 1) % HEADING_MAX; } } function rad2deg(r) { var d = (r * 180) / Math.PI; while (d < 0) { d += 360; } while (d >= 360) { d -= 360; } return d; } function to_cart(r, a) { var x = r * Math.cos(a); var y = r * Math.sin(a); return [ x, y ]; } function to_polar(x, y) { var r = Math.sqrt((x*x) + (y*y)); var a = Math.atan2(x, y); return [ r, a ]; } function translate(vert, x, y, d) { var vs, p, c, a; a = (((Math.PI * 2) * d) / 360) + (Math.PI/2); var l = vert.size(); var v = new [l]; for (var i = 0; i < l; i += 1) { vs = vert[i]; p = to_polar(vs[0], vs[1]); c = to_cart(p[0], p[1] + a); c[0] += x; c[1] += y; v[i] = c; } return v; } function draw_lines(dc, v, s) { var p1, p2; dc.setPenWidth(s); var l = v.size(); for (var i = 1; i < l; i += 1) { p1 = v[i - 1]; p2 = v[i]; dc.drawLine(p1[0], p1[1], p2[0], p2[1]); } } function alpha(c, a) { return c | (a << 24); } function set_fill(dc, color) { if (dc has :setFill) { dc.setFill(color); } else { dc.setColor(color, TRANSPARENT); } } }