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,6 +1,13 @@
|
|
|
1
1
|
import { createConsole } from "../../utils/Console.ts";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
createServerMessage,
|
|
4
|
+
MessageLike,
|
|
5
|
+
ServerMessage,
|
|
6
|
+
} from "../ServerUtils.ts";
|
|
7
|
+
import {
|
|
8
|
+
addEventListeners,
|
|
9
|
+
removeEventListeners,
|
|
10
|
+
} from "../../utils/EventUtils.ts";
|
|
4
11
|
import ClientConnectionManager from "../../connection/ClientConnectionManager.ts";
|
|
5
12
|
import BaseClient, { ServerURL } from "../BaseClient.ts";
|
|
6
13
|
import type * as ws from "ws";
|
|
@@ -15,7 +22,7 @@ import {
|
|
|
15
22
|
} from "./WebSocketUtils.ts";
|
|
16
23
|
import { parseMessage } from "../../utils/ParseUtils.ts";
|
|
17
24
|
|
|
18
|
-
const _console = createConsole("WebSocketClient", { log:
|
|
25
|
+
const _console = createConsole("WebSocketClient", { log: false });
|
|
19
26
|
|
|
20
27
|
class WebSocketClient extends BaseClient {
|
|
21
28
|
// WEBSOCKET
|
|
@@ -93,10 +100,16 @@ class WebSocketClient extends BaseClient {
|
|
|
93
100
|
sendMessage(message: MessageLike) {
|
|
94
101
|
this.assertConnection();
|
|
95
102
|
this.#webSocket!.send(message);
|
|
103
|
+
this.#pingTimer.restart();
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
sendServerMessage(...messages: ServerMessage[]) {
|
|
99
|
-
this.sendMessage(
|
|
107
|
+
this.sendMessage(
|
|
108
|
+
createWebSocketMessage({
|
|
109
|
+
type: "serverMessage",
|
|
110
|
+
data: createServerMessage(...messages),
|
|
111
|
+
})
|
|
112
|
+
);
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
#sendWebSocketMessage(...messages: WebSocketMessage[]) {
|
|
@@ -114,11 +127,12 @@ class WebSocketClient extends BaseClient {
|
|
|
114
127
|
#onWebSocketOpen(event: ws.Event) {
|
|
115
128
|
_console.log("webSocket.open", event);
|
|
116
129
|
this.#pingTimer.start();
|
|
117
|
-
this._connectionStatus = "connected";
|
|
130
|
+
//this._connectionStatus = "connected";
|
|
131
|
+
this._sendRequiredMessages();
|
|
118
132
|
}
|
|
119
133
|
async #onWebSocketMessage(event: ws.MessageEvent) {
|
|
120
134
|
_console.log("webSocket.message", event);
|
|
121
|
-
this.#pingTimer.restart();
|
|
135
|
+
//this.#pingTimer.restart();
|
|
122
136
|
//@ts-expect-error
|
|
123
137
|
const arrayBuffer = await event.data.arrayBuffer();
|
|
124
138
|
const dataView = new DataView(arrayBuffer);
|
|
@@ -130,7 +144,8 @@ class WebSocketClient extends BaseClient {
|
|
|
130
144
|
this._connectionStatus = "notConnected";
|
|
131
145
|
|
|
132
146
|
Object.entries(this.devices).forEach(([id, device]) => {
|
|
133
|
-
const connectionManager =
|
|
147
|
+
const connectionManager =
|
|
148
|
+
device.connectionManager! as ClientConnectionManager;
|
|
134
149
|
connectionManager.isConnected = false;
|
|
135
150
|
});
|
|
136
151
|
|
|
@@ -142,12 +157,18 @@ class WebSocketClient extends BaseClient {
|
|
|
142
157
|
}
|
|
143
158
|
}
|
|
144
159
|
#onWebSocketError(event: ws.ErrorEvent) {
|
|
145
|
-
_console.error("webSocket.error", event
|
|
160
|
+
_console.error("webSocket.error", event);
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
// PARSING
|
|
149
164
|
#parseWebSocketMessage(dataView: DataView) {
|
|
150
|
-
parseMessage(
|
|
165
|
+
parseMessage(
|
|
166
|
+
dataView,
|
|
167
|
+
WebSocketMessageTypes,
|
|
168
|
+
this.#onServerMessage.bind(this),
|
|
169
|
+
null,
|
|
170
|
+
true
|
|
171
|
+
);
|
|
151
172
|
}
|
|
152
173
|
|
|
153
174
|
#onServerMessage(messageType: WebSocketMessageType, dataView: DataView) {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
createWebSocketMessage,
|
|
13
13
|
} from "./WebSocketUtils.ts";
|
|
14
14
|
|
|
15
|
-
const _console = createConsole("WebSocketServer", { log:
|
|
15
|
+
const _console = createConsole("WebSocketServer", { log: false });
|
|
16
16
|
|
|
17
17
|
/** NODE_START */
|
|
18
18
|
import type * as ws from "ws";
|
|
@@ -3,13 +3,15 @@ import { createMessage, Message } from "../ServerUtils.ts";
|
|
|
3
3
|
|
|
4
4
|
const _console = createConsole("WebSocketUtils", { log: false });
|
|
5
5
|
|
|
6
|
-
export const webSocketPingTimeout =
|
|
6
|
+
export const webSocketPingTimeout = 30_000;
|
|
7
7
|
export const webSocketReconnectTimeout = 3_000;
|
|
8
8
|
|
|
9
9
|
export const WebSocketMessageTypes = ["ping", "pong", "serverMessage"] as const;
|
|
10
10
|
export type WebSocketMessageType = (typeof WebSocketMessageTypes)[number];
|
|
11
11
|
|
|
12
|
-
export type WebSocketMessage =
|
|
12
|
+
export type WebSocketMessage =
|
|
13
|
+
| WebSocketMessageType
|
|
14
|
+
| Message<WebSocketMessageType>;
|
|
13
15
|
export function createWebSocketMessage(...messages: WebSocketMessage[]) {
|
|
14
16
|
_console.log("createWebSocketMessage", ...messages);
|
|
15
17
|
return createMessage(WebSocketMessageTypes, ...messages);
|
|
@@ -23,16 +23,16 @@ class CenterOfPressureHelper {
|
|
|
23
23
|
this.#range.x.update(centerOfPressure.x);
|
|
24
24
|
this.#range.y.update(centerOfPressure.y);
|
|
25
25
|
}
|
|
26
|
-
getNormalization(centerOfPressure: CenterOfPressure): CenterOfPressure {
|
|
26
|
+
getNormalization(centerOfPressure: CenterOfPressure, weightByRange: boolean): CenterOfPressure {
|
|
27
27
|
return {
|
|
28
|
-
x: this.#range.x.getNormalization(centerOfPressure.x,
|
|
29
|
-
y: this.#range.y.getNormalization(centerOfPressure.y,
|
|
28
|
+
x: this.#range.x.getNormalization(centerOfPressure.x, weightByRange),
|
|
29
|
+
y: this.#range.y.getNormalization(centerOfPressure.y, weightByRange),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
updateAndGetNormalization(centerOfPressure: CenterOfPressure) {
|
|
33
|
+
updateAndGetNormalization(centerOfPressure: CenterOfPressure, weightByRange: boolean) {
|
|
34
34
|
this.update(centerOfPressure);
|
|
35
|
-
return this.getNormalization(centerOfPressure);
|
|
35
|
+
return this.getNormalization(centerOfPressure, weightByRange);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
package/src/utils/Console.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isInDev, isInLensStudio } from "./environment.ts";
|
|
1
|
+
import { isInDev, isInLensStudio, isInNode } from "./environment.ts";
|
|
2
2
|
|
|
3
3
|
declare var Studio: any | undefined;
|
|
4
4
|
|
|
@@ -34,6 +34,31 @@ if (isInLensStudio) {
|
|
|
34
34
|
__console = console;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function getCallerFunctionPath(): string {
|
|
38
|
+
const stack = new Error().stack;
|
|
39
|
+
if (!stack) return "";
|
|
40
|
+
|
|
41
|
+
const lines = stack.split("\n");
|
|
42
|
+
const callerLine = lines[3] || lines[2];
|
|
43
|
+
|
|
44
|
+
const match = callerLine.match(/at (.*?) \(/) || callerLine.match(/at (.*)/);
|
|
45
|
+
if (!match) return "";
|
|
46
|
+
|
|
47
|
+
const fullFn = match[1].trim();
|
|
48
|
+
return `[${fullFn}]`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function wrapWithLocation(fn: LogFunction): LogFunction {
|
|
52
|
+
return (...args: any[]) => {
|
|
53
|
+
if (isInNode) {
|
|
54
|
+
const functionPath = getCallerFunctionPath();
|
|
55
|
+
fn(functionPath, ...args);
|
|
56
|
+
} else {
|
|
57
|
+
fn(...args);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
37
62
|
// console.assert not supported in WebBLE
|
|
38
63
|
if (!__console.assert) {
|
|
39
64
|
const assert: AssertLogFunction = (condition, ...data) => {
|
|
@@ -54,10 +79,18 @@ if (!__console.table) {
|
|
|
54
79
|
|
|
55
80
|
function emptyFunction() {}
|
|
56
81
|
|
|
57
|
-
const log: LogFunction =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
82
|
+
const log: LogFunction = isInNode
|
|
83
|
+
? wrapWithLocation(__console.log!.bind(__console))
|
|
84
|
+
: __console.log!.bind(__console);
|
|
85
|
+
const warn: LogFunction = isInNode
|
|
86
|
+
? wrapWithLocation(__console.warn!.bind(__console))
|
|
87
|
+
: __console.warn!.bind(__console);
|
|
88
|
+
const error: LogFunction = isInNode
|
|
89
|
+
? wrapWithLocation(__console.error!.bind(__console))
|
|
90
|
+
: __console.error!.bind(__console);
|
|
91
|
+
const table: LogFunction = isInNode
|
|
92
|
+
? wrapWithLocation(__console.table!.bind(__console))
|
|
93
|
+
: __console.table!.bind(__console);
|
|
61
94
|
const assert: AssertLogFunction = __console.assert.bind(__console);
|
|
62
95
|
|
|
63
96
|
class Console {
|
|
@@ -133,21 +166,41 @@ class Console {
|
|
|
133
166
|
|
|
134
167
|
/** @throws {Error} if value's type doesn't match */
|
|
135
168
|
assertTypeWithError(value: any, type: string) {
|
|
136
|
-
this.assertWithError(
|
|
169
|
+
this.assertWithError(
|
|
170
|
+
typeof value == type,
|
|
171
|
+
`value ${value} of type "${typeof value}" not of type "${type}"`
|
|
172
|
+
);
|
|
137
173
|
}
|
|
138
174
|
|
|
139
175
|
/** @throws {Error} if value's type doesn't match */
|
|
140
176
|
assertEnumWithError(value: string, enumeration: readonly string[]) {
|
|
141
|
-
this.assertWithError(
|
|
177
|
+
this.assertWithError(
|
|
178
|
+
enumeration.includes(value),
|
|
179
|
+
`invalid enum "${value}"`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** @throws {Error} if value is not within some range */
|
|
184
|
+
assertRangeWithError(name: string, value: number, min: number, max: number) {
|
|
185
|
+
this.assertWithError(
|
|
186
|
+
value >= min && value <= max,
|
|
187
|
+
`${name} ${value} must be within ${min}-${max}`
|
|
188
|
+
);
|
|
142
189
|
}
|
|
143
190
|
}
|
|
144
191
|
|
|
145
|
-
export function createConsole(
|
|
192
|
+
export function createConsole(
|
|
193
|
+
type: string,
|
|
194
|
+
levelFlags?: ConsoleLevelFlags
|
|
195
|
+
): Console {
|
|
146
196
|
return Console.create(type, levelFlags);
|
|
147
197
|
}
|
|
148
198
|
|
|
149
199
|
/** @throws {Error} if no console with type is found */
|
|
150
|
-
export function setConsoleLevelFlagsForType(
|
|
200
|
+
export function setConsoleLevelFlagsForType(
|
|
201
|
+
type: string,
|
|
202
|
+
levelFlags: ConsoleLevelFlags
|
|
203
|
+
) {
|
|
151
204
|
Console.setLevelFlagsForType(type, levelFlags);
|
|
152
205
|
}
|
|
153
206
|
|
package/src/utils/MathUtils.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { PressureSensorPosition } from "../sensor/PressureSensorDataManager.ts";
|
|
1
2
|
import { createConsole } from "./Console.ts";
|
|
2
3
|
|
|
3
|
-
const _console = createConsole("MathUtils", { log:
|
|
4
|
+
const _console = createConsole("MathUtils", { log: false });
|
|
4
5
|
|
|
5
6
|
export function getInterpolation(value: number, min: number, max: number, span: number) {
|
|
6
7
|
if (span == undefined) {
|
|
@@ -51,3 +52,32 @@ export interface Euler {
|
|
|
51
52
|
pitch: number;
|
|
52
53
|
roll: number;
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
export function computeVoronoiWeights(points: PressureSensorPosition[], sampleCount = 100000) {
|
|
57
|
+
const n = points.length;
|
|
58
|
+
const counts = new Array(n).fill(0);
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < sampleCount; i++) {
|
|
61
|
+
const x = Math.random();
|
|
62
|
+
const y = Math.random();
|
|
63
|
+
|
|
64
|
+
// Find the closest input point
|
|
65
|
+
let minDist = Infinity;
|
|
66
|
+
let closestIndex = -1;
|
|
67
|
+
|
|
68
|
+
for (let j = 0; j < n; j++) {
|
|
69
|
+
const { x: px, y: py } = points[j];
|
|
70
|
+
const dist = (px - x) ** 2 + (py - y) ** 2; // Squared Euclidean distance
|
|
71
|
+
if (dist < minDist) {
|
|
72
|
+
minDist = dist;
|
|
73
|
+
closestIndex = j;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Increment count for the closest point
|
|
78
|
+
counts[closestIndex]++;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Convert counts to weights (sum to 1)
|
|
82
|
+
return counts.map((c) => c / sampleCount);
|
|
83
|
+
}
|
package/src/utils/ParseUtils.ts
CHANGED
|
@@ -2,12 +2,18 @@ import { sliceDataView } from "./ArrayBufferUtils.ts";
|
|
|
2
2
|
import { createConsole } from "./Console.ts";
|
|
3
3
|
import { textDecoder } from "./Text.ts";
|
|
4
4
|
|
|
5
|
-
const _console = createConsole("ParseUtils", { log:
|
|
5
|
+
const _console = createConsole("ParseUtils", { log: false });
|
|
6
6
|
|
|
7
|
-
export function parseStringFromDataView(
|
|
7
|
+
export function parseStringFromDataView(
|
|
8
|
+
dataView: DataView,
|
|
9
|
+
byteOffset: number = 0
|
|
10
|
+
) {
|
|
8
11
|
const stringLength = dataView.getUint8(byteOffset++);
|
|
9
12
|
const string = textDecoder.decode(
|
|
10
|
-
dataView.buffer.slice(
|
|
13
|
+
dataView.buffer.slice(
|
|
14
|
+
dataView.byteOffset + byteOffset,
|
|
15
|
+
dataView.byteOffset + byteOffset + stringLength
|
|
16
|
+
)
|
|
11
17
|
);
|
|
12
18
|
byteOffset += stringLength;
|
|
13
19
|
return { string, byteOffset };
|
|
@@ -16,14 +22,21 @@ export function parseStringFromDataView(dataView: DataView, byteOffset: number =
|
|
|
16
22
|
export function parseMessage<MessageType extends string>(
|
|
17
23
|
dataView: DataView,
|
|
18
24
|
messageTypes: readonly MessageType[],
|
|
19
|
-
callback: (
|
|
25
|
+
callback: (
|
|
26
|
+
messageType: MessageType,
|
|
27
|
+
dataView: DataView,
|
|
28
|
+
context?: any
|
|
29
|
+
) => void,
|
|
20
30
|
context?: any,
|
|
21
31
|
parseMessageLengthAsUint16: boolean = false
|
|
22
32
|
) {
|
|
23
33
|
let byteOffset = 0;
|
|
24
34
|
while (byteOffset < dataView.byteLength) {
|
|
25
35
|
const messageTypeEnum = dataView.getUint8(byteOffset++);
|
|
26
|
-
_console.assertWithError(
|
|
36
|
+
_console.assertWithError(
|
|
37
|
+
messageTypeEnum in messageTypes,
|
|
38
|
+
`invalid messageTypeEnum ${messageTypeEnum}`
|
|
39
|
+
);
|
|
27
40
|
const messageType = messageTypes[messageTypeEnum];
|
|
28
41
|
|
|
29
42
|
let messageLength: number;
|
|
@@ -34,7 +47,13 @@ export function parseMessage<MessageType extends string>(
|
|
|
34
47
|
messageLength = dataView.getUint8(byteOffset++);
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
_console.log({
|
|
50
|
+
_console.log({
|
|
51
|
+
messageTypeEnum,
|
|
52
|
+
messageType,
|
|
53
|
+
messageLength,
|
|
54
|
+
dataView,
|
|
55
|
+
byteOffset,
|
|
56
|
+
});
|
|
38
57
|
|
|
39
58
|
const _dataView = sliceDataView(dataView, byteOffset, messageLength);
|
|
40
59
|
_console.log({ _dataView });
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export function throttle<T extends (...args: any[]) => void>(
|
|
2
|
+
fn: T,
|
|
3
|
+
interval: number,
|
|
4
|
+
trailing = false
|
|
5
|
+
): (...args: Parameters<T>) => void {
|
|
6
|
+
let lastTime = 0;
|
|
7
|
+
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
8
|
+
let lastArgs: Parameters<T> | null = null;
|
|
9
|
+
|
|
10
|
+
return function (...args: Parameters<T>) {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const remaining = interval - (now - lastTime);
|
|
13
|
+
|
|
14
|
+
if (remaining <= 0) {
|
|
15
|
+
if (timeout) {
|
|
16
|
+
clearTimeout(timeout);
|
|
17
|
+
timeout = null;
|
|
18
|
+
}
|
|
19
|
+
lastTime = now;
|
|
20
|
+
fn(...args);
|
|
21
|
+
} else if (trailing) {
|
|
22
|
+
lastArgs = args;
|
|
23
|
+
if (!timeout) {
|
|
24
|
+
timeout = setTimeout(() => {
|
|
25
|
+
lastTime = Date.now();
|
|
26
|
+
timeout = null;
|
|
27
|
+
if (lastArgs) {
|
|
28
|
+
fn(...lastArgs);
|
|
29
|
+
lastArgs = null;
|
|
30
|
+
}
|
|
31
|
+
}, remaining);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function debounce<T extends (...args: any[]) => void>(
|
|
38
|
+
fn: T,
|
|
39
|
+
interval: number,
|
|
40
|
+
callImmediately = false
|
|
41
|
+
): (...args: Parameters<T>) => void {
|
|
42
|
+
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
43
|
+
|
|
44
|
+
return function (...args: Parameters<T>) {
|
|
45
|
+
const callNow = callImmediately && !timeout;
|
|
46
|
+
|
|
47
|
+
if (timeout) {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
timeout = setTimeout(() => {
|
|
52
|
+
timeout = null;
|
|
53
|
+
if (!callImmediately) {
|
|
54
|
+
fn(...args);
|
|
55
|
+
}
|
|
56
|
+
}, interval);
|
|
57
|
+
|
|
58
|
+
if (callNow) {
|
|
59
|
+
fn(...args);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
package/src/utils/Timer.ts
CHANGED
|
@@ -52,7 +52,7 @@ class Timer {
|
|
|
52
52
|
_console.log("interval already running");
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
_console.log(
|
|
55
|
+
_console.log(`starting interval every ${this.#interval}ms`);
|
|
56
56
|
this.#intervalId = setInterval(this.#callback, this.#interval);
|
|
57
57
|
if (immediately) {
|
|
58
58
|
this.#callback();
|
package/src/utils/checksum.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createConsole } from "./Console.ts";
|
|
2
2
|
|
|
3
|
-
const _console = createConsole("checksum", { log:
|
|
3
|
+
const _console = createConsole("checksum", { log: false });
|
|
4
4
|
|
|
5
5
|
// https://github.com/googlecreativelab/tiny-motion-trainer/blob/5fceb49f018ae0c403bf9f0ccc437309c2acb507/frontend/src/tf4micro-motion-kit/modules/bleFileTransfer#L195
|
|
6
6
|
|
package/src/utils/mcumgr.js
CHANGED