brilliantsole 0.0.27 → 0.0.29

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 (202) hide show
  1. package/assets/3d/anchor.glb +0 -0
  2. package/assets/3d/coin.glb +0 -0
  3. package/assets/3d/glasses.glb +0 -0
  4. package/assets/audio/bounceMedium.wav +0 -0
  5. package/assets/audio/bounceStrong.wav +0 -0
  6. package/assets/audio/bounceWeak.wav +0 -0
  7. package/assets/audio/coin.wav +0 -0
  8. package/assets/audio/getUp.wav +0 -0
  9. package/assets/audio/grab.wav +0 -0
  10. package/assets/audio/kick.wav +0 -0
  11. package/assets/audio/platterFadeIn old.wav +0 -0
  12. package/assets/audio/platterFadeIn.wav +0 -0
  13. package/assets/audio/platterFadeOut.wav +0 -0
  14. package/assets/audio/punch.wav +0 -0
  15. package/assets/audio/punchSqueak.wav +0 -0
  16. package/assets/audio/purr.wav +0 -0
  17. package/assets/audio/purrFadeOut.wav +0 -0
  18. package/assets/audio/release.wav +0 -0
  19. package/assets/audio/splat.wav +0 -0
  20. package/assets/audio/stomp.wav +0 -0
  21. package/build/brilliantsole.cjs +3091 -741
  22. package/build/brilliantsole.cjs.map +1 -1
  23. package/build/brilliantsole.js +2759 -709
  24. package/build/brilliantsole.js.map +1 -1
  25. package/build/brilliantsole.ls.js +2602 -543
  26. package/build/brilliantsole.ls.js.map +1 -1
  27. package/build/brilliantsole.min.js +1 -1
  28. package/build/brilliantsole.min.js.map +1 -1
  29. package/build/brilliantsole.module.d.ts +295 -65
  30. package/build/brilliantsole.module.js +2749 -710
  31. package/build/brilliantsole.module.js.map +1 -1
  32. package/build/brilliantsole.module.min.d.ts +295 -65
  33. package/build/brilliantsole.module.min.js +1 -1
  34. package/build/brilliantsole.module.min.js.map +1 -1
  35. package/build/brilliantsole.node.module.d.ts +289 -62
  36. package/build/brilliantsole.node.module.js +3080 -742
  37. package/build/brilliantsole.node.module.js.map +1 -1
  38. package/build/dts/BS-output.d.ts +10 -0
  39. package/build/dts/BS.d.ts +21 -8
  40. package/build/dts/CameraManager.d.ts +72 -0
  41. package/build/dts/Device.d.ts +64 -13
  42. package/build/dts/DeviceInformationManager.d.ts +4 -4
  43. package/build/dts/DeviceManager.d.ts +2 -0
  44. package/build/dts/FileTransferManager.d.ts +18 -8
  45. package/build/dts/InformationManager.d.ts +2 -0
  46. package/build/dts/MicrophoneManager.d.ts +88 -0
  47. package/build/dts/TfliteManager.d.ts +22 -2
  48. package/build/dts/WifiManager.d.ts +61 -0
  49. package/build/dts/connection/BaseConnectionManager.d.ts +35 -3
  50. package/build/dts/connection/ClientConnectionManager.d.ts +7 -2
  51. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +2 -1
  52. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -0
  53. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  54. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  55. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  56. package/build/dts/devicePair/DevicePair.d.ts +5 -5
  57. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  58. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  59. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  60. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  61. package/build/dts/server/BaseClient.d.ts +5 -3
  62. package/build/dts/server/ServerUtils.d.ts +1 -1
  63. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  64. package/build/dts/utils/AudioUtils.d.ts +2 -0
  65. package/build/dts/utils/Console.d.ts +2 -0
  66. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  67. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  68. package/build/index.d.ts +292 -62
  69. package/build/index.node.d.ts +286 -59
  70. package/examples/3d/scene.html +19 -5
  71. package/examples/3d-generic/index.html +144 -0
  72. package/examples/3d-generic/script.js +266 -0
  73. package/examples/basic/index.html +267 -17
  74. package/examples/basic/script.js +958 -105
  75. package/examples/camera/barcode-detector.js +109 -0
  76. package/examples/camera/depth-estimation.js +71 -0
  77. package/examples/camera/face-detector.js +119 -0
  78. package/examples/camera/face-landmark.js +111 -0
  79. package/examples/camera/gesture-recognition.js +97 -0
  80. package/examples/camera/hand-landmark.js +74 -0
  81. package/examples/camera/image-segmentation.js +98 -0
  82. package/examples/camera/image-to-text.js +43 -0
  83. package/examples/camera/image-upscale.js +75 -0
  84. package/examples/camera/index.html +129 -0
  85. package/examples/camera/object-detection.js +98 -0
  86. package/examples/camera/pose-landmark.js +60 -0
  87. package/examples/camera/script.js +316 -0
  88. package/examples/camera/utils.js +165 -0
  89. package/examples/camera/yolo-tiny.js +54 -0
  90. package/examples/camera/yolo.js +119 -0
  91. package/examples/edge-impulse/script.js +157 -48
  92. package/examples/edge-impulse-test/README.md +11 -0
  93. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  94. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  95. package/examples/edge-impulse-test/index.html +75 -0
  96. package/examples/edge-impulse-test/run-impulse.js +135 -0
  97. package/examples/edge-impulse-test/script.js +200 -0
  98. package/examples/glasses-gestures/README.md +11 -0
  99. package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
  100. package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
  101. package/examples/glasses-gestures/index.html +69 -0
  102. package/examples/glasses-gestures/run-impulse.js +135 -0
  103. package/examples/glasses-gestures/script.js +226 -0
  104. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  105. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  106. package/examples/gloves/index.html +4 -1
  107. package/examples/gloves/run-impulse.js +135 -0
  108. package/examples/gloves/script.js +367 -51
  109. package/examples/graph/script.js +94 -37
  110. package/examples/microphone/gender.js +54 -0
  111. package/examples/microphone/index.html +102 -0
  112. package/examples/microphone/script.js +394 -0
  113. package/examples/microphone/utils.js +45 -0
  114. package/examples/microphone/whisper-realtime.js +166 -0
  115. package/examples/microphone/whisper.js +132 -0
  116. package/examples/punch/index.html +135 -0
  117. package/examples/punch/punch.tflite +0 -0
  118. package/examples/punch/script.js +169 -0
  119. package/examples/server/index.html +98 -22
  120. package/examples/server/script.js +317 -109
  121. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  122. package/examples/utils/aframe/aframe-master.min.js +2 -0
  123. package/examples/utils/aframe/bs-vibration.js +150 -0
  124. package/examples/utils/aframe/force-pushable.js +80 -0
  125. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  126. package/examples/utils/aframe/grabbable-listener.js +31 -0
  127. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  128. package/examples/utils/aframe/grow-shrink.js +25 -0
  129. package/examples/utils/aframe/hand-punch.js +119 -0
  130. package/examples/utils/aframe/my-obb-collider.js +293 -0
  131. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  132. package/examples/utils/aframe/occlude-mesh.js +42 -0
  133. package/examples/utils/aframe/palm-up-detector.js +47 -0
  134. package/examples/utils/aframe/shadow-material.js +20 -0
  135. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  136. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  137. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  138. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  139. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  140. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  141. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  142. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  143. package/examples/webxr-2/components/bs-ankle.js +337 -0
  144. package/examples/webxr-2/components/coin.js +84 -0
  145. package/examples/webxr-2/components/custom-wrap.js +17 -0
  146. package/examples/webxr-2/components/goomba.js +3250 -0
  147. package/examples/webxr-2/components/init-shell-material.js +215 -0
  148. package/examples/webxr-2/components/platter.js +172 -0
  149. package/examples/webxr-2/components/shell.js +374 -0
  150. package/examples/webxr-2/components/soccer-ball.js +250 -0
  151. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  152. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  153. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  154. package/examples/webxr-2/index.html +996 -0
  155. package/examples/webxr-2/kick.tflite +0 -0
  156. package/examples/webxr-2/kick2.tflite +0 -0
  157. package/examples/webxr-2/run-impulse.js +135 -0
  158. package/examples/webxr-2/script.js +384 -0
  159. package/examples/webxr-3/components/bs-camera.js +65 -0
  160. package/examples/webxr-3/index.html +134 -0
  161. package/examples/webxr-3/script.js +432 -0
  162. package/package.json +2 -1
  163. package/src/.prettierrc +4 -0
  164. package/src/BS.ts +79 -8
  165. package/src/CameraManager.ts +497 -0
  166. package/src/Device.ts +691 -86
  167. package/src/DeviceInformationManager.ts +19 -10
  168. package/src/DeviceManager.ts +85 -25
  169. package/src/FileTransferManager.ts +145 -20
  170. package/src/InformationManager.ts +40 -15
  171. package/src/MicrophoneManager.ts +599 -0
  172. package/src/TfliteManager.ts +171 -25
  173. package/src/WifiManager.ts +323 -0
  174. package/src/connection/BaseConnectionManager.ts +130 -30
  175. package/src/connection/ClientConnectionManager.ts +34 -10
  176. package/src/connection/bluetooth/BluetoothConnectionManager.ts +8 -2
  177. package/src/connection/bluetooth/NobleConnectionManager.ts +147 -41
  178. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +99 -34
  179. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  180. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  181. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  182. package/src/devicePair/DevicePair.ts +95 -25
  183. package/src/devicePair/DevicePairPressureSensorDataManager.ts +27 -7
  184. package/src/scanner/BaseScanner.ts +49 -11
  185. package/src/scanner/NobleScanner.ts +76 -14
  186. package/src/sensor/MotionSensorDataManager.ts +21 -6
  187. package/src/sensor/PressureSensorDataManager.ts +37 -8
  188. package/src/sensor/SensorConfigurationManager.ts +73 -22
  189. package/src/sensor/SensorDataManager.ts +109 -23
  190. package/src/server/BaseClient.ts +150 -36
  191. package/src/server/BaseServer.ts +50 -2
  192. package/src/server/ServerUtils.ts +39 -9
  193. package/src/server/udp/UDPServer.ts +73 -22
  194. package/src/server/udp/UDPUtils.ts +9 -2
  195. package/src/server/websocket/WebSocketClient.ts +27 -7
  196. package/src/server/websocket/WebSocketUtils.ts +4 -2
  197. package/src/utils/AudioUtils.ts +65 -0
  198. package/src/utils/Console.ts +62 -9
  199. package/src/utils/ParseUtils.ts +24 -5
  200. package/src/utils/ThrottleUtils.ts +62 -0
  201. package/src/utils/Timer.ts +1 -1
  202. package/src/vibration/VibrationManager.ts +166 -40
