fix(posture): IMU polling 을 msp → mtb 로 변경 (alignment 명령 우회)
증상: msp 명령이 펌웨어에서 rsp: 응답 안 보내는 듯 — adb logcat 에 rsp/POSTURE
로그 한 줄도 안 보임. msp 자체가 작동 안 함.
수정: msp 대신 mtb (alignment 모드, rim: 응답 보장) 로 polling.
PiezoPacketCollector:
var skipNextComplete: Boolean = false 추가
raa: complete 시 skipNextComplete 가 true 면 onComplete invoke 건너뛰고
flag reset. 자동 1회 use.
PiezoMonitoringView LaunchedEffect:
- msp(5초) → mtb(10초) 로 전환
- mtb 전에 piezoCollector.skipNextComplete = true 설정 → user 의
측정 callback 가 posture poll 때문에 spurious fire 되는 거 차단
- sendMtb() throttled 면 (canSendMaa fail) flag rollback
- 측정 중 (isMeasuring/isAutoMeasuring/isSpotInProgress) 일 땐 skip
→ 사용자 측정과 충돌 방지
trade-off: BLE 트래픽 ↑ (10초마다 mtb = piezo 6ch + IMU). msp 보다 무거움.
하지만 msp 미작동이라 다른 선택지 없음.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,9 @@ class PiezoPacketCollector {
|
||||
// Callbacks
|
||||
var onComplete: ((PiezoEchoResult) -> Unit)? = null
|
||||
var onMultiChannelComplete: ((List<PiezoChannelData>) -> Unit)? = null
|
||||
/** true 면 다음 onMultiChannelComplete 1회 skip (자동 reset).
|
||||
* posture polling 으로 mtb 보낼 때 측정 callback 가 spurious fire 되는 거 차단용. */
|
||||
var skipNextComplete: Boolean = false
|
||||
var onLog: ((String) -> Unit)? = null
|
||||
|
||||
private var recursionDepth = 0
|
||||
@@ -228,7 +231,12 @@ class PiezoPacketCollector {
|
||||
else -> {
|
||||
val validChannels = channelResults.filterNotNull()
|
||||
onLog?.invoke("raa: session=$currentSetSession complete — ${validChannels.size} channels")
|
||||
onMultiChannelComplete?.invoke(validChannels)
|
||||
if (skipNextComplete) {
|
||||
skipNextComplete = false
|
||||
onLog?.invoke("raa: skip onComplete (posture poll)")
|
||||
} else {
|
||||
onMultiChannelComplete?.invoke(validChannels)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 다음 set을 위해 reset (isMultiChannel/onComplete 등 유지)
|
||||
|
||||
+14
-6
@@ -591,7 +591,10 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
}
|
||||
}
|
||||
|
||||
// IMU polling + 자세 분류 (Phase 1) — 5초 주기로 msp 명령 → rsp: 응답 받아 분류.
|
||||
// IMU polling + 자세 분류 (Phase 1) — 10초 주기로 mtb 명령 → rim: 응답 받아 분류.
|
||||
// msp 가 펌웨어에서 rsp: 응답 안 보내는 듯해 mtb (alignment) 로 우회.
|
||||
// mtb 는 piezo measurement 도 트리거하므로 piezoCollector.skipNextComplete 로
|
||||
// user 의 측정 callback 가 spurious fire 되는 거 차단.
|
||||
LaunchedEffect(isConnected, isDemoMode) {
|
||||
Log.d("ImuDbg", "LaunchedEffect start isConnected=$isConnected isDemoMode=$isDemoMode")
|
||||
if (isDemoMode) {
|
||||
@@ -609,13 +612,18 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
Log.d("ImuDbg", "imuCollector log: $msg")
|
||||
}
|
||||
while (isActive) {
|
||||
if (isConnected) {
|
||||
Log.d("ImuDbg", "→ sendImuQuery (msp)")
|
||||
bleManager.sendImuQuery()
|
||||
if (isConnected && !isMeasuring && !isAutoMeasuring && !isSpotInProgress) {
|
||||
Log.d("ImuDbg", "→ sendMtb (posture poll)")
|
||||
bleManager.piezoCollector.skipNextComplete = true
|
||||
val sent = bleManager.sendMtb()
|
||||
if (!sent) {
|
||||
bleManager.piezoCollector.skipNextComplete = false // throttled, no response coming
|
||||
Log.d("ImuDbg", "mtb throttled — skip this cycle")
|
||||
}
|
||||
} else {
|
||||
Log.d("ImuDbg", "skip (not connected)")
|
||||
Log.d("ImuDbg", "skip (connected=$isConnected measuring=$isMeasuring auto=$isAutoMeasuring spot=$isSpotInProgress)")
|
||||
}
|
||||
kotlinx.coroutines.delay(5000)
|
||||
kotlinx.coroutines.delay(10000)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user