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.
Files changed (215) hide show
  1. package/README.md +16 -10
  2. package/assets/3d/anchor.glb +0 -0
  3. package/assets/3d/coin.glb +0 -0
  4. package/assets/3d/glasses.glb +0 -0
  5. package/assets/3d/rightHand.glb +0 -0
  6. package/assets/audio/bounceMedium.wav +0 -0
  7. package/assets/audio/bounceStrong.wav +0 -0
  8. package/assets/audio/bounceWeak.wav +0 -0
  9. package/assets/audio/coin.wav +0 -0
  10. package/assets/audio/getUp.wav +0 -0
  11. package/assets/audio/grab.wav +0 -0
  12. package/assets/audio/kick.wav +0 -0
  13. package/assets/audio/platterFadeIn old.wav +0 -0
  14. package/assets/audio/platterFadeIn.wav +0 -0
  15. package/assets/audio/platterFadeOut.wav +0 -0
  16. package/assets/audio/punch.wav +0 -0
  17. package/assets/audio/punchSqueak.wav +0 -0
  18. package/assets/audio/purr.wav +0 -0
  19. package/assets/audio/purrFadeOut.wav +0 -0
  20. package/assets/audio/release.wav +0 -0
  21. package/assets/audio/splat.wav +0 -0
  22. package/assets/audio/stomp.wav +0 -0
  23. package/assets/images/ukaton-pressure-0.svg +9 -0
  24. package/assets/images/ukaton-pressure-1.svg +9 -0
  25. package/assets/images/ukaton-pressure-10.svg +9 -0
  26. package/assets/images/ukaton-pressure-11.svg +9 -0
  27. package/assets/images/ukaton-pressure-12.svg +9 -0
  28. package/assets/images/ukaton-pressure-13.svg +9 -0
  29. package/assets/images/ukaton-pressure-14.svg +9 -0
  30. package/assets/images/ukaton-pressure-15.svg +9 -0
  31. package/assets/images/ukaton-pressure-2.svg +9 -0
  32. package/assets/images/ukaton-pressure-3.svg +9 -0
  33. package/assets/images/ukaton-pressure-4.svg +9 -0
  34. package/assets/images/ukaton-pressure-5.svg +9 -0
  35. package/assets/images/ukaton-pressure-6.svg +9 -0
  36. package/assets/images/ukaton-pressure-7.svg +9 -0
  37. package/assets/images/ukaton-pressure-8.svg +9 -0
  38. package/assets/images/ukaton-pressure-9.svg +9 -0
  39. package/assets/images/ukaton-right-insole.svg +798 -0
  40. package/build/brilliantsole.cjs +2870 -882
  41. package/build/brilliantsole.cjs.map +1 -1
  42. package/build/brilliantsole.js +2477 -782
  43. package/build/brilliantsole.js.map +1 -1
  44. package/build/brilliantsole.ls.js +2260 -592
  45. package/build/brilliantsole.ls.js.map +1 -1
  46. package/build/brilliantsole.min.js +1 -1
  47. package/build/brilliantsole.min.js.map +1 -1
  48. package/build/brilliantsole.module.d.ts +302 -116
  49. package/build/brilliantsole.module.js +2468 -782
  50. package/build/brilliantsole.module.js.map +1 -1
  51. package/build/brilliantsole.module.min.d.ts +302 -116
  52. package/build/brilliantsole.module.min.js +1 -1
  53. package/build/brilliantsole.module.min.js.map +1 -1
  54. package/build/brilliantsole.node.module.d.ts +295 -113
  55. package/build/brilliantsole.node.module.js +2860 -882
  56. package/build/brilliantsole.node.module.js.map +1 -1
  57. package/build/dts/BS-output.d.ts +10 -0
  58. package/build/dts/BS.d.ts +21 -9
  59. package/build/dts/CameraManager.d.ts +72 -0
  60. package/build/dts/Device.d.ts +53 -16
  61. package/build/dts/DeviceInformationManager.d.ts +4 -4
  62. package/build/dts/DeviceManager.d.ts +3 -0
  63. package/build/dts/FileTransferManager.d.ts +18 -8
  64. package/build/dts/InformationManager.d.ts +8 -5
  65. package/build/dts/TfliteManager.d.ts +22 -2
  66. package/build/dts/WifiManager.d.ts +61 -0
  67. package/build/dts/connection/BaseConnectionManager.d.ts +37 -3
  68. package/build/dts/connection/ClientConnectionManager.d.ts +11 -2
  69. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
  70. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +3 -1
  71. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +2 -0
  72. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  73. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  74. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  75. package/build/dts/devicePair/DevicePair.d.ts +14 -10
  76. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
  77. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
  78. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  79. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  80. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  81. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  82. package/build/dts/server/BaseClient.d.ts +6 -3
  83. package/build/dts/server/ServerUtils.d.ts +1 -1
  84. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  85. package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
  86. package/build/dts/utils/Console.d.ts +2 -0
  87. package/build/dts/utils/MathUtils.d.ts +2 -0
  88. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  89. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  90. package/build/index.d.ts +299 -113
  91. package/build/index.node.d.ts +292 -110
  92. package/examples/3d/scene.html +19 -5
  93. package/examples/3d/script.js +90 -17
  94. package/examples/3d-generic/index.html +144 -0
  95. package/examples/3d-generic/script.js +266 -0
  96. package/examples/balance/script.js +2 -1
  97. package/examples/basic/index.html +232 -18
  98. package/examples/basic/script.js +746 -106
  99. package/examples/bottango/index.html +11 -1
  100. package/examples/bottango/script.js +2 -2
  101. package/examples/center-of-pressure/index.html +114 -114
  102. package/examples/center-of-pressure/script.js +1 -1
  103. package/examples/device-pair/index.html +58 -58
  104. package/examples/device-pair/script.js +12 -8
  105. package/examples/edge-impulse/script.js +135 -44
  106. package/examples/edge-impulse-test/README.md +11 -0
  107. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  108. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  109. package/examples/edge-impulse-test/index.html +75 -0
  110. package/examples/edge-impulse-test/run-impulse.js +135 -0
  111. package/examples/edge-impulse-test/script.js +200 -0
  112. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  113. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  114. package/examples/gloves/index.html +119 -0
  115. package/examples/gloves/run-impulse.js +135 -0
  116. package/examples/gloves/scene.html +124 -0
  117. package/examples/gloves/script.js +931 -0
  118. package/examples/graph/index.html +11 -1
  119. package/examples/graph/script.js +94 -37
  120. package/examples/pressure/index.html +180 -12
  121. package/examples/pressure/script.js +144 -7
  122. package/examples/punch/index.html +135 -0
  123. package/examples/punch/punch.tflite +0 -0
  124. package/examples/punch/script.js +169 -0
  125. package/examples/recording/index.html +191 -183
  126. package/examples/server/index.html +109 -23
  127. package/examples/server/script.js +322 -111
  128. package/examples/ukaton-firmware-update/index.html +20 -0
  129. package/examples/ukaton-firmware-update/manifest.json +11 -0
  130. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  131. package/examples/utils/aframe/aframe-master.min.js +2 -0
  132. package/examples/utils/aframe/bs-vibration.js +150 -0
  133. package/examples/utils/aframe/force-pushable.js +80 -0
  134. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  135. package/examples/utils/aframe/grabbable-listener.js +31 -0
  136. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  137. package/examples/utils/aframe/grow-shrink.js +25 -0
  138. package/examples/utils/aframe/hand-punch.js +119 -0
  139. package/examples/utils/aframe/my-obb-collider.js +293 -0
  140. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  141. package/examples/utils/aframe/occlude-mesh.js +42 -0
  142. package/examples/utils/aframe/palm-up-detector.js +47 -0
  143. package/examples/utils/aframe/shadow-material.js +20 -0
  144. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  145. package/examples/webxr/script.js +3 -3
  146. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  147. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  148. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  149. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  150. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  151. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  152. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  153. package/examples/webxr-2/components/bs-ankle.js +337 -0
  154. package/examples/webxr-2/components/coin.js +84 -0
  155. package/examples/webxr-2/components/custom-wrap.js +17 -0
  156. package/examples/webxr-2/components/goomba.js +3250 -0
  157. package/examples/webxr-2/components/init-shell-material.js +215 -0
  158. package/examples/webxr-2/components/platter.js +172 -0
  159. package/examples/webxr-2/components/shell.js +374 -0
  160. package/examples/webxr-2/components/soccer-ball.js +250 -0
  161. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  162. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  163. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  164. package/examples/webxr-2/index.html +996 -0
  165. package/examples/webxr-2/kick.tflite +0 -0
  166. package/examples/webxr-2/kick2.tflite +0 -0
  167. package/examples/webxr-2/run-impulse.js +135 -0
  168. package/examples/webxr-2/script.js +384 -0
  169. package/package.json +2 -1
  170. package/src/.prettierrc +4 -0
  171. package/src/BS.ts +66 -9
  172. package/src/CameraManager.ts +499 -0
  173. package/src/Device.ts +620 -92
  174. package/src/DeviceInformationManager.ts +22 -11
  175. package/src/DeviceManager.ts +94 -25
  176. package/src/FileTransferManager.ts +146 -21
  177. package/src/FirmwareManager.ts +1 -1
  178. package/src/InformationManager.ts +62 -20
  179. package/src/TfliteManager.ts +172 -26
  180. package/src/WifiManager.ts +323 -0
  181. package/src/connection/BaseConnectionManager.ts +145 -30
  182. package/src/connection/ClientConnectionManager.ts +47 -11
  183. package/src/connection/bluetooth/BluetoothConnectionManager.ts +14 -3
  184. package/src/connection/bluetooth/NobleConnectionManager.ts +155 -42
  185. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +104 -35
  186. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  187. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  188. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  189. package/src/devicePair/DevicePair.ts +145 -49
  190. package/src/devicePair/DevicePairPressureSensorDataManager.ts +72 -24
  191. package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
  192. package/src/scanner/BaseScanner.ts +49 -11
  193. package/src/scanner/NobleScanner.ts +81 -17
  194. package/src/sensor/BarometerSensorDataManager.ts +1 -1
  195. package/src/sensor/MotionSensorDataManager.ts +22 -7
  196. package/src/sensor/PressureSensorDataManager.ts +47 -13
  197. package/src/sensor/SensorConfigurationManager.ts +75 -24
  198. package/src/sensor/SensorDataManager.ts +107 -26
  199. package/src/server/BaseClient.ts +192 -37
  200. package/src/server/BaseServer.ts +201 -43
  201. package/src/server/ServerUtils.ts +39 -9
  202. package/src/server/udp/UDPServer.ts +74 -23
  203. package/src/server/udp/UDPUtils.ts +9 -2
  204. package/src/server/websocket/WebSocketClient.ts +30 -9
  205. package/src/server/websocket/WebSocketServer.ts +1 -1
  206. package/src/server/websocket/WebSocketUtils.ts +4 -2
  207. package/src/utils/CenterOfPressureHelper.ts +5 -5
  208. package/src/utils/Console.ts +62 -9
  209. package/src/utils/MathUtils.ts +31 -1
  210. package/src/utils/ParseUtils.ts +25 -6
  211. package/src/utils/ThrottleUtils.ts +62 -0
  212. package/src/utils/Timer.ts +1 -1
  213. package/src/utils/checksum.ts +1 -1
  214. package/src/utils/mcumgr.js +1 -1
  215. package/src/vibration/VibrationManager.ts +166 -40
