akashkolte Claude Sonnet 4.6 commited on
Commit
623fcd9
·
1 Parent(s): 79a823e

Fix affect and gesture misclassification

Browse files

- Lower HAPPY LCP threshold 0.015 → 0.008 so smiles register
- Raise EMA alpha 0.3 → 0.4 for faster affect response
- Stricter fingersCurled check (0.85×) to prevent borderline pointing from satisfying thumb curl
- Check POINTING before THUMBS_UP so raised-thumb pointing fires correct label

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

frontend/src/hooks/useSensing.ts CHANGED
@@ -15,7 +15,7 @@ import {
15
  } from "../lib/sensing";
16
  import { DEFAULT_AIR_TEMPLATES } from "../lib/airTemplates";
17
 
18
- const EMA_ALPHA = 0.3;
19
 
20
  export function useSensing() {
21
  const faceLandmarkerRef = useRef<FaceLandmarker | null>(null);
 
15
  } from "../lib/sensing";
16
  import { DEFAULT_AIR_TEMPLATES } from "../lib/airTemplates";
17
 
18
+ const EMA_ALPHA = 0.4;
19
 
20
  export function useSensing() {
21
  const faceLandmarkerRef = useRef<FaceLandmarker | null>(null);
frontend/src/lib/sensing.ts CHANGED
@@ -19,8 +19,7 @@ export function classifyAffect(v: AffectVector): Affect {
19
  // FRUSTRATED: a clear frown, OR brows lowered + squinting — either signals displeasure
20
  if (v.LCP < -0.015) return "FRUSTRATED";
21
  if (v.BRI > -0.2 && v.EAR < 0.18) return "FRUSTRATED";
22
- // HAPPY: meaningful upward pull of lip corners (tighter than the old 0.005)
23
- if (v.LCP > 0.015) return "HAPPY";
24
  return "NEUTRAL";
25
  }
26
 
@@ -105,21 +104,25 @@ export function classifyGesture(landmarks: Point3D[]): GestureName | null {
105
  const pinkyTip = p[20];
106
  const indexMcp = p[5];
107
 
 
 
108
  const fingersCurled = [
109
  [indexTip, p[5]],
110
  [middleTip, p[9]],
111
  [ringTip, p[13]],
112
- ].every(([tip, mcp]) => norm3(tip) < norm3(mcp));
113
-
114
- if (thumbTip.y < -0.3 && fingersCurled) return "THUMBS_UP";
115
- if (thumbTip.y > 0.3 && fingersCurled) return "THUMBS_DOWN";
116
 
 
 
117
  const indexExtended = norm3(indexTip) > norm3(indexMcp) * 1.3;
118
  const othersCurled = [middleTip, ringTip, pinkyTip].every(
119
  (tip) => norm3(tip) < 0.5
120
  );
121
  if (indexExtended && othersCurled) return "POINTING";
122
 
 
 
 
123
  const allExtended = [indexTip, middleTip, ringTip, pinkyTip].every(
124
  (tip) => norm3(tip) > 0.5
125
  );
 
19
  // FRUSTRATED: a clear frown, OR brows lowered + squinting — either signals displeasure
20
  if (v.LCP < -0.015) return "FRUSTRATED";
21
  if (v.BRI > -0.2 && v.EAR < 0.18) return "FRUSTRATED";
22
+ if (v.LCP > 0.008) return "HAPPY";
 
23
  return "NEUTRAL";
24
  }
25
 
 
104
  const pinkyTip = p[20];
105
  const indexMcp = p[5];
106
 
107
+ // Require tip to be meaningfully closer to wrist than MCP (0.85×), not just barely under —
108
+ // prevents borderline pointing poses from satisfying the curl check.
109
  const fingersCurled = [
110
  [indexTip, p[5]],
111
  [middleTip, p[9]],
112
  [ringTip, p[13]],
113
+ ].every(([tip, mcp]) => norm3(tip) < norm3(mcp) * 0.85);
 
 
 
114
 
115
+ // Check POINTING before THUMBS_UP — pointing with a raised thumb would otherwise
116
+ // satisfy fingersCurled on a noisy frame and fire the wrong label first.
117
  const indexExtended = norm3(indexTip) > norm3(indexMcp) * 1.3;
118
  const othersCurled = [middleTip, ringTip, pinkyTip].every(
119
  (tip) => norm3(tip) < 0.5
120
  );
121
  if (indexExtended && othersCurled) return "POINTING";
122
 
123
+ if (thumbTip.y < -0.3 && fingersCurled) return "THUMBS_UP";
124
+ if (thumbTip.y > 0.3 && fingersCurled) return "THUMBS_DOWN";
125
+
126
  const allExtended = [indexTip, middleTip, ringTip, pinkyTip].every(
127
  (tip) => norm3(tip) > 0.5
128
  );