Files
Sylpheed/tools/re-capture/take_off_armed.py
Sylpheed RE agent 06d00d4529 tools: launch_mission reaches Stage 02 flight unattended again - wait for screens, not seconds
Two separate reasons the scripted route stopped, both measured rather than guessed:

* LOAD -> READY ROOM is not 28 s. Both runs on 2026-08-23 overran it, so the next
  press was eaten by the transition and the run ended up in OPTIONS once and
  BRIEFINGS once. wait_screen.sh now waits for the screen, with an optional
  --tap that clears a dialog the caller cannot know about (a freshly restored
  profile inserts "Auto-Save is active. OK?" here).
* The READY ROOM is DRAWN long before it is USABLE: it comes up with a
  "Preparing to Sortie" spinner and TAKE OFF greyed out. The two states differ by
  1.7 units of blue whole-image, so screen_id.py cannot separate them and should
  not try. take_off_armed.py tests the label instead: 0.0000 bright pixels while
  preparing, 0.1633 once armed, on three captures from two runs. It carries its
  own position check - the always-enabled BRIEFINGS label below reads 0.1027 in
  all three, to four decimals, so if that reference is dark the boxes are off the
  labels and the answer is "unknown", not a confident wrong one.

screen_id.py gains a "readyroom" class from the same measurements; nothing else
reclassifies.

Verified end to end and unattended: boot -> title -> LOAD GAME -> slot 01 ->
READY ROOM -> TAKE OFF -> "IN FLIGHT at 34s", pilot bound and engaging.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
2026-08-23 18:02:12 +00:00

54 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""Is the READY ROOM's TAKE OFF item ARMED, or still `Preparing to Sortie`?
`screen_id.py` answers "which screen", by whole-image statistics, and that is the
right contract for it — but it cannot answer this, because the two states of the
READY ROOM differ by a spinner and a greyed word and are otherwise the same
image: measured (13.4, 38.2, 135.2) while preparing against (12.7, 36.5, 133.5)
when armed. Waiting on that 1.7-unit difference would be superstition.
The disabled state is unambiguous where it actually shows: the TAKE OFF label has
**no** pixel above 170 while preparing, and **16.3 %** of its pixels above 170
once armed. Measured on three captures from two independent runs.
This does use fixed boxes, which `screen_id.py`'s header warns about — so it
carries its own check: the BRIEFINGS label below it is always enabled, and reads
**0.1027 bright in all three captures**, to four decimal places, across those two
runs. If that reference is not bright, the boxes are not on the labels and the
answer is `unknown` rather than `not armed` — which is the failure mode the
warning is about.
Only meaningful ON the READY ROOM — ask `screen_id.py` first. The MAIN MENU has
its own text in these boxes and reads `armed` (0.1342), which is not a bug in
this test but the reason it is not a screen classifier.
Usage: take_off_armed.py <png> -> prints armed|preparing|unknown
exit 0 only when armed
"""
import sys
from PIL import Image
TAKE_OFF = (548, 140, 745, 182)
BRIEFINGS = (548, 196, 760, 238) # always enabled — the position self-check
BRIGHT = 170
def bright_fraction(im, box):
px = list(im.crop(box).getdata())
return sum(1 for v in px if v > BRIGHT) / len(px)
def state(path):
im = Image.open(path).convert("L")
ref = bright_fraction(im, BRIEFINGS)
if ref < 0.04:
return "unknown", 0.0, ref
tgt = bright_fraction(im, TAKE_OFF)
return ("armed" if tgt > 0.04 else "preparing"), tgt, ref
if __name__ == "__main__":
st, tgt, ref = state(sys.argv[1])
print(f"{st} take_off={tgt:.4f} briefings_ref={ref:.4f}")
sys.exit(0 if st == "armed" else 1)