feat(posture): Poll Interval 슬라이더 + default 10s → 3s

증상: 자세 갱신이 10초마다라 너무 느림. 빠르게 테스트하고 싶음.

수정:
  1) GreenZoneConstants.posturePollIntervalMs (default 3000ms) 신규
     - polling loop 의 delay(10000) → delay(GreenZoneConstants.posturePollIntervalMs)
     - 슬라이더 변경 즉시 다음 iteration 부터 적용

  2) PiezoMonitoring dev settings: Poll Interval 슬라이더 추가
     - 위치: Lying Duration 슬라이더 바로 아래
     - 범위: 1초 ~ 15초 (연속)
     - 표시: "X.X초"
     - 변경 시 GreenZoneConstants 에 즉시 반영

default 변경: 10초 → 3초.
  - mtb 한 cycle ≈ 400ms, 3초 polling = device 활동 ≈ 13% (가벼움)
  - 1초까지 줄여도 캐싱/throttle 충돌 거의 없음 (canSendMaa 500ms gate)

BLE 부담 vs 응답성 trade-off:
  | interval | 1시간 device 사용 | 자세 변화 최대 지연 |
  |   1초    |     ~24분 (40%)   |     ~1초           |
  |   3초    |     ~8분 (13%)    |     ~3초           |
  |   5초    |     ~5분 (8%)     |     ~5초           |
  |   10초   |     ~2.5분 (4%)   |     ~10초          |

낙상 예방엔 1-3초가 적정. 평상시 사용엔 5-10초.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 09:14:32 +09:00
parent 91d7f75cbd
commit 0bb484ae45
2 changed files with 27 additions and 1 deletions
@@ -31,6 +31,9 @@ object GreenZoneConstants {
/** Posture pitch 임계값 (deg). |pitch| > 이 값 → LYING, ≤ 이 값 → NON_LYING. dev 모드에서 조정 가능. */
@Volatile var pitchLyingThreshold: Float = 25f
/** Posture polling 간격 (ms). PiezoMonitoring 에서 mtb 보내는 주기. dev 모드에서 조정 가능. */
@Volatile var posturePollIntervalMs: Long = 3000L
// ═══════════════════════════════════════════════════════════
// 신호 범위
// ═══════════════════════════════════════════════════════════
@@ -694,7 +694,7 @@ fun PiezoMonitoringView(appState: AppState) {
} else {
Log.d("ImuDbg", "skip (connected=$isConnected measuring=$isMeasuring auto=$isAutoMeasuring spot=$isSpotInProgress)")
}
kotlinx.coroutines.delay(10000)
kotlinx.coroutines.delay(GreenZoneConstants.posturePollIntervalMs)
}
}
@@ -1853,6 +1853,29 @@ fun PiezoMonitoringView(appState: AppState) {
steps = 0,
colors = SliderDefaults.colors(thumbColor = MlPrimary, activeTrackColor = MlPrimary)
)
// Posture polling 주기 (자세 갱신 빈도)
var pollIntervalVal by remember {
mutableStateOf(GreenZoneConstants.posturePollIntervalMs / 1000f)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Poll Interval", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
Spacer(modifier = Modifier.width(8.dp))
Text("%.1f초".format(pollIntervalVal),
fontSize = 13.sp, fontWeight = FontWeight.Bold, color = MlPrimary)
Spacer(modifier = Modifier.weight(1f))
Text("자세 갱신 주기", fontSize = 10.sp, color = MlSecondaryText)
}
Slider(
value = pollIntervalVal,
onValueChange = {
pollIntervalVal = it
GreenZoneConstants.posturePollIntervalMs = (it * 1000).toLong()
},
valueRange = 1f..15f, // 1초 ~ 15초
steps = 0,
colors = SliderDefaults.colors(thumbColor = MlPrimary, activeTrackColor = MlPrimary)
)
}
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))