feat(v1): compose temporal fall event pipeline

This commit is contained in:
ila
2026-07-21 11:57:22 +08:00
parent 906e06565e
commit f03662bf5a
16 changed files with 554 additions and 34 deletions
+45
View File
@@ -0,0 +1,45 @@
"""Translate per-track pose facts into state-machine evidence."""
from typing import Dict
from v1.evidence import PoseEvidence
from v1.fall_state import Evidence, FallState
class FallEvidencePolicy:
"""Require a recent rapid drop before a horizontal pose becomes a candidate."""
def __init__(self, suspect_window_seconds: float) -> None:
self._suspect_window_seconds = float(suspect_window_seconds)
self._rapid_drop_at: Dict[str, float] = {}
def evaluate(
self,
track_id: str,
pose_evidence: PoseEvidence,
now: float,
state: FallState,
) -> Evidence:
timestamp = float(now)
if not pose_evidence.accepted:
self._rapid_drop_at.pop(track_id, None)
return Evidence(accepted=False, is_fall_candidate=False)
if pose_evidence.rapid_vertical_change:
self._rapid_drop_at[track_id] = timestamp
candidate = False
if state is FallState.SUSPECT:
candidate = pose_evidence.horizontal_pose
elif pose_evidence.horizontal_pose and track_id in self._rapid_drop_at:
candidate = timestamp - self._rapid_drop_at[track_id] <= self._suspect_window_seconds
recovery = (
state in (FallState.CONFIRMED, FallState.RECOVERING)
and not pose_evidence.horizontal_pose
and not pose_evidence.rapid_vertical_change
)
return Evidence(
accepted=pose_evidence.accepted,
is_fall_candidate=candidate,
is_recovery_candidate=recovery,
)