fix(alignment): 0/6 walls sanity check · 부착 안 됐을 때 "위로 올려" false positive 방지
증상 (사용자 보고 2026-08-05):
Alignment 모드에서 센서를 부착하지 않았는데 "↑ 위로 올려" 힌트가 계속 노출.
원인:
DetachmentDetection 임계 (mean AND std 둘 다 < 30) 를 노이즈로 통과하면
alignment 알고리즘이 그대로 실행됨. AlignmentAdvice 는 CH3 미검출을
"misaligned" 로 해석 → MOVE_UP 반환. "detached" 케이스와 구분 못함.
수정 (Option B: sanity check + Option C: 명확 문구):
PlacementGuideView V2 branch 에서 v2Aligner.push 결과의
detected.count { it } == 0 (6채널 모두 wall 미검출) 감지 시
alignment advice 무시하고 placement_check_attachment 힌트로 override.
strings.xml (KR/EN):
placement_check_attachment
· KR: "부착 상태 확인 필요 — 모든 채널에서 신호가 감지되지 않습니다.
센서를 치골 위에 밀착시켜 주세요."
· EN: "Attachment check needed — no signal from any channel.
Ensure sensor is firmly placed above pubic bone."
효과:
- 노이즈만 있고 실제 부착 없는 경우 "위로 올려" 반복 대신 명확한 부착 안내
- alignment 알고리즘 자체는 유지 (0/6 만 특별 처리 · 1/6 이상은 정상 흐름)
- DetachmentDetection 임계는 그대로 (실제 부착·미부착 경계 케이스 영향 없음)
검증: BUILD SUCCESSFUL 17s
This commit is contained in:
+11
-1
@@ -921,11 +921,21 @@ fun PlacementGuideView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bleManager.debugLogger.info("ALIGN_V2 phase=${v2Aligner.phase} state=${st.state} action=${st.action} u4=${st.summary?.u4} u5=${st.summary?.u5} ch3=${st.summary?.ch3} bestSet=${v2Aligner.bestCenterSet}")
|
bleManager.debugLogger.info("ALIGN_V2 phase=${v2Aligner.phase} state=${st.state} action=${st.action} u4=${st.summary?.u4} u5=${st.summary?.u5} ch3=${st.summary?.ch3} bestSet=${v2Aligner.bestCenterSet}")
|
||||||
|
// 2026-08-05 sanity check: 6채널 모두 wall 미검출 → 부착 이슈 가능성.
|
||||||
|
// DetachmentDetection AND (mean·std) 임계를 통과했더라도 EMI/노이즈로
|
||||||
|
// 실제 접촉 없이 alignment 가 "위로 올려" 힌트 반복 노출하는 케이스 방지.
|
||||||
|
val detectedCount = st.summary?.detected?.count { it } ?: 0
|
||||||
// Localized message via string resource (falls back to st.msg for dev builds)
|
// Localized message via string resource (falls back to st.msg for dev builds)
|
||||||
val localizedMsg = st.msgKey?.let { key ->
|
val localizedMsg = st.msgKey?.let { key ->
|
||||||
context.getString(key, *st.msgArgs.toTypedArray())
|
context.getString(key, *st.msgArgs.toTypedArray())
|
||||||
} ?: st.msg
|
} ?: st.msg
|
||||||
if (st.state == "accum") {
|
if (detectedCount == 0) {
|
||||||
|
// 0/6 walls · alignment advice 무시 · 부착 확인 안내로 override.
|
||||||
|
directionHint = context.getString(R.string.placement_check_attachment)
|
||||||
|
directionIcon = ""
|
||||||
|
placementScore = 0
|
||||||
|
bleManager.debugLogger.info("ALIGN_V2 sanity: 0/6 walls · override to attachment check")
|
||||||
|
} else if (st.state == "accum") {
|
||||||
directionHint = localizedMsg
|
directionHint = localizedMsg
|
||||||
directionIcon = ""
|
directionIcon = ""
|
||||||
placementScore = 5
|
placementScore = 5
|
||||||
|
|||||||
@@ -335,6 +335,8 @@
|
|||||||
<string name="mtb_response_delayed">기기 응답이 지연되고 있습니다. 잠시만 기다려주세요…</string>
|
<string name="mtb_response_delayed">기기 응답이 지연되고 있습니다. 잠시만 기다려주세요…</string>
|
||||||
<string name="mtb_response_reconnect">기기 응답 실패 · 재부팅이 필요할 수 있습니다 (전원 15초 롱프레스).</string>
|
<string name="mtb_response_reconnect">기기 응답 실패 · 재부팅이 필요할 수 있습니다 (전원 15초 롱프레스).</string>
|
||||||
<string name="placement_detached_restart">센서가 분리되었습니다. 치골 위에서 다시 시작해주세요.</string>
|
<string name="placement_detached_restart">센서가 분리되었습니다. 치골 위에서 다시 시작해주세요.</string>
|
||||||
|
<!-- 2026-08-05 · 0/6 walls sanity check (alignment 알고리즘 override) -->
|
||||||
|
<string name="placement_check_attachment">부착 상태 확인 필요 — 모든 채널에서 신호가 감지되지 않습니다. 센서를 치골 위에 밀착시켜 주세요.</string>
|
||||||
<string name="placement_signal_lost">신호를 놓쳤습니다 — 위로 올려주세요 ↑</string>
|
<string name="placement_signal_lost">신호를 놓쳤습니다 — 위로 올려주세요 ↑</string>
|
||||||
<string name="placement_sweep_start">배꼽 근처에서 시작해 천천히 아래로 내려주세요 ↓</string>
|
<string name="placement_sweep_start">배꼽 근처에서 시작해 천천히 아래로 내려주세요 ↓</string>
|
||||||
<string name="placement_too_far">너무 멀어요 — 위로 올려주세요 ↑</string>
|
<string name="placement_too_far">너무 멀어요 — 위로 올려주세요 ↑</string>
|
||||||
|
|||||||
@@ -335,6 +335,8 @@
|
|||||||
<string name="mtb_response_delayed">Device response delayed. Please wait…</string>
|
<string name="mtb_response_delayed">Device response delayed. Please wait…</string>
|
||||||
<string name="mtb_response_reconnect">Device not responding. A reboot may be required (long-press power 15 seconds).</string>
|
<string name="mtb_response_reconnect">Device not responding. A reboot may be required (long-press power 15 seconds).</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>
|
||||||
|
<!-- 2026-08-05 · 0/6 walls sanity check (alignment 알고리즘 override) -->
|
||||||
|
<string name="placement_check_attachment">Attachment check needed — no signal from any channel. Ensure sensor is firmly placed above pubic bone.</string>
|
||||||
<string name="placement_signal_lost">Signal lost — slide up ↑</string>
|
<string name="placement_signal_lost">Signal lost — slide up ↑</string>
|
||||||
<string name="placement_sweep_start">Start near navel, slide down slowly ↓</string>
|
<string name="placement_sweep_start">Start near navel, slide down slowly ↓</string>
|
||||||
<string name="placement_too_far">Too far — slide up ↑</string>
|
<string name="placement_too_far">Too far — slide up ↑</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user