gps-plus-slam-app-framework 1.4.0 → 1.8.0
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/dist/absolute-orientation-BAxc15J6.d.ts +54 -0
- package/dist/{accuracy-circles-Pi2YeCrM.d.ts → accuracy-circles-DkWBkF5g.d.ts} +16 -6
- package/dist/{app-selectors-CrOucL00.d.ts → app-selectors-JqydaUMN.d.ts} +1 -1
- package/dist/ar/bresenham3d.d.ts +1 -1
- package/dist/ar/camera-blit-capture.d.ts +1 -1
- package/dist/ar/capability-checker.d.ts +1 -1
- package/dist/ar/capture-failure-tracker.d.ts +1 -1
- package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
- package/dist/ar/depth-grid-lookup.d.ts +1 -1
- package/dist/ar/depth-occluder.d.ts +127 -0
- package/dist/ar/depth-occluder.js +299 -0
- package/dist/ar/depth-sampler.d.ts +2 -2
- package/dist/ar/depth-sampler.js +24 -4
- package/dist/ar/depth-unprojection.d.ts +1 -1
- package/dist/ar/depth-unprojection.js +52 -21
- package/dist/ar/enable-gps-ar.d.ts +1 -1
- package/dist/ar/enable-gps-ar.js +1 -1
- package/dist/ar/frame-loop.d.ts +1 -1
- package/dist/ar/frame-loop.js +12 -2
- package/dist/ar/image-capture.d.ts +2 -2
- package/dist/ar/image-capture.js +1 -154
- package/dist/ar/image-quality.d.ts +2 -0
- package/dist/ar/image-quality.js +169 -0
- package/dist/ar/index.d.ts +32 -30
- package/dist/ar/index.js +7 -5
- package/dist/ar/occlusion-mesh-worker.d.ts +58 -0
- package/dist/ar/occlusion-mesh-worker.js +129 -0
- package/dist/ar/occupancy-grid.d.ts +2 -2
- package/dist/ar/occupancy-grid.js +287 -31
- package/dist/ar/occupancy-mesher.d.ts +2 -0
- package/dist/ar/occupancy-mesher.js +638 -0
- package/dist/ar/planar-pnp.d.ts +1 -1
- package/dist/ar/qr-debug-view.d.ts +1 -1
- package/dist/ar/qr-derived-pose.d.ts +1 -1
- package/dist/ar/qr-detection-controller.d.ts +1 -1
- package/dist/ar/qr-frontend.d.ts +1 -1
- package/dist/ar/qr-pose.d.ts +1 -1
- package/dist/ar/qr-size-depth-context.d.ts +2 -2
- package/dist/ar/qr-size-measurer.d.ts +1 -1
- package/dist/ar/replay-scene.d.ts +1 -1
- package/dist/ar/replay-scene.js +1 -1
- package/dist/ar/scene-node-names.d.ts +1 -1
- package/dist/ar/webxr-nue-basis.d.ts +1 -1
- package/dist/ar/webxr-session.d.ts +4 -4
- package/dist/ar/webxr-session.js +2 -2
- package/dist/ar/xr-camera-texture.d.ts +1 -1
- package/dist/ar/xr-error-handler.d.ts +1 -1
- package/dist/ar/xr-frame-loop.d.ts +1 -1
- package/dist/ar/xr-frame-loop.js +12 -2
- package/dist/{ar-Dc72Ksiu.js → ar-BqCudtqE.js} +4 -3
- package/dist/{ar-world-group-alignment-DDLkgNf_.d.ts → ar-world-group-alignment-BlvGcIAk.d.ts} +1 -1
- package/dist/capture-motion-gate-BGoAMkmf.d.ts +24 -0
- package/dist/capture-motion-gate-_NdTSwKi.js +106 -0
- package/dist/cell-key-DIB4rOTV.js +51 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/{create-slam-app-store-Ce2FMKCp.d.ts → create-slam-app-store-D3nzh9Wb.d.ts} +50 -40
- package/dist/create-slam-app-store-DXiAnJwR.js +156 -0
- package/dist/{depth-grid-lookup-vMDrGTk_.d.ts → depth-grid-lookup-D5atpNZ3.d.ts} +1 -1
- package/dist/{depth-sampler-DwfPYzS7.d.ts → depth-sampler-CwObAwEA.d.ts} +33 -1
- package/dist/{depth-unprojection-CK3b9htH.d.ts → depth-unprojection-DRdBU90S.d.ts} +1 -1
- package/dist/{enable-gps-ar-CjZ1nEdu.d.ts → enable-gps-ar-DvGzBOrp.d.ts} +4 -4
- package/dist/{frame-conversions-D_Af8Dt3.d.ts → frame-conversions-C4bnNOEY.d.ts} +1 -1
- package/dist/{fused-path-C0FHe67t.d.ts → fused-path-C5pp0PJU.d.ts} +1 -1
- package/dist/geo/h3-proximity.d.ts +1 -1
- package/dist/geo/index.d.ts +1 -1
- package/dist/geodesic-angle-BTldfFgs.js +39 -0
- package/dist/{gps-anchor-C6I9NDHA.d.ts → gps-anchor-BjECcYnD.d.ts} +1 -1
- package/dist/{gps-ar-pose-sampler-DaHg2aPZ.d.ts → gps-ar-pose-sampler-DEGNk2CI.d.ts} +1 -1
- package/dist/{gps-event-coordinator-C7hwHyLA.d.ts → gps-event-coordinator-CHtIkhb7.d.ts} +21 -11
- package/dist/{image-capture-C2Feywet.d.ts → image-capture-Bp6Pd4Md.d.ts} +103 -3
- package/dist/image-capture-DVcuqMtX.js +374 -0
- package/dist/image-quality-BMx2ko9-.d.ts +158 -0
- package/dist/index-D4vrgV4b.d.ts +2 -0
- package/dist/index-D74JTX4I.d.ts +22 -0
- package/dist/{index-m_LneUSi.d.ts → index-DlsOo2IB.d.ts} +1 -1
- package/dist/{index-BvLo2poy.d.ts → index-cCQWuYqy.d.ts} +3 -3
- package/dist/index.d.ts +82 -77
- package/dist/index.js +15 -10
- package/dist/{leaflet-map-overlay-bnb2U1NQ.d.ts → leaflet-map-overlay-BOZFW5kT.d.ts} +64 -10
- package/dist/leaflet-map-overlay-CBWPvaX9.js +452 -0
- package/dist/lerp-utils-Qs8OhumS.d.ts +42 -0
- package/dist/map-data-D7rpMC6f.js +120 -0
- package/dist/{map-data-DdjPiSav.d.ts → map-data-PNfGKGWx.d.ts} +22 -2
- package/dist/{map-overlay-draw-CPVdAsFq.d.ts → map-overlay-draw-DiroaJed.d.ts} +1 -1
- package/dist/{null-storage-backend-CuSdYFsM.d.ts → null-storage-backend-B1-jlpin.d.ts} +2 -2
- package/dist/occlusion-mesh-b28lRJ6S.d.ts +194 -0
- package/dist/occupancy-grid-BV7RhB7I.d.ts +194 -0
- package/dist/occupancy-mesher-C2ecWhNp.d.ts +100 -0
- package/dist/{opfs-storage-DMtlt57S.d.ts → opfs-storage-CTkxvxN4.d.ts} +5 -0
- package/dist/{opfs-storage-backend-CeQAb0SD.d.ts → opfs-storage-backend-D6Z03fML.d.ts} +2 -2
- package/dist/{persistence-middleware-5eearhSV.d.ts → persistence-middleware-CG-t08X4.d.ts} +1 -1
- package/dist/{planar-pnp-cjthe7Be.d.ts → planar-pnp-D7bc_rLX.d.ts} +1 -1
- package/dist/{qr-debug-view-B8gTzjMm.d.ts → qr-debug-view-BJooqbiP.d.ts} +1 -1
- package/dist/{qr-derived-pose-DinKE600.d.ts → qr-derived-pose-BwNWn8oV.d.ts} +2 -2
- package/dist/{qr-detected-slice-Cpv-dg82.d.ts → qr-detected-slice-TzVb8bij.d.ts} +4 -4
- package/dist/{qr-detection-controller-Cd2Ih4cC.d.ts → qr-detection-controller-Bo4XfQTP.d.ts} +3 -3
- package/dist/{qr-frontend-DufZp2xS.d.ts → qr-frontend-BPURlh3S.d.ts} +1 -1
- package/dist/{qr-pose-aggregation-CFlmLm6w.d.ts → qr-pose-aggregation-CypnmjA-.d.ts} +1 -1
- package/dist/{qr-pose-aggregation-DXR9STHs.js → qr-pose-aggregation-DBiaLW0O.js} +1 -10
- package/dist/{qr-size-depth-context-onu36E9s.d.ts → qr-size-depth-context-apAOmbrZ.d.ts} +2 -2
- package/dist/{qr-size-measurer-D7739ZpB.d.ts → qr-size-measurer-DxiMqRUw.d.ts} +3 -3
- package/dist/recording-options-vASCFzc5.d.ts +667 -0
- package/dist/{recording-replayer-CUEK82tM.d.ts → recording-replayer-D0V9WkmY.d.ts} +2 -2
- package/dist/{recording-slice-B-uCgGoh.d.ts → recording-slice-DTUtSVgd.d.ts} +2 -2
- package/dist/{replay-engine-BSVd7Zzb.d.ts → replay-engine-xdrUgWJi.d.ts} +1 -1
- package/dist/{replay-scene-CPt56pps.d.ts → replay-scene-zJ8SFDjE.d.ts} +3 -3
- package/dist/sensors/absolute-orientation.d.ts +2 -0
- package/dist/sensors/absolute-orientation.js +162 -0
- package/dist/sensors/gps-error-handler.d.ts +1 -1
- package/dist/sensors/gps.d.ts +1 -1
- package/dist/sensors/index.d.ts +5 -4
- package/dist/sensors/index.js +2 -1
- package/dist/sensors/permission-checker.d.ts +1 -1
- package/dist/state/app-selectors.d.ts +1 -1
- package/dist/state/combined-root-state.d.ts +1 -1
- package/dist/state/create-slam-app-store.d.ts +1 -1
- package/dist/state/create-slam-app-store.js +1 -74
- package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
- package/dist/state/gps-event-coordinator.d.ts +2 -2
- package/dist/state/gps-event-coordinator.js +27 -17
- package/dist/state/index.d.ts +20 -20
- package/dist/state/index.js +4 -4
- package/dist/state/persistence-middleware.d.ts +1 -1
- package/dist/state/persistence-middleware.js +30 -19
- package/dist/state/qr-detected-slice.d.ts +3 -3
- package/dist/state/qr-detected-slice.js +1 -1
- package/dist/state/recording-options.d.ts +2 -2
- package/dist/state/recording-options.js +286 -25
- package/dist/state/recording-replayer.d.ts +2 -2
- package/dist/state/recording-replayer.js +1 -1
- package/dist/state/recording-slice.d.ts +1 -1
- package/dist/state/replay-engine.d.ts +1 -1
- package/dist/state/store-subscribers.d.ts +2 -2
- package/dist/state/store-subscribers.js +2 -1
- package/dist/state/subscribe-to-selector.d.ts +1 -1
- package/dist/state/tracking-quality.d.ts +2 -2
- package/dist/state/tracking-quality.js +49 -128
- package/dist/state/tracking-slice.d.ts +1 -1
- package/dist/{state-IEw0ZsBu.js → state-BeKvn4B-.js} +1 -1
- package/dist/storage/file-system-utils.d.ts +1 -1
- package/dist/storage/index.d.ts +8 -8
- package/dist/storage/null-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage.d.ts +1 -1
- package/dist/storage/opfs-storage.js +25 -1
- package/dist/storage/storage-backend.d.ts +1 -1
- package/dist/storage/zip-coverage-embed.d.ts +1 -1
- package/dist/storage/zip-export.d.ts +1 -1
- package/dist/storage/zip-reader.d.ts +1 -1
- package/dist/{storage-backend-CTJHNdMp.d.ts → storage-backend-sEtmM4yW.d.ts} +1 -1
- package/dist/{store-subscribers-BZP81hjh.d.ts → store-subscribers-DScA7tdT.d.ts} +2 -2
- package/dist/{subscribe-to-selector-Bp3sLx8L.d.ts → subscribe-to-selector-B9ylM5Oh.d.ts} +1 -1
- package/dist/test-utils/browser-mocks.d.ts +1 -1
- package/dist/test-utils/zip-round-trip-helpers.d.ts +1 -1
- package/dist/{tracking-slice-DJZ9qeGg.d.ts → tracking-slice-DMkHlbny.d.ts} +1 -1
- package/dist/types/ar-types.d.ts +1 -1
- package/dist/types/geo-types.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/utils/concurrency.d.ts +1 -1
- package/dist/utils/failure-tracker.d.ts +1 -1
- package/dist/utils/format-file-size.d.ts +1 -1
- package/dist/utils/fused-path.d.ts +1 -1
- package/dist/utils/index.d.ts +8 -7
- package/dist/utils/index.js +2 -1
- package/dist/utils/list-formatter.d.ts +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/visualization/accuracy-circles.d.ts +1 -1
- package/dist/visualization/accuracy-circles.js +17 -8
- package/dist/visualization/alignment-lerper.d.ts +1 -1
- package/dist/visualization/ar-world-group-alignment.d.ts +1 -1
- package/dist/visualization/ar-world-group-alignment.js +1 -1
- package/dist/visualization/camera-follower.d.ts +1 -1
- package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
- package/dist/visualization/frame-conversions.d.ts +1 -1
- package/dist/visualization/frustum-visibility.d.ts +1 -1
- package/dist/visualization/gps-anchor.d.ts +1 -1
- package/dist/visualization/gps-compass-cubes.d.ts +1 -1
- package/dist/visualization/gps-event-markers.d.ts +1 -1
- package/dist/visualization/gps-event-markers.js +1 -1
- package/dist/visualization/hit-test-reticle.d.ts +1 -1
- package/dist/visualization/index.d.ts +20 -19
- package/dist/visualization/index.js +4 -3
- package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
- package/dist/visualization/leaflet-map-overlay.js +1 -282
- package/dist/visualization/lerp-utils.d.ts +2 -2
- package/dist/visualization/lerp-utils.js +27 -3
- package/dist/visualization/map-data.d.ts +1 -1
- package/dist/visualization/map-data.js +1 -32
- package/dist/visualization/map-overlay-draw.d.ts +1 -1
- package/dist/visualization/map-overlay-draw.js +24 -2
- package/dist/visualization/map-overlay.d.ts +1 -1
- package/dist/visualization/occluder-mesh-driver.d.ts +130 -0
- package/dist/visualization/occluder-mesh-driver.js +219 -0
- package/dist/visualization/occlusion-mesh.d.ts +2 -0
- package/dist/visualization/occlusion-mesh.js +437 -0
- package/dist/visualization/three-dispose.d.ts +1 -1
- package/dist/visualization/vis-colors.d.ts +1 -1
- package/dist/{webxr-session-CJF9Nijp.js → webxr-session-BCP2XK7k.js} +110 -14
- package/dist/{webxr-session-COsOjJwn.d.ts → webxr-session-cRG2SYAQ.d.ts} +83 -10
- package/package.json +4 -4
- package/dist/index-eaI1Z1KR.d.ts +0 -2
- package/dist/lerp-utils-kLxMJ2Xj.d.ts +0 -20
- package/dist/occupancy-grid-Bvi2Gw1U.d.ts +0 -82
- package/dist/recording-options-D93kksJU.d.ts +0 -369
- /package/dist/{alignment-lerper-BUTsQ2yu.d.ts → alignment-lerper-gD70k7Fq.d.ts} +0 -0
- /package/dist/{ar-types-BckI1E-O.d.ts → ar-types-Cc5yvBwn.d.ts} +0 -0
- /package/dist/{bresenham3d-ByjcmEgM.d.ts → bresenham3d-DGc4nIb-.d.ts} +0 -0
- /package/dist/{camera-blit-capture-CqWe1G7s.d.ts → camera-blit-capture-BimSdyih.d.ts} +0 -0
- /package/dist/{camera-follower-BTb2Yp12.d.ts → camera-follower-DfBm2J5i.d.ts} +0 -0
- /package/dist/{capability-checker-CXqoJYtb.d.ts → capability-checker-BTTpygvZ.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-BL5SoG2a.d.ts → capture-failure-tracker-_BVfhpxv.d.ts} +0 -0
- /package/dist/{chromium-camera-access-workaround-BNK189P0.d.ts → chromium-camera-access-workaround-C6yJLXz9.d.ts} +0 -0
- /package/dist/{concurrency-DqAlKX4j.d.ts → concurrency-DPeGBH0X.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-m-ab19vp.d.ts → css3d-renderer-manager-CPpVtvgs.d.ts} +0 -0
- /package/dist/{failure-tracker-Cnc_xWUw.d.ts → failure-tracker-CeKf5HIc.d.ts} +0 -0
- /package/dist/{file-system-utils-Bs7lpeVP.d.ts → file-system-utils-DueXHxo9.d.ts} +0 -0
- /package/dist/{format-file-size-BFUWvir1.d.ts → format-file-size-DxN-EBLc.d.ts} +0 -0
- /package/dist/{frame-loop-BEO9_q3k.d.ts → frame-loop-7GBMBu68.d.ts} +0 -0
- /package/dist/{frustum-visibility-D_RGmH98.d.ts → frustum-visibility-CokkgS_i.d.ts} +0 -0
- /package/dist/{geo-types-DqiBzPO9.d.ts → geo-types-DrGVu8nS.d.ts} +0 -0
- /package/dist/{gps-C5inWeNV.d.ts → gps-CDKDQokE.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-BExxrWJ-.d.ts → gps-compass-cubes-1mooS3BS.d.ts} +0 -0
- /package/dist/{gps-error-handler-C2bS69oJ.d.ts → gps-error-handler-C34GQuTu.d.ts} +0 -0
- /package/dist/{gps-event-markers-Dd0G2bD0.d.ts → gps-event-markers-Di2nBzx-.d.ts} +0 -0
- /package/dist/{h3-proximity-B57C6rYL.d.ts → h3-proximity-D0GTHQmr.d.ts} +0 -0
- /package/dist/{hit-test-reticle-Dqak9hiR.d.ts → hit-test-reticle-CaQbrhbk.d.ts} +0 -0
- /package/dist/{list-formatter-ct8txwvR.d.ts → list-formatter-DLFDnS70.d.ts} +0 -0
- /package/dist/{logger-CzQrCe6C.d.ts → logger-CqTd5Kpk.d.ts} +0 -0
- /package/dist/{map-overlay-Dci4yvm3.d.ts → map-overlay-BCQgvIgU.d.ts} +0 -0
- /package/dist/{permission-checker-CtPtPQRq.d.ts → permission-checker-B-VtjnBA.d.ts} +0 -0
- /package/dist/{qr-pose-Bt2reSw7.d.ts → qr-pose-y3vaEd6x.d.ts} +0 -0
- /package/dist/{scene-node-names-CdNeQjOE.d.ts → scene-node-names-CGb-ylBd.d.ts} +0 -0
- /package/dist/{session-disposers-D8wnO-uW.js → session-disposers-BPrMplIC.js} +0 -0
- /package/dist/{three-dispose-BCZkSJp2.d.ts → three-dispose-BMOAmPhb.d.ts} +0 -0
- /package/dist/{vis-colors-BZsSLI4i.d.ts → vis-colors-C7HI0u9_.d.ts} +0 -0
- /package/dist/{webxr-nue-basis-CW1wsbm6.d.ts → webxr-nue-basis-CaCnYxuq.d.ts} +0 -0
- /package/dist/{xr-camera-texture-BmrP7iNZ.d.ts → xr-camera-texture-q0eIDSRg.d.ts} +0 -0
- /package/dist/{xr-error-handler-BEjRgZjt.d.ts → xr-error-handler-uVGDu9IX.d.ts} +0 -0
- /package/dist/{xr-frame-loop-K8ebdjLw.d.ts → xr-frame-loop-DX3JPpAU.d.ts} +0 -0
- /package/dist/{zip-coverage-embed-tFohI2J4.d.ts → zip-coverage-embed-ncVbaZAz.d.ts} +0 -0
- /package/dist/{zip-export-DDWXInTR.d.ts → zip-export-CtiUnAlJ.d.ts} +0 -0
- /package/dist/{zip-reader-Q2ue6zlC.d.ts → zip-reader-CvruaGvD.d.ts} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as geodesicAngleRad } from "../geodesic-angle-BTldfFgs.js";
|
|
2
|
+
import { selectTrackingPhase } from "./tracking-slice.js";
|
|
2
3
|
import { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectZeroReference } from "./app-selectors.js";
|
|
3
4
|
import { calcGpsCoords, distanceInMeters } from "gps-plus-slam-js";
|
|
4
5
|
import { mat4, quat, vec3 } from "gl-matrix";
|
|
@@ -13,19 +14,15 @@ const DEFAULT_TRACKING_QUALITY_OPTIONS = {
|
|
|
13
14
|
coverageDirectionSpreadDeg: 90,
|
|
14
15
|
convergenceRotationWarnDeg: 6,
|
|
15
16
|
convergenceTranslationWarnM: 2,
|
|
16
|
-
compassWarnDeg: 15,
|
|
17
|
-
compassFailDeg: 35,
|
|
18
17
|
warmupMinObservations: 10,
|
|
19
18
|
warmupMinCoverage: .5,
|
|
20
19
|
residualConfidenceTargetM: 3,
|
|
21
20
|
gpsAccuracyFloorM: 1,
|
|
22
|
-
firstAgreementMinStreak: 3,
|
|
23
21
|
degradedHoldoff: 3,
|
|
24
22
|
convergenceEmaAlpha: .3
|
|
25
23
|
};
|
|
26
24
|
const initialState = {
|
|
27
25
|
recentAlignments: [],
|
|
28
|
-
firstAgreementObservationIndex: null,
|
|
29
26
|
report: null,
|
|
30
27
|
degradedConsecutiveCount: 0,
|
|
31
28
|
smoothedConvergence: null
|
|
@@ -47,11 +44,6 @@ function emaBlend(prev, raw, alpha) {
|
|
|
47
44
|
if (prev === null) return raw;
|
|
48
45
|
return prev + (Number.isFinite(alpha) ? alpha : 1) * (raw - prev);
|
|
49
46
|
}
|
|
50
|
-
function wrapToHalfCircle(deg) {
|
|
51
|
-
let d = (deg + 180) % 360 - 180;
|
|
52
|
-
if (d < -180) d += 360;
|
|
53
|
-
return d;
|
|
54
|
-
}
|
|
55
47
|
function bearingDeg(north, east) {
|
|
56
48
|
let deg = Math.atan2(east, north) * 180 / Math.PI;
|
|
57
49
|
if (deg < 0) deg += 360;
|
|
@@ -88,6 +80,20 @@ function rampUp(value, low, high) {
|
|
|
88
80
|
return (value - low) / (high - low);
|
|
89
81
|
}
|
|
90
82
|
/**
|
|
83
|
+
* True iff the matrix is well-formed: exactly 16 elements, all finite (no
|
|
84
|
+
* NaN/Infinity). The length check matters because `computeConvergence` scores a
|
|
85
|
+
* pair as corrupt (fail side) only when this returns false; without it a finite
|
|
86
|
+
* but wrong-length snapshot (`AlignmentSnapshot.matrix` is typed `number[]`,
|
|
87
|
+
* not a 16-tuple) would slip past here, then hit `matrixDelta`'s own length
|
|
88
|
+
* guard which returns ZERO deltas = "perfectly stable" — inflating the score
|
|
89
|
+
* instead of degrading it (the same trap the non-finite guard avoids).
|
|
90
|
+
*/
|
|
91
|
+
function isFiniteMatrix(m) {
|
|
92
|
+
if (m.length !== 16) return false;
|
|
93
|
+
for (let i = 0; i < m.length; i++) if (!Number.isFinite(m[i])) return false;
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
91
97
|
* §4.1 matrix-history convergence over the buffered snapshots.
|
|
92
98
|
*
|
|
93
99
|
* Reuses the same kernel idea as `computeStabilityDelta` from the
|
|
@@ -118,7 +124,15 @@ function computeConvergence(snapshots, options = {}) {
|
|
|
118
124
|
let sumTransM = 0;
|
|
119
125
|
let pairCount = 0;
|
|
120
126
|
for (let i = 1; i < snapshots.length; i++) {
|
|
121
|
-
const
|
|
127
|
+
const prevM = snapshots[i - 1].matrix;
|
|
128
|
+
const currM = snapshots[i].matrix;
|
|
129
|
+
if (!isFiniteMatrix(prevM) || !isFiniteMatrix(currM)) {
|
|
130
|
+
sumRotDeg += rotFail;
|
|
131
|
+
sumTransM += transFail;
|
|
132
|
+
pairCount += 1;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const { rotationDeltaDeg, translationDeltaM } = matrixDelta(prevM, currM);
|
|
122
136
|
sumRotDeg += Math.abs(rotationDeltaDeg);
|
|
123
137
|
sumTransM += Math.abs(translationDeltaM);
|
|
124
138
|
pairCount += 1;
|
|
@@ -137,7 +151,8 @@ function computeConvergence(snapshots, options = {}) {
|
|
|
137
151
|
* the column-major layout that gl-matrix and the framework use.
|
|
138
152
|
*
|
|
139
153
|
* Rotation: extract the orientation quaternion with `mat4.getRotation`
|
|
140
|
-
* and compute the relative angle via `
|
|
154
|
+
* and compute the relative angle via the shared `geodesicAngleRad` kernel
|
|
155
|
+
* (radians, converted to degrees here).
|
|
141
156
|
* Translation: extract the origin column with `mat4.getTranslation` and
|
|
142
157
|
* compute the Euclidean distance.
|
|
143
158
|
*
|
|
@@ -161,15 +176,16 @@ function matrixDelta(prev, curr) {
|
|
|
161
176
|
mat4.getRotation(currQuat, currMat);
|
|
162
177
|
quat.normalize(prevQuat, prevQuat);
|
|
163
178
|
quat.normalize(currQuat, currQuat);
|
|
164
|
-
const angleRad =
|
|
165
|
-
const rotationDeltaDeg = Number.
|
|
179
|
+
const angleRad = geodesicAngleRad(prevQuat, currQuat);
|
|
180
|
+
const rotationDeltaDeg = Number.isFinite(angleRad) ? angleRad * 180 / Math.PI : 0;
|
|
166
181
|
const prevT = vec3.create();
|
|
167
182
|
const currT = vec3.create();
|
|
168
183
|
mat4.getTranslation(prevT, prevMat);
|
|
169
184
|
mat4.getTranslation(currT, currMat);
|
|
185
|
+
const rawTranslation = vec3.distance(prevT, currT);
|
|
170
186
|
return {
|
|
171
187
|
rotationDeltaDeg,
|
|
172
|
-
translationDeltaM:
|
|
188
|
+
translationDeltaM: Number.isFinite(rawTranslation) ? rawTranslation : 0
|
|
173
189
|
};
|
|
174
190
|
}
|
|
175
191
|
/**
|
|
@@ -319,56 +335,6 @@ function computeCoverage(odometryPositions, options = {}) {
|
|
|
319
335
|
};
|
|
320
336
|
}
|
|
321
337
|
/**
|
|
322
|
-
* §4.3 — Compare the alignment matrix's mapping of AR-forward to ENU
|
|
323
|
-
* against the device compass heading. Returns `score = null` whenever
|
|
324
|
-
* the sensor's `absolute !== true` so the aggregate excludes the
|
|
325
|
-
* sub-score (per Q2 in the plan).
|
|
326
|
-
*
|
|
327
|
-
* AR-forward in our `ARPose` convention is `(0, 0, -1)` (right-handed,
|
|
328
|
-
* Y-up). We rotate that by the alignment's 3×3 rotation, take its
|
|
329
|
-
* North/East components, and compare against the compass alpha.
|
|
330
|
-
*/
|
|
331
|
-
function computeCompassAgreement(alignmentMatrix, sensorOrientation, arPose, options = {}) {
|
|
332
|
-
const warn = options.warnDeg ?? DEFAULT_TRACKING_QUALITY_OPTIONS.compassWarnDeg;
|
|
333
|
-
const fail = options.failDeg ?? DEFAULT_TRACKING_QUALITY_OPTIONS.compassFailDeg;
|
|
334
|
-
if (!alignmentMatrix || !sensorOrientation || !arPose) return {
|
|
335
|
-
score: null,
|
|
336
|
-
headingDeltaDeg: null
|
|
337
|
-
};
|
|
338
|
-
if (sensorOrientation.absolute !== true) return {
|
|
339
|
-
score: null,
|
|
340
|
-
headingDeltaDeg: null
|
|
341
|
-
};
|
|
342
|
-
const q = arPose.orientation;
|
|
343
|
-
const fx = 0;
|
|
344
|
-
const fy = 0;
|
|
345
|
-
const fz = -1;
|
|
346
|
-
const x = q.x, y = q.y, z = q.z, w = q.w;
|
|
347
|
-
const tx = 2 * (y * fz - z * fy);
|
|
348
|
-
const ty = 2 * (z * fx - x * fz);
|
|
349
|
-
const tz = 2 * (x * fy - y * fx);
|
|
350
|
-
const arForwardLocal = [
|
|
351
|
-
fx + w * tx + (y * tz - z * ty),
|
|
352
|
-
fy + w * ty + (z * tx - x * tz),
|
|
353
|
-
fz + w * tz + (x * ty - y * tx)
|
|
354
|
-
];
|
|
355
|
-
const m = alignmentMatrix;
|
|
356
|
-
const enuN = m[0] * arForwardLocal[0] + m[4] * arForwardLocal[1] + m[8] * arForwardLocal[2];
|
|
357
|
-
m[1] * arForwardLocal[0] + m[5] * arForwardLocal[1] + m[9] * arForwardLocal[2];
|
|
358
|
-
const enuE = m[2] * arForwardLocal[0] + m[6] * arForwardLocal[1] + m[10] * arForwardLocal[2];
|
|
359
|
-
if (Math.hypot(enuN, enuE) < 1e-6) return {
|
|
360
|
-
score: null,
|
|
361
|
-
headingDeltaDeg: null
|
|
362
|
-
};
|
|
363
|
-
const alignmentHeadingDeg = bearingDeg(enuN, enuE);
|
|
364
|
-
const compassHeadingDeg = sensorOrientation.alpha;
|
|
365
|
-
const delta = Math.abs(wrapToHalfCircle(alignmentHeadingDeg - compassHeadingDeg));
|
|
366
|
-
return {
|
|
367
|
-
score: rampDown(delta, warn, fail),
|
|
368
|
-
headingDeltaDeg: delta
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
338
|
* §4.6 — Maximum lateral distance between raw GPS positions and the
|
|
373
339
|
* positions you would predict by transforming the matching odometry
|
|
374
340
|
* positions through the current alignment. Diagnostic only — never
|
|
@@ -418,9 +384,6 @@ const trackingQualitySlice = createSlice({
|
|
|
418
384
|
reportUpdated(state, action) {
|
|
419
385
|
state.report = action.payload;
|
|
420
386
|
},
|
|
421
|
-
firstAgreementReached(state, action) {
|
|
422
|
-
state.firstAgreementObservationIndex = action.payload;
|
|
423
|
-
},
|
|
424
387
|
/** §4.8 — update the hysteresis counter for ok → degraded holdoff. */
|
|
425
388
|
degradedCountUpdated(state, action) {
|
|
426
389
|
state.degradedConsecutiveCount = action.payload;
|
|
@@ -439,7 +402,7 @@ const trackingQualitySlice = createSlice({
|
|
|
439
402
|
}
|
|
440
403
|
}
|
|
441
404
|
});
|
|
442
|
-
const { snapshotPushed, snapshotsTrimmed, reportUpdated,
|
|
405
|
+
const { snapshotPushed, snapshotsTrimmed, reportUpdated, degradedCountUpdated, resetTrackingQuality } = trackingQualitySlice.actions;
|
|
443
406
|
const { smoothedConvergenceUpdated } = trackingQualitySlice.actions;
|
|
444
407
|
const trackingQualityReducer = trackingQualitySlice.reducer;
|
|
445
408
|
function selectTrackingQuality(state) {
|
|
@@ -448,9 +411,6 @@ function selectTrackingQuality(state) {
|
|
|
448
411
|
function selectRecentAlignments(state) {
|
|
449
412
|
return state.trackingQuality?.recentAlignments ?? EMPTY_SNAPSHOTS;
|
|
450
413
|
}
|
|
451
|
-
function selectFirstAgreementObservationIndex(state) {
|
|
452
|
-
return state.trackingQuality?.firstAgreementObservationIndex ?? null;
|
|
453
|
-
}
|
|
454
414
|
const EMPTY_SNAPSHOTS = Object.freeze([]);
|
|
455
415
|
/**
|
|
456
416
|
* Pure function — produces a {@link TrackingQualityReport} from a root
|
|
@@ -474,10 +434,7 @@ function computeTrackingQualityReport(rootState, options = {}) {
|
|
|
474
434
|
const odometryPositions = selectOdometryPositions(rootState);
|
|
475
435
|
const zeroRef = selectZeroReference(rootState);
|
|
476
436
|
const trackingPhase = selectTrackingPhase(rootState);
|
|
477
|
-
const sensorOrientation = selectLastSensorOrientation(rootState);
|
|
478
|
-
const lastPose = selectLastValidPose(rootState);
|
|
479
437
|
const snapshots = selectRecentAlignments(rootState);
|
|
480
|
-
const firstAgreementIdx = selectFirstAgreementObservationIndex(rootState);
|
|
481
438
|
const coverage = computeCoverage(odometryPositions, {
|
|
482
439
|
walkedDistanceM: opts.coverageWalkedDistanceM,
|
|
483
440
|
directionSpreadDeg: opts.coverageDirectionSpreadDeg
|
|
@@ -492,15 +449,10 @@ function computeTrackingQualityReport(rootState, options = {}) {
|
|
|
492
449
|
rotationWarnDeg: opts.convergenceRotationWarnDeg,
|
|
493
450
|
translationWarnM: opts.convergenceTranslationWarnM
|
|
494
451
|
});
|
|
495
|
-
const compass = computeCompassAgreement(alignmentMatrix, sensorOrientation, lastPose, {
|
|
496
|
-
warnDeg: opts.compassWarnDeg,
|
|
497
|
-
failDeg: opts.compassFailDeg
|
|
498
|
-
});
|
|
499
452
|
const gpsVsFusedMaxDivergenceM = computeGpsVsFusedDivergence(alignmentMatrix, gpsPositions, odometryPositions, zeroRef);
|
|
500
453
|
const subScores = {
|
|
501
454
|
convergence: clamp01(emaBlend(rootState.trackingQuality?.smoothedConvergence ?? null, convergence.score, opts.convergenceEmaAlpha)),
|
|
502
455
|
residualConsensus: clamp01(residual.score),
|
|
503
|
-
compassAgreement: compass.score === null ? null : clamp01(compass.score),
|
|
504
456
|
gpsAccuracy: clamp01(gpsAccuracy.score),
|
|
505
457
|
coverage: clamp01(coverage.score)
|
|
506
458
|
};
|
|
@@ -510,7 +462,6 @@ function computeTrackingQualityReport(rootState, options = {}) {
|
|
|
510
462
|
subScores.gpsAccuracy,
|
|
511
463
|
subScores.coverage
|
|
512
464
|
];
|
|
513
|
-
if (subScores.compassAgreement !== null) aggregateInputs.push(subScores.compassAgreement);
|
|
514
465
|
const confidence = clamp01(Math.min(...aggregateInputs));
|
|
515
466
|
const observationsSeen = gpsPositions.length;
|
|
516
467
|
let state;
|
|
@@ -529,8 +480,6 @@ function computeTrackingQualityReport(rootState, options = {}) {
|
|
|
529
480
|
medianRecentGpsAccuracyM: gpsAccuracy.medianM,
|
|
530
481
|
walkedDistanceM: coverage.walkedDistanceM,
|
|
531
482
|
directionSpreadDeg: coverage.directionSpreadDeg,
|
|
532
|
-
headingDeltaDeg: compass.headingDeltaDeg,
|
|
533
|
-
compassDriftDetected: firstAgreementIdx !== null && compass.headingDeltaDeg !== null && compass.headingDeltaDeg > opts.compassWarnDeg,
|
|
534
483
|
observationsSeen,
|
|
535
484
|
gpsVsFusedMaxDivergenceM
|
|
536
485
|
}
|
|
@@ -540,15 +489,14 @@ function computeTrackingQualityReport(rootState, options = {}) {
|
|
|
540
489
|
* Per-field tolerances for the {@link reportsEqual} dispatch gate.
|
|
541
490
|
*
|
|
542
491
|
* Why this exists: `tracking/poseReceived` fires on *every* XR frame
|
|
543
|
-
* (30–60 fps). The
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
* quality actually moved.
|
|
492
|
+
* (30–60 fps). The per-frame recompute reuses GPS/odometry windows that
|
|
493
|
+
* are unchanged between pose frames, so the float sub-scores and
|
|
494
|
+
* diagnostics (and `confidence`) jitter by imperceptible floating-point
|
|
495
|
+
* amounts on a held-still device. With a strict `!==` comparison every
|
|
496
|
+
* such frame produced a fresh `reportUpdated` dispatch → high Redux
|
|
497
|
+
* churn and a HUD re-render at frame rate. The tolerances below quantise
|
|
498
|
+
* those sub-perceptual changes so the gate only fires when the
|
|
499
|
+
* user-visible quality actually moved.
|
|
552
500
|
*
|
|
553
501
|
* The gate compares the freshly computed report against the *last
|
|
554
502
|
* dispatched* report (the stored `prev`), not against the previous
|
|
@@ -567,10 +515,9 @@ const REPORT_METRE_EPSILON_M = .001;
|
|
|
567
515
|
* (both `null` ⇒ equal; exactly one `null` ⇒ different) and otherwise
|
|
568
516
|
* compares with an absolute epsilon. Non-finite values are compared with
|
|
569
517
|
* {@link Object.is}, so a genuine finite↔NaN/Infinity transition still
|
|
570
|
-
* fires a dispatch, but a *persistently* NaN diagnostic
|
|
571
|
-
*
|
|
572
|
-
* `
|
|
573
|
-
* `Object.is(NaN, NaN)` is `true` whereas `NaN === NaN` is `false`.
|
|
518
|
+
* fires a dispatch, but a *persistently* NaN diagnostic does NOT churn
|
|
519
|
+
* the gate every frame — `Object.is(NaN, NaN)` is `true` whereas
|
|
520
|
+
* `NaN === NaN` is `false`.
|
|
574
521
|
*/
|
|
575
522
|
function nearlyEqual(a, b, eps) {
|
|
576
523
|
if (a === null || b === null) return a === b;
|
|
@@ -585,8 +532,8 @@ function nearlyEqual(a, b, eps) {
|
|
|
585
532
|
*
|
|
586
533
|
* Float fields use the per-field tolerances above
|
|
587
534
|
* ({@link REPORT_SCORE_EPSILON} et al.) so imperceptible per-frame
|
|
588
|
-
*
|
|
589
|
-
*
|
|
535
|
+
* jitter does not churn the store — see the constants' doc comment for
|
|
536
|
+
* the rationale.
|
|
590
537
|
*/
|
|
591
538
|
function reportsEqual(a, b) {
|
|
592
539
|
if (a === b) return true;
|
|
@@ -595,10 +542,10 @@ function reportsEqual(a, b) {
|
|
|
595
542
|
if (!nearlyEqual(a.confidence, b.confidence, REPORT_SCORE_EPSILON)) return false;
|
|
596
543
|
const sa = a.subScores;
|
|
597
544
|
const sb = b.subScores;
|
|
598
|
-
if (!nearlyEqual(sa.convergence, sb.convergence, REPORT_SCORE_EPSILON) || !nearlyEqual(sa.residualConsensus, sb.residualConsensus, REPORT_SCORE_EPSILON) || !nearlyEqual(sa.
|
|
545
|
+
if (!nearlyEqual(sa.convergence, sb.convergence, REPORT_SCORE_EPSILON) || !nearlyEqual(sa.residualConsensus, sb.residualConsensus, REPORT_SCORE_EPSILON) || !nearlyEqual(sa.gpsAccuracy, sb.gpsAccuracy, REPORT_SCORE_EPSILON) || !nearlyEqual(sa.coverage, sb.coverage, REPORT_SCORE_EPSILON)) return false;
|
|
599
546
|
const da = a.diagnostics;
|
|
600
547
|
const db = b.diagnostics;
|
|
601
|
-
return da.
|
|
548
|
+
return da.observationsSeen === db.observationsSeen && nearlyEqual(da.recentSumRotationDeltaDeg, db.recentSumRotationDeltaDeg, REPORT_ANGLE_EPSILON_DEG) && nearlyEqual(da.directionSpreadDeg, db.directionSpreadDeg, REPORT_ANGLE_EPSILON_DEG) && nearlyEqual(da.recentSumTranslationDeltaM, db.recentSumTranslationDeltaM, REPORT_METRE_EPSILON_M) && nearlyEqual(da.medianResidualM, db.medianResidualM, REPORT_METRE_EPSILON_M) && nearlyEqual(da.medianRecentGpsAccuracyM, db.medianRecentGpsAccuracyM, REPORT_METRE_EPSILON_M) && nearlyEqual(da.walkedDistanceM, db.walkedDistanceM, REPORT_METRE_EPSILON_M) && nearlyEqual(da.gpsVsFusedMaxDivergenceM, db.gpsVsFusedMaxDivergenceM, REPORT_METRE_EPSILON_M);
|
|
602
549
|
}
|
|
603
550
|
function matricesNearlyEqual(a, b) {
|
|
604
551
|
if (a.length !== b.length) return false;
|
|
@@ -650,16 +597,14 @@ function createTrackingQualityListenerMiddleware(options = {}) {
|
|
|
650
597
|
...DEFAULT_TRACKING_QUALITY_OPTIONS,
|
|
651
598
|
...options
|
|
652
599
|
};
|
|
653
|
-
let compassStreak = 0;
|
|
654
600
|
const listenerMiddleware = createListenerMiddleware();
|
|
655
601
|
listenerMiddleware.startListening({
|
|
656
602
|
predicate: (action) => inputActionPredicate(action),
|
|
657
603
|
effect: (action, api) => {
|
|
658
604
|
const state = api.getState();
|
|
659
605
|
if (action.type === TRACKING_QUALITY_INPUT_ACTIONS.startSession || action.type === TRACKING_QUALITY_INPUT_ACTIONS.resetTracking) {
|
|
660
|
-
compassStreak = 0;
|
|
661
606
|
const tq = state.trackingQuality;
|
|
662
|
-
if (tq && (tq.recentAlignments.length > 0 || tq.
|
|
607
|
+
if (tq && (tq.recentAlignments.length > 0 || tq.report !== null || tq.degradedConsecutiveCount > 0)) api.dispatch(resetTrackingQuality());
|
|
663
608
|
return;
|
|
664
609
|
}
|
|
665
610
|
if (action.type === TRACKING_QUALITY_INPUT_ACTIONS.gpsRecorded || action.type === TRACKING_QUALITY_INPUT_ACTIONS.setZeroPos) {
|
|
@@ -678,30 +623,6 @@ function createTrackingQualityListenerMiddleware(options = {}) {
|
|
|
678
623
|
}
|
|
679
624
|
}
|
|
680
625
|
}
|
|
681
|
-
const midState = api.getState();
|
|
682
|
-
const midTq = midState.trackingQuality;
|
|
683
|
-
if (midTq && midTq.firstAgreementObservationIndex === null) {
|
|
684
|
-
const snapshots = selectRecentAlignments(midState);
|
|
685
|
-
if (snapshots.length >= 2) {
|
|
686
|
-
const conv = computeConvergence(snapshots, {
|
|
687
|
-
rotationWarnDeg: opts.convergenceRotationWarnDeg,
|
|
688
|
-
translationWarnM: opts.convergenceTranslationWarnM
|
|
689
|
-
});
|
|
690
|
-
const sensorOr = selectLastSensorOrientation(midState);
|
|
691
|
-
const pose = selectLastValidPose(midState);
|
|
692
|
-
const compass = computeCompassAgreement(selectAlignmentMatrix(midState), sensorOr, pose, {
|
|
693
|
-
warnDeg: opts.compassWarnDeg,
|
|
694
|
-
failDeg: opts.compassFailDeg
|
|
695
|
-
});
|
|
696
|
-
if (conv.score >= .7 && compass.headingDeltaDeg !== null && compass.headingDeltaDeg <= opts.compassWarnDeg) {
|
|
697
|
-
compassStreak += 1;
|
|
698
|
-
if (compassStreak >= opts.firstAgreementMinStreak) {
|
|
699
|
-
const obsCount = selectGpsPositions(midState).length;
|
|
700
|
-
api.dispatch(firstAgreementReached(obsCount));
|
|
701
|
-
}
|
|
702
|
-
} else compassStreak = 0;
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
626
|
const next = api.getState();
|
|
706
627
|
const report = computeTrackingQualityReport(next, opts);
|
|
707
628
|
const prev = next.trackingQuality?.report ?? null;
|
|
@@ -720,4 +641,4 @@ function createTrackingQualityListenerMiddleware(options = {}) {
|
|
|
720
641
|
return listenerMiddleware.middleware;
|
|
721
642
|
}
|
|
722
643
|
//#endregion
|
|
723
|
-
export { DEFAULT_TRACKING_QUALITY_OPTIONS,
|
|
644
|
+
export { DEFAULT_TRACKING_QUALITY_OPTIONS, computeConvergence, computeCoverage, computeGpsAccuracy, computeGpsVsFusedDivergence, computeResidualConsensus, computeTrackingQualityReport, createTrackingQualityListenerMiddleware, degradedCountUpdated, matrixDelta, reportUpdated, resetTrackingQuality, selectRecentAlignments, selectTrackingQuality, snapshotPushed, snapshotsTrimmed, trackingQualityReducer };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TrackingSliceState, c as poseLost, d as selectLastRestartedPayload, f as selectLastSensorOrientation, g as trackingReducer, h as selectTrackingPhase, i as TrackingPhase, l as poseReceived, m as selectLostFrameCount, n as PoseReceivedPayload, o as clearLastRestartedPayload, p as selectLastValidPose, r as ResetTransformData, s as originReset, t as DeviceOrientation, u as resetTracking } from "../tracking-slice-
|
|
1
|
+
import { a as TrackingSliceState, c as poseLost, d as selectLastRestartedPayload, f as selectLastSensorOrientation, g as trackingReducer, h as selectTrackingPhase, i as TrackingPhase, l as poseReceived, m as selectLostFrameCount, n as PoseReceivedPayload, o as clearLastRestartedPayload, p as selectLastValidPose, r as ResetTransformData, s as originReset, t as DeviceOrientation, u as resetTracking } from "../tracking-slice-DMkHlbny.js";
|
|
2
2
|
export { DeviceOrientation, PoseReceivedPayload, ResetTransformData, TrackingPhase, TrackingSliceState, clearLastRestartedPayload, originReset, poseLost, poseReceived, resetTracking, selectLastRestartedPayload, selectLastSensorOrientation, selectLastValidPose, selectLostFrameCount, selectTrackingPhase, trackingReducer };
|
|
@@ -7,7 +7,7 @@ import "./state/gps-ar-pose-sampler.js";
|
|
|
7
7
|
import "./state/app-selectors.js";
|
|
8
8
|
import { selectTrackingQuality } from "./state/tracking-quality.js";
|
|
9
9
|
import "./state/persistence-middleware.js";
|
|
10
|
-
import "./
|
|
10
|
+
import "./create-slam-app-store-DXiAnJwR.js";
|
|
11
11
|
import "./state/recording-replayer.js";
|
|
12
12
|
import "./state/store-subscribers.js";
|
|
13
13
|
import { add2dImage, calcRelativeCoordsInMeters, recordGpsEvent as recordGpsEvent$1, setZeroPos as setZeroPos$1 } from "gps-plus-slam-js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatTimestamp, i as formatFrameFilename, n as SESSION_IMAGES_DIR, r as formatActionFilename, t as LEGACY_SESSION_IMAGES_DIR } from "../file-system-utils-
|
|
1
|
+
import { a as formatTimestamp, i as formatFrameFilename, n as SESSION_IMAGES_DIR, r as formatActionFilename, t as LEGACY_SESSION_IMAGES_DIR } from "../file-system-utils-DueXHxo9.js";
|
|
2
2
|
export { LEGACY_SESSION_IMAGES_DIR, SESSION_IMAGES_DIR, formatActionFilename, formatFrameFilename, formatTimestamp };
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, n as SessionMetadata, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "../opfs-storage-
|
|
2
|
-
import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-
|
|
3
|
-
import { a as ZipActionEntry, c as loadEntriesFromSubdir, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, o as ZipSubdirEntry, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip, t as Entry, u as loadSessionMetadata } from "../zip-reader-
|
|
4
|
-
import { t as NullStorageBackend } from "../null-storage-backend-
|
|
5
|
-
import { t as OpfsStorageBackend } from "../opfs-storage-backend-
|
|
6
|
-
import { a as formatTimestamp, i as formatFrameFilename, r as formatActionFilename } from "../file-system-utils-
|
|
7
|
-
import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportSessionAsZip, r as ZipExportContributor, s as exportSessionHandleAsZip, t as ExportSessionAsZipOptions } from "../zip-export-
|
|
8
|
-
import { t as embedCoverageInSessionJson } from "../zip-coverage-embed-
|
|
1
|
+
import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, n as SessionMetadata, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "../opfs-storage-CTkxvxN4.js";
|
|
2
|
+
import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-sEtmM4yW.js";
|
|
3
|
+
import { a as ZipActionEntry, c as loadEntriesFromSubdir, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, o as ZipSubdirEntry, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip, t as Entry, u as loadSessionMetadata } from "../zip-reader-CvruaGvD.js";
|
|
4
|
+
import { t as NullStorageBackend } from "../null-storage-backend-B1-jlpin.js";
|
|
5
|
+
import { t as OpfsStorageBackend } from "../opfs-storage-backend-D6Z03fML.js";
|
|
6
|
+
import { a as formatTimestamp, i as formatFrameFilename, r as formatActionFilename } from "../file-system-utils-DueXHxo9.js";
|
|
7
|
+
import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportSessionAsZip, r as ZipExportContributor, s as exportSessionHandleAsZip, t as ExportSessionAsZipOptions } from "../zip-export-CtiUnAlJ.js";
|
|
8
|
+
import { t as embedCoverageInSessionJson } from "../zip-coverage-embed-ncVbaZAz.js";
|
|
9
9
|
export { type CreateSessionResult, type Entry, type ExportSessionAsZipOptions, type GpsPathCoord, MAX_ACTION_FILE_SIZE, NullStorageBackend, OpfsStorageBackend, type RecordedAction, type SessionMetadata, type StorageBackend, type ZipActionEntry, type ZipContributorAddFile, type ZipExportContributor, type ZipExportResult, type ZipSubdirEntry, checkStorageQuota, createSession, downloadZip, embedCoverageInSessionJson, exportSessionAsZip, exportSessionHandleAsZip, formatActionFilename, formatFrameFilename, formatTimestamp, getAppRootHandle, getSessionHandle, getSessionsRootHandle, initOpfsStorage, listSessions, loadActionsFromZip, loadEntriesFromSubdir, loadGpsPathFromBlob, loadSessionMetadataFromBlob, loadSessionMetadata as loadSessionMetadataFromZip, readZipEntries, resetOpfsStorage, resetSessionHandles, syncToExternalZip, writeSessionMetadata };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as NullStorageBackend } from "../null-storage-backend-
|
|
1
|
+
import { t as NullStorageBackend } from "../null-storage-backend-B1-jlpin.js";
|
|
2
2
|
export { NullStorageBackend };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as OpfsStorageBackend } from "../opfs-storage-backend-
|
|
1
|
+
import { t as OpfsStorageBackend } from "../opfs-storage-backend-D6Z03fML.js";
|
|
2
2
|
export { OpfsStorageBackend };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, f as setSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, m as writeFrame, n as SessionMetadata, o as getSessionHandle, p as writeAction, r as checkStorageQuota, s as getSessionsRootHandle, t as CreateSessionResult, u as resetOpfsStorage } from "../opfs-storage-
|
|
1
|
+
import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, f as setSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, m as writeFrame, n as SessionMetadata, o as getSessionHandle, p as writeAction, r as checkStorageQuota, s as getSessionsRootHandle, t as CreateSessionResult, u as resetOpfsStorage } from "../opfs-storage-CTkxvxN4.js";
|
|
2
2
|
export { CreateSessionResult, SessionMetadata, checkStorageQuota, createSession, getAppRootHandle, getSessionHandle, getSessionsRootHandle, initOpfsStorage, listSessions, resetOpfsStorage, resetSessionHandles, setSessionHandles, writeAction, writeFrame, writeSessionMetadata };
|
|
@@ -89,6 +89,19 @@ function getAppRootHandle() {
|
|
|
89
89
|
return gpsPlusSlamDir;
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
+
* True when a session directory named `name` already exists under `dir`.
|
|
93
|
+
* Used by {@link createSession} to avoid silently reusing a directory when two
|
|
94
|
+
* recordings start within the same (second-resolution) timestamp.
|
|
95
|
+
*/
|
|
96
|
+
async function sessionDirExists(dir, name) {
|
|
97
|
+
try {
|
|
98
|
+
await dir.getDirectoryHandle(name, { create: false });
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
92
105
|
* Create a new recording session.
|
|
93
106
|
*
|
|
94
107
|
* Creates the directory structure:
|
|
@@ -96,6 +109,11 @@ function getAppRootHandle() {
|
|
|
96
109
|
* - /gps-plus-slam/sessions/recording-{timestamp}/actions/
|
|
97
110
|
* - /gps-plus-slam/sessions/recording-{timestamp}/images/ (legacy: frames/)
|
|
98
111
|
*
|
|
112
|
+
* The folder name is `recording-{timestamp}` at whole-second resolution; if a
|
|
113
|
+
* directory with that name already exists (two recordings started in the same
|
|
114
|
+
* UTC second), a numeric suffix (`-2`, `-3`, …) is appended so the new session
|
|
115
|
+
* never silently reuses and corrupts the earlier one's directory.
|
|
116
|
+
*
|
|
99
117
|
* @param timestamp - Session start time (used for folder naming)
|
|
100
118
|
* @param _contextTag - Opaque tag; not used by the flat layout but accepted
|
|
101
119
|
* for interface compatibility with wrapping backends
|
|
@@ -104,7 +122,13 @@ function getAppRootHandle() {
|
|
|
104
122
|
*/
|
|
105
123
|
async function createSession(timestamp, _contextTag) {
|
|
106
124
|
if (!sessionsDir) throw new Error("OPFS storage not initialized. Call initOpfsStorage first.");
|
|
107
|
-
const
|
|
125
|
+
const baseName = `recording-${formatTimestamp(timestamp)}`;
|
|
126
|
+
let sessionName = baseName;
|
|
127
|
+
let suffix = 1;
|
|
128
|
+
while (await sessionDirExists(sessionsDir, sessionName)) {
|
|
129
|
+
suffix += 1;
|
|
130
|
+
sessionName = `${baseName}-${suffix}`;
|
|
131
|
+
}
|
|
108
132
|
currentSessionHandle = await sessionsDir.getDirectoryHandle(sessionName, { create: true });
|
|
109
133
|
actionsHandle = await currentSessionHandle.getDirectoryHandle("actions", { create: true });
|
|
110
134
|
framesHandle = await currentSessionHandle.getDirectoryHandle(SESSION_IMAGES_DIR, { create: true });
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-
|
|
1
|
+
import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-sEtmM4yW.js";
|
|
2
2
|
export { CreateSessionResult, StorageBackend };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as embedCoverageInSessionJson } from "../zip-coverage-embed-
|
|
1
|
+
import { t as embedCoverageInSessionJson } from "../zip-coverage-embed-ncVbaZAz.js";
|
|
2
2
|
export { embedCoverageInSessionJson };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportSessionAsZip, r as ZipExportContributor, s as exportSessionHandleAsZip, t as ExportSessionAsZipOptions } from "../zip-export-
|
|
1
|
+
import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportSessionAsZip, r as ZipExportContributor, s as exportSessionHandleAsZip, t as ExportSessionAsZipOptions } from "../zip-export-CtiUnAlJ.js";
|
|
2
2
|
export { ExportSessionAsZipOptions, ZipContributorAddFile, ZipExportContributor, ZipExportResult, downloadZip, exportSessionAsZip, exportSessionHandleAsZip, syncToExternalZip };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ZipActionEntry, c as loadEntriesFromSubdir, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, o as ZipSubdirEntry, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip, t as Entry, u as loadSessionMetadata } from "../zip-reader-
|
|
1
|
+
import { a as ZipActionEntry, c as loadEntriesFromSubdir, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, o as ZipSubdirEntry, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip, t as Entry, u as loadSessionMetadata } from "../zip-reader-CvruaGvD.js";
|
|
2
2
|
export { Entry, GpsPathCoord, MAX_ACTION_FILE_SIZE, RecordedAction, ZipActionEntry, ZipSubdirEntry, loadActionsFromZip, loadEntriesFromSubdir, loadGpsPathFromBlob, loadSessionMetadata, loadSessionMetadataFromBlob, readZipEntries };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as MapData } from "./map-data-
|
|
2
|
-
import { t as SubscribableStore } from "./subscribe-to-selector-
|
|
1
|
+
import { t as MapData } from "./map-data-PNfGKGWx.js";
|
|
2
|
+
import { t as SubscribableStore } from "./subscribe-to-selector-B9ylM5Oh.js";
|
|
3
3
|
import { LatLong, Matrix4, Quaternion, Vector3 } from "gps-plus-slam-js";
|
|
4
4
|
|
|
5
5
|
//#region ../src/state/store-subscribers.d.ts
|
package/dist/types/ar-types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as RgbTuple, i as DepthSample, n as ArPoseTuples, o as WebXRQuaternion, r as DepthPoint, s as WebXRVec3, t as ARPose } from "../ar-types-
|
|
1
|
+
import { a as RgbTuple, i as DepthSample, n as ArPoseTuples, o as WebXRQuaternion, r as DepthPoint, s as WebXRVec3, t as ARPose } from "../ar-types-Cc5yvBwn.js";
|
|
2
2
|
export { ARPose, ArPoseTuples, DepthPoint, DepthSample, RgbTuple, WebXRQuaternion, WebXRVec3 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-
|
|
1
|
+
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-DrGVu8nS.js";
|
|
2
2
|
export { GpsCoord, RawGpsSample, RefPointMarker };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as RgbTuple, i as DepthSample, n as ArPoseTuples, o as WebXRQuaternion, r as DepthPoint, s as WebXRVec3, t as ARPose } from "../ar-types-
|
|
2
|
-
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-
|
|
1
|
+
import { a as RgbTuple, i as DepthSample, n as ArPoseTuples, o as WebXRQuaternion, r as DepthPoint, s as WebXRVec3, t as ARPose } from "../ar-types-Cc5yvBwn.js";
|
|
2
|
+
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-DrGVu8nS.js";
|
|
3
3
|
export { ARPose, ArPoseTuples, DepthPoint, DepthSample, GpsCoord, RawGpsSample, RefPointMarker, RgbTuple, WebXRQuaternion, WebXRVec3 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as mapWithConcurrencyLimit, t as forEachWithConcurrencyLimit } from "../concurrency-
|
|
1
|
+
import { n as mapWithConcurrencyLimit, t as forEachWithConcurrencyLimit } from "../concurrency-DPeGBH0X.js";
|
|
2
2
|
export { forEachWithConcurrencyLimit, mapWithConcurrencyLimit };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-
|
|
1
|
+
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-CeKf5HIc.js";
|
|
2
2
|
export { FailureTracker, FailureTrackerConfig, createFailureTracker };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as formatFileSize } from "../format-file-size-
|
|
1
|
+
import { t as formatFileSize } from "../format-file-size-DxN-EBLc.js";
|
|
2
2
|
export { formatFileSize };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-
|
|
1
|
+
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-C5pp0PJU.js";
|
|
2
2
|
export { FusedPathInput, computeFusedPath, fusedGpsFromOdom };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-
|
|
2
|
-
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-
|
|
3
|
-
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-
|
|
4
|
-
import { n as mapWithConcurrencyLimit } from "../concurrency-
|
|
5
|
-
import { t as
|
|
6
|
-
import { t as
|
|
7
|
-
|
|
1
|
+
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-CqTd5Kpk.js";
|
|
2
|
+
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-C5pp0PJU.js";
|
|
3
|
+
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-CeKf5HIc.js";
|
|
4
|
+
import { n as mapWithConcurrencyLimit } from "../concurrency-DPeGBH0X.js";
|
|
5
|
+
import { t as geodesicAngleRad } from "../index-D74JTX4I.js";
|
|
6
|
+
import { t as formatFileSize } from "../format-file-size-DxN-EBLc.js";
|
|
7
|
+
import { t as listFormatter } from "../list-formatter-DLFDnS70.js";
|
|
8
|
+
export { FailureTracker, FailureTrackerConfig, FusedPathInput, LogEntry, LogLevel, Logger, clearLogBuffer, computeFusedPath, createFailureTracker, createLogger, formatFileSize, fusedGpsFromOdom, geodesicAngleRad, getGlobalLogLevel, getLogBuffer, listFormatter, mapWithConcurrencyLimit, setGlobalLogLevel, subscribeToLogs };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LogLevel, clearLogBuffer, createLogger, getGlobalLogLevel, getLogBuffer, setGlobalLogLevel, subscribeToLogs } from "./logger.js";
|
|
2
2
|
import { createFailureTracker } from "./failure-tracker.js";
|
|
3
|
+
import { t as geodesicAngleRad } from "../geodesic-angle-BTldfFgs.js";
|
|
3
4
|
import { computeFusedPath, fusedGpsFromOdom } from "./fused-path.js";
|
|
4
5
|
import { mapWithConcurrencyLimit } from "./concurrency.js";
|
|
5
6
|
import { formatFileSize } from "./format-file-size.js";
|
|
6
7
|
import { listFormatter } from "./list-formatter.js";
|
|
7
|
-
export { LogLevel, clearLogBuffer, computeFusedPath, createFailureTracker, createLogger, formatFileSize, fusedGpsFromOdom, getGlobalLogLevel, getLogBuffer, listFormatter, mapWithConcurrencyLimit, setGlobalLogLevel, subscribeToLogs };
|
|
8
|
+
export { LogLevel, clearLogBuffer, computeFusedPath, createFailureTracker, createLogger, formatFileSize, fusedGpsFromOdom, geodesicAngleRad, getGlobalLogLevel, getLogBuffer, listFormatter, mapWithConcurrencyLimit, setGlobalLogLevel, subscribeToLogs };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as listFormatter } from "../list-formatter-
|
|
1
|
+
import { t as listFormatter } from "../list-formatter-DLFDnS70.js";
|
|
2
2
|
export { listFormatter };
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-
|
|
1
|
+
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-CqTd5Kpk.js";
|
|
2
2
|
export { LogEntry, LogLevel, Logger, clearLogBuffer, createLogger, getGlobalLogLevel, getLogBuffer, setGlobalLogLevel, subscribeToLogs };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as addAccuracyCircles, i as AccuracyCircleSample, n as ACCURACY_CIRCLE_STROKE_OPACITY, r as ACCURACY_CIRCLE_WEIGHT, t as ACCURACY_CIRCLE_FILL_OPACITY } from "../accuracy-circles-
|
|
1
|
+
import { a as addAccuracyCircles, i as AccuracyCircleSample, n as ACCURACY_CIRCLE_STROKE_OPACITY, r as ACCURACY_CIRCLE_WEIGHT, t as ACCURACY_CIRCLE_FILL_OPACITY } from "../accuracy-circles-DkWBkF5g.js";
|
|
2
2
|
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, AccuracyCircleSample, addAccuracyCircles };
|