@@ -1,6 +1,13 @@
1
1
  import { createConsole } from "../../utils/Console.ts";
2
- import { createServerMessage, MessageLike, ServerMessage } from "../ServerUtils.ts";
3
- import { addEventListeners, removeEventListeners } from "../../utils/EventUtils.ts";
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: true });
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(createWebSocketMessage({ type: "serverMessage", data: createServerMessage(...messages) }));
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 = device.connectionManager! as ClientConnectionManager;
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.message);
160
+ _console.error("webSocket.error", event);
146
161
  }
147
162
 
148
163
  // PARSING
149
164
  #parseWebSocketMessage(dataView: DataView) {
150
- parseMessage(dataView, WebSocketMessageTypes, this.#onServerMessage.bind(this), null, true);
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: true });
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 = 30_000_000;
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 = WebSocketMessageType | Message<WebSocketMessageType>;
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, false),
29
- y: this.#range.y.getNormalization(centerOfPressure.y, false),
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
 
@@ -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 = __console.log!.bind(__console);
58
- const warn: LogFunction = __console.warn!.bind(__console);
59
- const error: LogFunction = __console.error!.bind(__console);
60
- const table: LogFunction = __console.table!.bind(__console);
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(typeof value == type, `value ${value} of type "${typeof value}" not of type "${type}"`);
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(enumeration.includes(value), `invalid enum "${value}"`);
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(type: string, levelFlags?: ConsoleLevelFlags): Console {
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(type: string, levelFlags: ConsoleLevelFlags) {
200
+ export function setConsoleLevelFlagsForType(
201
+ type: string,
202
+ levelFlags: ConsoleLevelFlags
203
+ ) {
151
204
  Console.setLevelFlagsForType(type, levelFlags);
152
205
  }
153
206
 
@@ -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: true });
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
+ }
@@ -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: true });
5
+ const _console = createConsole("ParseUtils", { log: false });
6
6
 
7
- export function parseStringFromDataView(dataView: DataView, byteOffset: number = 0) {
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(dataView.byteOffset + byteOffset, dataView.byteOffset + byteOffset + stringLength)
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: (messageType: MessageType, dataView: DataView, context?: any) => void,
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(messageTypeEnum in messageTypes, `invalid messageTypeEnum ${messageTypeEnum}`);
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({ messageTypeEnum, messageType, messageLength, dataView, byteOffset });
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
+ }
@@ -52,7 +52,7 @@ class Timer {
52
52
  _console.log("interval already running");
53
53
  return;
54
54
  }
55
- _console.log("starting interval");
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();
@@ -1,6 +1,6 @@
1
1
  import { createConsole } from "./Console.ts";
2
2
 
3
- const _console = createConsole("checksum", { log: true });
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
 
@@ -33,7 +33,7 @@
33
33
  import { CBOR } from "./cbor.js";
34
34
  import { createConsole } from "./Console.ts";
35
35
 
36
- const _console = createConsole("mcumgr", { log: true });
36
+ const _console = createConsole("mcumgr", { log: false });
37
37
 
38
38
  export const constants = {
39
39
  // Opcodes