Skip to content

Commit 401f205

Browse files
committed
trail: Fix parsing -- crlf removal is needed.
More documentation, display # points during recovery Switch to ui library, and start using it.
1 parent 9360190 commit 401f205

File tree

2 files changed

+148
-50
lines changed

2 files changed

+148
-50
lines changed

apps/trail/trail.app.js

Lines changed: 146 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -181,42 +181,72 @@ let gps = {
181181
},
182182
};
183183

184-
/* ui library 0.1.2 */
184+
/* ui library 0.2.0 -- see skyspy */
185+
//Bangle.on("drag", (b) => ui.touchHandler(b));
185186
let ui = {
186187
display: 0,
187188
numScreens: 2,
189+
name: ".oO busy",
190+
screens: [ "Screen 1", "Screen 2", "Screen 3", "Screen 4", "Screen 5", "Screen 6" ],
191+
help: [ "F1", "F2", "<", ">" ],
192+
clear: function() {
193+
g.reset()
194+
.setColor(g.theme.bg)
195+
.fillRect(0, this.wi, this.w, this.y2)
196+
.setColor(g.theme.fg);
197+
},
198+
draw: function(screen) {},
188199
drawMsg: function(msg) {
189-
g.reset().setFont("Vector", 35)
190-
.setColor(1,1,1)
191-
.fillRect(0, this.wi, 176, 176)
192-
.setColor(0,0,0)
200+
this.clear();
201+
g.setFont("Vector", 35)
193202
.drawString(msg, 5, 30)
194203
.flip();
195204
},
196205
drawBusy: function() {
197-
this.drawMsg("\n.oO busy");
206+
this.clear();
207+
g.setFont("Vector", 35);
208+
let help = this.help;
209+
g.setFontAlign(-1, -1).drawString(help[0], 0, this.wi);
210+
g.setFontAlign(1, -1).drawString(help[1], this.w, this.wi);
211+
g.setFontAlign(-1, 1).drawString(help[2], 0, this.h+this.wi);
212+
g.setFontAlign(1, 1).drawString(help[3], this.w, this.h+this.wi);
213+
g.setFontAlign(0, 0)
214+
.drawString(this.name, this.w/2, this.h/2);
215+
g.reset();
216+
},
217+
drawScreen: function() {
218+
this.drawMsg(this.screens[this.display]);
219+
let t1 = getTime();
220+
this.draw();
221+
let t = getTime() - t1;
222+
if (t > 30) {
223+
print("Draw took", t, "msec");
224+
}
198225
},
199226
nextScreen: function() {
200227
print("nextS");
201228
this.display = this.display + 1;
202229
if (this.display == this.numScreens)
203230
this.display = 0;
204-
this.drawBusy();
231+
this.drawScreen();
205232
},
206233
prevScreen: function() {
207234
print("prevS");
208235
this.display = this.display - 1;
209236
if (this.display < 0)
210237
this.display = this.numScreens - 1;
211-
this.drawBusy();
238+
this.drawScreen();
212239
},
213240
onSwipe: function(dir) {
214241
this.nextScreen();
215242
},
216-
h: 176,
243+
wi: 24,
244+
y2: 176,
245+
h: 152,
217246
w: 176,
218-
wi: 32,
219247
last_b: 0,
248+
topLeft: function() { this.drawMsg("Unimpl"); },
249+
topRight: function() { this.drawMsg("Unimpl"); },
220250
touchHandler: function(d) {
221251
let x = Math.floor(d.x);
222252
let y = Math.floor(d.y);
@@ -228,46 +258,85 @@ let ui = {
228258

229259
print("touch", x, y, this.h, this.w);
230260

231-
/*
232-
if ((x<this.h/2) && (y<this.w/2)) {
233-
}
234-
if ((x>this.h/2) && (y<this.w/2)) {
235-
}
236-
*/
237-
238-
if ((x<this.h/2) && (y>this.w/2)) {
261+
if ((x<this.w/2) && (y<this.y2/2))
262+
this.topLeft();
263+
if ((x>this.w/2) && (y<this.y2/2))
264+
this.topRight();
265+
if ((x<this.w/2) && (y>this.y2/2)) {
239266
print("prev");
240267
this.prevScreen();
241268
}
242-
if ((x>this.h/2) && (y>this.w/2)) {
269+
if ((x>this.w/2) && (y>this.y2/2)) {
243270
print("next");
244271
this.nextScreen();
245272
}
246273
},
247274
init: function() {
275+
this.h = this.y2 - this.wi;
248276
this.drawBusy();
249-
}
277+
},
278+
/* radial angle -- convert 0..1 to 0..2pi */
279+
radA: function(p) { return p*(Math.PI*2); },
280+
/* radial distance -- convert 0..1 to something that fits on screen */
281+
radD: function(d) { return d*(ui.h/2); },
282+
283+
/* given angle/distance, get X coordinate */
284+
radX: function(p, d) {
285+
let a = this.radA(p);
286+
return this.w/2 + Math.sin(a)*this.radD(d);
287+
},
288+
/* given angle/distance, get Y coordinate */
289+
radY: function(p, d) {
290+
let a = this.radA(p);
291+
return this.h/2 - Math.cos(a)*this.radD(d) + this.wi;
292+
},
293+
radLine: function(a1, d1, a2, d2) {
294+
g.drawLine(this.radX(a1, d1), this.radY(a1, d1), this.radX(a2, d2), this.radY(a2, d2));
295+
},
296+
radCircle: function(d) {
297+
g.drawCircle(this.radX(0, 0), this.radY(0, 0), this.radD(d));
298+
if (1)
299+
return;
300+
let step = 0.05;
301+
for (let i = 0; i < 1; i += 0.05) {
302+
this.radLine(i - step, d, i, d);
303+
}
304+
},
250305
};
251306

252-
/* egt 0.0.1 */
307+
/* egt 0.0.3 */
253308
let egt = {
254309
init: function() {
255310
},
311+
removeCRLF: function(s) {
312+
let end = s.length;
313+
while (end > 0) {
314+
let ch = s[end - 1];
315+
if (ch === '\n' || ch === '\r') {
316+
end--;
317+
} else {
318+
break;
319+
}
320+
}
321+
return s.slice(0, end);
322+
},
323+
256324
parse: function(l) {
325+
l = this.removeCRLF(l);
257326
let r = {};
258327
let s = l.split(' ');
259-
328+
260329
if (s === undefined)
261330
return r;
262-
331+
263332
if (s[1] === undefined)
264333
return r;
265-
334+
266335
if (s[1].split('=')[1] === undefined) {
267336
r.lat = 1 * s[0];
268337
r.lon = 1 * s[1];
269338
if (!r.lat || !r.lon) {
270-
print("Parse error at ", l);
339+
print("Parse error at ", l, "have (", s[0], s[1], ")");
271340
}
272341
}
273342

@@ -282,6 +351,7 @@ let egt = {
282351
},
283352
};
284353

354+
285355
/* zoom library v0.0.4 */
286356
var zoom = {
287357
buf : 0,
@@ -367,9 +437,8 @@ var zoom = {
367437
}
368438
};
369439

370-
371440
function toCartesian(v) {
372-
const R = 6371; // Poloměr Země v km
441+
const R = 6371; // Earth radius in km
373442
const latRad = v.lat * Math.PI / 180;
374443
const lonRad = v.lon * Math.PI / 180;
375444

@@ -424,6 +493,7 @@ function angleDifference(angle1, angle2) {
424493
return difference;
425494
}
426495

496+
/* These are initialized by read() function, below */
427497
var start = {}, destination = {}, num = 0, dist = 0;
428498

429499
function read(pp, n) {
@@ -447,13 +517,15 @@ function read(pp, n) {
447517
start = p;
448518
pp.lat = p.lat;
449519
pp.lon = p.lon;
520+
/* FIXME: won't init destination */
521+
return;
450522
}
451523
prev = p;
452524
}
453525
l = f.readLine();
454526
if (!(num % 30)) {
455527
g.clear();
456-
zoom.geoPaint(prev, 0, 1500);
528+
zoom.geoPaint(prev, 0, 2500);
457529
g.drawString(num + "\n" + fmt.fmtDist(dist / 1000), 3, 3);
458530
g.flip();
459531
print(num, "points");
@@ -467,7 +539,9 @@ function read(pp, n) {
467539
destination = prev;
468540
}
469541

542+
/* Convert to storagefile, and find out start/stop points (and display some eye-candy) */
470543
function time_read(n) {
544+
ui.drawMsg("Converting");
471545
print("Converting...");
472546
to_storage(n);
473547
print("Running...");
@@ -488,6 +562,8 @@ function time_read(n) {
488562
setTimeout(step, 100);
489563
}
490564

565+
/* Main code for displaying track */
566+
491567
var track_name = "", inf, point_num, track = [], track_points = 30, north = {}, point_drawn;
492568

493569
function step_init() {
@@ -524,6 +600,7 @@ function paint(pp, p1, p2, thick) {
524600
zoom.geoLine(p1, p2);
525601
}
526602

603+
/* Paint points in window around current position */
527604
function paint_all(pp) {
528605
let prev = 0;
529606
let mDist = 99999999999, m = 0;
@@ -557,10 +634,13 @@ function paint_all(pp) {
557634
if (fast)
558635
return { quiet: 0, offtrack : 0 };
559636
print("Best segment was", m, "dist", mDist);
560-
if (fmt.distance(track[m], zoom.origin) > 1500) {
637+
/* If we are too far from ... */
638+
if (fmt.distance(track[m], zoom.origin) > 2500) {
561639
zoom.geoNew(track[m], 3000); // FIXME: this will flicker
562640
point_drawn = 0;
563641
}
642+
643+
/* Estimate distance to next turn/intersection */
564644
let ahead = 0, a = fmt.bearing(track[m-1], track[m]), quiet = -1;
565645
for (let i = m+1; i < track.length; i++) {
566646
let a2 = fmt.bearing(track[i-1], track[i]);
@@ -583,6 +663,8 @@ function drop_last() {
583663
track.shift();
584664
}
585665

666+
/* Display data for given position -- pp.
667+
Drop data that are more than 150 meters behind current position */
586668
function step_to(pp, pass_all) {
587669
if (0) {
588670
g.setColor(0.5, 0.5, 1);
@@ -591,9 +673,7 @@ function step_to(pp, pass_all) {
591673
g.setColor(1, 0.5, 0.5);
592674
paint(pp, pp, north, 1);
593675
}
594-
595676
let quiet = paint_all(pp);
596-
597677
while (distSegment(track[0], track[1], pp) > 150 &&
598678
track.length > 10) {
599679
drop_last();
@@ -626,17 +706,25 @@ function step() {
626706
let quiet = step_to(pp, 1);
627707
if (1) {
628708
g.setColor(0, 0, 0);
629-
zoom.geoPaint(pp, -pp.course, 500);
709+
let zoom_scale = 0;
710+
switch (ui.display) {
711+
case 0: zoom_scale = 500; break;
712+
case 1: zoom_scale = 1500; break;
713+
case 2: zoom_scale = 2500; break;
714+
case 3: /* draw some statistics? */ break;
715+
}
716+
if (zoom_scale)
717+
zoom.geoPaint(pp, -pp.course, zoom_scale);
630718
}
631719

632720
{
633-
pp.x = ui.w/2;
634-
pp.y = ui.h*0.5;
635-
636-
g.setColor(0, 0, 1);
637-
let sc = 2.5;
638-
g.drawPoly([ pp.x, pp.y, pp.x - 5*sc, pp.y + 12*sc, pp.x + 5*sc, pp.y + 12*sc ], true);
721+
/* Draw arrow representing current position */
722+
pp.x = ui.w/2;
723+
pp.y = ui.h*0.5;
639724

725+
g.setColor(0, 0, 1);
726+
let sc = 2.5;
727+
g.drawPoly([ pp.x, pp.y, pp.x - 5*sc, pp.y + 12*sc, pp.x + 5*sc, pp.y + 12*sc ], true);
640728
}
641729

642730
g.setColor(0, 0, 0);
@@ -668,6 +756,10 @@ function step() {
668756
setTimeout(step, 1000);
669757
}
670758

759+
/* Recovery: If we get completely lost, we can do this.
760+
It works similar to main loop, but faster.
761+
It simply drop points until we are 400meters from the fix, then main code can take over.
762+
*/
671763
function recover() {
672764
ui.drawMsg("Recover...");
673765
step_init();
@@ -676,7 +768,7 @@ function recover() {
676768
pp.ppm = 0.08 * 3; /* Pixels per meter */
677769
if (!fix.fix) {
678770
print("Can't recover with no fix\n");
679-
fix.lat = 50.010507;
771+
fix.lat = 50.010507; /* FIXME */
680772
fix.lon = 14.765840;
681773
}
682774
load_next();
@@ -693,10 +785,11 @@ function recover() {
693785
step_to(pp, 1);
694786
if (!load_next())
695787
break;
696-
ui.drawMsg("Recover\n" + fmt.fmtDist(d / 1000));
788+
ui.drawMsg("Recover\n" + fmt.fmtDist(d / 1000) + "\n" + point_num + "/" + num);
697789
}
698790
}
699791

792+
/* Convert "normal" file to storagefile... so that we can read lines from it */
700793
function to_storage(n) {
701794
let f2 = require("Storage").open(n+".st", "w");
702795
let pos = 0;
@@ -711,7 +804,6 @@ function to_storage(n) {
711804
}
712805
}
713806

714-
ui.init();
715807
fmt.init();
716808
egt.init();
717809
gps.init();
@@ -725,23 +817,27 @@ l = st.list(l, {sf:false});
725817

726818
print(l);
727819

820+
/* After user selected the track, we can switch to main interface */
728821
function load_track(x) {
822+
ui.init();
823+
ui.numScreens = 4;
824+
ui.screens = [ "Detail", "Mid", "Overview", "Stats" ];
825+
729826
Bangle.buzz(50, 1);
730827
ui.drawMsg("Loading\n"+x);
731828
track_name = x;
732829
time_read(x);
733-
734-
Bangle.setUI("clockupdown", btn => {
735-
print("Button", btn);
736-
if (btn == -1) {
737-
recover();
738-
}
739-
if (btn == 1) {
740-
demo_mode = 1;
741-
}
830+
831+
Bangle.on("drag", (b) => ui.touchHandler(b));
832+
Bangle.setUI({
833+
mode : "custom",
834+
clock : 0
742835
});
836+
ui.topLeft = () => { ui.drawMsg("Demo mode"); demo_mode = 1; }
837+
ui.topRight = () => { ui.drawMsg("Recover"); recover(); };
743838
}
744839

840+
/* Display menu with tracks. */
745841
var menu = {
746842
"< Back" : Bangle.load
747843
};

0 commit comments

Comments
 (0)