From 73e2596842118d46c31066aa2c4a346da2402ddc Mon Sep 17 00:00:00 2001 From: jjangddu Date: Tue, 11 Aug 2026 13:35:51 +0900 Subject: [PATCH] =?UTF-8?q?fix(alignment):=20"=EA=B8=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=EC=9D=B4=20=EC=A7=80=EC=97=B0=EB=90=98?= =?UTF-8?q?=EA=B3=A0=20=EC=9E=88=EC=8A=B5=EB=8B=88=EB=8B=A4"=20stuck=20+?= =?UTF-8?q?=20=EC=9E=AC=EC=A7=84=EC=9E=85=20stale=20=EC=B9=B4=EC=9A=B4?= =?UTF-8?q?=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 증상 (사용자 로그 2026-08-11 12:35): · 첫 alignment 완료 → PiezoMonitoringView → alignment 재진입 시 "기기 응답이 지연되고 있습니다" 문구가 뜨고 사라지지 않음. · 실제 BLE 는 mtb 1회 timeout 후 다음 프레임에 즉시 raa 정상 응답 → 카운터 리셋됐으나 화면만 못 따라감. 원인 (2가지): A. LaunchedEffect(mtbTimeoutCount) 에 mtbTimeoutCount==0 브랜치 없음. 카운터 1→0 정상 복구 시 문구 초기화 로직이 없어 stuck. B. 재진입 시 이전 view (PiezoMonitoring) 에서 남은 mtb timeout 카운터가 그대로 유지 → 첫 mtb 성공 전 UI 가 이미 "응답 지연" 로 초기화될 수 있음. 수정: A) when 절 재구성 · == 0 브랜치에서 delayed/reconnect 문구였다면 clear. B) 화면 진입 LaunchedEffect(Unit) 에서 consecutiveMtbTimeouts.value = 0. RSSI 는 원인 아님 — 재진입 구간 RSSI -65~-62 로 양호. CMDQ (depth=1) 상 이전 view 잔여 mim IMU 큐 지연이 mtb 1회 timeout 을 유발한 것으로 보이나 · 그건 즉시 자동 복구되므로 UI 층만 손보면 됨. --- .../ui/views/monitoring/PlacementGuideView.kt | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt index 9fac660..2923204 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt @@ -135,6 +135,9 @@ fun PlacementGuideView(appState: AppState) { if (isClinicalAlign) com.medithings.vesiscan.managers.AlignmentAlgo.V2 else com.medithings.vesiscan.managers.AlignmentAlgo.V1 v2Aligner.reset() + // 2026-08-11: 이전 view (PiezoMonitoring 등) 에서 남은 stale mtb timeout 카운터 초기화. + // 재진입 시 첫 mtb 가 정상 응답해도 이전 값 때문에 UI 가 "응답 지연" 로 시작하는 버그 방지. + bleManager.consecutiveMtbTimeouts.value = 0 // Clinical alignment session 진입 시 — 자동으로 scan 시작 (Step 0 baseline 캡쳐). // waitingForStart 는 true 유지 — 사용자는 여전히 Start 눌러 알고리즘 시작 결정. // baseline cycles 는 measurement.json 에 phase="STEP_0_BASELINE" 로 누적됨. @@ -177,14 +180,26 @@ fun PlacementGuideView(appState: AppState) { // BleManager.sendMtb 는 raa 응답 대기 3초 후 consecutiveMtbTimeouts 를 증가시킴. val mtbTimeoutCount by bleManager.consecutiveMtbTimeouts LaunchedEffect(mtbTimeoutCount) { - if (mtbTimeoutCount in 1..2) { - directionHint = context.getString(R.string.mtb_response_delayed) - directionIcon = "" - } else if (mtbTimeoutCount >= 3) { - directionHint = context.getString(R.string.mtb_response_reconnect) - directionIcon = "" - bleManager.debugLogger.warn("MTB_FORCE_RECONNECT after $mtbTimeoutCount consecutive timeouts") - bleManager.forceDisconnectAndReconnect() + val delayedMsg = context.getString(R.string.mtb_response_delayed) + val reconnectMsg = context.getString(R.string.mtb_response_reconnect) + when { + // 2026-08-11: 정상 복구 시 UI 문구 복원 (기존엔 브랜치 없어 "응답 지연" stuck). + mtbTimeoutCount == 0 -> { + if (directionHint == delayedMsg || directionHint == reconnectMsg) { + directionHint = "" + directionIcon = "" + } + } + mtbTimeoutCount in 1..2 -> { + directionHint = delayedMsg + directionIcon = "" + } + mtbTimeoutCount >= 3 -> { + directionHint = reconnectMsg + directionIcon = "" + bleManager.debugLogger.warn("MTB_FORCE_RECONNECT after $mtbTimeoutCount consecutive timeouts") + bleManager.forceDisconnectAndReconnect() + } } }