debug(posture): logcat 로 IMU 흐름 가시화 — ImuDbg 태그 도입
증상: PiezoMonitoring 진입해도 자세 ?_ 만 표시, logcat 에 rsp/POSTURE
로그 안 보임.
원인: debugLogger.tx/rx 는 내부 Entry 리스트에만 적재하고 android.util.Log
호출 안 함 → adb logcat | grep 에 안 보임.
수정: 핵심 IMU 흐름에 android.util.Log.d("ImuDbg", ...) 추가.
PiezoMonitoringView.LaunchedEffect:
- 시작 시 isConnected/isDemoMode 값 로그
- sendImuQuery 매 호출 "→ sendImuQuery (msp)"
- 연결 안 되어 있으면 "skip (not connected)"
- imuCollector.onComplete 결과 (자세 + pitch/acc/gyro)
- imuCollector.onLog 도 ImuDbg 로 forward (parseRsp 로그 보임)
BleManager:
- rsp: 응답 시 hex dump 도 ImuDbg 로 (debugLogger 와 별개)
- rxs: (cmd_not_supported) 응답 시 ImuDbg 로 warn
rxs: 중복 핸들러 정리 (기존 1개 → 새 1개로 통합)
테스트: "adb logcat | grep ImuDbg" 한 줄로 전체 흐름 확인 가능.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1199,10 +1199,6 @@ class BleManager private constructor(private val context: Context) {
|
|||||||
val state = if (data.size >= 5) data[4].toInt() and 0xFF else -1
|
val state = if (data.size >= 5) data[4].toInt() and 0xFF else -1
|
||||||
debugLogger.rx("rls", data.size, "led_state=$state")
|
debugLogger.rx("rls", data.size, "led_state=$state")
|
||||||
}
|
}
|
||||||
"rxs:" -> {
|
|
||||||
val echoCmd = if (data.size > 4) String(data, 4, minOf(data.size - 4, 10), Charsets.US_ASCII).trim() else "?"
|
|
||||||
debugLogger.rx("rxs", data.size, "cmd_not_supported: $echoCmd")
|
|
||||||
}
|
|
||||||
"rbb:" -> {
|
"rbb:" -> {
|
||||||
debugLogger.rx("rbb", data.size, "full measurement header (battery+IMU+temp)")
|
debugLogger.rx("rbb", data.size, "full measurement header (battery+IMU+temp)")
|
||||||
onMbbHeaderReceived?.invoke(data)
|
onMbbHeaderReceived?.invoke(data)
|
||||||
@@ -1212,9 +1208,15 @@ class BleManager private constructor(private val context: Context) {
|
|||||||
// msp 명령 응답 — IMU 데이터. format 불명확이라 defensive parsing.
|
// msp 명령 응답 — IMU 데이터. format 불명확이라 defensive parsing.
|
||||||
val hex = data.take(kotlin.math.min(data.size, 24)).joinToString(" ") { "%02X".format(it) }
|
val hex = data.take(kotlin.math.min(data.size, 24)).joinToString(" ") { "%02X".format(it) }
|
||||||
debugLogger.rx("rsp", data.size, "IMU data hex=$hex")
|
debugLogger.rx("rsp", data.size, "IMU data hex=$hex")
|
||||||
|
android.util.Log.d("ImuDbg", "rsp RX len=${data.size} hex=$hex")
|
||||||
imuCollector.parseRsp(data)
|
imuCollector.parseRsp(data)
|
||||||
onImuReceived?.invoke(data)
|
onImuReceived?.invoke(data)
|
||||||
}
|
}
|
||||||
|
"rxs:" -> {
|
||||||
|
val echoCmd = if (data.size > 4) String(data, 4, minOf(data.size - 4, 10), Charsets.US_ASCII).trim() else "?"
|
||||||
|
android.util.Log.w("ImuDbg", "rxs cmd_not_supported: $echoCmd")
|
||||||
|
debugLogger.rx("rxs", data.size, "cmd_not_supported: $echoCmd")
|
||||||
|
}
|
||||||
"rim:" -> {
|
"rim:" -> {
|
||||||
val num = if (data.size >= 6) ((data[4].toInt() and 0xFF) shl 8) or (data[5].toInt() and 0xFF) else 0
|
val num = if (data.size >= 6) ((data[4].toInt() and 0xFF) shl 8) or (data[5].toInt() and 0xFF) else 0
|
||||||
debugLogger.rx("rim", data.size, "IMU ${num} samples")
|
debugLogger.rx("rim", data.size, "IMU ${num} samples")
|
||||||
|
|||||||
+9
-4
@@ -591,24 +591,29 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMU polling + 자세 분류 (Phase 1) — 5초 주기로 msp 명령 → rim: 응답 받아 분류.
|
// IMU polling + 자세 분류 (Phase 1) — 5초 주기로 msp 명령 → rsp: 응답 받아 분류.
|
||||||
// monitoring 페이지 머무는 동안만 작동. demo 모드는 fake 자세 (toggle 없이 SUPINE).
|
|
||||||
LaunchedEffect(isConnected, isDemoMode) {
|
LaunchedEffect(isConnected, isDemoMode) {
|
||||||
|
Log.d("ImuDbg", "LaunchedEffect start isConnected=$isConnected isDemoMode=$isDemoMode")
|
||||||
if (isDemoMode) {
|
if (isDemoMode) {
|
||||||
currentPosture = com.example.medilightv2android.managers.Posture.SUPINE
|
currentPosture = com.example.medilightv2android.managers.Posture.SUPINE
|
||||||
return@LaunchedEffect
|
return@LaunchedEffect
|
||||||
}
|
}
|
||||||
bleManager.imuCollector.onComplete = { samples ->
|
bleManager.imuCollector.onComplete = { samples ->
|
||||||
val r = com.example.medilightv2android.managers.ImuPostureClassifier.classify(samples)
|
val r = com.example.medilightv2android.managers.ImuPostureClassifier.classify(samples)
|
||||||
// UNKNOWN 이면 직전 posture 유지 (motion artifact 시 잠깐 흔들림 방지)
|
|
||||||
if (r.posture != com.example.medilightv2android.managers.Posture.UNKNOWN) {
|
if (r.posture != com.example.medilightv2android.managers.Posture.UNKNOWN) {
|
||||||
currentPosture = r.posture
|
currentPosture = r.posture
|
||||||
}
|
}
|
||||||
Log.d("PiezoMonitor", "POSTURE ${r.posture} pitch=${"%.1f".format(r.pitchDeg)}° accMag=${"%.2f".format(r.accMag)}g gyro=${"%.1f".format(r.gyroMagDps)}dps (${r.reason})")
|
Log.d("ImuDbg", "POSTURE ${r.posture} pitch=${"%.1f".format(r.pitchDeg)}° accMag=${"%.2f".format(r.accMag)}g gyro=${"%.1f".format(r.gyroMagDps)}dps (${r.reason}) samples=${samples.size}")
|
||||||
|
}
|
||||||
|
bleManager.imuCollector.onLog = { msg ->
|
||||||
|
Log.d("ImuDbg", "imuCollector log: $msg")
|
||||||
}
|
}
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
|
Log.d("ImuDbg", "→ sendImuQuery (msp)")
|
||||||
bleManager.sendImuQuery()
|
bleManager.sendImuQuery()
|
||||||
|
} else {
|
||||||
|
Log.d("ImuDbg", "skip (not connected)")
|
||||||
}
|
}
|
||||||
kotlinx.coroutines.delay(5000)
|
kotlinx.coroutines.delay(5000)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user