diff --git a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt index 53e1865..1d71c6c 100644 --- a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt +++ b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt @@ -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 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:" -> { debugLogger.rx("rbb", data.size, "full measurement header (battery+IMU+temp)") onMbbHeaderReceived?.invoke(data) @@ -1212,9 +1208,15 @@ class BleManager private constructor(private val context: Context) { // msp 명령 응답 — IMU 데이터. format 불명확이라 defensive parsing. val hex = data.take(kotlin.math.min(data.size, 24)).joinToString(" ") { "%02X".format(it) } debugLogger.rx("rsp", data.size, "IMU data hex=$hex") + android.util.Log.d("ImuDbg", "rsp RX len=${data.size} hex=$hex") imuCollector.parseRsp(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:" -> { 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") diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index 90afb32..c54118c 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -591,24 +591,29 @@ fun PiezoMonitoringView(appState: AppState) { } } - // IMU polling + 자세 분류 (Phase 1) — 5초 주기로 msp 명령 → rim: 응답 받아 분류. - // monitoring 페이지 머무는 동안만 작동. demo 모드는 fake 자세 (toggle 없이 SUPINE). + // IMU polling + 자세 분류 (Phase 1) — 5초 주기로 msp 명령 → rsp: 응답 받아 분류. LaunchedEffect(isConnected, isDemoMode) { + Log.d("ImuDbg", "LaunchedEffect start isConnected=$isConnected isDemoMode=$isDemoMode") if (isDemoMode) { currentPosture = com.example.medilightv2android.managers.Posture.SUPINE return@LaunchedEffect } bleManager.imuCollector.onComplete = { samples -> val r = com.example.medilightv2android.managers.ImuPostureClassifier.classify(samples) - // UNKNOWN 이면 직전 posture 유지 (motion artifact 시 잠깐 흔들림 방지) if (r.posture != com.example.medilightv2android.managers.Posture.UNKNOWN) { 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) { if (isConnected) { + Log.d("ImuDbg", "→ sendImuQuery (msp)") bleManager.sendImuQuery() + } else { + Log.d("ImuDbg", "skip (not connected)") } kotlinx.coroutines.delay(5000) }