Skip to content

Develop - #4

Merged
Flazzarious merged 34 commits into
mainfrom
develop
Oct 5, 2026
Merged

Flazzarious merged 34 commits into
mainfrom
develop

Conversation

@Flazzarious

Copy link
Copy Markdown
Owner

No description provided.

Flazzarious and others added 30 commits September 27, 2026 12:15
Add plan, research, data model, contracts (settings form, telemetry
window, lib modules, audio) and quickstart validation guide.

Sensor speed is taken as m/s, as in DFM Speed Announcer v2.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Features branch from develop as feature/NNN-name, releases go through
release/x.y.z to main and are tagged <script>-v<version>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aaron supplied a car HUD speedometer as the style to follow. The photo
isn't committed (third-party product image); its elements are described
instead: dark round face, ~270 deg sweep, rim ticks and numbers, glowing
value arc, red overspeed zone, big center number, subtle max marker, and
secondary rows. Adds a per-size layout (full dial when double, compact
arc when single; exact window sizes to be measured in planning) and
updates FR-014/014a/016/017 and the gauge acceptance scenarios.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Aaron: the gauge assumes the DS-24 II display; older transmitters are
not supported for the gauge. JETI lists the II display as 4", 480x480 px,
not the original DS-24's 320x240.

- Spec 001: DS-24 II / DC-24 II is the gauge target; new FR-013a shows a
  notice on other transmitters while callouts/warnings keep working;
  window sizes must be measured with the probe and recorded in plan.md.
