fix(align): GREEN zone 조기 리셋 완화 + 문구 개선

증상:
1. Sensor Alignment 완료 GREEN 진입 후 일정 시간 (약 7초 hold 종료 +
   추가 몇 초) 지나면 UI 가 갑자기 "단계 0/3 / 정렬 시작" 으로
   초기화되어 처음부터 재시작해야 하는 불쾌한 UX.
2. GREEN 문구 "제 위치입니다!" 가 다소 어색.

원인:
PlacementGuideView V1 로직 (line 1098) 의 3-strike 규칙 —
`greenHeld` (7초 hold) 종료 후 `guideResult.isPass=false` 가 **3회
연속** 나오면 전체 리셋 (isLocked=false, waitingForStart=true,
scanCount=0, phase=VERTICAL, rTracker.reset() ...). 그런데 사용자가
GREEN 상태에서 버튼 안 누르고 그대로 기다리면 자연스러운 미세 자세
흔들림 (1~2초) 만으로 3회 실패 성립 → 완전 리셋.

수정:
1. `placement_in_position` "제 위치입니다!" → "최적의 위치입니다!"
   (영문: "In position!" → "Optimal position!").
2. 3-strike → 10-strike 완화. 10회 연속 실패 (약 5초+) 는 되어야
   진짜 이탈로 간주. 그 사이는 GREEN 유지 + "최적의 위치입니다" 표시.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 12:20:15 +09:00
parent 04607241ac
commit 2172304e50
3 changed files with 10 additions and 6 deletions
@@ -1096,15 +1096,19 @@ fun PlacementGuideView(appState: AppState) {
if (lastLedMode != 6) { bleManager.sendLedMode(6); lastLedMode = 6 }
bleManager.debugLogger.info("PLACEMENT_GREEN cv=${"%.3f".format(guideResult.cv)} lr_dev=${"%.3f".format(guideResult.lrDev)} score=${guideResult.score} otsu=${"%.0f".format(analyzer.lastOtsuThreshold)}")
} else if (isLocked && !greenHeld) {
// hold 지남 + 실패 → 3회 연속 실패해야 이탈
// hold 지남 + 실패 → N 회 연속 실패해야 이탈.
// 2026-07-07 fix: 3-strike → 10-strike 완화. 사용자가 GREEN 진입 후
// 버튼을 누르지 않고 그대로 기다릴 때, 미세한 자세 흔들림 (1~2초)
// 만으로 3회 실패 → "0/3 정렬시작" 완전 리셋되어 처음부터 재시작하는
// 불쾌한 UX 발생. 10회 (약 5초+) 는 되어야 진짜 이탈로 간주.
greenFailCount++
if (greenFailCount < 3) {
if (greenFailCount < 10) {
// 아직 이탈 안 함 — GREEN 유지
directionHint = context.getString(R.string.placement_in_position)
directionIcon = "checkmark.circle"
placementPhase = PlacementPhase.GREEN
} else {
// 3회 연속 실패 → 진짜 이탈
// 10회 연속 실패 → 진짜 이탈
isLocked = false
greenLockedAtMs = 0L
greenFailCount = 0
@@ -1120,7 +1124,7 @@ fun PlacementGuideView(appState: AppState) {
maxCenterSeen = 0; stableAtMax = 0; boundaryHit = false
sweepLastDetected = 0; sweepEverSawAll = false
rTracker.reset()
bleManager.debugLogger.info("PLACEMENT_GREEN_EXIT after 3 consecutive fails")
bleManager.debugLogger.info("PLACEMENT_GREEN_EXIT after 10 consecutive fails")
}
} else if (!greenHeld) {
// GREEN 아닌 상태 + hold 아닌 상태에서 실패