@pose-tracker/react-native-pose-estimation-light 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/lib/PoseTrackerProvider.js +3 -0
- package/lib/client.d.ts +11 -0
- package/lib/client.js +8 -0
- package/lib/engine/types.d.ts +5 -0
- package/lib/events/classicMessage.d.ts +2 -2
- package/lib/events/classicMessage.js +4 -1
- package/lib/sdkVersion.d.ts +1 -1
- package/lib/sdkVersion.js +1 -1
- package/lib/types/events.d.ts +36 -1
- package/package.json +1 -1
- package/src/PoseTrackerProvider.tsx +3 -0
- package/src/client.ts +22 -2
- package/src/engine/types.ts +5 -0
- package/src/events/classicMessage.ts +7 -2
- package/src/sdkVersion.ts +1 -1
- package/src/types/events.ts +34 -0
package/README.md
CHANGED
|
@@ -47,6 +47,10 @@ npx expo install react-native-webview expo-camera
|
|
|
47
47
|
**Required:** host app must declare camera permissions — see
|
|
48
48
|
[PERMISSIONS.md](../../docs/PERMISSIONS.md).
|
|
49
49
|
|
|
50
|
+
**Media inputs (v0.2):** camera (default), uploaded video, still image — host
|
|
51
|
+
picks the file. See [MEDIA_SOURCES.md](../../docs/MEDIA_SOURCES.md) and
|
|
52
|
+
https://docs.posetracker.com/media-sources.
|
|
53
|
+
|
|
50
54
|
## Quick start (keypoints — needs network, no API key)
|
|
51
55
|
|
|
52
56
|
```tsx
|
package/lib/client.d.ts
CHANGED
|
@@ -102,6 +102,12 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
|
|
|
102
102
|
* triaging Android GPU issues in the field.
|
|
103
103
|
*/
|
|
104
104
|
onDiagnostic?: (message: string) => void;
|
|
105
|
+
/**
|
|
106
|
+
* When true, exercise sessions request `engine_debug` snapshots from the
|
|
107
|
+
* remote engine (bundle ≥ 1.2.4). Overridable per call via
|
|
108
|
+
* `startExercise(id, { debug: true|false })`.
|
|
109
|
+
*/
|
|
110
|
+
debugEngine?: boolean;
|
|
105
111
|
}
|
|
106
112
|
/**
|
|
107
113
|
* Per-session options for {@link PoseTrackerClient.startExercise} — the SDK
|
|
@@ -118,6 +124,11 @@ export interface StartExerciseOptions {
|
|
|
118
124
|
userHeightCm?: number;
|
|
119
125
|
/** Device pitch in degrees — jump exercises compensate camera tilt. */
|
|
120
126
|
devicePitchDeg?: number;
|
|
127
|
+
/**
|
|
128
|
+
* Request throttled `engine_debug` events for this session (movement FSM
|
|
129
|
+
* QA). Defaults to {@link PoseTrackerClientOptions.debugEngine}.
|
|
130
|
+
*/
|
|
131
|
+
debug?: boolean;
|
|
121
132
|
}
|
|
122
133
|
export declare class PoseTrackerClient {
|
|
123
134
|
private status;
|
package/lib/client.js
CHANGED
|
@@ -818,17 +818,21 @@ class PoseTrackerClient {
|
|
|
818
818
|
this.stopExercise();
|
|
819
819
|
this.currentExerciseId = exerciseId;
|
|
820
820
|
this.keypointsSuppressionLogged = false;
|
|
821
|
+
const debug = options.debug ?? this.options.debugEngine === true;
|
|
821
822
|
this.session = this.engine.createSession({
|
|
822
823
|
exercise,
|
|
823
824
|
locale: this.options.locale ?? 'en',
|
|
824
825
|
difficulty: options.difficulty,
|
|
825
826
|
minGrade: this.features.minGrade ?? undefined,
|
|
827
|
+
debug,
|
|
826
828
|
features: {
|
|
827
829
|
angles: this.features.angles,
|
|
828
830
|
recommendations: this.features.recommendations,
|
|
829
831
|
progression: this.features.progression,
|
|
830
832
|
},
|
|
831
833
|
}, (event) => this.emitFromSession(event));
|
|
834
|
+
this.options.onDiagnostic?.(`[posetracker] startExercise id=${exercise.id} difficulty=${options.difficulty ?? 'medium'} ` +
|
|
835
|
+
`debug=${debug} engine=${this.engine.version} minGrade=${this.features.minGrade ?? 'off'}`);
|
|
832
836
|
}
|
|
833
837
|
/** Custom engine session (jump_analysis / air_time_jump). */
|
|
834
838
|
startCustomExercise(custom, options) {
|
|
@@ -1032,6 +1036,10 @@ class PoseTrackerClient {
|
|
|
1032
1036
|
return;
|
|
1033
1037
|
}
|
|
1034
1038
|
const classic = (0, classicMessage_1.toClassicNativeMessage)(event);
|
|
1039
|
+
if (classic == null) {
|
|
1040
|
+
// SDK-only events (e.g. engine_debug) have no classic equivalent.
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1035
1043
|
this.messageListeners.forEach((l) => {
|
|
1036
1044
|
try {
|
|
1037
1045
|
l(classic);
|
package/lib/engine/types.d.ts
CHANGED
|
@@ -36,6 +36,11 @@ export interface EngineSessionOptions {
|
|
|
36
36
|
minGrade?: MinGrade;
|
|
37
37
|
/** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
|
|
38
38
|
features?: EngineSessionFeatures;
|
|
39
|
+
/**
|
|
40
|
+
* When true, the engine emits throttled `engine_debug` events (movement
|
|
41
|
+
* FSM snapshot). Requires engine bundle ≥ 1.2.4. Ignored by older engines.
|
|
42
|
+
*/
|
|
43
|
+
debug?: boolean;
|
|
39
44
|
}
|
|
40
45
|
export interface EngineSession {
|
|
41
46
|
/** Feed one estimated pose; the session emits events through the sink. */
|
|
@@ -26,6 +26,6 @@ export declare function anglesToClassicTree(angles: AngleValue[]): {
|
|
|
26
26
|
/**
|
|
27
27
|
* Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
|
|
28
28
|
* Returns null for SDK-only events that have no classic equivalent and should
|
|
29
|
-
* not be mirrored (
|
|
29
|
+
* not be mirrored (e.g. `engine_debug` QA snapshots).
|
|
30
30
|
*/
|
|
31
|
-
export declare function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMessage;
|
|
31
|
+
export declare function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMessage | null;
|
|
@@ -49,7 +49,7 @@ function anglesToClassicTree(angles) {
|
|
|
49
49
|
/**
|
|
50
50
|
* Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
|
|
51
51
|
* Returns null for SDK-only events that have no classic equivalent and should
|
|
52
|
-
* not be mirrored (
|
|
52
|
+
* not be mirrored (e.g. `engine_debug` QA snapshots).
|
|
53
53
|
*/
|
|
54
54
|
function toClassicNativeMessage(event) {
|
|
55
55
|
switch (event.type) {
|
|
@@ -236,6 +236,9 @@ function toClassicNativeMessage(event) {
|
|
|
236
236
|
totalParts: event.totalParts,
|
|
237
237
|
timestampMs: event.timestampMs,
|
|
238
238
|
};
|
|
239
|
+
case 'engine_debug':
|
|
240
|
+
// SDK-only QA stream — no classic WebView equivalent; skip onMessage.
|
|
241
|
+
return null;
|
|
239
242
|
default: {
|
|
240
243
|
const _exhaustive = event;
|
|
241
244
|
return { type: 'unknown', event: _exhaustive };
|
package/lib/sdkVersion.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** AUTO-GENERATED by scripts/sync-sdk-version.mjs — do not edit. */
|
|
2
|
-
export declare const SDK_VERSION = "0.2.
|
|
2
|
+
export declare const SDK_VERSION = "0.2.1";
|
package/lib/sdkVersion.js
CHANGED
package/lib/types/events.d.ts
CHANGED
|
@@ -154,6 +154,40 @@ export interface ProgressionEvent {
|
|
|
154
154
|
value: number;
|
|
155
155
|
timestampMs: number;
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Throttled movement / rep-FSM snapshot for QA (engine ≥ 1.2.4).
|
|
159
|
+
* Enable via `PoseTrackerClientOptions.debugEngine` or `startExercise(..., { debug: true })`.
|
|
160
|
+
*/
|
|
161
|
+
export interface EngineDebugEvent {
|
|
162
|
+
type: 'engine_debug';
|
|
163
|
+
exerciseId: string;
|
|
164
|
+
engineVersion: string;
|
|
165
|
+
ready: boolean;
|
|
166
|
+
postureHint: string;
|
|
167
|
+
direction?: string;
|
|
168
|
+
missingKeypoints: string[];
|
|
169
|
+
stepIndex: number;
|
|
170
|
+
stepCount: number;
|
|
171
|
+
stepPosition: number | null;
|
|
172
|
+
stepProgression: number;
|
|
173
|
+
progression: number;
|
|
174
|
+
/** Raw FSM rep count (before minGrade gate). */
|
|
175
|
+
rawCount: number;
|
|
176
|
+
/** Public counter after minGrade gate. */
|
|
177
|
+
publicCount: number;
|
|
178
|
+
difficulty: string;
|
|
179
|
+
minGrade: MinGrade | null;
|
|
180
|
+
pointOfView: 'low' | 'up';
|
|
181
|
+
computeError?: string;
|
|
182
|
+
lastSkipReason: string | null;
|
|
183
|
+
posesProcessed: number;
|
|
184
|
+
visibleKeypoints: number;
|
|
185
|
+
knees: {
|
|
186
|
+
left: number | null;
|
|
187
|
+
right: number | null;
|
|
188
|
+
};
|
|
189
|
+
timestampMs: number;
|
|
190
|
+
}
|
|
157
191
|
export interface RecommendationsEvent {
|
|
158
192
|
type: 'recommendations';
|
|
159
193
|
/** Localized form advice strings. */
|
|
@@ -309,7 +343,7 @@ export interface RuntimeDownloadProgressEvent {
|
|
|
309
343
|
partBytes: number;
|
|
310
344
|
timestampMs: number;
|
|
311
345
|
}
|
|
312
|
-
export type PoseTrackerEvent = InitializationEvent | ErrorEvent | WarningEvent | RuntimeDownloadProgressEvent | KeypointsEvent | AnglesEvent | CounterEvent | PostureEvent | ProgressionEvent | RecommendationsEvent | FormScoreEvent | ExerciseSummaryEvent | JumpCalibrationEvent | JumpStartedEvent | JumpHeightEvent | JumpDiscardedEvent | JumpResultEvent | JumpSummaryEvent | QualityChangedEvent | PerformanceWarningEvent;
|
|
346
|
+
export type PoseTrackerEvent = InitializationEvent | ErrorEvent | WarningEvent | RuntimeDownloadProgressEvent | KeypointsEvent | AnglesEvent | CounterEvent | PostureEvent | ProgressionEvent | EngineDebugEvent | RecommendationsEvent | FormScoreEvent | ExerciseSummaryEvent | JumpCalibrationEvent | JumpStartedEvent | JumpHeightEvent | JumpDiscardedEvent | JumpResultEvent | JumpSummaryEvent | QualityChangedEvent | PerformanceWarningEvent;
|
|
313
347
|
export type PoseTrackerEventType = PoseTrackerEvent['type'];
|
|
314
348
|
export type PoseTrackerEventListener = (event: PoseTrackerEvent) => void;
|
|
315
349
|
/**
|
|
@@ -325,6 +359,7 @@ export interface PoseTrackerCallbacks {
|
|
|
325
359
|
onCounter?: (event: CounterEvent) => void;
|
|
326
360
|
onPosture?: (event: PostureEvent) => void;
|
|
327
361
|
onProgression?: (event: ProgressionEvent) => void;
|
|
362
|
+
onEngineDebug?: (event: EngineDebugEvent) => void;
|
|
328
363
|
onRecommendations?: (event: RecommendationsEvent) => void;
|
|
329
364
|
onFormScore?: (event: FormScoreEvent) => void;
|
|
330
365
|
onExerciseSummary?: (event: ExerciseSummaryEvent) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pose-tracker/react-native-pose-estimation-light",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Human pose estimation SDK for React Native (light / online) — MoveNet Lightning via CDN + model URL each session, no bundled weights. iOS & Android (Expo Go). Optional API-key exercise engine.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -281,6 +281,9 @@ export function usePoseTracker(callbacks: PoseTrackerCallbacks = {}): PoseTracke
|
|
|
281
281
|
case 'progression':
|
|
282
282
|
cb.onProgression?.(event);
|
|
283
283
|
break;
|
|
284
|
+
case 'engine_debug':
|
|
285
|
+
cb.onEngineDebug?.(event);
|
|
286
|
+
break;
|
|
284
287
|
case 'recommendations':
|
|
285
288
|
cb.onRecommendations?.(event);
|
|
286
289
|
break;
|
package/src/client.ts
CHANGED
|
@@ -69,7 +69,6 @@ import {
|
|
|
69
69
|
import {
|
|
70
70
|
toClassicNativeMessage,
|
|
71
71
|
type ClassicMessageListener,
|
|
72
|
-
type ClassicNativeMessage,
|
|
73
72
|
} from './events/classicMessage';
|
|
74
73
|
import {
|
|
75
74
|
FREE_PLAN_FEATURES_MESSAGE,
|
|
@@ -164,6 +163,12 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
|
|
|
164
163
|
* triaging Android GPU issues in the field.
|
|
165
164
|
*/
|
|
166
165
|
onDiagnostic?: (message: string) => void;
|
|
166
|
+
/**
|
|
167
|
+
* When true, exercise sessions request `engine_debug` snapshots from the
|
|
168
|
+
* remote engine (bundle ≥ 1.2.4). Overridable per call via
|
|
169
|
+
* `startExercise(id, { debug: true|false })`.
|
|
170
|
+
*/
|
|
171
|
+
debugEngine?: boolean;
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
/**
|
|
@@ -181,6 +186,11 @@ export interface StartExerciseOptions {
|
|
|
181
186
|
userHeightCm?: number;
|
|
182
187
|
/** Device pitch in degrees — jump exercises compensate camera tilt. */
|
|
183
188
|
devicePitchDeg?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Request throttled `engine_debug` events for this session (movement FSM
|
|
191
|
+
* QA). Defaults to {@link PoseTrackerClientOptions.debugEngine}.
|
|
192
|
+
*/
|
|
193
|
+
debug?: boolean;
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
export class PoseTrackerClient {
|
|
@@ -1040,12 +1050,14 @@ export class PoseTrackerClient {
|
|
|
1040
1050
|
this.stopExercise();
|
|
1041
1051
|
this.currentExerciseId = exerciseId;
|
|
1042
1052
|
this.keypointsSuppressionLogged = false;
|
|
1053
|
+
const debug = options.debug ?? this.options.debugEngine === true;
|
|
1043
1054
|
this.session = this.engine.createSession(
|
|
1044
1055
|
{
|
|
1045
1056
|
exercise,
|
|
1046
1057
|
locale: this.options.locale ?? 'en',
|
|
1047
1058
|
difficulty: options.difficulty,
|
|
1048
1059
|
minGrade: this.features.minGrade ?? undefined,
|
|
1060
|
+
debug,
|
|
1049
1061
|
features: {
|
|
1050
1062
|
angles: this.features.angles,
|
|
1051
1063
|
recommendations: this.features.recommendations,
|
|
@@ -1054,6 +1066,10 @@ export class PoseTrackerClient {
|
|
|
1054
1066
|
},
|
|
1055
1067
|
(event) => this.emitFromSession(event),
|
|
1056
1068
|
);
|
|
1069
|
+
this.options.onDiagnostic?.(
|
|
1070
|
+
`[posetracker] startExercise id=${exercise.id} difficulty=${options.difficulty ?? 'medium'} ` +
|
|
1071
|
+
`debug=${debug} engine=${this.engine.version} minGrade=${this.features.minGrade ?? 'off'}`,
|
|
1072
|
+
);
|
|
1057
1073
|
}
|
|
1058
1074
|
|
|
1059
1075
|
/** Custom engine session (jump_analysis / air_time_jump). */
|
|
@@ -1280,7 +1296,11 @@ export class PoseTrackerClient {
|
|
|
1280
1296
|
// Skip the classic-message conversion entirely (per-frame allocation).
|
|
1281
1297
|
return;
|
|
1282
1298
|
}
|
|
1283
|
-
const classic
|
|
1299
|
+
const classic = toClassicNativeMessage(event);
|
|
1300
|
+
if (classic == null) {
|
|
1301
|
+
// SDK-only events (e.g. engine_debug) have no classic equivalent.
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1284
1304
|
this.messageListeners.forEach((l) => {
|
|
1285
1305
|
try {
|
|
1286
1306
|
l(classic);
|
package/src/engine/types.ts
CHANGED
|
@@ -39,6 +39,11 @@ export interface EngineSessionOptions {
|
|
|
39
39
|
minGrade?: MinGrade;
|
|
40
40
|
/** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
|
|
41
41
|
features?: EngineSessionFeatures;
|
|
42
|
+
/**
|
|
43
|
+
* When true, the engine emits throttled `engine_debug` events (movement
|
|
44
|
+
* FSM snapshot). Requires engine bundle ≥ 1.2.4. Ignored by older engines.
|
|
45
|
+
*/
|
|
46
|
+
debug?: boolean;
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
export interface EngineSession {
|
|
@@ -59,9 +59,11 @@ export function anglesToClassicTree(angles: AngleValue[]): {
|
|
|
59
59
|
/**
|
|
60
60
|
* Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
|
|
61
61
|
* Returns null for SDK-only events that have no classic equivalent and should
|
|
62
|
-
* not be mirrored (
|
|
62
|
+
* not be mirrored (e.g. `engine_debug` QA snapshots).
|
|
63
63
|
*/
|
|
64
|
-
export function toClassicNativeMessage(
|
|
64
|
+
export function toClassicNativeMessage(
|
|
65
|
+
event: PoseTrackerEvent,
|
|
66
|
+
): ClassicNativeMessage | null {
|
|
65
67
|
switch (event.type) {
|
|
66
68
|
case 'initialization':
|
|
67
69
|
return {
|
|
@@ -247,6 +249,9 @@ export function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMe
|
|
|
247
249
|
totalParts: event.totalParts,
|
|
248
250
|
timestampMs: event.timestampMs,
|
|
249
251
|
};
|
|
252
|
+
case 'engine_debug':
|
|
253
|
+
// SDK-only QA stream — no classic WebView equivalent; skip onMessage.
|
|
254
|
+
return null;
|
|
250
255
|
default: {
|
|
251
256
|
const _exhaustive: never = event;
|
|
252
257
|
return { type: 'unknown', event: _exhaustive };
|
package/src/sdkVersion.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** AUTO-GENERATED by scripts/sync-sdk-version.mjs — do not edit. */
|
|
2
|
-
export const SDK_VERSION = '0.2.
|
|
2
|
+
export const SDK_VERSION = '0.2.1';
|
package/src/types/events.ts
CHANGED
|
@@ -198,6 +198,38 @@ export interface ProgressionEvent {
|
|
|
198
198
|
timestampMs: number;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Throttled movement / rep-FSM snapshot for QA (engine ≥ 1.2.4).
|
|
203
|
+
* Enable via `PoseTrackerClientOptions.debugEngine` or `startExercise(..., { debug: true })`.
|
|
204
|
+
*/
|
|
205
|
+
export interface EngineDebugEvent {
|
|
206
|
+
type: 'engine_debug';
|
|
207
|
+
exerciseId: string;
|
|
208
|
+
engineVersion: string;
|
|
209
|
+
ready: boolean;
|
|
210
|
+
postureHint: string;
|
|
211
|
+
direction?: string;
|
|
212
|
+
missingKeypoints: string[];
|
|
213
|
+
stepIndex: number;
|
|
214
|
+
stepCount: number;
|
|
215
|
+
stepPosition: number | null;
|
|
216
|
+
stepProgression: number;
|
|
217
|
+
progression: number;
|
|
218
|
+
/** Raw FSM rep count (before minGrade gate). */
|
|
219
|
+
rawCount: number;
|
|
220
|
+
/** Public counter after minGrade gate. */
|
|
221
|
+
publicCount: number;
|
|
222
|
+
difficulty: string;
|
|
223
|
+
minGrade: MinGrade | null;
|
|
224
|
+
pointOfView: 'low' | 'up';
|
|
225
|
+
computeError?: string;
|
|
226
|
+
lastSkipReason: string | null;
|
|
227
|
+
posesProcessed: number;
|
|
228
|
+
visibleKeypoints: number;
|
|
229
|
+
knees: { left: number | null; right: number | null };
|
|
230
|
+
timestampMs: number;
|
|
231
|
+
}
|
|
232
|
+
|
|
201
233
|
export interface RecommendationsEvent {
|
|
202
234
|
type: 'recommendations';
|
|
203
235
|
/** Localized form advice strings. */
|
|
@@ -389,6 +421,7 @@ export type PoseTrackerEvent =
|
|
|
389
421
|
| CounterEvent
|
|
390
422
|
| PostureEvent
|
|
391
423
|
| ProgressionEvent
|
|
424
|
+
| EngineDebugEvent
|
|
392
425
|
| RecommendationsEvent
|
|
393
426
|
| FormScoreEvent
|
|
394
427
|
| ExerciseSummaryEvent
|
|
@@ -418,6 +451,7 @@ export interface PoseTrackerCallbacks {
|
|
|
418
451
|
onCounter?: (event: CounterEvent) => void;
|
|
419
452
|
onPosture?: (event: PostureEvent) => void;
|
|
420
453
|
onProgression?: (event: ProgressionEvent) => void;
|
|
454
|
+
onEngineDebug?: (event: EngineDebugEvent) => void;
|
|
421
455
|
onRecommendations?: (event: RecommendationsEvent) => void;
|
|
422
456
|
onFormScore?: (event: FormScoreEvent) => void;
|
|
423
457
|
onExerciseSummary?: (event: ExerciseSummaryEvent) => void;
|