@@ -0,0 +1,75 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Browser inference demo</title>
6
+
7
+ <style>
8
+ #features {
9
+ width: 50%;
10
+ font-size: 18px;
11
+ }
12
+
13
+ #results {
14
+ font-family: monospace;
15
+ white-space: pre;
16
+ }
17
+ </style>
18
+ </head>
19
+ <body>
20
+ <nav>
21
+ <a href="../../">home</a>
22
+ </nav>
23
+
24
+ <h1></h1>
25
+
26
+ <button id="toggleConnection">connect</button>
27
+
28
+ <p>
29
+ <input type="text" id="features" placeholder="Paste your features here" />
30
+ </p>
31
+ <p>
32
+ <button id="run-inference">Run inference</button>
33
+ </p>
34
+ <p id="results"></p>
35
+
36
+ <script src="edge-impulse-standalone.js"></script>
37
+ <script src="run-impulse.js"></script>
38
+ <script src="./script.js" type="module"></script>
39
+ <script>
40
+ (async () => {
41
+ return;
42
+
43
+ var classifier = new EdgeImpulseClassifier();
44
+ await classifier.init();
45
+
46
+ let project = classifier.getProjectInfo();
47
+ document.querySelector("h1").textContent =
48
+ project.owner +
49
+ " / " +
50
+ project.name +
51
+ " (version " +
52
+ project.deploy_version +
53
+ ")";
54
+
55
+ document.querySelector("#run-inference").onclick = () => {
56
+ try {
57
+ let features = document
58
+ .querySelector("#features")
59
+ .value.split(",")
60
+ .map((x) => Number(x.trim()));
61
+ console.log("classify", features);
62
+ let res = classifier.classify(features);
63
+ document.querySelector("#results").textContent = JSON.stringify(
64
+ res,
65
+ null,
66
+ 4
67
+ );
68
+ } catch (ex) {
69
+ alert("Failed to classify: " + (ex.message || ex.toString()));
70
+ }
71
+ };
72
+ })();
73
+ </script>
74
+ </body>
75
+ </html>
@@ -0,0 +1,135 @@
1
+ // Classifier module
2
+ let classifierInitialized = false;
3
+ Module.onRuntimeInitialized = function() {
4
+ classifierInitialized = true;
5
+ };
6
+
7
+ class EdgeImpulseClassifier {
8
+ _initialized = false;
9
+
10
+ init() {
11
+ if (classifierInitialized === true) return Promise.resolve();
12
+
13
+ return new Promise((resolve) => {
14
+ Module.onRuntimeInitialized = () => {
15
+ classifierInitialized = true;
16
+ Module.init();
17
+ resolve();
18
+ };
19
+ });
20
+ }
21
+
22
+ getProjectInfo() {
23
+ if (!classifierInitialized) throw new Error('Module is not initialized');
24
+ return this._convertToOrdinaryJsObject(Module.get_project(), Module.emcc_classification_project_t.prototype);
25
+ }
26
+
27
+ classify(rawData, debug = false) {
28
+ if (!classifierInitialized) throw new Error('Module is not initialized');
29
+
30
+ const obj = this._arrayToHeap(rawData);
31
+ let ret = Module.run_classifier(obj.buffer.byteOffset, rawData.length, debug);
32
+ Module._free(obj.ptr);
33
+
34
+ if (ret.result !== 0) {
35
+ throw new Error('Classification failed (err code: ' + ret.result + ')');
36
+ }
37
+
38
+ return this._fillResultStruct(ret);
39
+ }
40
+
41
+ classifyContinuous(rawData, enablePerfCal = true) {
42
+ if (!classifierInitialized) throw new Error('Module is not initialized');
43
+
44
+ const obj = this._arrayToHeap(rawData);
45
+ let ret = Module.run_classifier_continuous(obj.buffer.byteOffset, rawData.length, false, enablePerfCal);
46
+ Module._free(obj.ptr);
47
+
48
+ if (ret.result !== 0) {
49
+ throw new Error('Classification failed (err code: ' + ret.result + ')');
50
+ }
51
+
52
+ return this._fillResultStruct(ret);
53
+ }
54
+
55
+ getProperties() {
56
+ if (!classifierInitialized) throw new Error('Module is not initialized');
57
+ return this._convertToOrdinaryJsObject(Module.get_properties(), Module.emcc_classification_properties_t.prototype);
58
+ }
59
+
60
+ /**
61
+ * Override the threshold on a learn block (you can find thresholds via getProperties().thresholds)
62
+ * @param {*} obj, e.g. { id: 16, min_score: 0.2 } to set min. object detection threshold to 0.2 for block ID 16
63
+ */
64
+ setThreshold(obj) {
65
+ const ret = Module.set_threshold(obj);
66
+ if (!ret.success) {
67
+ throw new Error(ret.error);
68
+ }
69
+ }
70
+
71
+ _arrayToHeap(data) {
72
+ let typedArray = new Float32Array(data);
73
+ let numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
74
+ let ptr = Module._malloc(numBytes);
75
+ let heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
76
+ heapBytes.set(new Uint8Array(typedArray.buffer));
77
+ return { ptr: ptr, buffer: heapBytes };
78
+ }
79
+
80
+ _convertToOrdinaryJsObject(emboundObj, prototype) {
81
+ let newObj = { };
82
+ for (const key of Object.getOwnPropertyNames(prototype)) {
83
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, key);
84
+
85
+ if (descriptor && typeof descriptor.get === 'function') {
86
+ newObj[key] = emboundObj[key]; // Evaluates the getter and assigns as an own property.
87
+ }
88
+ }
89
+ return newObj;
90
+ }
91
+
92
+ _fillResultStruct(ret) {
93
+ let props = Module.get_properties();
94
+
95
+ let jsResult = {
96
+ anomaly: ret.anomaly,
97
+ results: []
98
+ };
99
+
100
+ for (let cx = 0; cx < ret.size(); cx++) {
101
+ let c = ret.get(cx);
102
+ if (props.model_type === 'object_detection' || props.model_type === 'constrained_object_detection') {
103
+ jsResult.results.push({ label: c.label, value: c.value, x: c.x, y: c.y, width: c.width, height: c.height });
104
+ }
105
+ else {
106
+ jsResult.results.push({ label: c.label, value: c.value });
107
+ }
108
+ c.delete();
109
+ }
110
+
111
+ if (props.has_object_tracking) {
112
+ jsResult.object_tracking_results = [];
113
+ for (let cx = 0; cx < ret.object_tracking_size(); cx++) {
114
+ let c = ret.object_tracking_get(cx);
115
+ jsResult.object_tracking_results.push({ object_id: c.object_id, label: c.label, value: c.value, x: c.x, y: c.y, width: c.width, height: c.height });
116
+ c.delete();
117
+ }
118
+ }
119
+
120
+ if (props.has_visual_anomaly_detection) {
121
+ jsResult.visual_ad_max = ret.visual_ad_max;
122
+ jsResult.visual_ad_mean = ret.visual_ad_mean;
123
+ jsResult.visual_ad_grid_cells = [];
124
+ for (let cx = 0; cx < ret.visual_ad_grid_cells_size(); cx++) {
125
+ let c = ret.visual_ad_grid_cells_get(cx);
126
+ jsResult.visual_ad_grid_cells.push({ label: c.label, value: c.value, x: c.x, y: c.y, width: c.width, height: c.height });
127
+ c.delete();
128
+ }
129
+ }
130
+
131
+ ret.delete();
132
+
133
+ return jsResult;
134
+ }
135
+ }
@@ -0,0 +1,200 @@
1
+ import * as BS from "../../build/brilliantsole.module.js";
2
+ window.BS = BS;
3
+ console.log(BS);
4
+
5
+ // MODEL
6
+ var classifier = new EdgeImpulseClassifier();
7
+ await classifier.init();
8
+ window.classifier = classifier;
9
+
10
+ let project = classifier.getProjectInfo();
11
+ document.querySelector("h1").textContent =
12
+ project.owner +
13
+ " / " +
14
+ project.name +
15
+ " (version " +
16
+ project.deploy_version +
17
+ ")";
18
+
19
+ /** @param {number[]} features */
20
+ function classify(features) {
21
+ try {
22
+ let res = classifier.classify(features);
23
+ document.querySelector("#results").textContent = JSON.stringify(
24
+ res,
25
+ null,
26
+ 4
27
+ );
28
+ console.log(res);
29
+ const didPinch = res.results[1].value > 0.5;
30
+ if (didPinch) {
31
+ console.log("PINCH!");
32
+ lastTimeGestureRecognized = Date.now();
33
+ }
34
+ } catch (ex) {
35
+ alert("Failed to classify: " + (ex.message || ex.toString()));
36
+ }
37
+ }
38
+
39
+ // DEVICE
40
+
41
+ const device = new BS.Device();
42
+ console.log({ device });
43
+ window.device = device;
44
+
45
+ // CONNECT
46
+
47
+ const toggleConnectionButton = document.getElementById("toggleConnection");
48
+ toggleConnectionButton.addEventListener("click", () =>
49
+ device.toggleConnection()
50
+ );
51
+ device.addEventListener("connectionStatus", () => {
52
+ let disabled = false;
53
+ let innerText = device.connectionStatus;
54
+ switch (device.connectionStatus) {
55
+ case "notConnected":
56
+ innerText = "connect";
57
+ break;
58
+ case "connected":
59
+ innerText = "disconnect";
60
+ break;
61
+ }
62
+ toggleConnectionButton.disabled = disabled;
63
+ toggleConnectionButton.innerText = innerText;
64
+ });
65
+
66
+ // SENSOR CONFIG
67
+
68
+ const sensorRate = 20;
69
+ /** @type {BS.TfliteSensorType[]} */
70
+ const sensorTypes = ["linearAcceleration", "gyroscope"];
71
+ /** @type {BS.SensorConfiguration} */
72
+ const sensorConfiguration = {};
73
+ sensorTypes.forEach((sensorType) => {
74
+ sensorConfiguration[sensorType] = sensorRate;
75
+
76
+ device.addEventListener(sensorType, (event) => {
77
+ let data = [];
78
+ switch (event.message.sensorType) {
79
+ case "pressure":
80
+ data = event.message.pressure.sensors.map((sensor) => sensor.rawValue);
81
+ break;
82
+ case "linearAcceleration":
83
+ {
84
+ const { x, y, z } = event.message.linearAcceleration;
85
+ data = [x, y, z];
86
+ }
87
+ break;
88
+ case "gyroscope":
89
+ {
90
+ const { x, y, z } = event.message.gyroscope;
91
+ data = [x, y, z];
92
+ }
93
+ break;
94
+ case "magnetometer":
95
+ {
96
+ const { x, y, z } = event.message.magnetometer;
97
+ data = [x, y, z];
98
+ }
99
+ break;
100
+ }
101
+ data = data.map((value) => value * sensorScalars[sensorType]);
102
+ appendData(event.message.timestamp, sensorType, data);
103
+ });
104
+ });
105
+
106
+ device.addEventListener("connected", () => {
107
+ device.setSensorConfiguration(sensorConfiguration);
108
+ });
109
+
110
+ const sensorScalars = {
111
+ pressure: 1 / (2 ** 16 - 1),
112
+ linearAcceleration: 1 / 4,
113
+ gyroscope: 1 / 720,
114
+ magnetometer: 1 / 2500,
115
+ };
116
+
117
+ // BUFFER
118
+ const time = 600; // ms
119
+ const numberOfSamples = time / sensorRate;
120
+ const numberOfFeaturesInEachSensorType = {};
121
+ BS.TfliteSensorTypes.forEach((sensorType) => {
122
+ switch (sensorType) {
123
+ case "pressure":
124
+ numberOfFeaturesInEachSensorType[sensorType] = 8; // change to 16 for ukaton
125
+ break;
126
+ case "linearAcceleration":
127
+ case "gyroscope":
128
+ case "magnetometer":
129
+ numberOfFeaturesInEachSensorType[sensorType] = 3;
130
+ break;
131
+ }
132
+ });
133
+ let numberOfFeaturesInOneSample = 0;
134
+ sensorTypes.forEach((sensorType) => {
135
+ numberOfFeaturesInOneSample += numberOfFeaturesInEachSensorType[sensorType];
136
+ });
137
+ const numberOfFeatures = numberOfFeaturesInOneSample * numberOfSamples;
138
+ console.log({
139
+ time,
140
+ numberOfSamples,
141
+ numberOfFeaturesInOneSample,
142
+ numberOfFeatures,
143
+ });
144
+ const samples = [];
145
+ let pendingSample;
146
+ let lastTimeClassified = 0;
147
+ let lastTimeGestureRecognized = 0;
148
+ let classificationDelay = 0;
149
+ let gestureDelay = 500;
150
+ let isClassifying = false;
151
+ /**
152
+ * @param {number} timestamp
153
+ * @param {BS.TfliteSensorType} sensorType
154
+ * @param {number[]} data
155
+ */
156
+ function appendData(timestamp, sensorType, data) {
157
+ //console.log({ timestamp, sensorType, data });
158
+ if (!pendingSample || timestamp != pendingSample.timestamp) {
159
+ pendingSample = { timestamp };
160
+ //console.log("pendingSample", pendingSample);
161
+ }
162
+ pendingSample[sensorType] = data;
163
+ const gotAllSensorSamples = sensorTypes.every(
164
+ (sensorType) => sensorType in pendingSample
165
+ );
166
+ if (gotAllSensorSamples) {
167
+ //console.log("got all samples");
168
+ samples.push(pendingSample);
169
+ pendingSample = undefined;
170
+ }
171
+
172
+ //console.log(`collected ${samples.length} samples`);
173
+
174
+ while (samples.length > numberOfSamples) {
175
+ samples.shift();
176
+ }
177
+
178
+ if (!isClassifying && samples.length == numberOfSamples) {
179
+ const now = Date.now();
180
+ if (
181
+ now - lastTimeGestureRecognized < gestureDelay ||
182
+ now - lastTimeClassified < classificationDelay
183
+ ) {
184
+ return;
185
+ }
186
+ const features = [];
187
+ samples.forEach((sample) => {
188
+ const _features = [];
189
+ sensorTypes.forEach((sensorType) => {
190
+ _features.push(...sample[sensorType]);
191
+ features.push(..._features);
192
+ });
193
+ });
194
+ isClassifying = true;
195
+ console.log("classifying", features);
196
+ classify(features);
197
+ isClassifying = false;
198
+ lastTimeClassified = now;
199
+ }
200
+ }
@@ -0,0 +1,11 @@
1
+ # Running your impulse using WebAssembly in the browser
2
+
3
+ For more information see the documentation at https://docs.edgeimpulse.com/docs/through-webassembly-browser
4
+
5
+ To start, open a terminal or command prompt and run:
6
+
7
+ ```
8
+ $ python3 server.py
9
+ ```
10
+
11
+ Then open http://localhost:8082 in a browser to see the application.