- tools/probe/PROBE.lua: dev tool that prints the small/large window and
  form canvas sizes plus font heights (copied to the emulator's Apps).
- docs/jeti-api-notes.md: target hardware section with a table to fill.
- CLAUDE.md, README: note the target and the probe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Measured in the emulator (fw 6.04) with PROBE.lua: small 157x60, large
157x127. Lua on the II keeps the original's window sizes, not 480x480.

- docs/jeti-api-notes.md, spec 001, CLAUDE.md: record sizes; layouts
  sized for them (compact arc when single, ~110-120 px dial with corner
  rows when double).
- Spec 001: add a full-screen window (dial + side panel, like the
  reference). FR-013: two windows, the per-app maximum: single/double
  (auto) and full screen.
- PROBE.lua 1.1: MODE switch; MODE 2 measures full-screen sizes 3 and 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Measured with PROBE.lua 1.1 in the emulator: full-screen sizes 3 and 4
are both 320x260 on the II, so the spec drops the status-bar option.
Spec 001, API notes and CLAUDE.md now list all three window sizes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
The reference photo lives at docs/vendor/gauge-reference.jpg on the dev
PC (gitignored, third-party product image) so Claude Code can open it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
41 tasks in 8 phases, organized by user story. US1 (callouts) is the
MVP; MANUAL tasks mark the emulator and transmitter checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/emulator/sensors.json for LeonAirRC's Emulator Telemetry app
(installed separately, emulator only): MSpeed 450 Velocity 0-450 km/h
on P5 and GPS Speed 0-300 km/h on P6. Control fully down = sensor lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Per research R3 (API doc + JETI forum), sensors send speed in m/s, so the
emulated MSpeed 450 and GPS now report m/s (0-125 and 0-83.3, about
450 and 300 km/h). R3 gains two notes: call system.getSensor* via
`system` each time (Emulator Telemetry swaps them) and the emulator
sensor ranges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Plan follows the spec's visual design reference and measured DS-24 II
window sizes: dark face, numbered scale, overspeed zone, compact /
round / full-screen layouts, size-0 pilot-sized window with a fallback
setting, colors without red/orange, and a notice on other transmitters
(research R6-R8, R12). Quickstart uses tools/emulator/sensors.json.

tasks.md regenerated: 46 tasks; US3 rebuilt for the new layouts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New app src/Apps/AG-SpdGa.lua with shared modules ag_dens (ISA density
factor) and ag_gauge (dial geometry and drawing), per spec 001:
- US1/US2: DFM v2.1 callout timing, stall/overspeed/airspeed-alive
  warnings with vibration, startup announcement
- US3: compact, round and full-screen gauge layouts after the design
  reference, layout cache, spike-filtered session max, DS-24 II notice
- US4: optional true-airspeed correction from elevation and temperature
- US5: grouped settings, units conversion, threshold-order warning

The max filter also counts a reading held for 1 s; without it a steady
speed never registered (research R5). Reused DFM WAVs are credited in
src/Apps/AG-SpdGa/CREDITS.txt. PROBE.lua gains a size-0 mode.

Verified: check.py, LuaLS (no problems), tests/test_ag_dens.lua and a
48-check mock-API run under Lua 5.3 (fengari). Emulator and transmitter
checks (T005, T017, T021, T029, T035, T039, T046) are still open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes found in the JETI Studio emulator (DS-24 II, firmware 6.04):
- Callouts never played: the ms time counter is a wrapped, negative
  32-bit value. All time checks now compare differences.
- Single and double windows were clipped: the II desktop draws each
  window's title bar inside the canvas, hiding ~25 px at the bottom.
  Layouts draw into h - TITLE_H; the compact layout is reworked for
  ~34 px.
- The dial face drew past the window border (the renderer does not
  clip): ag_gauge.face can now cut the circle flat at maxY.
- Full screen uses size 4, as DFM-InsP does; size 3 is covered by the
  desktop's model tile.

Refinements from the user's review:
- Full-screen window titled "Speed Gauge"; larger scale and unit text
  on the full-screen dial.
- Max marker thicker and longer; new Yellow preset is its default.
- Glow bands fading toward the center behind the value arc and the
  overspeed zone (ag_gauge.arc gains alpha).
- Past the overspeed mark the value arc switches to the overspeed color.

Spec (FR-013, FR-014, FR-017), research, data model, contracts and
quickstart updated to match. docs/jeti-api-notes.md records the visible
window sizes, scale, fonts, device string and Emulated Telemetry
behavior. PROBE.lua gains a size-0 mode, a ruler, an isPlayback log and
an empty-title test.

Verified: check.py, LuaLS, test_ag_dens.lua and the mock-API harness
(51 checks including wrapped clock, visible-area bounds and overspeed
color); layouts reviewed in the emulator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Full-screen gauge:
- MAX moves from the side panel to the open bottom of the dial, centered
  under the speed, without a unit.
- Side panel rows are spread over the visible height (about 10 px apart):
  STALL, OVERSPEED, AIR DENSITY (+N%, OFF or GPS, always shown), and
  while correction is on ELEVATION (as set, ft or m) and RAW SENSOR
  (uncorrected speed).

Fix: when the sensor is lost, RAW SENSOR shows "---" instead of keeping
its last value.

Spec, plan, contract and quickstart brought up to date with the review
decisions: glow and overspeed coloring, yellow max marker, visible
window sizes and title bar, compact layout, settings labels, and the
now-verified emulator assumptions.

Verified: check.py, LuaLS, and the mock-API harness (72 checks,
including text-overlap and visible-area checks for every layout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured in the emulator with system.getCPU(): the CPU figure in the app
list is the highest per-call budget use (the script is killed at 100%),
not an average. Start-up 24%, loop 0-1%, small/double draw up to 18%,
full-screen draw up to 43% (down from 66%).

- Glow bands use a coarse 10-degree dial and fewer, wider bands; visible
  edges keep 5-degree steps (10 degrees looked blocky on the II).
- Drawing split into fixed parts, moving parts and scale labels.
- Off-screen image caching was tried and removed: on the II emulator the
  image showed nothing and the figure did not drop.
- SC-007 revised to "worst single call below 50%, full screen included";
  the user accepted the full-screen glow as designed. Plan, research,
  quickstart and tasks updated (T030 closed).

docs/jeti-api-notes.md records what the CPU figure means, how to log it,
that alpha glow (not fills) is the cost, and that off-screen images don't
work. PROBE.lua prints Lua memory every 5 s.

Verified: check.py, LuaLS, mock-API harness (73 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aaron compared generated samples (Lessac, Amy, Ryan) and chose Amy as
the clearest.

- Clarification session 2026-09-28; User Story 6 (P3) with acceptance
  scenarios; edge cases for partial installs and number+unit splicing.
- FR-030-FR-037: number files 0-500, unit and warning phrases; Voice
  setting (Speed Gauge / Transmitter); startup check with per-callout
  fallback to the transmitter voice and DFM's recordings (never silent);
  generator in tools/voice/; generated files not committed (Amy model is
  CC BY-SA, training data license undocumented); Piper/Amy credits.
- FR-010 and assumptions updated; SC-009 (timing, from measured Amy
  durations) and SC-010 (no silent callouts without voice files).
- .gitignore: src/Apps/AG-SpdGa/voice/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Aaron asked for tighter, realistic limits (proposed -10..8,000 ft and
-10..120 F). Checking real airfields showed -10..8,000 ft would exclude
Leadville (9,934 ft), Telluride (9,078 ft), Furnace Creek (-208 ft),
Thermal (-114 ft) and Schiphol (-11 ft); he chose -300..10,000 ft. For
temperature he chose the wider -20..130 F for margin.

- Clarifications session 2026-09-30.
- FR-020: limits table (imperial and metric: -90..3,050 m, -29..54 C);
  standard temperature stays within limits across the elevation range.
- Edge case: values saved outside the limits are clamped on load.
- data-model.md: elev/temp ranges updated to match.

Code (form limits, unit-switch clamps, clamp on load) still uses the old
limits and needs a follow-up change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Aaron: Speed Gauge should be able to use the MSpeed's temperature, with
the sensor selectable or the temperature set manually.

- Clarification recorded; User Story 4 gains scenarios 7-9 (sensor
  reading, fallback on loss, no jitter).
- FR-038-FR-043: Temperature source Standard/Manual/Sensor (default
  Standard); sensor list limited to temperature values, stored by
  identity; readings used only if valid and within FR-020 limits, else
  standard temperature; read at most every 5 s with 1 C hysteresis;
  settings show the temperature and its source; stall/landing checks
  and GPS unaffected.
- Settings table, edge cases (warm fuselage, late/missing sensor) and
  assumptions (MSpeed EX reports temperature; pressure still out of
  scope) updated.
- data-model.md: tSrc/tId/tPar/tLbl replace tStd (27 keys), with a
  cfgV 1 -> 2 migration.
- tools/emulator/sensors.json: MSpeed 450 Temperature, -29..54 C on P7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Aaron: when the sensor reads out of range (e.g. heat-soaked in the sun
before flight) use the default, and resume the sensor once it's back in
range; show the sensor temperature on the full-screen gauge.

- FR-040: out-of-range/invalid readings use standard temperature;
  resume automatically after 10 s valid and in range (no flapping);
  note that in-range heat soak can't be detected.
- User Story 4 scenario 8a: 140 F at takeoff -> standard; cools to
  95 F in flight -> sensor resumes.
- FR-044: full-screen side panel Temperature row (value, unit, source,
  "SENSOR OUT" while rejected); full-screen layout text now six rows.
- Clarifications recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZc7boqR33nD9xyYsGNLBg
Add a "PR source is develop" check that fails any pull request into main
whose source is not this repo's develop branch (required by the main
ruleset), and document the branch flow in CLAUDE.md: feature/* branches
from develop and merges back by PR; develop goes to main by PR only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UXZ3gE435jMKRzKW9FRfiy
Spec 001 plan, tasks and implementation for the 2026-09-28/30 spec
changes, plus fixes from the first run on a real DS-24 II (2026-10-03).

- Temperature source Standard / Manual / Sensor (FR-038..FR-044): sensor
  read every 5 s, reject-and-resume, 1 C hysteresis, live status in
  settings, TEMP row on the full-screen panel.
- FR-020 limits (-300..10000 ft, -20..130 F), clamp on load, cfgV 1 -> 2
  migration of the 0.1.0 tStd checkbox.
- App voice (Piper "Amy", FR-030..FR-037): tools/voice/make_voice.py
  generates 512 WAVs locally (gitignored, CC BY-SA model); per-phrase
  fallback to the transmitter voice and DFM's recordings. Speech at 1.3x
  after listening on the transmitter.
- Layouts redesigned for the transmitter's real Lua windows (150x23,
  150x68, 316x159; the emulator reports larger ones): bar strip, small
  dial, full screen with one-line panel rows. The full-screen window is
  named "Speed Gauge (full screen)".
- Smooth dial: tools/dial/make_dial.py draws anti-aliased face/track PNGs,
  since the transmitter enlarges Lua lines without smoothing.
- Grouped constants into tables to stay under Lua's 200-local limit.
- Probe: sensor unit strings, MODE 5 (untitled full-screen window).
- docs/jeti-api-notes.md: transmitter sizes, fonts, scaling, no emulator
  audio, local-variable limit.

Open: SC-009's 1.3 s limit (longest number now 1.50 s), manual checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up from transmitter testing on 2026-10-03.

- Glow: nested filled ring segments with solved per-layer alphas, on a
  5-degree path; no seams from overlapping polyline joints.
- Solid arcs: pre-drawn anti-aliased ring images (overspeed zone, speed
  arc in each color, speed arc past the limit) from tools/dial/make_dial.py,
  shown through lcd.setClipping in three 90-degree sectors. setClipping
  also moves the drawing origin, so images are drawn at minus the clip
  corner.
- ag_gauge: new band() (filled ring segment), drawn in pieces of at most
  18 dial steps. Speed Gauge is the module's only user.
- JETI Studio's simulator crashes in Qt6Core once filled arcs are drawn;
  the emulator's windows (widths 157, 320) draw arcs and glow as
  polylines instead. The transmitter keeps images and filled bands.
- "Gauge full scale" renamed "Gauge max limit", with explanatory hints.
- Voice generator: default speed 1.3, hint wording.
- RAW row shows "---" before the first reading.
- TEMPORARY: DEBUG_CPU readout on the full-screen gauge (remove before
  release, task T080).
- docs/jeti-api-notes.md: text vs line resolution, setClipping origin,
  DFM-InsP uses the same 318 x 159 area.

Open: live pitot test, emulator crash confirmation, SC-009 limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The emulator's full-screen gauge stopped with the speed at full scale
(no new Windows crash logged, so most likely the per-call CPU limit).
In the emulator's windows the polyline glow now draws every other band
at double width: 5 lines per arc instead of 9, same area and fade. The
transmitter's filled bands are unchanged. Confirmed working in the
emulator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…voice

From the first live tests on the transmitter (2026-10-03).

- Full screen went blank at the overspeed setting: the live glow bands
  pushed one redraw to the CPU limit. The glow is now baked into the ring
  images (tools/dial/make_dial.py); no live glow when they exist.
  drawRing clips by quadrant, so neighbors join exactly along the dial's
  center lines.
- "Callouts start above" (vArm, default 30 mph): normal and continuous
  callouts and "airspeed alive" wait until first exceeded, then stay
  armed for the session. Replaces the half-of-landing-speed rule, which
  continuous mode bypassed (FR-009).
- "Landing speed callouts" on/off (landOn, default on). Off: landing
  speed no longer makes callouts fast and short; it still arms the stall
  warning (FR-006, FR-008). Settings keys: 30, the limit.
- Short hints under both callout switches.
- Voice generator default speed 1.5, so every number up to 199 fits
  SC-009's 1.3 s (longest 1.28 s). Voice WAVs stay uncommitted (FR-035).
- Spec, data model, contracts, quickstart, research and tasks (T076,
  T086-T089) updated.

Open: live pitot retest, T088 (voice detection), T080 (remove DEBUG_CPU).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Voice files (user decision, 2026-10-03):
- Commit the 512 generated voice WAVs, CREDITS.txt and index.txt in
  src/Apps/AG-SpdGa/voice/ (1.5x, longest number 1.28 s).
- These files are CC BY-SA 4.0, like the Amy voice model, not MIT like
  the rest of the repository; the license of the model's training
  recordings is undocumented. Labeled in CREDITS.md, README.md, the
  folder's CREDITS.txt and tools/voice/README.md.
- Spec FR-035 changed from "MUST NOT be committed" to committed; the
  voice/ line is removed from .gitignore.

From the live test (no crashes; worst CPU 14% at speed):
- Stall warning at most twice per slowdown; the count resets once above
  landing speed (FR-010, US2 #1).
- Continuous callouts speak only while above "Callouts start above"
  (FR-009a); hint updated.
- "Gauge max limit" hint lists the MSpeed (20-350 km/h) and MSpeed 450
  EX (80-450 km/h) ranges.
- Quickstart 7a/7b; tasks T062, T090.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From live testing on the transmitter (2026-10-04).

- CPU readout off (DEBUG_CPU = false; T080): worst full-screen redraw
  was 14% at speed.
- No callout below 5 mph or its equivalent in any units (FR-008b).
- "Longest time between callouts" 2-60 s (was 10-60), never below the
  shortest: it stops at the shortest, and raising the shortest raises it;
  corrected on load too (FR-005).
- Max-speed callout "max N unit" once the session max hasn't risen for
  1 s and beats the last announced max by the callout sensitivity
  (FR-019a). New voice phrase max.wav (513 files); the generator's new
  --missing option made it without changing the committed WAVs.
- Spec, data model, contracts, quickstart (13c-13e) and tasks (T091).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- APP_VERSION 0.3.0 after live pitot testing on the DS-24 II.
- CLAUDE.md: target window sizes are the transmitter's (150x23, 150x68,
  316x159), not the emulator's; emulator plays no Lua audio.
- docs/jeti-api-notes.md: facts verified on the transmitter (device
  string, size 0, 22.05 kHz WAV, the degree sign, renderer reuse,
  temperature unit, CPU); local-variable count 191 of 200.
- DEBUG_CPU comment: diagnostic, off for release.
- plan.md release note; tasks T043 done, T070 partly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in develop's "main only from develop" branch rule (5747cc5) so
the pull request into develop merges cleanly.

CLAUDE.md conflict: kept develop's Branches section (enforced on GitHub)
and folded in this branch's details that still fit: matching branch and
spec-folder names, the Spec Kit note, release tags after the develop ->
main PR, ask before pushing/PRs/tagging. Dropped the release/x.y.z and
hotfix flow, which the new rule doesn't allow. README's branching table
updated to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Flazzarious and others added 4 commits October 4, 2026 19:50
- README apps table: Speed Gauge is a release candidate (0.3.0).
- tasks.md: manual checks the user confirmed on the transmitter
  (2026-10-04) ticked: T017, T021, T029, T035, T039, T046, T072, T077.
  T088 closed (no "Voice files missing" seen); T070 closed with the
  queue pause and warning cut-off judged "fine in use".
- Still open: T059 (temperature source checks) and T066 (voice checks),
  which the user hasn't tested separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Flazzarious
Flazzarious merged commit 9ebb27b into main Oct 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants