starting pose detection

This commit is contained in:
2026-09-05 22:33:13 +08:00
parent afb9d800ff
commit cb941006c5
9 changed files with 424 additions and 2 deletions
@@ -82,6 +82,19 @@ class CameraViewModel : ViewModel() {
// several practice approaches back to back.
private val liveStepDetector = LiveStepDetector()
// Live delivery-phase classification (starting stance, approach, etc)
private val posePhaseDetector = PosePhaseDetector()
private val _posePhase = MutableStateFlow<BowlingPhase?>(null)
//The bowler's current delivery phase, or null if no phase currently validates.
val posePhase: StateFlow<BowlingPhase?> = _posePhase.asStateFlow()
// Raw torso/knee/elbow angle readings behind posePhase above, for
// showing the bowler the actual numbers rather than just a pass/fail
// signal -- see PosePhaseDetector.Metrics.
private val _poseMetrics = MutableStateFlow<PosePhaseDetector.Metrics?>(null)
//This frame's torso/knee/elbow angle readings, or null if pose detection is off.
val poseMetrics: StateFlow<PosePhaseDetector.Metrics?> = _poseMetrics.asStateFlow()
// Steps detected so far in the current attempt (since the last reset,
// whether that reset was a new recording starting or the bowler
// returning to a stationary stance mid-recording -- see
@@ -119,7 +132,12 @@ class CameraViewModel : ViewModel() {
*/
fun onPoseToggled(enabled: Boolean) {
_poseEnabled.value = enabled
if (!enabled) _poseAngles.value = null
if (!enabled) {
_poseAngles.value = null
posePhaseDetector.reset()
_posePhase.value = null
_poseMetrics.value = null
}
}
/**
@@ -135,6 +153,9 @@ class CameraViewModel : ViewModel() {
*/
fun onPoseFrameUpdated(landmarks: Map<Int, SmoothedLandmark>, angles: PoseAngles) {
_poseAngles.value = angles
val phaseResult = posePhaseDetector.update(landmarks, angles) //for pose detector
_posePhase.value = phaseResult.phase
_poseMetrics.value = phaseResult.metrics
if (_recordingState.value is RecordingState.Recording) {
val smoothedAnkleHip = ankleHipSmoother.smooth(landmarks)
val frame = buildPoseFrame(