brilliantsole 0.0.26 → 0.0.28
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 +16 -10
- package/assets/3d/anchor.glb +0 -0
- package/assets/3d/coin.glb +0 -0
- package/assets/3d/glasses.glb +0 -0
- package/assets/3d/rightHand.glb +0 -0
- package/assets/audio/bounceMedium.wav +0 -0
- package/assets/audio/bounceStrong.wav +0 -0
- package/assets/audio/bounceWeak.wav +0 -0
- package/assets/audio/coin.wav +0 -0
- package/assets/audio/getUp.wav +0 -0
- package/assets/audio/grab.wav +0 -0
- package/assets/audio/kick.wav +0 -0
- package/assets/audio/platterFadeIn old.wav +0 -0
- package/assets/audio/platterFadeIn.wav +0 -0
- package/assets/audio/platterFadeOut.wav +0 -0
- package/assets/audio/punch.wav +0 -0
- package/assets/audio/punchSqueak.wav +0 -0
- package/assets/audio/purr.wav +0 -0
- package/assets/audio/purrFadeOut.wav +0 -0
- package/assets/audio/release.wav +0 -0
- package/assets/audio/splat.wav +0 -0
- package/assets/audio/stomp.wav +0 -0
- package/assets/images/ukaton-pressure-0.svg +9 -0
- package/assets/images/ukaton-pressure-1.svg +9 -0
- package/assets/images/ukaton-pressure-10.svg +9 -0
- package/assets/images/ukaton-pressure-11.svg +9 -0
- package/assets/images/ukaton-pressure-12.svg +9 -0
- package/assets/images/ukaton-pressure-13.svg +9 -0
- package/assets/images/ukaton-pressure-14.svg +9 -0
- package/assets/images/ukaton-pressure-15.svg +9 -0
- package/assets/images/ukaton-pressure-2.svg +9 -0
- package/assets/images/ukaton-pressure-3.svg +9 -0
- package/assets/images/ukaton-pressure-4.svg +9 -0
- package/assets/images/ukaton-pressure-5.svg +9 -0
- package/assets/images/ukaton-pressure-6.svg +9 -0
- package/assets/images/ukaton-pressure-7.svg +9 -0
- package/assets/images/ukaton-pressure-8.svg +9 -0
- package/assets/images/ukaton-pressure-9.svg +9 -0
- package/assets/images/ukaton-right-insole.svg +798 -0
- package/build/brilliantsole.cjs +2870 -882
- package/build/brilliantsole.cjs.map +1 -1
- package/build/brilliantsole.js +2477 -782
- package/build/brilliantsole.js.map +1 -1
- package/build/brilliantsole.ls.js +2260 -592
- package/build/brilliantsole.ls.js.map +1 -1
- package/build/brilliantsole.min.js +1 -1
- package/build/brilliantsole.min.js.map +1 -1
- package/build/brilliantsole.module.d.ts +302 -116
- package/build/brilliantsole.module.js +2468 -782
- package/build/brilliantsole.module.js.map +1 -1
- package/build/brilliantsole.module.min.d.ts +302 -116
- package/build/brilliantsole.module.min.js +1 -1
- package/build/brilliantsole.module.min.js.map +1 -1
- package/build/brilliantsole.node.module.d.ts +295 -113
- package/build/brilliantsole.node.module.js +2860 -882
- package/build/brilliantsole.node.module.js.map +1 -1
- package/build/dts/BS-output.d.ts +10 -0
- package/build/dts/BS.d.ts +21 -9
- package/build/dts/CameraManager.d.ts +72 -0
- package/build/dts/Device.d.ts +53 -16
- package/build/dts/DeviceInformationManager.d.ts +4 -4
- package/build/dts/DeviceManager.d.ts +3 -0
- package/build/dts/FileTransferManager.d.ts +18 -8
- package/build/dts/InformationManager.d.ts +8 -5
- package/build/dts/TfliteManager.d.ts +22 -2
- package/build/dts/WifiManager.d.ts +61 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +37 -3
- package/build/dts/connection/ClientConnectionManager.d.ts +11 -2
- package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +3 -1
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +2 -0
- package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
- package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
- package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
- package/build/dts/devicePair/DevicePair.d.ts +14 -10
- package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
- package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
- package/build/dts/scanner/BaseScanner.d.ts +4 -1
- package/build/dts/scanner/NobleScanner.d.ts +2 -1
- package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
- package/build/dts/sensor/SensorDataManager.d.ts +5 -4
- package/build/dts/server/BaseClient.d.ts +6 -3
- package/build/dts/server/ServerUtils.d.ts +1 -1
- package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
- package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
- package/build/dts/utils/Console.d.ts +2 -0
- package/build/dts/utils/MathUtils.d.ts +2 -0
- package/build/dts/utils/ThrottleUtils.d.ts +2 -0
- package/build/dts/vibration/VibrationManager.d.ts +19 -2
- package/build/index.d.ts +299 -113
- package/build/index.node.d.ts +292 -110
- package/examples/3d/scene.html +19 -5
- package/examples/3d/script.js +90 -17
- package/examples/3d-generic/index.html +144 -0
- package/examples/3d-generic/script.js +266 -0
- package/examples/balance/script.js +2 -1
- package/examples/basic/index.html +232 -18
- package/examples/basic/script.js +746 -106
- package/examples/bottango/index.html +11 -1
- package/examples/bottango/script.js +2 -2
- package/examples/center-of-pressure/index.html +114 -114
- package/examples/center-of-pressure/script.js +1 -1
- package/examples/device-pair/index.html +58 -58
- package/examples/device-pair/script.js +12 -8
- package/examples/edge-impulse/script.js +135 -44
- package/examples/edge-impulse-test/README.md +11 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
- package/examples/edge-impulse-test/index.html +75 -0
- package/examples/edge-impulse-test/run-impulse.js +135 -0
- package/examples/edge-impulse-test/script.js +200 -0
- package/examples/gloves/edge-impulse-standalone.js +7228 -0
- package/examples/gloves/edge-impulse-standalone.wasm +0 -0
- package/examples/gloves/index.html +119 -0
- package/examples/gloves/run-impulse.js +135 -0
- package/examples/gloves/scene.html +124 -0
- package/examples/gloves/script.js +931 -0
- package/examples/graph/index.html +11 -1
- package/examples/graph/script.js +94 -37
- package/examples/pressure/index.html +180 -12
- package/examples/pressure/script.js +144 -7
- package/examples/punch/index.html +135 -0
- package/examples/punch/punch.tflite +0 -0
- package/examples/punch/script.js +169 -0
- package/examples/recording/index.html +191 -183
- package/examples/server/index.html +109 -23
- package/examples/server/script.js +322 -111
- package/examples/ukaton-firmware-update/index.html +20 -0
- package/examples/ukaton-firmware-update/manifest.json +11 -0
- package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
- package/examples/utils/aframe/aframe-master.min.js +2 -0
- package/examples/utils/aframe/bs-vibration.js +150 -0
- package/examples/utils/aframe/force-pushable.js +80 -0
- package/examples/utils/aframe/grabbable-anchor.js +46 -0
- package/examples/utils/aframe/grabbable-listener.js +31 -0
- package/examples/utils/aframe/grabbable-physics-body.js +190 -0
- package/examples/utils/aframe/grow-shrink.js +25 -0
- package/examples/utils/aframe/hand-punch.js +119 -0
- package/examples/utils/aframe/my-obb-collider.js +293 -0
- package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
- package/examples/utils/aframe/occlude-mesh.js +42 -0
- package/examples/utils/aframe/palm-up-detector.js +47 -0
- package/examples/utils/aframe/shadow-material.js +20 -0
- package/examples/utils/aframe/soft-shadow-light.js +9 -0
- package/examples/webxr/script.js +3 -3
- package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
- package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
- package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
- package/examples/webxr-2/assets/images/shellTexture.png +0 -0
- package/examples/webxr-2/components/bs-ankle.js +337 -0
- package/examples/webxr-2/components/coin.js +84 -0
- package/examples/webxr-2/components/custom-wrap.js +17 -0
- package/examples/webxr-2/components/goomba.js +3250 -0
- package/examples/webxr-2/components/init-shell-material.js +215 -0
- package/examples/webxr-2/components/platter.js +172 -0
- package/examples/webxr-2/components/shell.js +374 -0
- package/examples/webxr-2/components/soccer-ball.js +250 -0
- package/examples/webxr-2/components/squashed-goomba.js +249 -0
- package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
- package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
- package/examples/webxr-2/index.html +996 -0
- package/examples/webxr-2/kick.tflite +0 -0
- package/examples/webxr-2/kick2.tflite +0 -0
- package/examples/webxr-2/run-impulse.js +135 -0
- package/examples/webxr-2/script.js +384 -0
- package/package.json +2 -1
- package/src/.prettierrc +4 -0
- package/src/BS.ts +66 -9
- package/src/CameraManager.ts +499 -0
- package/src/Device.ts +620 -92
- package/src/DeviceInformationManager.ts +22 -11
- package/src/DeviceManager.ts +94 -25
- package/src/FileTransferManager.ts +146 -21
- package/src/FirmwareManager.ts +1 -1
- package/src/InformationManager.ts +62 -20
- package/src/TfliteManager.ts +172 -26
- package/src/WifiManager.ts +323 -0
- package/src/connection/BaseConnectionManager.ts +145 -30
- package/src/connection/ClientConnectionManager.ts +47 -11
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +14 -3
- package/src/connection/bluetooth/NobleConnectionManager.ts +155 -42
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +104 -35
- package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
- package/src/connection/udp/UDPConnectionManager.ts +356 -0
- package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
- package/src/devicePair/DevicePair.ts +145 -49
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +72 -24
- package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
- package/src/scanner/BaseScanner.ts +49 -11
- package/src/scanner/NobleScanner.ts +81 -17
- package/src/sensor/BarometerSensorDataManager.ts +1 -1
- package/src/sensor/MotionSensorDataManager.ts +22 -7
- package/src/sensor/PressureSensorDataManager.ts +47 -13
- package/src/sensor/SensorConfigurationManager.ts +75 -24
- package/src/sensor/SensorDataManager.ts +107 -26
- package/src/server/BaseClient.ts +192 -37
- package/src/server/BaseServer.ts +201 -43
- package/src/server/ServerUtils.ts +39 -9
- package/src/server/udp/UDPServer.ts +74 -23
- package/src/server/udp/UDPUtils.ts +9 -2
- package/src/server/websocket/WebSocketClient.ts +30 -9
- package/src/server/websocket/WebSocketServer.ts +1 -1
- package/src/server/websocket/WebSocketUtils.ts +4 -2
- package/src/utils/CenterOfPressureHelper.ts +5 -5
- package/src/utils/Console.ts +62 -9
- package/src/utils/MathUtils.ts +31 -1
- package/src/utils/ParseUtils.ts +25 -6
- package/src/utils/ThrottleUtils.ts +62 -0
- package/src/utils/Timer.ts +1 -1
- package/src/utils/checksum.ts +1 -1
- package/src/utils/mcumgr.js +1 -1
- package/src/vibration/VibrationManager.ts +166 -40
|
@@ -1,17 +1,26 @@
|
|
|
1
|
+
import { ConnectionType } from "./connection/BaseConnectionManager.ts";
|
|
1
2
|
import Device, { SendMessageCallback } from "./Device.ts";
|
|
2
3
|
import { createConsole } from "./utils/Console.ts";
|
|
4
|
+
import { isInBrowser } from "./utils/environment.ts";
|
|
3
5
|
import EventDispatcher from "./utils/EventDispatcher.ts";
|
|
4
6
|
import { Uint16Max } from "./utils/MathUtils.ts";
|
|
5
7
|
import { textDecoder, textEncoder } from "./utils/Text.ts";
|
|
6
8
|
import autoBind from "auto-bind";
|
|
7
9
|
|
|
8
|
-
const _console = createConsole("InformationManager", { log:
|
|
10
|
+
const _console = createConsole("InformationManager", { log: false });
|
|
9
11
|
|
|
10
|
-
export const DeviceTypes = [
|
|
12
|
+
export const DeviceTypes = [
|
|
13
|
+
"leftInsole",
|
|
14
|
+
"rightInsole",
|
|
15
|
+
"leftGlove",
|
|
16
|
+
"rightGlove",
|
|
17
|
+
"glasses",
|
|
18
|
+
"generic",
|
|
19
|
+
] as const;
|
|
11
20
|
export type DeviceType = (typeof DeviceTypes)[number];
|
|
12
21
|
|
|
13
|
-
export const
|
|
14
|
-
export type
|
|
22
|
+
export const Sides = ["left", "right"] as const;
|
|
23
|
+
export type Side = (typeof Sides)[number];
|
|
15
24
|
|
|
16
25
|
export const MinNameLength = 2;
|
|
17
26
|
export const MaxNameLength = 30;
|
|
@@ -43,8 +52,13 @@ export interface InformationEventMessages {
|
|
|
43
52
|
getCurrentTime: { currentTime: number };
|
|
44
53
|
}
|
|
45
54
|
|
|
46
|
-
export type InformationEventDispatcher = EventDispatcher<
|
|
47
|
-
|
|
55
|
+
export type InformationEventDispatcher = EventDispatcher<
|
|
56
|
+
Device,
|
|
57
|
+
InformationEventType,
|
|
58
|
+
InformationEventMessages
|
|
59
|
+
>;
|
|
60
|
+
export type SendInformationMessageCallback =
|
|
61
|
+
SendMessageCallback<InformationMessageType>;
|
|
48
62
|
|
|
49
63
|
class InformationManager {
|
|
50
64
|
constructor() {
|
|
@@ -88,7 +102,9 @@ class InformationManager {
|
|
|
88
102
|
_console.assertTypeWithError(updatedBatteryCurrent, "number");
|
|
89
103
|
this.#batteryCurrent = updatedBatteryCurrent;
|
|
90
104
|
_console.log({ batteryCurrent: this.#batteryCurrent });
|
|
91
|
-
this.#dispatchEvent("getBatteryCurrent", {
|
|
105
|
+
this.#dispatchEvent("getBatteryCurrent", {
|
|
106
|
+
batteryCurrent: this.#batteryCurrent,
|
|
107
|
+
});
|
|
92
108
|
}
|
|
93
109
|
|
|
94
110
|
#id!: string;
|
|
@@ -115,13 +131,11 @@ class InformationManager {
|
|
|
115
131
|
}
|
|
116
132
|
async setName(newName: string) {
|
|
117
133
|
_console.assertTypeWithError(newName, "string");
|
|
118
|
-
_console.
|
|
119
|
-
newName
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
newName.length < MaxNameLength,
|
|
124
|
-
`name must be less than ${MaxNameLength} characters long ("${newName}" is ${newName.length} characters long)`
|
|
134
|
+
_console.assertRangeWithError(
|
|
135
|
+
"newName",
|
|
136
|
+
newName.length,
|
|
137
|
+
MinNameLength,
|
|
138
|
+
MaxNameLength
|
|
125
139
|
);
|
|
126
140
|
const setNameData = textEncoder.encode(newName);
|
|
127
141
|
_console.log({ setNameData });
|
|
@@ -144,7 +158,10 @@ class InformationManager {
|
|
|
144
158
|
}
|
|
145
159
|
#assertValidDeviceTypeEnum(typeEnum: number) {
|
|
146
160
|
_console.assertTypeWithError(typeEnum, "number");
|
|
147
|
-
_console.assertWithError(
|
|
161
|
+
_console.assertWithError(
|
|
162
|
+
typeEnum in DeviceTypes,
|
|
163
|
+
`invalid typeEnum ${typeEnum}`
|
|
164
|
+
);
|
|
148
165
|
}
|
|
149
166
|
updateType(updatedType: DeviceType) {
|
|
150
167
|
this.#assertValidDeviceType(updatedType);
|
|
@@ -177,17 +194,30 @@ class InformationManager {
|
|
|
177
194
|
case "rightInsole":
|
|
178
195
|
return true;
|
|
179
196
|
default:
|
|
180
|
-
// for future non-insole device types
|
|
181
197
|
return false;
|
|
182
198
|
}
|
|
183
199
|
}
|
|
184
200
|
|
|
185
|
-
get
|
|
201
|
+
get isGlove() {
|
|
202
|
+
switch (this.type) {
|
|
203
|
+
case "leftGlove":
|
|
204
|
+
case "rightGlove":
|
|
205
|
+
return true;
|
|
206
|
+
default:
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
get side(): Side {
|
|
186
212
|
switch (this.type) {
|
|
187
213
|
case "leftInsole":
|
|
214
|
+
case "leftGlove":
|
|
188
215
|
return "left";
|
|
189
216
|
case "rightInsole":
|
|
217
|
+
case "rightGlove":
|
|
190
218
|
return "right";
|
|
219
|
+
default:
|
|
220
|
+
return "left";
|
|
191
221
|
}
|
|
192
222
|
}
|
|
193
223
|
|
|
@@ -213,7 +243,8 @@ class InformationManager {
|
|
|
213
243
|
|
|
214
244
|
#onCurrentTime(currentTime: number) {
|
|
215
245
|
_console.log({ currentTime });
|
|
216
|
-
this.#isCurrentTimeSet =
|
|
246
|
+
this.#isCurrentTimeSet =
|
|
247
|
+
currentTime != 0 || Math.abs(Date.now() - currentTime) < Uint16Max;
|
|
217
248
|
if (!this.#isCurrentTimeSet) {
|
|
218
249
|
this.#setCurrentTime(false);
|
|
219
250
|
}
|
|
@@ -223,7 +254,10 @@ class InformationManager {
|
|
|
223
254
|
const dataView = new DataView(new ArrayBuffer(8));
|
|
224
255
|
dataView.setBigUint64(0, BigInt(Date.now()), true);
|
|
225
256
|
const promise = this.waitForEvent("getCurrentTime");
|
|
226
|
-
this.sendMessage(
|
|
257
|
+
this.sendMessage(
|
|
258
|
+
[{ type: "setCurrentTime", data: dataView.buffer }],
|
|
259
|
+
sendImmediately
|
|
260
|
+
);
|
|
227
261
|
await promise;
|
|
228
262
|
}
|
|
229
263
|
|
|
@@ -261,7 +295,13 @@ class InformationManager {
|
|
|
261
295
|
this.updateType(type);
|
|
262
296
|
break;
|
|
263
297
|
case "getMtu":
|
|
264
|
-
|
|
298
|
+
let mtu = dataView.getUint16(0, true);
|
|
299
|
+
if (
|
|
300
|
+
this.connectionType != "webSocket" &&
|
|
301
|
+
this.connectionType != "udp"
|
|
302
|
+
) {
|
|
303
|
+
mtu = Math.min(mtu, 512);
|
|
304
|
+
}
|
|
265
305
|
_console.log({ mtu });
|
|
266
306
|
this.#updateMtu(mtu);
|
|
267
307
|
break;
|
|
@@ -278,6 +318,8 @@ class InformationManager {
|
|
|
278
318
|
clear() {
|
|
279
319
|
this.#isCurrentTimeSet = false;
|
|
280
320
|
}
|
|
321
|
+
|
|
322
|
+
connectionType?: ConnectionType;
|
|
281
323
|
}
|
|
282
324
|
|
|
283
325
|
export default InformationManager;
|
package/src/TfliteManager.ts
CHANGED
|
@@ -8,8 +8,9 @@ import { parseTimestamp } from "./utils/MathUtils.ts";
|
|
|
8
8
|
import { SensorType } from "./sensor/SensorDataManager.ts";
|
|
9
9
|
import Device, { SendMessageCallback } from "./Device.ts";
|
|
10
10
|
import autoBind from "auto-bind";
|
|
11
|
+
import { FileConfiguration as BaseFileConfiguration } from "./FileTransferManager.ts";
|
|
11
12
|
|
|
12
|
-
const _console = createConsole("TfliteManager", { log:
|
|
13
|
+
const _console = createConsole("TfliteManager", { log: false });
|
|
13
14
|
|
|
14
15
|
export const TfliteMessageTypes = [
|
|
15
16
|
"getTfliteName",
|
|
@@ -34,6 +35,17 @@ export type TfliteMessageType = (typeof TfliteMessageTypes)[number];
|
|
|
34
35
|
export const TfliteEventTypes = TfliteMessageTypes;
|
|
35
36
|
export type TfliteEventType = (typeof TfliteEventTypes)[number];
|
|
36
37
|
|
|
38
|
+
export const RequiredTfliteMessageTypes: TfliteMessageType[] = [
|
|
39
|
+
"getTfliteName",
|
|
40
|
+
"getTfliteTask",
|
|
41
|
+
"getTfliteSampleRate",
|
|
42
|
+
"getTfliteSensorTypes",
|
|
43
|
+
"tfliteIsReady",
|
|
44
|
+
"getTfliteCaptureDelay",
|
|
45
|
+
"getTfliteThreshold",
|
|
46
|
+
"getTfliteInferencingEnabled",
|
|
47
|
+
];
|
|
48
|
+
|
|
37
49
|
export const TfliteTasks = ["classification", "regression"] as const;
|
|
38
50
|
export type TfliteTask = (typeof TfliteTasks)[number];
|
|
39
51
|
|
|
@@ -54,14 +66,36 @@ export interface TfliteInference {
|
|
|
54
66
|
values: number[];
|
|
55
67
|
maxValue?: number;
|
|
56
68
|
maxIndex?: number;
|
|
69
|
+
maxClass?: string;
|
|
70
|
+
classValues?: { [key: string]: number };
|
|
57
71
|
}
|
|
58
72
|
|
|
59
|
-
export type TfliteEventDispatcher = EventDispatcher<
|
|
73
|
+
export type TfliteEventDispatcher = EventDispatcher<
|
|
74
|
+
Device,
|
|
75
|
+
TfliteEventType,
|
|
76
|
+
TfliteEventMessages
|
|
77
|
+
>;
|
|
60
78
|
export type SendTfliteMessageCallback = SendMessageCallback<TfliteMessageType>;
|
|
61
79
|
|
|
62
|
-
export const TfliteSensorTypes
|
|
80
|
+
export const TfliteSensorTypes = [
|
|
81
|
+
"pressure",
|
|
82
|
+
"linearAcceleration",
|
|
83
|
+
"gyroscope",
|
|
84
|
+
"magnetometer",
|
|
85
|
+
] as const satisfies readonly SensorType[];
|
|
63
86
|
export type TfliteSensorType = (typeof TfliteSensorTypes)[number];
|
|
64
87
|
|
|
88
|
+
export interface TfliteFileConfiguration extends BaseFileConfiguration {
|
|
89
|
+
type: "tflite";
|
|
90
|
+
name: string;
|
|
91
|
+
sensorTypes: TfliteSensorType[];
|
|
92
|
+
task: TfliteTask;
|
|
93
|
+
sampleRate: number;
|
|
94
|
+
captureDelay?: number;
|
|
95
|
+
threshold?: number;
|
|
96
|
+
classes?: string[];
|
|
97
|
+
}
|
|
98
|
+
|
|
65
99
|
class TfliteManager {
|
|
66
100
|
constructor() {
|
|
67
101
|
autoBind(this);
|
|
@@ -73,7 +107,10 @@ class TfliteManager {
|
|
|
73
107
|
_console.assertEnumWithError(task, TfliteTasks);
|
|
74
108
|
}
|
|
75
109
|
#assertValidTaskEnum(taskEnum: number) {
|
|
76
|
-
_console.assertWithError(
|
|
110
|
+
_console.assertWithError(
|
|
111
|
+
taskEnum in TfliteTasks,
|
|
112
|
+
`invalid taskEnum ${taskEnum}`
|
|
113
|
+
);
|
|
77
114
|
}
|
|
78
115
|
|
|
79
116
|
eventDispatcher!: TfliteEventDispatcher;
|
|
@@ -116,7 +153,10 @@ class TfliteManager {
|
|
|
116
153
|
const promise = this.waitForEvent("getTfliteName");
|
|
117
154
|
|
|
118
155
|
const setNameData = textEncoder.encode(newName);
|
|
119
|
-
this.sendMessage(
|
|
156
|
+
this.sendMessage(
|
|
157
|
+
[{ type: "setTfliteName", data: setNameData.buffer }],
|
|
158
|
+
sendImmediately
|
|
159
|
+
);
|
|
120
160
|
|
|
121
161
|
await promise;
|
|
122
162
|
}
|
|
@@ -147,7 +187,10 @@ class TfliteManager {
|
|
|
147
187
|
const promise = this.waitForEvent("getTfliteTask");
|
|
148
188
|
|
|
149
189
|
const taskEnum = TfliteTasks.indexOf(newTask);
|
|
150
|
-
this.sendMessage(
|
|
190
|
+
this.sendMessage(
|
|
191
|
+
[{ type: "setTfliteTask", data: Uint8Array.from([taskEnum]).buffer }],
|
|
192
|
+
sendImmediately
|
|
193
|
+
);
|
|
151
194
|
|
|
152
195
|
await promise;
|
|
153
196
|
}
|
|
@@ -164,7 +207,9 @@ class TfliteManager {
|
|
|
164
207
|
#updateSampleRate(sampleRate: number) {
|
|
165
208
|
_console.log({ sampleRate });
|
|
166
209
|
this.#sampleRate = sampleRate;
|
|
167
|
-
this.#dispatchEvent("getTfliteSampleRate", {
|
|
210
|
+
this.#dispatchEvent("getTfliteSampleRate", {
|
|
211
|
+
tfliteSampleRate: sampleRate,
|
|
212
|
+
});
|
|
168
213
|
}
|
|
169
214
|
async setSampleRate(newSampleRate: number, sendImmediately?: boolean) {
|
|
170
215
|
_console.assertTypeWithError(newSampleRate, "number");
|
|
@@ -182,40 +227,56 @@ class TfliteManager {
|
|
|
182
227
|
|
|
183
228
|
const dataView = new DataView(new ArrayBuffer(2));
|
|
184
229
|
dataView.setUint16(0, newSampleRate, true);
|
|
185
|
-
this.sendMessage(
|
|
230
|
+
this.sendMessage(
|
|
231
|
+
[{ type: "setTfliteSampleRate", data: dataView.buffer }],
|
|
232
|
+
sendImmediately
|
|
233
|
+
);
|
|
186
234
|
|
|
187
235
|
await promise;
|
|
188
236
|
}
|
|
189
237
|
|
|
190
238
|
static AssertValidSensorType(sensorType: SensorType) {
|
|
191
239
|
SensorDataManager.AssertValidSensorType(sensorType);
|
|
192
|
-
|
|
240
|
+
const tfliteSensorType = sensorType as TfliteSensorType;
|
|
241
|
+
_console.assertWithError(
|
|
242
|
+
TfliteSensorTypes.includes(tfliteSensorType),
|
|
243
|
+
`invalid tflite sensorType "${sensorType}"`
|
|
244
|
+
);
|
|
193
245
|
}
|
|
194
246
|
|
|
195
|
-
#sensorTypes:
|
|
247
|
+
#sensorTypes: TfliteSensorType[] = [];
|
|
196
248
|
get sensorTypes() {
|
|
197
249
|
return this.#sensorTypes.slice();
|
|
198
250
|
}
|
|
199
251
|
#parseSensorTypes(dataView: DataView) {
|
|
200
252
|
_console.log("parseSensorTypes", dataView);
|
|
201
|
-
const sensorTypes:
|
|
253
|
+
const sensorTypes: TfliteSensorType[] = [];
|
|
202
254
|
for (let index = 0; index < dataView.byteLength; index++) {
|
|
203
255
|
const sensorTypeEnum = dataView.getUint8(index);
|
|
204
|
-
const sensorType = SensorTypes[sensorTypeEnum];
|
|
256
|
+
const sensorType = SensorTypes[sensorTypeEnum] as TfliteSensorType;
|
|
205
257
|
if (sensorType) {
|
|
206
|
-
|
|
258
|
+
if (TfliteSensorTypes.includes(sensorType)) {
|
|
259
|
+
sensorTypes.push(sensorType);
|
|
260
|
+
} else {
|
|
261
|
+
_console.error(`invalid tfliteSensorType ${sensorType}`);
|
|
262
|
+
}
|
|
207
263
|
} else {
|
|
208
264
|
_console.error(`invalid sensorTypeEnum ${sensorTypeEnum}`);
|
|
209
265
|
}
|
|
210
266
|
}
|
|
211
267
|
this.#updateSensorTypes(sensorTypes);
|
|
212
268
|
}
|
|
213
|
-
#updateSensorTypes(sensorTypes:
|
|
269
|
+
#updateSensorTypes(sensorTypes: TfliteSensorType[]) {
|
|
214
270
|
_console.log({ sensorTypes });
|
|
215
271
|
this.#sensorTypes = sensorTypes;
|
|
216
|
-
this.#dispatchEvent("getTfliteSensorTypes", {
|
|
272
|
+
this.#dispatchEvent("getTfliteSensorTypes", {
|
|
273
|
+
tfliteSensorTypes: sensorTypes,
|
|
274
|
+
});
|
|
217
275
|
}
|
|
218
|
-
async setSensorTypes(
|
|
276
|
+
async setSensorTypes(
|
|
277
|
+
newSensorTypes: SensorType[],
|
|
278
|
+
sendImmediately?: boolean
|
|
279
|
+
) {
|
|
219
280
|
newSensorTypes.forEach((sensorType) => {
|
|
220
281
|
TfliteManager.AssertValidSensorType(sensorType);
|
|
221
282
|
});
|
|
@@ -223,10 +284,17 @@ class TfliteManager {
|
|
|
223
284
|
const promise = this.waitForEvent("getTfliteSensorTypes");
|
|
224
285
|
|
|
225
286
|
newSensorTypes = arrayWithoutDuplicates(newSensorTypes);
|
|
226
|
-
const newSensorTypeEnums = newSensorTypes
|
|
287
|
+
const newSensorTypeEnums = newSensorTypes
|
|
288
|
+
.map((sensorType) => SensorTypes.indexOf(sensorType))
|
|
289
|
+
.sort();
|
|
227
290
|
_console.log(newSensorTypes, newSensorTypeEnums);
|
|
228
291
|
this.sendMessage(
|
|
229
|
-
[
|
|
292
|
+
[
|
|
293
|
+
{
|
|
294
|
+
type: "setTfliteSensorTypes",
|
|
295
|
+
data: Uint8Array.from(newSensorTypeEnums).buffer,
|
|
296
|
+
},
|
|
297
|
+
],
|
|
230
298
|
sendImmediately
|
|
231
299
|
);
|
|
232
300
|
|
|
@@ -263,7 +331,9 @@ class TfliteManager {
|
|
|
263
331
|
#updateCaptueDelay(captureDelay: number) {
|
|
264
332
|
_console.log({ captureDelay });
|
|
265
333
|
this.#captureDelay = captureDelay;
|
|
266
|
-
this.#dispatchEvent("getTfliteCaptureDelay", {
|
|
334
|
+
this.#dispatchEvent("getTfliteCaptureDelay", {
|
|
335
|
+
tfliteCaptureDelay: captureDelay,
|
|
336
|
+
});
|
|
267
337
|
}
|
|
268
338
|
async setCaptureDelay(newCaptureDelay: number, sendImmediately: boolean) {
|
|
269
339
|
_console.assertTypeWithError(newCaptureDelay, "number");
|
|
@@ -276,7 +346,10 @@ class TfliteManager {
|
|
|
276
346
|
|
|
277
347
|
const dataView = new DataView(new ArrayBuffer(2));
|
|
278
348
|
dataView.setUint16(0, newCaptureDelay, true);
|
|
279
|
-
this.sendMessage(
|
|
349
|
+
this.sendMessage(
|
|
350
|
+
[{ type: "setTfliteCaptureDelay", data: dataView.buffer }],
|
|
351
|
+
sendImmediately
|
|
352
|
+
);
|
|
280
353
|
|
|
281
354
|
await promise;
|
|
282
355
|
}
|
|
@@ -297,7 +370,10 @@ class TfliteManager {
|
|
|
297
370
|
}
|
|
298
371
|
async setThreshold(newThreshold: number, sendImmediately: boolean) {
|
|
299
372
|
_console.assertTypeWithError(newThreshold, "number");
|
|
300
|
-
_console.assertWithError(
|
|
373
|
+
_console.assertWithError(
|
|
374
|
+
newThreshold >= 0,
|
|
375
|
+
`threshold must be positive (got ${newThreshold})`
|
|
376
|
+
);
|
|
301
377
|
if (this.#threshold == newThreshold) {
|
|
302
378
|
_console.log(`redundant threshold assignment ${newThreshold}`);
|
|
303
379
|
return;
|
|
@@ -307,7 +383,10 @@ class TfliteManager {
|
|
|
307
383
|
|
|
308
384
|
const dataView = new DataView(new ArrayBuffer(4));
|
|
309
385
|
dataView.setFloat32(0, newThreshold, true);
|
|
310
|
-
this.sendMessage(
|
|
386
|
+
this.sendMessage(
|
|
387
|
+
[{ type: "setTfliteThreshold", data: dataView.buffer }],
|
|
388
|
+
sendImmediately
|
|
389
|
+
);
|
|
311
390
|
|
|
312
391
|
await promise;
|
|
313
392
|
}
|
|
@@ -324,16 +403,23 @@ class TfliteManager {
|
|
|
324
403
|
#updateInferencingEnabled(inferencingEnabled: boolean) {
|
|
325
404
|
_console.log({ inferencingEnabled });
|
|
326
405
|
this.#inferencingEnabled = inferencingEnabled;
|
|
327
|
-
this.#dispatchEvent("getTfliteInferencingEnabled", {
|
|
406
|
+
this.#dispatchEvent("getTfliteInferencingEnabled", {
|
|
407
|
+
tfliteInferencingEnabled: inferencingEnabled,
|
|
408
|
+
});
|
|
328
409
|
}
|
|
329
|
-
async setInferencingEnabled(
|
|
410
|
+
async setInferencingEnabled(
|
|
411
|
+
newInferencingEnabled: boolean,
|
|
412
|
+
sendImmediately: boolean = true
|
|
413
|
+
) {
|
|
330
414
|
_console.assertTypeWithError(newInferencingEnabled, "boolean");
|
|
331
415
|
if (!newInferencingEnabled && !this.isReady) {
|
|
332
416
|
return;
|
|
333
417
|
}
|
|
334
418
|
this.#assertIsReady();
|
|
335
419
|
if (this.#inferencingEnabled == newInferencingEnabled) {
|
|
336
|
-
_console.log(
|
|
420
|
+
_console.log(
|
|
421
|
+
`redundant inferencingEnabled assignment ${newInferencingEnabled}`
|
|
422
|
+
);
|
|
337
423
|
return;
|
|
338
424
|
}
|
|
339
425
|
|
|
@@ -375,7 +461,11 @@ class TfliteManager {
|
|
|
375
461
|
_console.log({ timestamp });
|
|
376
462
|
|
|
377
463
|
const values: number[] = [];
|
|
378
|
-
for (
|
|
464
|
+
for (
|
|
465
|
+
let index = 0, byteOffset = 2;
|
|
466
|
+
byteOffset < dataView.byteLength;
|
|
467
|
+
index++, byteOffset += 4
|
|
468
|
+
) {
|
|
379
469
|
const value = dataView.getFloat32(byteOffset, true);
|
|
380
470
|
values.push(value);
|
|
381
471
|
}
|
|
@@ -398,6 +488,15 @@ class TfliteManager {
|
|
|
398
488
|
_console.log({ maxIndex, maxValue });
|
|
399
489
|
inference.maxIndex = maxIndex;
|
|
400
490
|
inference.maxValue = maxValue;
|
|
491
|
+
if (this.#configuration?.classes) {
|
|
492
|
+
const { classes } = this.#configuration;
|
|
493
|
+
inference.maxClass = classes[maxIndex];
|
|
494
|
+
inference.classValues = {};
|
|
495
|
+
values.forEach((value, index) => {
|
|
496
|
+
const key = classes[index];
|
|
497
|
+
inference.classValues![key] = value;
|
|
498
|
+
});
|
|
499
|
+
}
|
|
401
500
|
}
|
|
402
501
|
|
|
403
502
|
this.#dispatchEvent("tfliteInference", { tfliteInference: inference });
|
|
@@ -445,6 +544,53 @@ class TfliteManager {
|
|
|
445
544
|
throw Error(`uncaught messageType ${messageType}`);
|
|
446
545
|
}
|
|
447
546
|
}
|
|
547
|
+
|
|
548
|
+
#configuration?: TfliteFileConfiguration;
|
|
549
|
+
get configuration() {
|
|
550
|
+
return this.#configuration;
|
|
551
|
+
}
|
|
552
|
+
sendConfiguration(
|
|
553
|
+
configuration: TfliteFileConfiguration,
|
|
554
|
+
sendImmediately?: boolean
|
|
555
|
+
) {
|
|
556
|
+
if (configuration == this.#configuration) {
|
|
557
|
+
_console.log("redundant tflite configuration assignment");
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
this.#configuration = configuration;
|
|
561
|
+
_console.log("assigned new tflite configuration", this.configuration);
|
|
562
|
+
if (!this.configuration) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const { name, task, captureDelay, sampleRate, threshold, sensorTypes } =
|
|
566
|
+
this.configuration;
|
|
567
|
+
this.setName(name, false);
|
|
568
|
+
this.setTask(task, false);
|
|
569
|
+
if (captureDelay != undefined) {
|
|
570
|
+
this.setCaptureDelay(captureDelay, false);
|
|
571
|
+
}
|
|
572
|
+
this.setSampleRate(sampleRate, false);
|
|
573
|
+
if (threshold != undefined) {
|
|
574
|
+
this.setThreshold(threshold, false);
|
|
575
|
+
}
|
|
576
|
+
this.setSensorTypes(sensorTypes, sendImmediately);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
clear() {
|
|
580
|
+
this.#configuration = undefined;
|
|
581
|
+
this.#inferencingEnabled = false;
|
|
582
|
+
this.#sensorTypes = [];
|
|
583
|
+
this.#sampleRate = 0;
|
|
584
|
+
this.#isReady = false;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
requestRequiredInformation() {
|
|
588
|
+
_console.log("requesting required tflite information");
|
|
589
|
+
const messages = RequiredTfliteMessageTypes.map((messageType) => ({
|
|
590
|
+
type: messageType,
|
|
591
|
+
}));
|
|
592
|
+
this.sendMessage(messages, false);
|
|
593
|
+
}
|
|
448
594
|
}
|
|
449
595
|
|
|
450
596
|
export default TfliteManager;
|