mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-08 05:06:11 +00:00
feat(companion): GPS averaging for waypoint marking (Mark avg)
Add a "Mark avg" trail setting (Off/5/10/30 s). When set, Tools › Trail › Mark here samples the GPS fix once a second for the chosen window and stores the mean position instead of one instantaneous fix — a steadier, more accurate mark for a precise spot. A progress screen shows time left + sample count; Cancel aborts; the window then opens the label keyboard as usual. Off (default) keeps marking instant. Sampling runs in WaypointsView::poll() (forwarded from TrailScreen::poll()) so it ticks on the main loop, independent of the slow e-ink render cadence; int64 accumulators avoid overflow over 30 samples. Persisted as NodePrefs::gps_avg_idx (schema 0xC0DE0016): struct field + option table, DataStore rd/write/clamp in lockstep. sizeof unchanged (the uint8_t fits existing tail padding) so the 2488 tripwire still holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
35622b7693
commit
c60a7a7f64
@@ -72,7 +72,7 @@ class TrailScreen : public UIScreen {
|
||||
// (Start/Stop tracking, Reset). PopupMenu stores label pointers verbatim, so
|
||||
// the labels live in member buffers that get refreshed in openActionMenu()
|
||||
// and after every LEFT/RIGHT cycle.
|
||||
enum ActionId { ACT_MIN_DIST, ACT_UNITS, ACT_GRID, ACT_AUTOPAUSE, ACT_TOGGLE, ACT_SAVE, ACT_LOAD, ACT_RESET, ACT_EXPORT, ACT_EXPORT_SAVED, ACT_MARK, ACT_WAYPOINTS, ACT_FILE, ACT_SETTINGS,
|
||||
enum ActionId { ACT_MIN_DIST, ACT_UNITS, ACT_GRID, ACT_AUTOPAUSE, ACT_MARK_AVG, ACT_TOGGLE, ACT_SAVE, ACT_LOAD, ACT_RESET, ACT_EXPORT, ACT_EXPORT_SAVED, ACT_MARK, ACT_WAYPOINTS, ACT_FILE, ACT_SETTINGS,
|
||||
ACT_SHARE_NOW };
|
||||
// The action popup is multi-level: a short main menu, plus "Trail file…" and
|
||||
// "Settings…" submenus. _menu_level tracks which is open so input is routed
|
||||
@@ -88,6 +88,7 @@ class TrailScreen : public UIScreen {
|
||||
char _act_units_label[24];
|
||||
char _act_grid_label[16];
|
||||
char _act_autopause_label[24];
|
||||
char _act_mark_avg_label[24];
|
||||
char _act_toggle_label[20];
|
||||
|
||||
static const int SUMMARY_ITEM_COUNT = 5;
|
||||
@@ -136,6 +137,10 @@ public:
|
||||
return _store->isActive() ? 1000 : 5000;
|
||||
}
|
||||
|
||||
// Forward the loop tick to the waypoint UI so GPS averaging (Mark avg) can
|
||||
// sample independently of the render cadence (slow on e-ink).
|
||||
void poll() override { _wp.poll(); }
|
||||
|
||||
bool handleInput(char c) override {
|
||||
// Waypoint management UI consumes all input while active.
|
||||
if (_wp.active()) return _wp.handleInput(c);
|
||||
@@ -172,6 +177,7 @@ public:
|
||||
case ACT_MIN_DIST:
|
||||
case ACT_UNITS:
|
||||
case ACT_GRID:
|
||||
case ACT_MARK_AVG:
|
||||
case ACT_AUTOPAUSE: cycleSetting(act, 1); reopenSettingsAt(sel); return true;
|
||||
case ACT_SHARE_NOW: shareMyLocationNow(); break;
|
||||
case ACT_TOGGLE:
|
||||
@@ -318,6 +324,8 @@ private:
|
||||
"Grid: %s", _map_grid ? "ON" : "OFF");
|
||||
snprintf(_act_autopause_label, sizeof(_act_autopause_label),
|
||||
"Auto-pause: %s", NodePrefs::trailAutoPauseLabel(p ? p->trail_autopause_idx : 0));
|
||||
snprintf(_act_mark_avg_label, sizeof(_act_mark_avg_label),
|
||||
"Mark avg: %s", NodePrefs::gpsAvgLabel(p ? p->gps_avg_idx : 0));
|
||||
snprintf(_act_toggle_label, sizeof(_act_toggle_label),
|
||||
"%s tracking", _store->isActive() ? "Stop" : "Start");
|
||||
}
|
||||
@@ -382,6 +390,7 @@ private:
|
||||
_action_menu.begin("Settings", 4);
|
||||
pushAction(ACT_MIN_DIST, _act_min_dist_label);
|
||||
pushAction(ACT_AUTOPAUSE, _act_autopause_label);
|
||||
pushAction(ACT_MARK_AVG, _act_mark_avg_label);
|
||||
if (_view == V_SUMMARY) pushAction(ACT_UNITS, _act_units_label);
|
||||
if (_view == V_MAP) pushAction(ACT_GRID, _act_grid_label);
|
||||
}
|
||||
@@ -393,6 +402,7 @@ private:
|
||||
if (act == ACT_UNITS && p) { cycleUnits(p, dir); _cfg_dirty = true; refreshActionLabels(); return true; }
|
||||
if (act == ACT_GRID) { _map_grid = !_map_grid; refreshActionLabels(); return true; }
|
||||
if (act == ACT_AUTOPAUSE && p){ cycleAutoPause(p, dir); _cfg_dirty = true; refreshActionLabels(); return true; }
|
||||
if (act == ACT_MARK_AVG && p){ cycleMarkAvg(p, dir); _cfg_dirty = true; refreshActionLabels(); return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -435,6 +445,13 @@ private:
|
||||
: (idx + NodePrefs::TRAIL_AUTOPAUSE_COUNT - 1) % NodePrefs::TRAIL_AUTOPAUSE_COUNT;
|
||||
p->trail_autopause_idx = idx;
|
||||
}
|
||||
void cycleMarkAvg(NodePrefs* p, int dir) {
|
||||
uint8_t idx = p->gps_avg_idx;
|
||||
if (idx >= NodePrefs::GPS_AVG_COUNT) idx = 0;
|
||||
idx = (dir > 0) ? (idx + 1) % NodePrefs::GPS_AVG_COUNT
|
||||
: (idx + NodePrefs::GPS_AVG_COUNT - 1) % NodePrefs::GPS_AVG_COUNT;
|
||||
p->gps_avg_idx = idx;
|
||||
}
|
||||
|
||||
// One-shot manual share: build "[LOC]lat,lon" and hand it to the Messages
|
||||
// screen, where the user picks a DM or channel recipient. (Auto live-share
|
||||
|
||||
Reference in New Issue
Block a user