From de3a607f96caf3710cda1ad703765beedb43fcee Mon Sep 17 00:00:00 2001 From: jjangddu Date: Fri, 26 Jun 2026 11:20:54 +0900 Subject: [PATCH] =?UTF-8?q?ux(alignment=20v2):=20hint=20=EB=AC=B8=EA=B5=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=ED=96=89=EB=8F=99=20?= =?UTF-8?q?=EC=A4=91=EC=8B=AC=EC=9C=BC=EB=A1=9C=20=E2=80=94=20ch=20?= =?UTF-8?q?=EA=B8=B0=EC=88=A0=EC=9A=A9=EC=96=B4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V2 algorithm hint 만 수정 (V1 그대로): - INITIAL_ACCUM: '측정 준비 중' → '잠시 그대로 두세요' - VERTICAL_CLIMB: '↑ 위로 (ch3 미검출)' → '↑ 위로 조금씩 올리세요' - CH3_STABILIZE hold: '✓ ch3 검출! 위치 유지' → '✓ 좋아요! 그 위치 유지' - CH3_STABILIZE lost: '↑ ch3 다시 잃음 — 위로' → '↑ 살짝 놓침 — 다시 위로' - LR_BALANCE lost: '↑ chN 잃음 — 위치 회복' → '↑ 위치 살짝 벗어남 — 위로 약간' - LR_BALANCE done: '■ 정렬 완료 (ch1+ch2..., |Δ|=N)' → '✓ 정렬 완료! 그대로 측정 가능' - LR_BALANCE LR: '← chN 유지 + 좌우 균형 (|Δ|=N)' → '← 왼쪽으로 살짝' (or 오른쪽) - LR_BALANCE probe: '↔ ch... 좌우 천천히 (lateral 미검출)' → '↔ 좌우로 천천히 움직여 보세요' PlacementGuideView 의 V2-only baseline 메시지: - waitingForStart V2 branch: '센서를 치골 위에 두고 Start 를 누르세요' 원본 ch/Δ/setLabel 같은 임상 메타는 dev debug log (ALIGN_V2 ...) 로만 유지. Co-Authored-By: Claude Opus 4.7 --- .../managers/AlignmentAdvisorV2.kt | 23 +++++++++---------- .../ui/views/monitoring/PlacementGuideView.kt | 6 +++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/example/medilightv2android/managers/AlignmentAdvisorV2.kt b/app/src/main/java/com/example/medilightv2android/managers/AlignmentAdvisorV2.kt index d05e2cd..b616090 100644 --- a/app/src/main/java/com/example/medilightv2android/managers/AlignmentAdvisorV2.kt +++ b/app/src/main/java/com/example/medilightv2android/managers/AlignmentAdvisorV2.kt @@ -190,7 +190,7 @@ class AlignGuide4Stage( if (phase == Phase4.INITIAL_ACCUM) { initialCount++ if (initialCount < initialTarget) { - return Out(null, "측정 준비 중... (${initialCount}/${initialTarget})", + return Out(null, "잠시 그대로 두세요 (${initialCount}/${initialTarget})", phase, initialCount) } phase = Phase4.VERTICAL_CLIMB @@ -199,7 +199,7 @@ class AlignGuide4Stage( // === Phase 2: VERTICAL_CLIMB === if (phase == Phase4.VERTICAL_CLIMB) { if (!s.ch3) { - return Out(AlignAction.MOVE_UP, "↑ 위로 조금씩 올리세요 (ch3 미검출)", + return Out(AlignAction.MOVE_UP, "↑ 위로 조금씩 올리세요", phase, 0) } phase = Phase4.CH3_STABILIZE @@ -215,12 +215,12 @@ class AlignGuide4Stage( // ch3 잃었으면 → VERTICAL_CLIMB 회귀 phase = Phase4.VERTICAL_CLIMB stabilizeCount = 0 - return Out(AlignAction.MOVE_UP, "↑ ch3 다시 잃음 — 위로", + return Out(AlignAction.MOVE_UP, "↑ 살짝 놓침 — 다시 위로", phase, 0) } if (stabilizeCount < stabilizeTarget) { return Out(AlignAction.STOP, - "✓ ch3 검출! 위치 유지 (${stabilizeCount}/${stabilizeTarget})", + "✓ 좋아요! 그 위치 유지 (${stabilizeCount}/${stabilizeTarget})", phase, stabilizeCount) } phase = Phase4.LR_BALANCE @@ -228,14 +228,14 @@ class AlignGuide4Stage( // === Phase 4: LR_BALANCE === if (curSet.size > bestCenterSet.size) bestCenterSet = curSet - val setLabel = bestCenterSet.sortedDescending().joinToString("+") { "ch$it" } + val setLabel = bestCenterSet.sortedDescending().joinToString("+") { "ch$it" } // dev/debug only val lost = bestCenterSet - curSet if (lost.isNotEmpty()) { // 잃은 채널 있음 → 회복 우선. ch3 잃었으면 더 위로, 아니면 아래로. val recoveryDir = if (3 in lost) AlignAction.MOVE_UP else AlignAction.MOVE_DOWN - val lostLabel = lost.sortedDescending().joinToString(",") { "ch$it" } val arrow = if (recoveryDir == AlignAction.MOVE_UP) "↑" else "↓" - return Out(recoveryDir, "$arrow $lostLabel 잃음 — 위치 회복", phase, 0) + val dirWord = if (recoveryDir == AlignAction.MOVE_UP) "위" else "아래" + return Out(recoveryDir, "$arrow 위치 살짝 벗어남 — ${dirWord}로 약간", phase, 0) } // full set 유지 중 — 좌우 균형 (deadband + consecutive 악화 로 oscillation 차단) @@ -245,7 +245,7 @@ class AlignGuide4Stage( val imbal = kotlin.math.abs(u4 - u5) if (imbal <= latTol) { return Out(AlignAction.STOP, - "■ 정렬 완료 ($setLabel 유지, |Δ|=$imbal)", phase, 0) + "✓ 정렬 완료! 그대로 측정 가능", phase, 0) } if (lateralDir == null) { // 첫 진입 — u4/u5 비교로 방향 추정 @@ -269,12 +269,11 @@ class AlignGuide4Stage( } lateralImbal = imbal val arrow = if (lateralDir == AlignAction.MOVE_LEFT) "←" else "→" - return Out(lateralDir!!, "$arrow $setLabel 유지 + 좌우 균형 (|Δ|=$imbal)", - phase, 0) + val sideWord = if (lateralDir == AlignAction.MOVE_LEFT) "왼쪽" else "오른쪽" + return Out(lateralDir!!, "$arrow ${sideWord}으로 살짝", phase, 0) } // u4/u5 미검출 → probe - return Out(AlignAction.PROBE_LR, "↔ $setLabel 유지 + 좌우 천천히 (lateral 미검출)", - phase, 0) + return Out(AlignAction.PROBE_LR, "↔ 좌우로 천천히 움직여 보세요", phase, 0) } } diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt index d6c00b0..089b4d7 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt @@ -351,8 +351,10 @@ fun PlacementGuideView(appState: AppState) { val rawHint = buildString { val hint = directionHint.ifEmpty { " " } append(hint) + // 점 ... 애니메이션 — 알고리즘 진행 중인 메시지에 점 추가. if (hint.startsWith("Slide") || hint.startsWith("Optimizing") || - hint.startsWith("Checking") || hint.startsWith("Adjust")) { + hint.startsWith("Checking") || hint.startsWith("Adjust") || + hint.contains("이동") || hint.contains("천천히") || hint.contains("그대로")) { append(dots) } if (appState.isDevMode && !lastCv.isNaN()) { @@ -859,7 +861,7 @@ fun PlacementGuideView(appState: AppState) { // Clinical alignment session + waitingForStart 일 땐 알고리즘 skip — // baseline cycles 만 누적 (Start 누르기 전 자동 phase 진행 차단). if (waitingForStart) { - directionHint = "Place sensor above pubic bone, then press Start" + directionHint = "센서를 치골 위에 두고 Start 를 누르세요" directionIcon = "" placementScore = 0 } else {