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:
@@ -1096,15 +1096,19 @@ fun PlacementGuideView(appState: AppState) {
|
|||||||
if (lastLedMode != 6) { bleManager.sendLedMode(6); lastLedMode = 6 }
|
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)}")
|
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) {
|
} 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++
|
greenFailCount++
|
||||||
if (greenFailCount < 3) {
|
if (greenFailCount < 10) {
|
||||||
// 아직 이탈 안 함 — GREEN 유지
|
// 아직 이탈 안 함 — GREEN 유지
|
||||||
directionHint = context.getString(R.string.placement_in_position)
|
directionHint = context.getString(R.string.placement_in_position)
|
||||||
directionIcon = "checkmark.circle"
|
directionIcon = "checkmark.circle"
|
||||||
placementPhase = PlacementPhase.GREEN
|
placementPhase = PlacementPhase.GREEN
|
||||||
} else {
|
} else {
|
||||||
// 3회 연속 실패 → 진짜 이탈
|
// 10회 연속 실패 → 진짜 이탈
|
||||||
isLocked = false
|
isLocked = false
|
||||||
greenLockedAtMs = 0L
|
greenLockedAtMs = 0L
|
||||||
greenFailCount = 0
|
greenFailCount = 0
|
||||||
@@ -1120,7 +1124,7 @@ fun PlacementGuideView(appState: AppState) {
|
|||||||
maxCenterSeen = 0; stableAtMax = 0; boundaryHit = false
|
maxCenterSeen = 0; stableAtMax = 0; boundaryHit = false
|
||||||
sweepLastDetected = 0; sweepEverSawAll = false
|
sweepLastDetected = 0; sweepEverSawAll = false
|
||||||
rTracker.reset()
|
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) {
|
} else if (!greenHeld) {
|
||||||
// GREEN 아닌 상태 + hold 아닌 상태에서 실패
|
// GREEN 아닌 상태 + hold 아닌 상태에서 실패
|
||||||
|
|||||||
@@ -320,7 +320,7 @@
|
|||||||
<string name="placement_complete_alignment">정렬 완료</string>
|
<string name="placement_complete_alignment">정렬 완료</string>
|
||||||
<string name="placement_start_scanning">측정 시작</string>
|
<string name="placement_start_scanning">측정 시작</string>
|
||||||
<string name="placement_skip">건너뛰기</string>
|
<string name="placement_skip">건너뛰기</string>
|
||||||
<string name="placement_in_position">제 위치입니다!</string>
|
<string name="placement_in_position">최적의 위치입니다!</string>
|
||||||
<string name="placement_position_lost">위치를 놓쳤습니다. 치골 위에서 다시 시작해주세요.</string>
|
<string name="placement_position_lost">위치를 놓쳤습니다. 치골 위에서 다시 시작해주세요.</string>
|
||||||
<string name="placement_detached_restart">센서가 분리되었습니다. 치골 위에서 다시 시작해주세요.</string>
|
<string name="placement_detached_restart">센서가 분리되었습니다. 치골 위에서 다시 시작해주세요.</string>
|
||||||
<string name="placement_signal_lost">신호를 놓쳤습니다 — 위로 올려주세요 ↑</string>
|
<string name="placement_signal_lost">신호를 놓쳤습니다 — 위로 올려주세요 ↑</string>
|
||||||
|
|||||||
@@ -320,7 +320,7 @@
|
|||||||
<string name="placement_complete_alignment">Complete Alignment</string>
|
<string name="placement_complete_alignment">Complete Alignment</string>
|
||||||
<string name="placement_start_scanning">Start Scanning</string>
|
<string name="placement_start_scanning">Start Scanning</string>
|
||||||
<string name="placement_skip">Skip</string>
|
<string name="placement_skip">Skip</string>
|
||||||
<string name="placement_in_position">In position!</string>
|
<string name="placement_in_position">Optimal position!</string>
|
||||||
<string name="placement_position_lost">Position lost. Restart above pubic bone.</string>
|
<string name="placement_position_lost">Position lost. Restart above pubic bone.</string>
|
||||||
<string name="placement_detached_restart">Sensor detached. Restart above pubic bone.</string>
|
<string name="placement_detached_restart">Sensor detached. Restart above pubic bone.</string>
|
||||||
<string name="placement_signal_lost">Signal lost — slide up ↑</string>
|
<string name="placement_signal_lost">Signal lost — slide up ↑</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user