@wemap/providers 11.3.2 → 11.4.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/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/events/Types.ts","../src/ProvidersOptions.ts","../src/events/ProvidersLoggerOld.ts","../src/errors/ContainsIgnoredProviderError.ts","../src/providers/Provider.ts","../src/events/AvailabilityHelper.ts","../src/errors/AskImuOnDesktopError.ts","../src/errors/MissingSensorError.ts","../src/errors/MissingMagnetometerError.ts","../src/errors/GeolocationApiMissingError.ts","../src/errors/GeolocationPermissionDeniedError.ts","../src/errors/GeolocationPositionUnavailableError.ts","../src/providers/Constants.ts","../src/providers/position/absolute/GnssWifiProvider.ts","../src/errors/MissingArCoreError.ts","../src/errors/MissingNativeInterfaceError.ts","../src/providers/vision/ArCoreProvider.ts","../src/providers/position/relative/GeoRelativePositionFromArCoreProvider.ts","../src/providers/attitude/EkfAttitude.ts","../src/providers/imu/ImuProvider.ts","../src/errors/MissingAccelerometerError.ts","../src/providers/imu/AccelerometerProvider.ts","../src/errors/MissingGyroscopeError.ts","../src/providers/imu/GyroscopeProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromEkfProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromBrowserProvider.ts","../src/providers/imu/HighRotationsProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.ts","../src/providers/steps/StepDetectionLadetto.ts","../src/providers/steps/StepDetectionMinMaxPeaks.ts","../src/providers/steps/StepDetectionMinMaxPeaks2.ts","../src/providers/steps/StepDetectionMinMaxPeaks3.ts","../src/providers/steps/StepProvider.ts","../src/providers/position/relative/PdrProvider.ts","../src/providers/position/relative/GeoRelativePositionProvider.ts","../src/providers/inclination/InclinationFromAccProvider.ts","../src/providers/inclination/InclinationFromRelativeAttitudeProvider.ts","../src/providers/inclination/InclinationProvider.ts","../src/providers/vision/vps/VpsMetadata.ts","../src/providers/vision/vps/VpsRequest.ts","../src/providers/vision/vps/VpsResponse.ts","../src/providers/vision/vps/ImageRelocalization.ts","../src/providers/vision/vps/RelativeRotationCalc.ts","../src/errors/MissingPoleStarError.ts","../src/providers/position/absolute/PoleStarProvider.ts","../src/providers/vision/vps/VpsProvider.ts","../src/providers/position/absolute/AbsolutePositionProvider.ts","../src/providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.ts","../src/providers/attitude/relative/RelativeAttitudeProvider.ts","../src/providers/attitude/absolute/AbsoluteAttitudeProvider.ts","../src/providers/attitude/TurnProvider.ts","../src/providers/steps/StraightLineProvider.ts","../src/mapmatching/MapMatchingHandler.ts","../src/smoothers/PositionSmoother.ts","../src/smoothers/AttitudeSmoother.ts","../src/providers/imu/MagnetometerCalibrationProvider.ts","../src/errors/IpResolveServerError.ts","../src/providers/position/absolute/IpProvider.ts","../src/providers/vision/BarcodeProvider.ts","../src/providers/others/CameraNativeProvider.ts","../src/providers/others/CameraProjectionMatrixProvider.ts"],"sourcesContent":["import { Attitude, UserPosition } from \"@wemap/geo\";\nimport { Vector16_t, Vector3_t } from \"@wemap/maths\";\n\nexport type Acceleration = Readonly<{ readonly timestamp: number; readonly values: Vector3_t; }>\nexport type AngularRate = Readonly<{ readonly timestamp: number; readonly values: Vector3_t; }>\nexport type HighRotation = Readonly<{ readonly timestamp: number; }>\nexport type MagnetometerNeedCalibration = Readonly<{ readonly angle: number; }>\nexport class RelativeAttitude extends Attitude { }\nexport class AbsoluteAttitude extends Attitude { }\nexport class AbsolutePosition extends UserPosition { }\nexport type Inclination = number;\nexport type Barcode = string;\nexport type Step = { readonly size: number; readonly number: number; }\nexport type Turn = { readonly timestamp: number; }\nexport type StraightLine = boolean;\nexport type CameraProjectionMatrix = Vector16_t;\nexport type CameraNativeState = 'started' | 'stopped';\n\n","const ProvidersOptions = {\n\n /**\n * Does provider will use map to\n */\n useMapMatching: true,\n\n /**\n * Providers listed here will not be used by the system\n * List of {@link Provider#pname}\n */\n ignoreProviders: [] as string[],\n\n /**\n * Some providers are not used by default (i.e. PoleStar) because they\n * require data from an optional external service or because they drain more\n * battery. They can be added to this list to be used\n * List of {@link Provider#pname}\n */\n optionalProviders: [] as string[],\n\n stopOnError: true,\n\n checkAvailabilityOnStart: true,\n\n get hasPoleStar() {\n return this.optionalProviders.includes('PoleStar');\n }\n};\n\nexport default ProvidersOptions;\n","import Logger from '@wemap/logger';\n\ninterface MyObject { getName(): string }\n\nclass ProvidersLoggerOld {\n\n _enabled = false;\n\n currentId = 0;\n objectsIdMap = new WeakMap<MyObject, number>();\n\n pushEvents: { [key: number]: number } = {};\n pushEventsRef: { [key: number]: MyObject } = {};\n\n interval?: number;\n initDate?: number;\n\n\n get enabled() {\n return this._enabled;\n }\n\n set enabled(_newVal) {\n this._enabled = _newVal;\n }\n\n initializeInterval() {\n\n if (this.interval) {\n return;\n }\n\n this.interval = window.setInterval(() => {\n\n for (const [key, value] of Object.entries(this.pushEvents)) {\n Logger.debug('Received ' + value + ' notifications from '\n + this.pushEventsRef[Number(key)].getName() + ' last second');\n }\n\n this.pushEvents = {};\n this.pushEventsRef = {};\n }, 1000);\n }\n\n getObjectId(object: MyObject) {\n if (!this.objectsIdMap.has(object)) {\n this.objectsIdMap.set(object, ++this.currentId);\n }\n return this.objectsIdMap.get(object) as number;\n }\n\n addEvent(object: MyObject, method: string) {\n\n if (!this.enabled) {\n return;\n }\n\n if (!this.initDate) {\n this.initDate = Date.now();\n }\n\n this.initializeInterval();\n\n const objectId = this.getObjectId(object);\n const objectClassName = object.getName();\n\n Logger.debug(objectClassName + '[' + objectId + '].' + method);\n }\n\n incrementNotifications(object: MyObject) {\n\n if (!this.enabled) {\n return;\n }\n\n const objectId = this.getObjectId(object);\n\n let counter = this.pushEvents[objectId];\n if (!counter) {\n counter = 0;\n this.pushEventsRef[objectId] = object;\n }\n this.pushEvents[objectId] = counter + 1;\n }\n\n}\nexport default new ProvidersLoggerOld();\n","class ContainsIgnoredProviderError extends Error {\n\n static DEFAULT_MESSAGE = 'Contains ignored provider';\n\n constructor(message?: string) {\n super(message || ContainsIgnoredProviderError.DEFAULT_MESSAGE);\n }\n}\n\nexport default ContainsIgnoredProviderError;\n","import ProvidersLoggerOld from '../events/ProvidersLoggerOld.js';\nimport ContainsIgnoredProviderError from '../errors/ContainsIgnoredProviderError.js';\nimport ProvidersOptions from '../ProvidersOptions.js';\nimport { ProviderState } from './ProviderState.js';\nimport { AvailabilityPromise } from '../events/AvailabilityHelper.js';\nimport { NativeCallbackInterface, NativeInterface } from './NativeProviders.js';\n\ndeclare global {\n interface Window {\n __nativeProviders?: NativeInterface;\n __nativeJsProviders?: NativeCallbackInterface;\n }\n}\n\n/**\n * A provider is a meta class to define an entity which can be\n * started / stopped and provides a data of <E>\n */\nabstract class Provider<E> {\n\n static _callbackUniqueId = 0;\n static _uniqueId = 1;\n\n id: number;\n state: ProviderState = 'stopped';\n\n _lastEvent: E | null = null;\n\n _eventsCallbacks: {\n id: number,\n onEvent: ((event: E) => void) | null,\n onError: ((error: Error) => void) | null,\n optional: boolean\n }[] = [];\n\n _monitoringCallbacks: {\n id: number,\n onStarted: (() => void) | null,\n onStopped: (() => void) | null\n }[] = [];\n\n /**\n * Provider constructor\n */\n constructor() {\n this.id = Provider._uniqueId++;\n ProvidersLoggerOld.addEvent(this, 'constructor');\n }\n\n /**\n * Get the provider name\n */\n abstract getName(): string;\n\n\n /**\n * Resolve with an error if the provider is not available\n */\n getAvailability() {\n if (ProvidersOptions.ignoreProviders.includes(this.getName())) {\n return Promise.resolve(new ContainsIgnoredProviderError());\n }\n\n return this.availability();\n }\n\n protected abstract availability(): AvailabilityPromise;\n\n\n protected get hasNativeInterface() {\n return Boolean(this.nativeInterface);\n }\n\n protected get nativeInterface() {\n return typeof window !== 'undefined' && window.__nativeProviders as NativeInterface || null;\n }\n\n protected get nativeJsInterface(): NativeCallbackInterface | null {\n if (typeof window === 'undefined') {\n return null;\n }\n if (!window.__nativeJsProviders) {\n window.__nativeJsProviders = {};\n }\n return window.__nativeJsProviders;\n }\n\n\n get useCameraNatively() {\n return false;\n }\n\n\n addEventListener(\n onEvent: ((events: E) => void) | null = null,\n onError: ((error: Error) => void) | null = null,\n startIfNecessary = true\n ) {\n const id = ++Provider._callbackUniqueId;\n\n /**\n * Build callback\n */\n this._eventsCallbacks.push({\n id,\n onEvent: onEvent || (() => { /* do nothing */ }),\n onError: onError || (() => { /* do nothing */ }),\n optional: !startIfNecessary\n });\n\n\n // The caller just want to have callbacks without starting the provider,\n // the routine can be stopped here\n if (!startIfNecessary) {\n return id;\n }\n\n\n // If the provider is already started do not go further\n if (this.state !== 'stopped') {\n return id;\n }\n this.state = 'starting';\n\n // Check availability on start if defined in options\n let availabilityPromise: AvailabilityPromise = Promise.resolve();\n if (ProvidersOptions.checkAvailabilityOnStart) {\n availabilityPromise = this.getAvailability();\n }\n\n (async () => {\n const error = await availabilityPromise;\n if (error) {\n this.state = 'stopped';\n this.notifyError(error);\n return;\n }\n\n ProvidersLoggerOld.addEvent(this, 'start');\n\n // Call the child start function\n this.start();\n\n this.state = 'started';\n\n this._monitoringCallbacks.forEach(cb => cb.onStarted?.());\n })();\n\n return id;\n }\n\n removeEventListener(callbackUniqueId?: number) {\n\n // Search the caller object in callbacks list\n const callback = this._eventsCallbacks.find(_callback => _callback.id === callbackUniqueId);\n if (!callback) {\n // The callback object is not found. Maybe it is already stopped.\n return;\n }\n\n // Remove the current callback from the list of the callbacks\n this._eventsCallbacks = this._eventsCallbacks.filter(_callback => _callback !== callback);\n\n // If this callback was optional, do not go further to stop the provider\n if (callback.optional) {\n return;\n }\n\n // If there is callbacks that are not optionals for start, do not stop the provider\n if (this._eventsCallbacks.find(_callback => !_callback.optional)) {\n return;\n }\n\n // If the provider is already stopped, do not stop it again.\n // This condition can be true if checkAvailabilityOnStart is true and returns an error\n if (this.state === 'stopped') {\n return;\n }\n\n ProvidersLoggerOld.addEvent(this, 'stop');\n // Call the child stop function\n this.stop();\n\n this.state = 'stopped';\n\n this._monitoringCallbacks.forEach(cb => cb.onStopped?.());\n }\n\n\n addMonitoringListener(onStarted?: (() => void) | null, onStopped?: (() => void) | null) {\n const id = Provider._callbackUniqueId++;\n this._monitoringCallbacks.push({\n id,\n onStarted: onStarted || null,\n onStopped: onStopped || null\n });\n return id;\n }\n\n removeMonitoringListener(callbackUniqueId?: number) {\n this._monitoringCallbacks = this._monitoringCallbacks.filter(\n _callback => _callback.id !== callbackUniqueId\n );\n }\n\n\n protected abstract start(): void\n protected abstract stop(): void\n\n\n /**\n * Notify the subscriber defined in {@link addEventListener}\n */\n notify = (event: E) => {\n // Logging\n ProvidersLoggerOld.incrementNotifications(this);\n\n // Notify callbacks\n this._eventsCallbacks.forEach(cb => cb.onEvent?.(event));\n\n // Keep a trace of the last events.\n this._lastEvent = event;\n }\n\n /**\n * Notify the subscriber defined in {@link addEventListener}\n */\n notifyError = (error: Error) => {\n this._eventsCallbacks.forEach(({\n id, onError\n }) => {\n if (ProvidersOptions.stopOnError) {\n this.removeEventListener(id);\n }\n onError?.(error);\n });\n }\n\n get lastEvent() {\n return this._lastEvent;\n }\n}\n\nexport default Provider;\n","export type AvailabilityPromise = Promise<Error | null | void>;\n\nexport default class AvailabilityHelper {\n\n static async every(availabilityPromises: AvailabilityPromise[]): AvailabilityPromise {\n for (const aPr of availabilityPromises) {\n const error = await aPr;\n if (error) {\n return error;\n }\n }\n return null;\n }\n\n static async some(availabilityPromises: AvailabilityPromise[]): AvailabilityPromise {\n let firstError;\n for (const aPr of availabilityPromises) {\n const error = await aPr;\n if (!error) {\n return null;\n } else if (!firstError) {\n firstError = error;\n }\n }\n return firstError || null;\n }\n\n}\n","class AskImuOnDesktopError extends Error {\n\n static DEFAULT_MESSAGE = 'It seems that you ask for IMU events on a desktop browser';\n\n constructor(message?: string) {\n super(message || AskImuOnDesktopError.DEFAULT_MESSAGE);\n }\n}\n\nexport default AskImuOnDesktopError;\n","class MissingSensorError extends Error {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve events, a sensor is missing';\n\n constructor(message?: string) {\n super(message || MissingSensorError.DEFAULT_MESSAGE);\n }\n\n from(fromMessage: string) {\n this.message += ' from ' + fromMessage;\n return this;\n }\n}\n\nexport default MissingSensorError;\n","import MissingSensorError from './MissingSensorError.js';\n\nclass MissingMagnetometerError extends MissingSensorError {\n constructor(message?: string) {\n super(message);\n }\n}\n\nexport default MissingMagnetometerError;\n","class GeolocationApiMissingError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation api is missing';\n\n constructor(message?: string) {\n super(message || GeolocationApiMissingError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationApiMissingError;\n","class GeolocationPermissionDeniedError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation permission denied';\n\n constructor(message?: string) {\n super(message || GeolocationPermissionDeniedError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationPermissionDeniedError;\n","class GeolocationPositionUnavailableError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation position unavailable';\n\n constructor(message?: string) {\n super(message || GeolocationPositionUnavailableError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationPositionUnavailableError;\n","const Constants = {\n DEFAULT_ALTITUDE: 1.6\n};\n\nexport default Constants;\n","import { UserPosition } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport GeolocationApiMissingError from '../../../errors/GeolocationApiMissingError.js';\nimport Provider from '../../Provider.js';\nimport GeolocationPermissionDeniedError from '../../../errors/GeolocationPermissionDeniedError.js';\nimport GeolocationPositionUnavailableError from '../../../errors/GeolocationPositionUnavailableError.js';\nimport Constants from '../../Constants.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\n\n/**\n * GnssWifiProvider is a provider based on navigator.geolocation.\n * This API does not allow us to know if the position returned is provided\n * by Wifi Fingerprinting algorithms or by GNSS. That is why the name is\n * \"GnssWifi\".\n */\nclass GnssWifiProvider extends Provider<AbsolutePosition> {\n\n static POSITION_OPTIONS = {\n enableHighAccuracy: true,\n timeout: Infinity,\n maximumAge: 0\n };\n\n static DEFAULT_DISCARD_POSITIONS_ABOVE = 50;\n\n discardPositionsAbove = GnssWifiProvider.DEFAULT_DISCARD_POSITIONS_ABOVE;\n\n geoLocationId?: number;\n\n getName = () => 'GnssWifi';\n\n\n availability() {\n return typeof (navigator) === 'object' && navigator.geolocation\n ? Promise.resolve()\n : Promise.resolve(new GeolocationApiMissingError());\n }\n\n start() {\n // Note: added timeout for a workaround on Safari/iOS when user disabled geolocation:\n // watchPosition does not send the error callback without the \"setTimeout\"\n setTimeout(() => {\n this.geoLocationId = navigator.geolocation.watchPosition(\n this.onNewPosition,\n this.onPositionError,\n GnssWifiProvider.POSITION_OPTIONS\n );\n }, 150);\n }\n\n stop() {\n if (typeof this.geoLocationId !== 'undefined') {\n navigator.geolocation.clearWatch(this.geoLocationId);\n }\n }\n\n private onNewPosition = (geolocation: GeolocationPosition) => {\n\n const { coords } = geolocation;\n if (!coords) {\n return;\n }\n\n let bearing;\n if (coords.heading) {\n bearing = deg2rad(coords.heading);\n }\n\n const timestamp = TimeUtils.unixTimestampToPreciseTime(geolocation.timestamp) / 1e3;\n\n const position = new UserPosition(\n coords.latitude,\n coords.longitude,\n Constants.DEFAULT_ALTITUDE,\n null,\n timestamp,\n coords.accuracy,\n bearing);\n\n if (typeof this.discardPositionsAbove === 'number'\n && coords.accuracy > this.discardPositionsAbove\n ) {\n return;\n }\n\n this.notify(position);\n\n };\n\n onPositionError = (error: GeolocationPositionError) => {\n\n Logger.warn(`[Providers] watchPosition error: [${error.code}] ${error.message}`);\n\n let customError;\n switch (error.code) {\n case 1:\n customError = new GeolocationPermissionDeniedError(error.message);\n break;\n case 2:\n customError = new GeolocationPositionUnavailableError(error.message);\n break;\n default:\n customError = new Error(error.message);\n }\n\n this.notifyError(customError);\n };\n}\n\nexport default new GnssWifiProvider();\n","class MissingArCoreError extends Error {\n\n static DEFAULT_MESSAGE = 'ARCore is missing';\n\n constructor(message?: string) {\n super(message || MissingArCoreError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingArCoreError;\n","class MissingNativeInterfaceError extends Error {\n\n static DEFAULT_MESSAGE = 'Native interface is missing. You are maybe trying to '\n + 'execute a code which is not available in a web browser';\n\n constructor(message?: string) {\n super(message || MissingNativeInterfaceError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingNativeInterfaceError;\n","import { RelativePosition } from '@wemap/geo';\nimport { deg2rad, Quaternion_t, Vector16_t, Vector3_t } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../Provider.js';\nimport MissingArCoreError from '../../errors/MissingArCoreError.js';\nimport MissingNativeInterfaceError from '../../errors/MissingNativeInterfaceError.js';\nimport { NativeArCore } from '../NativeProviders.js';\nimport { Barcode, CameraProjectionMatrix, RelativeAttitude} from '../../events/Types.js';\n\n\nexport type Payload = [number, ...[number | string]];\n\nexport type ArCoreEvent = Readonly<{\n readonly relativePosition: RelativePosition,\n readonly relativeAttitude: RelativeAttitude,\n readonly cameraProjection?: CameraProjectionMatrix,\n readonly barcode?: Barcode\n}>;\n\nclass ArCoreProvider extends Provider<ArCoreEvent> {\n\n static Payload = {\n Pose: {\n ref: 2 ** 0,\n size: 7\n },\n Barcode: {\n ref: 2 ** 1,\n size: 1\n },\n ProjMat: {\n ref: 2 ** 2,\n size: 16\n },\n ImageRef: {\n ref: 2 ** 3,\n size: 1\n }\n } as const;\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static RELATIVE_ATTITUDE_DRIFT = deg2rad(3) / 60;\n\n _nativeProvider?: NativeArCore;\n\n previousPosition = [0, 0, 0];\n\n getName = () => 'ArCore';\n\n availability() {\n try {\n const nativeProvider = this.nativeProvider;\n\n if (!nativeProvider.checkAvailability()) {\n return Promise.resolve(new MissingArCoreError());\n }\n\n } catch (e) {\n return Promise.resolve(e as Error);\n }\n\n return Promise.resolve();\n }\n\n start() {\n this.nativeProvider?.start();\n this.pullDataLoop();\n }\n\n stop() {\n this.nativeProvider?.stop();\n }\n\n pullDataLoop = () => {\n\n if (this.state === 'stopped') {\n return;\n }\n\n const payload = JSON.parse(this.nativeProvider.getInfo());\n if (payload.length > 1) {\n this.parsePayload(payload);\n }\n requestAnimationFrame(this.pullDataLoop);\n }\n\n parsePayload(payload: Payload) {\n\n const ref = payload[0];\n let bufferIndex = 1;\n\n let attitude: RelativeAttitude,\n position: RelativePosition,\n cameraProjection,\n barcode;\n\n const time = TimeUtils.preciseTime() / 1e3;\n\n if (ref & ArCoreProvider.Payload.Pose.ref) {\n\n attitude = new RelativeAttitude(\n payload.slice(bufferIndex, bufferIndex + 4) as Quaternion_t,\n time,\n ArCoreProvider.RELATIVE_ATTITUDE_DRIFT,\n );\n\n const newPosition = [\n payload[bufferIndex + 4], payload[bufferIndex + 5], payload[bufferIndex + 6]\n ] as Vector3_t;\n position = new RelativePosition(\n newPosition[0] - this.previousPosition[0],\n newPosition[1] - this.previousPosition[1],\n newPosition[2] - this.previousPosition[2],\n time,\n 1e-4\n );\n this.previousPosition = newPosition;\n\n bufferIndex += ArCoreProvider.Payload.Pose.size;\n }\n\n if (ref & ArCoreProvider.Payload.Barcode.ref) {\n barcode = payload[bufferIndex] as Barcode;\n bufferIndex += ArCoreProvider.Payload.Barcode.size;\n }\n\n if (ref & ArCoreProvider.Payload.ProjMat.ref) {\n cameraProjection = payload.slice(bufferIndex, bufferIndex + ArCoreProvider.Payload.ProjMat.size) as Vector16_t;\n bufferIndex += ArCoreProvider.Payload.ProjMat.size;\n }\n\n this.notify({\n relativePosition: position!,\n relativeAttitude: attitude!,\n ...(barcode && { barcode }),\n ...(cameraProjection && { cameraProjection })\n\n })\n }\n\n\n get nativeProvider() {\n\n if (!this._nativeProvider) {\n\n if (!this.nativeInterface) {\n throw new MissingNativeInterfaceError();\n }\n\n this._nativeProvider = this.nativeInterface.getArCoreProvider();\n if (!this._nativeProvider) {\n throw new MissingArCoreError();\n }\n }\n\n return this._nativeProvider;\n }\n\n\n enableBarcodeScanner() {\n try {\n this.nativeProvider.enableBarcodeScanner();\n } catch (e) {\n this.notifyError(e as Error);\n }\n }\n\n disableBarcodeScanner() {\n try {\n this.nativeProvider.disableBarcodeScanner();\n } catch (e) {\n this.notifyError(e as Error);\n }\n }\n\n get useCameraNatively() {\n return true;\n }\n}\n\nexport default new ArCoreProvider();\n","import { GeoRelativePosition, RelativePosition } from '@wemap/geo';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport ArCoreProvider, { ArCoreEvent } from '../../vision/ArCoreProvider.js';\nimport { AbsoluteAttitude, RelativeAttitude } from '../../../events/Types.js';\n\nclass GeoRelativePositionFromArCoreProvider extends Provider<GeoRelativePosition> {\n\n absoluteAttitudeProviderId?: number;\n arCoreProviderId?: number;\n absoluteAttitudeEvent?: AbsoluteAttitude;\n\n getName = () => 'GeoRelativePositionFromArCore';\n\n availability() {\n return AvailabilityHelper.every([\n ArCoreProvider.getAvailability(),\n AbsoluteAttitudeProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.arCoreProviderId = ArCoreProvider.addEventListener(\n this.onArCoreEvents,\n this.notifyError\n );\n\n this.absoluteAttitudeProviderId = AbsoluteAttitudeProvider.addEventListener(\n event => this.absoluteAttitudeEvent = event,\n this.notifyError\n );\n }\n\n stop() {\n ArCoreProvider.removeEventListener(this.arCoreProviderId);\n AbsoluteAttitudeProvider.removeEventListener(this.absoluteAttitudeProviderId);\n }\n\n onArCoreEvents = (event: ArCoreEvent) => {\n const relativeAttitudeEvent = event.relativeAttitude;\n const relativePositionEvent = event.relativePosition;\n\n if (relativeAttitudeEvent && relativePositionEvent && this.absoluteAttitudeEvent) {\n this.compute(relativePositionEvent, relativeAttitudeEvent, this.absoluteAttitudeEvent);\n }\n }\n\n compute(\n relativePosition: RelativePosition,\n relativeAttitude: RelativeAttitude,\n absoluteAttitude: AbsoluteAttitude\n ) {\n\n const rotation = absoluteAttitude.heading - relativeAttitude.heading;\n\n /**\n * Here, we transform \"relativePosition\" which is defined in ArCore frame to a relative \"position\" defined in ENU frame\n */\n const east = Math.cos(rotation) * relativePosition.x - Math.sin(rotation) * relativePosition.z;\n const north = -Math.sin(rotation) * relativePosition.x - Math.cos(rotation) * relativePosition.z;\n const up = relativePosition.y;\n\n /**\n * Relative position is defined in ENU frame\n */\n const position = new GeoRelativePosition(\n east,\n north,\n up,\n relativePosition.time,\n 0,\n absoluteAttitude.heading\n );\n\n this.notify(position);\n }\n}\n\nexport default new GeoRelativePositionFromArCoreProvider();\n","import { Matrix_t } from '@wemap/maths';\nimport {\n Matrix, Matrix3, Matrix3_t, Matrix4, Matrix4_t,\n Quaternion, Quaternion_t, Vector, Vector3, Vector3_t,\n Vector4_t\n} from '@wemap/maths';\n\ntype RelativeNoises = { acc: number, gyr: number };\ntype AbsoluteNoises = { acc: number, gyr: number, yc: number };\n\ntype RelativeNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t };\ntype AbsoluteNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t, yc: Matrix3_t };\n\nconst DEFAULT_RELATIVE_NOISES = {\n acc: 0.5,\n gyr: 0.3\n};\n\nconst DEFAULT_ABSOLUTE_NOISES = {\n acc: 0.5,\n gyr: 0.3,\n yc: 2\n};\n\nclass EkfAttitude {\n P: Matrix4_t;\n accRef: Vector3_t;\n cRef: Vector3_t;\n noises!: { relative: RelativeNoisesMat, absolute: AbsoluteNoisesMat };\n quaternion: Quaternion_t | null;\n\n constructor(accRef: Vector3_t = [0, 0, 1], ycRef: Vector3_t = [-1, 0, 0]) {\n\n this.accRef = accRef;\n this.cRef = ycRef;\n\n this.P = Matrix4.fromDiagVector(Array(4).fill(0.1 ** 2) as Vector4_t);\n\n this.quaternion = null;\n \n this.noises = {} as never;\n this.setRelativeNoises(DEFAULT_RELATIVE_NOISES);\n this.setAbsoluteNoises(DEFAULT_ABSOLUTE_NOISES);\n }\n\n setRelativeNoises(relativeNoises: RelativeNoises) {\n this.noises.relative = {\n acc: Matrix3.diag(Array(3).fill(relativeNoises.acc ** 2) as Vector3_t),\n gyr: Matrix3.diag(Array(3).fill(relativeNoises.gyr ** 2) as Vector3_t)\n };\n }\n\n\n setAbsoluteNoises(absoluteNoises: AbsoluteNoises) {\n this.noises.absolute = {\n acc: Matrix3.diag(Array(3).fill(absoluteNoises.acc ** 2) as Vector3_t),\n gyr: Matrix3.diag(Array(3).fill(absoluteNoises.gyr ** 2) as Vector3_t),\n yc: Matrix3.diag(Array(3).fill(absoluteNoises.yc ** 2) as Vector3_t)\n };\n }\n\n /**\n * Try to initialize filter.\n * To initialize, we need at least current acceleration (acc)\n */\n tryInitialize(acc: Vector3_t, mag?: Vector3_t) {\n\n const accNormalized = Vector3.normalize(acc);\n\n if (mag) {\n const magNormalized = Vector3.normalize(mag);\n\n const H = Vector3.normalize(Vector3.cross(magNormalized, accNormalized));\n const M = Vector3.cross(accNormalized, H);\n\n const R: Matrix3_t = [\n [H[0], M[0], accNormalized[0]],\n [H[1], M[1], accNormalized[1]],\n [H[2], M[2], accNormalized[2]]\n ];\n\n this.quaternion = Quaternion.fromMatrix3Matlab(R);\n\n } else {\n\n const r = Vector3.dot(accNormalized, this.accRef) + 1;\n const v = Vector3.cross(accNormalized, this.accRef);\n\n let quaternion: Quaternion_t = [r, v[0], v[1], v[2]];\n quaternion = Quaternion.normalize(quaternion);\n\n this.quaternion = quaternion;\n }\n\n return this.quaternion;\n }\n\n update(diffTime: number, acc: Vector3_t, gyr: Vector3_t, mag?: Vector3_t) {\n\n if (!this.quaternion) {\n return this.tryInitialize(acc, mag);\n }\n\n let q = this.quaternion;\n\n /* ------------\n * ESTIMATION\n * ------------*/\n\n const qArray = q;\n const gyrInt = Vector3.multiplyScalar(gyr, 0.5 * diffTime);\n const F = this.computeC([1, gyrInt[0], gyrInt[1], gyrInt[2]]);\n const qAPriori = Matrix4.multiplyVector(F, q);\n const E1 = Matrix3.diag([qArray[0], qArray[0], qArray[0]]);\n const eSkew = Matrix3.skew([qArray[1], qArray[2], qArray[3]]);\n\n const qPart = [-1 * qArray[1], -1 * qArray[2], -1 * qArray[3]];\n const E = Matrix.concatRow([qPart], Matrix3.sum(eSkew, E1));\n\n const Qk = Matrix4.multiplyScalar(\n Matrix.multiply(\n Matrix.multiply(E, this.noises[mag ? 'absolute' : 'relative'].gyr),\n Matrix.transpose(E)\n ) as Matrix4_t,\n (diffTime / 2) ** 2\n );\n\n const pAPriori = Matrix4.sum(\n Matrix4.multiply(\n Matrix4.multiply(F, this.P),\n Matrix4.transpose(F)\n ),\n Qk\n );\n\n /* ------------\n * CORRECTION\n * ------------*/\n\n const accNormalized = Vector3.normalize(acc);\n let dz, K: Matrix_t, H;\n\n if (mag) {\n\n const magNormalized = Vector3.normalize(mag);\n const yc = Vector3.cross(accNormalized, magNormalized);\n const ycNormalized = Vector3.normalize(yc);\n\n const dzYc = Vector3.subtract(ycNormalized, Quaternion.rotateMatlab(qAPriori, this.cRef));\n const dzAcc = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));\n dz = Vector.concat(dzYc, dzAcc);\n\n const HYc = this.jacobianES(qAPriori, this.cRef);\n const HAcc = this.jacobianES(qAPriori, this.accRef);\n H = Matrix.concatRow(HYc, HAcc);\n\n const RYc = Matrix.concatLine(this.noises.absolute.yc, Matrix3.zeros);\n const RAcc = Matrix.concatLine(Matrix3.zeros, this.noises.absolute.acc);\n const R = Matrix.concatRow(RYc, RAcc);\n\n K = Matrix.multiply(\n Matrix.multiply(pAPriori, Matrix.transpose(H)),\n Matrix.inverse(\n Matrix.sum(\n Matrix.multiply(\n Matrix.multiply(H, pAPriori),\n Matrix.transpose(H)\n ),\n R\n )\n ) as Matrix_t\n );\n } else {\n dz = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));\n H = this.jacobianES(qAPriori, this.accRef);\n const R = this.noises.relative.acc;\n\n K = Matrix.multiply(\n Matrix.multiply(pAPriori, Matrix.transpose(H)),\n Matrix3.inverse(\n Matrix3.sum(\n Matrix.multiply(\n Matrix.multiply(H, pAPriori),\n Matrix.transpose(H)\n ) as Matrix3_t,\n R\n )\n ) as Matrix_t\n );\n }\n\n q = Quaternion.sum(\n qAPriori,\n Matrix.multiplyVector(K, dz) as Quaternion_t\n );\n const P = Matrix4.multiply(\n Matrix4.subtract(\n Matrix4.identity,\n Matrix.multiply(K, H) as Matrix4_t\n ),\n pAPriori\n );\n\n q = Quaternion.normalize(q);\n this.quaternion = q;\n this.P = P;\n\n return q;\n }\n\n computeC(b: Vector4_t): Matrix4_t {\n return [\n [b[0], -b[1], -b[2], -b[3]],\n [b[1], b[0], b[3], -b[2]],\n [b[2], -b[3], b[0], b[1]],\n [b[3], b[2], -b[1], b[0]]\n ];\n }\n\n jacobianES(q: Quaternion_t, v: Vector3_t) {\n\n const [qw, qx, qy, qz] = q;\n const [vx, vy, vz] = v;\n\n return [\n [2 * qz * vy - 2 * qy * vz, 2 * qy * vy + 2 * qz * vz, 2 * qx * vy - 2 * qw * vz - 4 * qy * vx, 2 * qw * vy + 2 * qx * vz - 4 * qz * vx],\n [2 * qx * vz - 2 * qz * vx, 2 * qw * vz - 4 * qx * vy + 2 * qy * vx, 2 * qx * vx + 2 * qz * vz, 2 * qy * vz - 2 * qw * vx - 4 * qz * vy],\n [2 * qy * vx - 2 * qx * vy, 2 * qz * vx - 4 * qx * vz - 2 * qw * vy, 2 * qw * vx - 4 * qy * vz + 2 * qz * vy, 2 * qx * vx + 2 * qy * vy]\n ];\n }\n}\n\nexport default EkfAttitude;\n","import { deg2rad, Vector3_t } from '@wemap/maths';\nimport { Browser, BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../Provider.js';\nimport AskImuOnDesktopError from '../../errors/AskImuOnDesktopError.js';\nimport { Acceleration, AngularRate } from '../../events/Types.js';\n\n// https://stackoverflow.com/a/73369838/2239938\ninterface DeviceMotionEventiOS extends DeviceMotionEvent {\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n/**\n * Imu (Inertial Measurement Unit) provider retrieve acceleration data\n * and/or angular rate data from inertial sensors.\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via devicemotion)\n * Safari iOS (v12.0): YES (via devicemotion)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent}\n * Firefox Android (v65.0.1): YES (via devicemotion)\n *\n * -----------------------------------\n */\n\ntype ImuEvent = { readonly acceleration?: Acceleration, readonly angularRate?: AngularRate };\nclass ImuProvider extends Provider<ImuEvent> {\n\n getName = () => 'IMU';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n const subscribe = () => window.addEventListener('devicemotion', this.parseDeviceMotionEvent, true);\n\n const requestPermission = (DeviceMotionEvent as unknown as DeviceMotionEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(this.notifyError);\n } else {\n subscribe();\n }\n }\n\n stop() {\n window.removeEventListener('devicemotion', this.parseDeviceMotionEvent, true);\n }\n\n /**\n * devicemotion callback\n */\n private parseDeviceMotionEvent = (e: DeviceMotionEvent) => {\n\n const timestamp = e.timeStamp / 1e3;\n\n let acc: Vector3_t | undefined;\n if (e.accelerationIncludingGravity) {\n const {\n x, y, z\n } = e.accelerationIncludingGravity;\n\n if (typeof x === 'number' && typeof y === 'number' && typeof z === 'number') {\n acc = [x, y, z];\n\n if (BrowserUtils.getName() === Browser.SAFARI\n || BrowserUtils.getName() === Browser.IOS_WEBVIEW) {\n acc[0] *= -1;\n acc[1] *= -1;\n acc[2] *= -1;\n }\n }\n }\n\n let gyr: [number, number, number] | undefined;\n if (e.rotationRate) {\n const {\n alpha, beta, gamma\n } = e.rotationRate;\n\n if (typeof alpha === 'number' && typeof beta === 'number' && typeof gamma === 'number') {\n gyr = [deg2rad(alpha), deg2rad(beta), deg2rad(gamma)];\n }\n }\n\n\n if (acc || gyr) {\n this.notify({\n ...(acc && { acceleration: { timestamp, values: acc } }),\n ...(gyr && { angularRate: { timestamp, values: gyr } })\n });\n }\n }\n\n}\n\nexport default new ImuProvider();\n","import MissingSensorError from './MissingSensorError.js';\nclass MissingAccelerometerError extends MissingSensorError {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve Acceleration data';\n\n constructor(message?: string) {\n super(message || MissingAccelerometerError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingAccelerometerError;\n","import Provider from '../Provider.js';\nimport ImuProvider from './ImuProvider.js';\nimport MissingAccelerometerError from '../../errors/MissingAccelerometerError.js';\nimport { Acceleration } from '../../events/Types.js';\n\nclass AccelerometerProvider extends Provider<Acceleration> {\n\n private imuProviderId?: number;\n\n getName = () => 'Accelerometer';\n\n availability = () => ImuProvider.getAvailability();\n\n start() {\n this.imuProviderId = ImuProvider.addEventListener(event => {\n event.acceleration\n ? this.notify(event.acceleration)\n : this.notifyError(new MissingAccelerometerError().from('devicemotion'));\n\n }, this.notifyError);\n }\n\n stop() {\n ImuProvider.removeEventListener(this.imuProviderId);\n }\n}\n\nexport default new AccelerometerProvider();\n","import MissingSensorError from './MissingSensorError.js';\nclass MissingGyroscopeError extends MissingSensorError {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve Angular Rate data';\n\n constructor(message?: string) {\n super(message || MissingSensorError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingGyroscopeError;\n","import Provider from '../Provider.js';\nimport ImuProvider from './ImuProvider.js';\nimport MissingGyroscopeError from '../../errors/MissingGyroscopeError.js';\nimport { AngularRate } from '../../events/Types.js';\n\nclass GyroscopeProvider extends Provider<AngularRate> {\n\n private imuProviderId?: number;\n\n getName = () => 'Gyroscope';\n\n availability = () => ImuProvider.getAvailability();\n\n start() {\n this.imuProviderId = ImuProvider.addEventListener(event => {\n event.angularRate\n ? this.notify(event.angularRate)\n : this.notifyError(new MissingGyroscopeError().from('devicemotion'));\n }, this.notifyError);\n }\n\n stop() {\n ImuProvider.removeEventListener(this.imuProviderId);\n }\n}\n\nexport default new GyroscopeProvider();\n","import { deg2rad, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport EkfAttitude from '../EkfAttitude.js';\nimport Accelerometer from '../../imu/AccelerometerProvider.js';\nimport Gyroscope from '../../imu/GyroscopeProvider.js';\nimport { Acceleration, AngularRate, RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Relative attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation\n * The provider does not work until an offset is given.\n */\nclass RelativeAttitudeFromEkf extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n accelerometerProviderId?: number;\n ekfAttitude = new EkfAttitude();\n gyroscopeEvent?: AngularRate;\n gyroscopeProviderId?: number;\n\n lastTimestamp = 0;\n\n getName = () => 'RelativeAttitudeFromEkf';\n\n availability() {\n return AvailabilityHelper.every([\n Accelerometer.getAvailability(),\n Gyroscope.getAvailability()\n ]);\n }\n\n start() {\n this.accelerometerProviderId = Accelerometer.addEventListener(\n event => this.onAccelerometerEvent(event),\n error => this.notifyError(error)\n );\n\n this.gyroscopeProviderId = Gyroscope.addEventListener(\n event => this.gyroscopeEvent = event,\n error => this.notifyError(error)\n );\n }\n\n stop() {\n Accelerometer.removeEventListener(this.accelerometerProviderId);\n Gyroscope.removeEventListener(this.gyroscopeProviderId);\n }\n\n private onAccelerometerEvent = (accelerationEvent: Acceleration) => {\n\n if (!this.gyroscopeEvent) {\n return;\n }\n\n const {\n values: acceleration, timestamp\n } = accelerationEvent;\n\n // Handle timestamps and dt\n if (this.lastTimestamp === 0) {\n this.lastTimestamp = timestamp;\n return;\n }\n const diffTime = timestamp - this.lastTimestamp;\n this.lastTimestamp = timestamp;\n\n const quaternion = this.ekfAttitude.update(\n diffTime,\n acceleration as Vector3_t,\n this.gyroscopeEvent.values as Vector3_t\n );\n\n if (quaternion) {\n const attitude = new RelativeAttitude(quaternion,\n timestamp,\n RelativeAttitudeFromEkf.DEFAULT_DRIFT\n );\n this.notify(attitude);\n }\n };\n}\n\nexport default new RelativeAttitudeFromEkf();\n","import { deg2rad, Rotations } from '@wemap/maths';\nimport { BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AskImuOnDesktopError from '../../../errors/AskImuOnDesktopError.js';\nimport MissingSensorError from '../../../errors/MissingSensorError.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n// https://stackoverflow.com/a/73369838/2239938\ninterface DeviceOrientationEventiOS extends DeviceOrientationEvent {\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n/**\n * Relative attitude provider gives the device attitude in a custom frame (x-right, y-front, z-up) using\n * browser deviceorientation\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via deviceorientation but deviceorientation.alpha is unreliable! Sometimes it starts at 0°, sometimes at 270°)\n * Safari iOS (v12.0): YES (via deviceorientation)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}\n * Firefox Android (v65.0.1): YES (via deviceorientation)\n *\n * -----------------------------------\n */\n\nclass RelativeAttitudeFromBrowser extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n getName = () => 'RelativeAttitudeFromBrowser';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n const subscribe = () => window.addEventListener('deviceorientation', this.onDeviceOrientationEvent, true);\n\n const requestPermission = (DeviceOrientationEvent as unknown as DeviceOrientationEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(error => this.notifyError(error));\n } else {\n subscribe();\n }\n }\n\n stop() {\n window.removeEventListener('deviceorientation', this.onDeviceOrientationEvent, true);\n }\n\n onDeviceOrientationEvent = (e: DeviceOrientationEvent) => {\n\n if (typeof e.alpha !== 'number' || typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientation'));\n return;\n }\n\n const quaternion = Rotations.eulerToQuaternionZXYDegrees([e.alpha, e.beta, e.gamma]);\n const attitude = new RelativeAttitude(quaternion,\n e.timeStamp / 1e3,\n RelativeAttitudeFromBrowser.DEFAULT_DRIFT\n );\n this.notify(attitude);\n };\n}\n\nexport default new RelativeAttitudeFromBrowser();\n","import { Vector3, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport GyroscopeProvider from './GyroscopeProvider.js';\nimport { AngularRate, HighRotation } from '../../events/Types.js';\n\nclass HighRotationsProvider extends Provider<HighRotation> {\n\n static THRESHOLD = 10; // in radians by second\n static DELAY_CONSIDERATION = 3; // in seconds\n\n gyroscopeProviderId?: number;\n\n getName = () => 'HighRotationsProvider';\n\n availability = () => GyroscopeProvider.getAvailability();\n\n start() {\n this.gyroscopeProviderId = GyroscopeProvider.addEventListener(\n this._parseGyroscopeEvent,\n this.notifyError\n );\n }\n\n stop() {\n GyroscopeProvider.removeEventListener(this.gyroscopeProviderId);\n }\n\n isInProgress() {\n if (!this.lastEvent || !GyroscopeProvider.lastEvent) {\n return false;\n }\n\n const diffTime = GyroscopeProvider.lastEvent.timestamp - this.lastEvent.timestamp;\n return diffTime < HighRotationsProvider.DELAY_CONSIDERATION;\n }\n\n private _parseGyroscopeEvent = (gyroscopeEvent: AngularRate) => {\n\n const { values, timestamp } = gyroscopeEvent;\n const speed = Vector3.norm(values as Vector3_t);\n if (speed > HighRotationsProvider.THRESHOLD) {\n this.notify({ timestamp });\n }\n\n }\n}\n\nexport default new HighRotationsProvider();\n","import { deg2rad } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport RelativeAttitudeFromEkfProvider from './RelativeAttitudeFromEkfProvider.js';\nimport RelativeAttitudeFromBrowserProvider from './RelativeAttitudeFromBrowserProvider.js';\nimport HighRotationsProvider from '../../imu/HighRotationsProvider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n\nclass RelativeAttitudeFromInertial extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n _highRotationsProviderId?: number;\n listenerId?: number;\n provider?: Provider<RelativeAttitude>;\n\n getName = () => 'RelativeAttitudeFromInertial';\n\n availability() {\n return AvailabilityHelper.some([\n RelativeAttitudeFromEkfProvider.getAvailability(),\n RelativeAttitudeFromBrowserProvider.getAvailability()\n ]);\n }\n\n start() {\n\n RelativeAttitudeFromEkfProvider.getAvailability().then(availabilityError => {\n this.provider = !availabilityError ? RelativeAttitudeFromEkfProvider : RelativeAttitudeFromBrowserProvider;\n\n this.listenerId = this.provider.addEventListener(\n event => this._parseEvent(event),\n this.notifyError\n );\n this._highRotationsProviderId = HighRotationsProvider.addEventListener(\n null,\n this.notifyError\n );\n });\n }\n\n _parseEvent(event: RelativeAttitude) {\n const relativeAttitude = event.clone();\n if (HighRotationsProvider.isInProgress()) {\n let accuracy = (relativeAttitude.accuracy || 0) + (RelativeAttitudeFromInertial.DEFAULT_DRIFT * 100);\n accuracy = Math.min(accuracy, Math.PI);\n relativeAttitude.accuracy = accuracy;\n }\n this.notify(relativeAttitude);\n }\n\n stop() {\n if (this.provider) {\n this.provider.removeEventListener(this.listenerId);\n delete this.provider;\n }\n HighRotationsProvider.removeEventListener(this._highRotationsProviderId);\n }\n}\n\nexport default new RelativeAttitudeFromInertial();\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionLadetto {\n\n \n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 1; // in m.s-2\n\n\n frequency = 0;\n\n lastVerticalAcc = 0;\n maxAcceleration = 0;\n lastStepTimestamp = -StepDetectionLadetto.MIN_TIME_BETWEEN_STEPS;\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n let stepDetected = false;\n\n const verticalAcc = linearAcc[2];\n const timeInterval = timestamp - this.lastStepTimestamp;\n\n const upfront = verticalAcc > this.lastVerticalAcc;\n\n if (upfront) {\n if (verticalAcc > this.maxAcceleration) {\n this.maxAcceleration = verticalAcc;\n }\n } else if (this.maxAcceleration > StepDetectionLadetto.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && timeInterval > StepDetectionLadetto.MIN_TIME_BETWEEN_STEPS) {\n this.maxAcceleration = 0;\n\n const diffTime = timestamp - this.lastStepTimestamp;\n this.frequency = Math.min(Math.max((1 / diffTime), StepDetectionLadetto.MIN_FRENQUENCY), StepDetectionLadetto.MAX_FRENQUENCY);\n\n stepDetected = true;\n this.lastStepTimestamp = timestamp;\n } else {\n this.maxAcceleration = 0;\n }\n\n this.lastVerticalAcc = verticalAcc;\n\n return stepDetected;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepTimestamp ? this.lastStepSize * this.frequency : 0;\n }\n}\n\nexport default StepDetectionLadetto;\n","import { Vector3_t } from \"@wemap/maths\";\n\n\nclass StepDetectionMinMaxPeaks {\n\n static WINDOW_TIME = 0.3; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 1.5; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -1; // in m.s-2\n\n frequency = 0;\n lastStepTimestamp = -StepDetectionMinMaxPeaks.MIN_TIME_BETWEEN_STEPS;\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n if (this.lastStepTimestamp && this.lastStepTimestamp + StepDetectionMinMaxPeaks.MIN_TIME_BETWEEN_STEPS > timestamp) {\n return false;\n }\n\n let maxValue = Number.MIN_SAFE_INTEGER;\n let minValue = Number.MAX_SAFE_INTEGER;\n\n const windowTime = StepDetectionMinMaxPeaks.WINDOW_TIME;\n this.slidingWindow.forEach((item, index, object) => {\n if (item.timestamp < timestamp - windowTime) {\n object.splice(index, 1);\n } else {\n maxValue = Math.max(item.verticalAcc, maxValue);\n minValue = Math.min(item.verticalAcc, minValue);\n }\n });\n this.slidingWindow.push({\n timestamp: timestamp,\n verticalAcc: linearAcc[2]\n });\n\n\n if (maxValue > StepDetectionMinMaxPeaks.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && minValue < StepDetectionMinMaxPeaks.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks.MIN_FRENQUENCY), StepDetectionMinMaxPeaks.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n }\n\n return false;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepTimestamp ? this.lastStepSize * this.frequency : 0;\n }\n}\n\nexport default StepDetectionMinMaxPeaks;\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionMinMaxPeaks2 {\n\n static WINDOW_TIME = 0.3; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 0.75; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -0.3; // in m.s-2\n\n frequency = 0;\n influence = 0.2;\n\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n lastStepTimestamp = -StepDetectionMinMaxPeaks2.MIN_TIME_BETWEEN_STEPS;\n previousVerticalAcc = 0;\n\n compute(timestamp: number, linearAcc: Vector3_t, angularRate: Vector3_t) {\n\n const verticalAcc = this.influence * (linearAcc[2] * 2) + (1 - this.influence) * this.previousVerticalAcc;\n this.previousVerticalAcc = verticalAcc;\n\n\n if (Math.sqrt(angularRate[0] ** 2 + angularRate[1] ** 2 + angularRate[2] ** 2) > 0.75) {\n return false;\n }\n\n if (this.lastStepTimestamp && this.lastStepTimestamp + StepDetectionMinMaxPeaks2.MIN_TIME_BETWEEN_STEPS > timestamp) {\n return false;\n }\n\n let maxValue = Number.MIN_SAFE_INTEGER;\n let minValue = Number.MAX_SAFE_INTEGER;\n\n this.slidingWindow.forEach((item, index, object) => {\n if (item.timestamp < timestamp - StepDetectionMinMaxPeaks2.WINDOW_TIME) {\n object.splice(index, 1);\n } else {\n maxValue = Math.max(item.verticalAcc, maxValue);\n minValue = Math.min(item.verticalAcc, minValue);\n }\n });\n this.slidingWindow.push({\n timestamp: timestamp,\n verticalAcc: verticalAcc\n });\n\n\n if (maxValue > StepDetectionMinMaxPeaks2.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && minValue < StepDetectionMinMaxPeaks2.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks2.MIN_FRENQUENCY), StepDetectionMinMaxPeaks2.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n }\n\n return false;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepSize && this.frequency ? this.lastStepSize * this.frequency : 0;\n }\n\n mean(data: { verticalAcc: number }[]) {\n let sum = 0.0, mean = 0.0;\n\n for (let i = 0; i < data.length; ++i) {\n sum += data[i].verticalAcc;\n }\n mean = sum / data.length;\n return mean;\n }\n\n stddev(data: { verticalAcc: number }[]) {\n const theMean = this.mean(data);\n let standardDeviation = 0;\n for (let i = 0; i < data.length; ++i) {\n standardDeviation += (data[i].verticalAcc - theMean) ** 2;\n }\n\n return Math.sqrt(standardDeviation / data.length);\n }\n}\n\nexport default StepDetectionMinMaxPeaks2;\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionMinMaxPeaks3 {\n\n static WINDOW_TIME = 0.6; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.6; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 0.2; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -0.1; // in m.s-2\n\n frequency = 0;\n influence = 0.05;\n\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n lastStepTimestamp = -StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS;\n previousVerticalAcc = 0;\n previousHorizontalAcc = 0;\n\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n const verticalAcc = this.influence * linearAcc[2] + (1 - this.influence) * this.previousVerticalAcc;\n this.previousVerticalAcc = verticalAcc;\n\n // let horizontalAcc = Math.sqrt(linearAcc[0] ** 2 + linearAcc[1] ** 2);\n // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;\n // this.previousHorizontalAcc = horizontalAcc;\n\n // const angularRateNorm = Math.sqrt(angularRate[0] ** 2 + angularRate[1] ** 2 + angularRate[2] ** 2);\n // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;\n // this.previousangularRateNorm = angularRateNorm;\n\n // Update sliding window\n this.slidingWindow = this.slidingWindow.filter(item => item.timestamp >= timestamp - StepDetectionMinMaxPeaks3.WINDOW_TIME\n );\n this.slidingWindow.push({ timestamp, verticalAcc });\n // , horizontalAcc });\n\n // this.horizontalAccStd = this.stddev(this.slidingWindow.map(el => el.horizontalAcc));\n // this.verticalAccStd = this.stddev(this.slidingWindow.map(el => el.verticalAcc));\n\n\n const isTooEarlyForANewStep = this.lastStepTimestamp\n && this.lastStepTimestamp + StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS > timestamp;\n if (isTooEarlyForANewStep) {\n return false;\n }\n\n // Looking for max peak\n let maxValue = Number.MIN_VALUE;\n let maxValueIdx = -1;\n let foundMaxPeakHigherThanThreshold = false;\n this.slidingWindow.forEach((item, idx) => {\n if (item.verticalAcc > maxValue\n && item.verticalAcc >= StepDetectionMinMaxPeaks3.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD) {\n maxValue = item.verticalAcc;\n maxValueIdx = idx;\n foundMaxPeakHigherThanThreshold = true;\n }\n });\n if (!foundMaxPeakHigherThanThreshold) {\n return false;\n }\n\n // Looking for a value lower than a threshold before the max peak\n let hasLowNegativeValueBeforeMaxPeak = false;\n let minValueBeforeMaxPeak = Number.MAX_VALUE;\n for (let i = 0; i < maxValueIdx; i++) {\n const curValue = this.slidingWindow[i].verticalAcc;\n minValueBeforeMaxPeak = Math.min(minValueBeforeMaxPeak, curValue);\n if (curValue < StepDetectionMinMaxPeaks3.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n hasLowNegativeValueBeforeMaxPeak = true;\n break;\n }\n }\n if (!hasLowNegativeValueBeforeMaxPeak) {\n return false;\n }\n\n // looking for another minimum after max peak\n const diffMinMax = maxValue - minValueBeforeMaxPeak;\n const targetValue = maxValue - 0.5 * diffMinMax;\n let targetValueFoundAfterMaxPeak = false;\n for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {\n if (this.slidingWindow[i].verticalAcc <= targetValue) {\n targetValueFoundAfterMaxPeak = true;\n break;\n }\n }\n if (!targetValueFoundAfterMaxPeak) {\n return false;\n }\n\n // // looking for another local minimum / maximum after 100ms\n // let localMinimumFound = false;\n // let localMaximumFound = false;\n // let localMaxiumValue = Number.MIN_SAFE_INTEGER;\n // let localMinimumVal = null;\n // const maxPeakTimestamp = this.slidingWindow[maxValueIdx].timestamp;\n // for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {\n // const curVal = this.slidingWindow[i];\n // const prevVal = this.slidingWindow[i - 1];\n\n // if (curVal.timestamp > maxPeakTimestamp + 0.4) {\n // break;\n // }\n\n // if (!localMinimumFound) {\n // // if (curVal.timestamp < maxPeakTimestamp + 0.05) {\n // // // too early\n // // continue;\n // // }\n\n // if (curVal.verticalAcc > prevVal.verticalAcc) {\n // localMinimumFound = true;\n // localMinimumVal = prevVal;\n // }\n // continue;\n // }\n\n // if (!localMaximumFound) {\n\n // // if (curVal.timestamp < localMinimumVal.timestamp + 0.05) {\n // // // too early\n // // continue;\n // // }\n\n // if (curVal.verticalAcc < prevVal.verticalAcc) {\n // localMaximumFound = true;\n // localMaxiumValue = prevVal.verticalAcc;\n // break;\n // }\n // }\n // }\n // const localMinMaxFoundAfterPeak = localMinimumFound && localMaximumFound;\n // // && localMaxiumValue / maxValue < 0.8;\n // // if (!localMinMaxFoundAfterPeak) {\n // // return false;\n // // }\n\n\n // const highRotationDetected = angularRateNorm > 0.75;\n // // if (highRotationDetected) {\n // // return false;\n // // }\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks3.MIN_FRENQUENCY), StepDetectionMinMaxPeaks3.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepSize && this.frequency ? this.lastStepSize * this.frequency : 0;\n }\n\n mean(data: number[]) {\n let sum = 0.0, mean = 0.0;\n\n for (let i = 0; i < data.length; ++i) {\n sum += data[i];\n }\n mean = sum / data.length;\n return mean;\n }\n\n stddev(data: number[]) {\n const theMean = this.mean(data);\n let standardDeviation = 0;\n for (let i = 0; i < data.length; ++i) {\n standardDeviation += (data[i] - theMean) ** 2;\n }\n\n return Math.sqrt(standardDeviation / data.length);\n }\n}\n\nexport default StepDetectionMinMaxPeaks3;\n","import { Constants as GeoConstants } from '@wemap/geo';\nimport { Quaternion, Quaternion_t, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport { Acceleration, AngularRate, RelativeAttitude, Step } from '../../events/Types.js';\nimport RelativeAttitudeFromInertialProvider from '../attitude/relative/RelativeAttitudeFromInertialProvider.js';\nimport AccelerometerProvider from '../imu/AccelerometerProvider.js';\nimport GyroscopeProvider from '../imu/GyroscopeProvider.js';\nimport StepDetectionLadetto from './StepDetectionLadetto.js';\nimport StepDetectionMinMaxPeaks from './StepDetectionMinMaxPeaks.js';\nimport StepDetectionMinMaxPeaks2 from './StepDetectionMinMaxPeaks2.js';\nimport StepDetectionMinMaxPeaks3 from './StepDetectionMinMaxPeaks3.js';\n\n\ntype StepDetectorAlgorithmName = 'ladetto' | 'minMaxPeaks' | 'minMaxPeaks2' | 'minMaxPeaks3';\n\ntype StepDetectorAlgorithm = {\n compute(timestamp: number, linearAcc: Vector3_t, angularRate?: Vector3_t): boolean;\n lastStepSize: number;\n};\n\nclass StepProvider extends Provider<Step> {\n\n static DEFAULT_STEP_SIZE_MULTIPLIER = 1;\n static DEFAULT_ALGORITHM: StepDetectorAlgorithmName = 'minMaxPeaks3';\n\n accelerometerProviderId?: number;\n attitudeProviderId?: number;\n gyroscopeProviderId?: number;\n angularRateEvent?: AngularRate;\n attitudeEvent?: RelativeAttitude;\n numOfSteps = 0;\n stepDetector!: StepDetectorAlgorithm;\n\n _stepSizeMultiplier = StepProvider.DEFAULT_STEP_SIZE_MULTIPLIER;\n _algorithm: StepDetectorAlgorithmName = StepProvider.DEFAULT_ALGORITHM;\n _accValues: Vector3_t[] = [];\n\n constructor() {\n super();\n this.algorithm = this._algorithm;\n }\n\n getName = () => 'StepDetector';\n\n availability() {\n return AvailabilityHelper.every([\n AccelerometerProvider.getAvailability(),\n GyroscopeProvider.getAvailability(),\n RelativeAttitudeFromInertialProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.numOfSteps = 0;\n\n this.accelerometerProviderId = AccelerometerProvider.addEventListener(\n this.onAccelerometerEvent,\n this.notifyError\n );\n\n this.gyroscopeProviderId = GyroscopeProvider.addEventListener(\n event => this.angularRateEvent = event,\n this.notifyError\n );\n\n this.attitudeProviderId = RelativeAttitudeFromInertialProvider.addEventListener(\n event => this.attitudeEvent = event,\n this.notifyError\n );\n }\n\n stop() {\n AccelerometerProvider.removeEventListener(this.accelerometerProviderId);\n GyroscopeProvider.removeEventListener(this.gyroscopeProviderId);\n RelativeAttitudeFromInertialProvider.removeEventListener(this.attitudeProviderId);\n }\n\n onAccelerometerEvent = (accelerationEvent: Acceleration) => {\n\n if (!this.attitudeEvent || !this.angularRateEvent) {\n return;\n }\n\n const {\n values: acceleration, timestamp\n } = accelerationEvent;\n\n /**\n * Step Detection and Step Size Detection\n */\n const linearAcc = StepProvider.computeLinearAcceleration(\n this.attitudeEvent.quaternion, acceleration);\n const stepDetected = this.stepDetector.compute(timestamp, linearAcc, this.angularRateEvent.values);\n\n if (stepDetected) {\n const size = this.stepDetector.lastStepSize * this._stepSizeMultiplier;\n this.numOfSteps++;\n this.notify({ size, number: this.numOfSteps });\n }\n }\n\n // Linear acceleration in ENU\n static computeLinearAcceleration(quaternion: Quaternion_t, acc: Vector3_t) {\n const linearAcc = Quaternion.rotateMatlab(Quaternion.inverse(quaternion), acc);\n linearAcc[2] -= GeoConstants.EARTH_GRAVITY;\n return linearAcc;\n }\n\n set stepSizeMultiplier(stepSizeMultiplier) {\n this._stepSizeMultiplier = stepSizeMultiplier;\n }\n\n get stepSizeMultiplier() {\n return this._stepSizeMultiplier;\n }\n\n set algorithm(algorithm) {\n switch (algorithm) {\n case 'ladetto':\n this.stepDetector = new StepDetectionLadetto();\n break;\n case 'minMaxPeaks':\n this.stepDetector = new StepDetectionMinMaxPeaks();\n break;\n case 'minMaxPeaks2':\n this.stepDetector = new StepDetectionMinMaxPeaks2();\n break;\n case 'minMaxPeaks3':\n default:\n algorithm = 'minMaxPeaks3';\n this.stepDetector = new StepDetectionMinMaxPeaks3();\n break;\n }\n this._algorithm = algorithm;\n }\n\n get algorithm() {\n return this._algorithm;\n }\n}\n\nexport function createStepProvider(algorithm: StepDetectorAlgorithmName) {\n const stepProvider = new StepProvider();\n stepProvider.algorithm = algorithm;\n return stepProvider;\n}\n\nexport default new StepProvider();\n","import { GeoRelativePosition } from '@wemap/geo';\nimport { deg2rad } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport StepProvider from '../../steps/StepProvider.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport { Step, AbsoluteAttitude } from '../../../events/Types.js';\n\n\nclass PdrProvider extends Provider<GeoRelativePosition> {\n\n private absoluteAttitudeProviderId?: number;\n private stepDetectionProviderId?: number;\n private attitudeEvent?: AbsoluteAttitude;\n\n // https://ieeexplore.ieee.org/document/7346766\n // private misalignment = [1, 0, 0, 0];\n private misalignmentError = deg2rad(3);\n\n getName = () => 'Pdr';\n\n availability() {\n return AvailabilityHelper.every([\n StepProvider.getAvailability(),\n AbsoluteAttitudeProvider.getAvailability()\n ]);\n }\n\n\n start() {\n\n this.stepDetectionProviderId = StepProvider.addEventListener(\n this.onStepEvent,\n this.notifyError\n );\n\n this.absoluteAttitudeProviderId = AbsoluteAttitudeProvider.addEventListener(\n event => (this.attitudeEvent = event),\n this.notifyError\n );\n\n }\n\n stop() {\n StepProvider.removeEventListener(this.stepDetectionProviderId);\n AbsoluteAttitudeProvider.removeEventListener(this.absoluteAttitudeProviderId);\n }\n\n private onStepEvent = (stepEvent: Step) => {\n\n if (!this.attitudeEvent) {\n return;\n }\n\n const stepSize = stepEvent.size;\n\n /**\n * There is three frames because (device heading != walking direction):\n *\n * Device frame (x-Device Right, y-Device Top, z-Device Front)\n * Navigation frame (x-Nav East, y-Nav North, z-Nav Up)\n * Earth local frame (x-East y-North z-Up)\n *\n *\n * For the PDR, in order to find the step direction,\n * we are looking for the rotation between the device frame and the navigation frame.\n * Attitude is the rotation from the device frame to the earth local frame.\n * Misalignment is the rotation from the navigation frame to the earth local frame\n */\n const deviceAttitude = this.attitudeEvent;\n\n /**\n * For optimisation, as we define misalignment to identity, we do not process the quat mulitply formula.\n */\n // const deviceInNavFrame = Quaternion.multiply(deviceAttitude.quaternion, this.misalignment);\n // const deviceDirection = new Attitude(deviceInNavFrame).heading;\n const deviceDirection = deviceAttitude.heading;\n\n /**\n * A bad accuracy from PDR is due to three things:\n * - Attitude accuracy\n * - Misalignement (device heading != walking direction)\n * - Step detection false positives / false negatives\n * Following formula only use attitude accuracy with cone formula\n */\n const deviceDirectionAccuracy = deviceAttitude.accuracy! + this.misalignmentError;\n const accuracy = (stepSize / 2) * Math.sin(deviceDirectionAccuracy / 2);\n const timestamp = deviceAttitude.time;\n\n /**\n * Relative position is defined in ENU frame\n */\n const position = new GeoRelativePosition(\n stepSize * Math.sin(deviceDirection),\n stepSize * Math.cos(deviceDirection),\n 0,\n timestamp,\n accuracy,\n deviceDirection\n );\n\n this.notify(position);\n }\n}\n\nexport default new PdrProvider();\n","import { GeoRelativePosition } from '@wemap/geo';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport GeoRelativePositionFromArCoreProvider from './GeoRelativePositionFromArCoreProvider.js';\nimport PdrProvider from './PdrProvider.js';\n\n\nclass GeoRelativePositionProvider extends Provider<GeoRelativePosition> {\n\n providerId?: number;\n geoRelativeProvider?: Provider<GeoRelativePosition>;\n\n getName = () => 'GeoRelativePosition';\n\n availability() {\n return AvailabilityHelper.some([\n PdrProvider.getAvailability(),\n GeoRelativePositionFromArCoreProvider.getAvailability()\n ]);\n }\n\n async start() {\n const availabilityError = await GeoRelativePositionFromArCoreProvider.getAvailability();\n this.geoRelativeProvider = availabilityError ? PdrProvider : GeoRelativePositionFromArCoreProvider;\n this.providerId = this.geoRelativeProvider.addEventListener(this.notify, this.notifyError);\n }\n\n stop() {\n this.geoRelativeProvider?.removeEventListener(this.providerId);\n delete this.geoRelativeProvider;\n }\n}\n\nexport default new GeoRelativePositionProvider();\n","import Provider from '../Provider.js';\nimport AccelerometerProvider from '../imu/AccelerometerProvider.js';\nimport { Acceleration, Inclination } from '../../events/Types.js';\n\n/**\n * Inclination provider gives the inclination of the device using Imu Sensor\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationFromAccProvider extends Provider<Inclination> {\n\n providerId?: number;\n\n getName = () => 'InclinationFromAcc';\n\n availability = () => AccelerometerProvider.getAvailability();\n\n start() {\n this.providerId = AccelerometerProvider.addEventListener(\n this.onAccelerometerEvent,\n this.notifyError\n );\n }\n\n stop() {\n AccelerometerProvider.removeEventListener(this.providerId);\n }\n\n private onAccelerometerEvent = (accelerometerEvent: Acceleration) => {\n const acc = accelerometerEvent.values;\n\n const screenOrientation = window.orientation || 0;\n\n const sizeAcc = Math.sqrt(acc[0] * acc[0] + acc[1] * acc[1] + acc[2] * acc[2]);\n const accNormalized = [acc[0] / sizeAcc, acc[1] / sizeAcc, acc[2] / sizeAcc];\n\n const q = [accNormalized[2] + 1, accNormalized[1], -accNormalized[0], 0];\n const qSize = Math.sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]);\n const qNormalized = [q[0] / qSize, q[1] / qSize, q[2] / qSize, 0];\n\n let inclination;\n if (screenOrientation === 0) {\n inclination = Math.asin(2 * qNormalized[1] * qNormalized[0]);\n } else if (screenOrientation === 90) {\n inclination = -Math.asin(2 * qNormalized[2] * qNormalized[0]);\n } else if (screenOrientation === -90) {\n inclination = Math.asin(2 * qNormalized[2] * qNormalized[0]);\n } else { // if (screenOrientation === 180) {\n inclination = -Math.asin(2 * qNormalized[1] * qNormalized[0]);\n }\n\n this.notify(inclination);\n };\n}\n\nexport default new InclinationFromAccProvider();\n","import { Quaternion_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport RelativeAttitudeFromInertialProvider from '../attitude/relative/RelativeAttitudeFromInertialProvider.js';\nimport { Inclination } from '../../events/Types.js';\n\n\n/**\n * Inclination provider gives the inclination of the device using Relative Attitude\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationFromRelativeAttitudeProvider extends Provider<Inclination> {\n\n providerId?: number;\n\n getName = () => 'InclinationFromRelativeAttitude';\n\n availability = () => RelativeAttitudeFromInertialProvider.getAvailability();\n\n start() {\n this.providerId = RelativeAttitudeFromInertialProvider.addEventListener(\n attitudeEvent => {\n const inclination = this.enuQuatToInclination(attitudeEvent.quaternion);\n this.notify(inclination);\n },\n this.notifyError\n );\n }\n\n stop() {\n RelativeAttitudeFromInertialProvider.removeEventListener(this.providerId);\n }\n\n enuQuatToInclination(q: Quaternion_t) {\n const screenOrientation = window.orientation || 0;\n\n if (screenOrientation === 0) {\n return Math.asin(2 * (q[2] * q[3] + q[1] * q[0]));\n } else if (screenOrientation === 90) {\n return Math.asin(2 * (q[1] * q[3] - q[2] * q[0]));\n } else if (screenOrientation === -90) {\n return Math.asin(2 * (q[2] * q[0] - q[1] * q[3]));\n }\n // else if (screenOrientation === 180)\n return -Math.asin(2 * (q[2] * q[3] + q[1] * q[0]));\n }\n}\n\nexport default new InclinationFromRelativeAttitudeProvider();\n","import Provider from '../Provider.js';\nimport InclinationFromAccProvider from './InclinationFromAccProvider.js';\nimport InclinationFromRelativeAttitudeProvider from './InclinationFromRelativeAttitudeProvider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport { Inclination } from '../../events/Types.js';\n\n/**\n * Inclination provider gives the inclination of the device using Imu Sensor\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationProvider extends Provider<Inclination> {\n\n provider?: Provider<Inclination>;\n providerId?: number;\n\n getName = () => 'Inclination';\n\n availability() {\n return AvailabilityHelper.some([\n InclinationFromAccProvider.getAvailability(),\n InclinationFromRelativeAttitudeProvider.getAvailability()\n ]);\n }\n\n async start() {\n\n const startInclinationFromAcc = () => {\n this.provider = InclinationFromAccProvider;\n this.providerId = this.provider.addEventListener(\n this.notify,\n this.notifyError\n );\n };\n\n if (await InclinationFromRelativeAttitudeProvider.getAvailability()) {\n this.provider = InclinationFromRelativeAttitudeProvider;\n this.providerId = this.provider.addEventListener(\n this.notify,\n () => {\n InclinationFromRelativeAttitudeProvider.removeEventListener(this.providerId);\n startInclinationFromAcc();\n }\n );\n } else {\n startInclinationFromAcc();\n }\n }\n\n\n stop() {\n if (this.provider) {\n this.provider.removeEventListener(this.providerId);\n }\n }\n}\n\nexport default new InclinationProvider();\n","import { Calibration } from '@wemap/camera';\nimport { Attitude, AttitudeJson, UserPosition, UserPositionJson } from '@wemap/geo';\nimport { Device } from '@wemap/utils';\n\nexport type CoarsePoseJson = {\n attitude?: AttitudeJson,\n position?: UserPositionJson,\n};\n\nexport type CoarsePose = {\n attitude?: Attitude,\n position?: UserPosition,\n};\n\nexport type VpsMetadataJson = {\n size: [number, number], // [width, height]\n calibration?: Calibration,\n coarse?: CoarsePoseJson,\n device?: Device\n}\n\n\nclass VpsMetadata {\n\n constructor(\n public size: { width: number, height: number },\n public calibration: Calibration | null = null,\n public coarse: CoarsePose | null = null,\n public device: Device | null = null,\n ) { }\n\n toJson(): VpsMetadataJson {\n return {\n size: [this.size.width, this.size.height],\n ...(this.calibration && { calibration: this.calibration }),\n ...(this.coarse && {\n coarse: {\n ...(this.coarse.attitude && { attitude: this.coarse.attitude.toJson() }),\n ...(this.coarse.position && { position: this.coarse.position.toJson() })\n }\n }),\n ...(typeof this.device === 'object' && { device: this.device })\n };\n }\n\n\n static fromJson(json: VpsMetadataJson) {\n return new VpsMetadata(\n {\n width: json.size[0],\n height: json.size[1]\n },\n json.calibration,\n {\n ...(json.coarse?.position && { position: UserPosition.fromJson(json.coarse.position) }),\n ...(json.coarse?.attitude && { attitude: Attitude.fromJson(json.coarse.attitude) })\n },\n json.device\n );\n }\n}\n\nexport default VpsMetadata;\n","import { canvasToBase64, base64ToCanvas } from '@wemap/camera';\n\nimport VpsMetadata, { VpsMetadataJson } from './VpsMetadata.js';\n\nexport type VpsRequestJson = VpsMetadataJson & {\n image: string\n}\n\nclass VpsRequest {\n\n constructor(public metadata: VpsMetadata, public image: HTMLCanvasElement) {}\n\n toJson() {\n const base64Image = canvasToBase64(this.image);\n return {\n image: base64Image,\n ...this.metadata.toJson()\n };\n }\n\n static fromJson(json: VpsRequestJson) {\n return new VpsRequest(\n VpsMetadata.fromJson(json),\n base64ToCanvas(json.image)\n );\n }\n}\n\nexport default VpsRequest;\n","import { Attitude, AttitudeJson, UserPosition, UserPositionJson } from '@wemap/geo';\n\nexport type VpsResponseJson = {\n success: boolean,\n attitude?: AttitudeJson,\n position?: UserPositionJson\n}\n\nclass VpsResponse {\n\n constructor(\n public success: boolean,\n public attitude: Attitude | null = null,\n public position: UserPosition | null = null\n ) { }\n\n toJson(): VpsResponseJson {\n return {\n success: this.success,\n attitude: this.attitude?.toJson(),\n position: this.position?.toJson()\n }\n }\n\n static fromJson(json: VpsResponseJson, imageRecordTime: number | null = null) {\n\n let attitude: Attitude | null = null;\n if (json.attitude) {\n attitude = Attitude.fromJson(json.attitude);\n attitude.time = imageRecordTime;\n }\n\n let position: UserPosition | null = null;\n if (json.position) {\n position = UserPosition.fromJson(json.position);\n position.time = imageRecordTime;\n }\n\n return new VpsResponse(json.success, attitude, position);\n }\n}\n\nexport default VpsResponse;\n","import { Calibration, reduceImageSize, convertToGrayscale } from '@wemap/camera';\nimport Logger from '@wemap/logger';\nimport { Quaternion_t } from '@wemap/maths/index.js';\nimport { TimeUtils, UserAgentUtils } from '@wemap/utils';\nimport VpsMetadata, { CoarsePose } from './VpsMetadata.js';\n\nimport VpsRequest from './VpsRequest.js';\nimport VpsResponse from './VpsResponse.js';\n\nclass ImageRelocalization {\n\n static _prepareRequest(\n imageCanvas: HTMLCanvasElement,\n calibration: Calibration | null = null,\n coarsePose: CoarsePose | null = null\n ) {\n convertToGrayscale(imageCanvas);\n const reducedImage = reduceImageSize(imageCanvas, 1280);\n\n const metadata = new VpsMetadata(\n { width: reducedImage.width, height: reducedImage.height },\n calibration,\n coarsePose,\n UserAgentUtils.getDeviceFromUserAgent()\n );\n\n return new VpsRequest(metadata, reducedImage);\n }\n\n \n static async relocalize(\n endpointUrl: string,\n imageCanvas: HTMLCanvasElement,\n calibration: Calibration | null = null,\n coarsePose: CoarsePose | null = null,\n customHeaders: Record<string, string> | null = null\n ) {\n\n const timeBeforeRequest = TimeUtils.preciseTime() / 1e3;\n\n // 1. Prepare the request\n const vpsRequest = this._prepareRequest(imageCanvas, calibration, coarsePose);\n\n // 2. Send the request\n let serverResponse;\n try {\n const body = JSON.stringify(vpsRequest.toJson());\n Logger.debug(`[VPS] Request (${(body.length / 1024).toFixed(0)} kB) sent to server ${endpointUrl}`);\n serverResponse = await fetch(endpointUrl, {\n method: 'POST',\n body,\n headers: Object.assign(\n { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n customHeaders ? customHeaders : {}\n )\n });\n } catch (e) {\n Logger.debug('[VPS] Server respond error');\n return null;\n }\n\n if (serverResponse.status !== 200) {\n Logger.debug('[VPS] Server respond error');\n return null;\n }\n\n // 3. Parse the response\n const json = await serverResponse.json();\n const res = VpsResponse.fromJson(json, timeBeforeRequest);\n Logger.debug(`[VPS] Server respond ${res.success ? 'success' : 'not found'}`);\n return res;\n }\n\n static getHeadingFromQuaternion(quaternion: Quaternion_t) {\n\n const [qw, qx, qy, qz] = quaternion;\n\n const s = Math.sqrt(2) / 2;\n const C = [s * (qw - qx), s * (qw + qx), s * (qy + qz), s * (qz - qy)];\n return -Math.atan2(2 * C[3] * C[0] - 2 * C[2] * C[1], 1 - 2 * C[1] ** 2 - 2 * C[3] ** 2);\n\n // ---- Not optimized version ----\n\n // const eulerAnglesAR = Rotations.quaternionToEulerZXY(\n // Quaternion.multiply(\n // quaternion,\n // Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2)\n // )\n // );\n\n // return -eulerAnglesAR[0];\n }\n}\n\nexport default ImageRelocalization;\n","import { Attitude } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport RelativeAttitudeFromBrowser from '../../attitude/relative/RelativeAttitudeFromBrowserProvider.js';\n\nexport default class RelativeRotationCalc {\n\n _providerId?: number;\n\n _isRunning = false;\n _dataOnStart: Attitude | null = null;\n\n tickStart() {\n this._dataOnStart = null;\n\n if (this._isRunning) {\n // Do not start the provider if tickStart() has already been called without tickEnd()\n return;\n }\n\n this._isRunning = true;\n\n this._providerId = RelativeAttitudeFromBrowser.addEventListener(event => {\n if (!this._dataOnStart) {\n this._dataOnStart = event;\n }\n });\n }\n\n tickEnd() {\n if (!this._isRunning) {\n Logger.warn('You have to call tickStart before tickEnd');\n return null;\n }\n\n this._internalStop();\n\n if (!this._dataOnStart) {\n Logger.warn('Delay was too short between tickStart and tickEnd '\n + 'or RelativeAttitudeProvider cannot be retrieved.');\n return null;\n }\n\n const dataOnEnd = RelativeAttitudeFromBrowser.lastEvent!;\n return Attitude.diff(this._dataOnStart, dataOnEnd);\n }\n\n _internalStop() {\n RelativeAttitudeFromBrowser.removeEventListener(this._providerId);\n delete this._providerId;\n this._isRunning = false;\n }\n\n release() {\n if (this._isRunning) {\n this._internalStop();\n }\n }\n}\n","class MissingPoleStarError extends Error {\n\n static DEFAULT_MESSAGE = 'PoleStar is missing';\n\n constructor(message?: string) {\n super(message || MissingPoleStarError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingPoleStarError;\n","import { deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport MissingPoleStarError from '../../../errors/MissingPoleStarError.js';\nimport MissingNativeInterfaceError from '../../../errors/MissingNativeInterfaceError.js';\nimport Constants from '../../Constants.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\nimport { NativePolestarPosition } from '../../NativeProviders.js';\n\nclass PoleStarProvider extends Provider<AbsolutePosition> {\n\n getName = () => 'PoleStar';\n\n constructor() {\n super();\n this.addMethodsToNativeJsProvider();\n }\n\n availability() {\n try {\n this.nativeProvider.checkAvailability();\n return Promise.resolve();\n } catch (e) {\n return Promise.resolve(e as Error);\n }\n }\n\n setApiKey(apiKey: string) {\n this.nativeProvider.setApiKey(apiKey);\n }\n\n start() {\n this.nativeProvider.start();\n }\n\n stop() {\n this.nativeProvider.stop();\n }\n\n get nativeProvider() {\n\n if (!this.nativeInterface) {\n throw new MissingNativeInterfaceError();\n }\n\n const nativeProvider = this.nativeInterface.getPoleStarProvider();\n if (!nativeProvider) {\n throw new MissingPoleStarError();\n }\n\n return nativeProvider;\n }\n\n\n\n addMethodsToNativeJsProvider() {\n\n if (!this.nativeJsInterface) {\n return;\n }\n\n this.nativeJsInterface.polestar = {\n callbackError: (errorMessage: string) => this.notifyError(new Error(errorMessage)),\n callbackPosition: (jsonString: string) => {\n\n const json: NativePolestarPosition = JSON.parse(jsonString);\n\n const timestamp = TimeUtils.unixTimestampToPreciseTime(json.time) / 1e3;\n\n const position = new AbsolutePosition(\n json.lat,\n json.lng,\n Constants.DEFAULT_ALTITUDE,\n json.alt / 5,\n timestamp,\n json.accuracy,\n deg2rad(json.bearing)\n );\n\n this.notify(position);\n }\n };\n\n }\n}\n\nexport default new PoleStarProvider();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport { SharedCameras, Camera } from '@wemap/camera';\nimport { Attitude } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { Quaternion, deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport Inclination from '../../inclination/InclinationProvider.js';\nimport ImageRelocalization from './ImageRelocalization.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport RelativeRotationCalc from './RelativeRotationCalc.js';\nimport GnssWifiProvider from '../../position/absolute/GnssWifiProvider.js';\nimport AbsolutePositionProvider from '../../position/absolute/AbsolutePositionProvider.js';\nimport PoleStarProvider from '../../position/absolute/PoleStarProvider.js';\nimport { AbsoluteAttitude, AbsolutePosition } from '../../../events/Types.js';\nimport { CoarsePose } from './VpsMetadata.js';\n\nexport type VpsEvent = { absoluteAttitude: AbsoluteAttitude, absolutePosition: AbsolutePosition };\nclass VpsProvider extends Provider<VpsEvent> {\n\n static MIN_TIME_BETWEEN_TWO_REQUESTS = 1000; // in ms\n static DEFAULT_MIN_INCLINATION_FOR_REQUEST = deg2rad(60); // in radians\n static DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST = 200; // in ms\n static DEFAULT_USE_COARSE_POSE = true;\n static CAMERA_TO_SMARTPHONE_ROT = Quaternion.fromAxisAngle([1, 0, 0], Math.PI);\n\n _relativeRotationCalc?: RelativeRotationCalc;\n\n _serverError = false;\n _cameraError = false;\n\n _camera: Camera | null = null;\n _endpoint: string | null = null;\n\n _inclinationProviderId?: number;\n\n _minInclinationForRequest = VpsProvider.DEFAULT_MIN_INCLINATION_FOR_REQUEST;\n _waitTimeMinInclinationForRequest = VpsProvider.DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST;\n _useCoarsePose = VpsProvider.DEFAULT_USE_COARSE_POSE;\n\n getName = () => 'Vps';\n\n availability = () => Camera.checkAvailability();\n\n start() {\n\n // 1. Inclination\n this._inclinationProviderId = Inclination.addEventListener();\n\n // 2. Relative Rotation Calc\n this._relativeRotationCalc = new RelativeRotationCalc();\n\n // 3. Add listeners on shared cameras to detect new cameras\n SharedCameras.on('added', this._onCameraDetected);\n SharedCameras.on('removed', this._onCameraRemoved);\n\n // 4. If a camera already exists, use it\n if (SharedCameras.list.length) {\n if (SharedCameras.list.length > 1) {\n Logger.warn('It seems that more than 1 camera has been detected'\n + ' for VPS. Taking the first...');\n }\n this._useCamera(SharedCameras.list[0].camera);\n }\n }\n\n stop() {\n\n Inclination.removeEventListener(this._inclinationProviderId);\n\n this._relativeRotationCalc?.release();\n\n SharedCameras.off('added', this._onCameraDetected);\n SharedCameras.off('removed', this._onCameraRemoved);\n\n this._camera = null;\n }\n\n _onCameraDetected = ({ camera }: { camera: Camera }) => {\n if (this._camera) {\n Logger.warn('It seems that more than 1 camera has been detected'\n + ' for VPS. Taking the first...');\n }\n this._useCamera(camera);\n }\n\n _onCameraRemoved = () => {\n if (this._camera) {\n this._camera.off('started', this._internalStart);\n this._camera.off('stopped', this._internalStop);\n } else {\n Logger.warn('There is no previously detected camera but once has stopped');\n }\n this._camera = null;\n }\n\n _useCamera(camera: Camera) {\n this._camera = camera;\n\n camera.on('started', this._internalStart);\n camera.on('stopped', this._internalStop);\n\n if (camera.state === 'started') {\n this._internalStart();\n }\n }\n\n\n _internalStart = async () => {\n\n if (!this._endpoint) {\n this.notifyError(new Error('VPS endpoint has not been set before calling start()'));\n return;\n }\n\n let lastRequestTime = null;\n const isProviderStopped = () => this.state === 'stopped';\n while (!isProviderStopped()) {\n\n // 1. Handle the time to wait between two requests (MIN_TIME_BETWEEN_TWO_REQUESTS)\n if (lastRequestTime !== null) {\n const diffTime = TimeUtils.preciseTime() - lastRequestTime;\n const timeToWait = Math.max(0, VpsProvider.MIN_TIME_BETWEEN_TWO_REQUESTS - diffTime);\n await new Promise(resolve => setTimeout(resolve, timeToWait));\n }\n lastRequestTime = TimeUtils.preciseTime();\n\n // 2. Check if Vps is not stopped and camera is still started\n if (isProviderStopped()\n || !this._camera\n || this._camera.state !== 'started') {\n break;\n }\n\n // 2.a. Do not send an image if smartphone looks at the floor\n const inclination = Inclination.lastEvent ? Inclination.lastEvent : null;\n if (inclination !== null\n && inclination < this._minInclinationForRequest) {\n await new Promise(resolve => setTimeout(resolve, this._waitTimeMinInclinationForRequest));\n continue;\n }\n\n // 3. Get current image from camera and relocalize it.\n\n // 3.a. Get current image and time it.\n this._relativeRotationCalc?.tickStart();\n const image = await this._camera.currentImage;\n if (!image) {\n continue;\n }\n\n // 3.b. Retrieve coarse position if necessary.\n let coarsePose: CoarsePose | null = null;\n const bestCoarsePosition = AbsolutePositionProvider.getBestPositionEvent(GnssWifiProvider.lastEvent, PoleStarProvider.lastEvent);\n if (this._useCoarsePose && (bestCoarsePosition || AbsoluteAttitudeProvider.lastEvent)) {\n coarsePose = {\n ...(bestCoarsePosition && {position: bestCoarsePosition}),\n ...(AbsoluteAttitudeProvider.lastEvent && {attitude: AbsoluteAttitudeProvider.lastEvent})\n };\n }\n\n // 3.c. Send image and metadata.\n const res = await ImageRelocalization.relocalize(this._endpoint, image, null, coarsePose);\n if (!res || !res.success) {\n continue;\n }\n\n // 4. If relocalization is successful, apply the transforms\n const enuToCameraRot = res.attitude!.quaternion;\n const enuToSmartphoneRot = Quaternion.multiply(\n enuToCameraRot,\n VpsProvider.CAMERA_TO_SMARTPHONE_ROT\n );\n\n const deviceQuaternion = Quaternion.multiply(\n Quaternion.fromAxisAngle([0, 0, 1], deg2rad(window.orientation || 0)),\n enuToSmartphoneRot\n );\n\n const diffAttitude = this._relativeRotationCalc?.tickEnd() || new Attitude([1, 0, 0, 0]);\n const deviceQuaternionWithRelOffset = Quaternion.multiply(\n deviceQuaternion,\n diffAttitude.quaternion\n );\n const attitude = new AbsoluteAttitude(\n deviceQuaternionWithRelOffset,\n res.attitude!.time,\n res.attitude!.accuracy\n );\n\n // [16/06/22] Force VPS accuracy to 5m if the information does not exist\n // this allows to correctly fuse positions from different providers (VPS,\n // GnssWifi, Pole Star...)\n const devicePosition = res.position!.clone();\n if (devicePosition.accuracy === null) {\n devicePosition.accuracy = 5;\n }\n\n // 5. Finally, notify the listeners if the VPS is not stopped\n if (isProviderStopped()) {\n break;\n }\n\n this.notify({\n absoluteAttitude: attitude,\n absolutePosition: devicePosition\n });\n\n }\n }\n\n _internalStop = () => {\n // do nothing\n }\n\n get endpoint() {\n return this._endpoint;\n }\n\n set endpoint(endpoint) {\n this._endpoint = endpoint;\n }\n\n get minInclinationForRequest() {\n return this._minInclinationForRequest;\n }\n\n set minInclinationForRequest(minInclinationForRequest) {\n this._minInclinationForRequest = minInclinationForRequest;\n }\n\n get waitTimeMinInclinationForRequest() {\n return this._waitTimeMinInclinationForRequest;\n }\n\n set waitTimeMinInclinationForRequest(waitTimeMinInclinationForRequest) {\n this._waitTimeMinInclinationForRequest = waitTimeMinInclinationForRequest;\n }\n\n get useCoarsePose() {\n return this._useCoarsePose;\n }\n\n set useCoarsePose(useCoarsePose) {\n this._useCoarsePose = useCoarsePose;\n }\n}\n\nexport default new VpsProvider();\n","import { Level, GeoRelativePosition, UserPosition } from '@wemap/geo';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport MapMatchingHandler from '../../../mapmatching/MapMatchingHandler.js';\nimport GnssWifiProvider from './GnssWifiProvider.js';\nimport GeoRelativePositionProvider from '../relative/GeoRelativePositionProvider.js';\nimport ProvidersOptions from '../../../ProvidersOptions.js';\nimport VpsProvider from '../../vision/vps/VpsProvider.js';\nimport PoleStarProvider from './PoleStarProvider.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\nclass AbsolutePositionProvider extends Provider<AbsolutePosition> {\n\n // Use the new absolute position if its accuracy is at least x times better than the last one.\n static ACCURACY_RELOC_RATIO = 1; // or 1.5\n static USE_MM_FOR_FEED = true;\n\n _polestarProviderId?: number;\n _vpsProviderId?: number;\n _gnssWifiProviderId?: number;\n _relativePositionProviderId?: number;\n _mapMatchingHandlerId?: number;\n\n useAllAbsolutePositions = false;\n _waitUntilNextVpsPosition = false;\n _lastPolestarFix: number | null = null;\n\n getName = () => 'AbsolutePosition';\n\n\n availability() {\n return AvailabilityHelper.some([\n GeoRelativePositionProvider.getAvailability(),\n GnssWifiProvider.getAvailability(),\n ...(ProvidersOptions.hasPoleStar ? [PoleStarProvider.getAvailability()] : []),\n VpsProvider.getAvailability()\n ]);\n }\n\n\n start() {\n GeoRelativePositionProvider.getAvailability()\n .then((error) => {\n if (!error) {\n this._relativePositionProviderId = GeoRelativePositionProvider.addEventListener(\n e => this._onRelativePosition(e)\n );\n } else {\n // do nothing\n }\n });\n\n // GnssWifi\n this._gnssWifiProviderId = GnssWifiProvider.addEventListener(\n event => {\n const clone = event.clone();\n clone.bearing = null;\n this._onAbsolutePosition(clone, false);\n }\n );\n\n // Vps\n this._vpsProviderId = VpsProvider.addEventListener(\n event => this._onAbsolutePosition(event.absolutePosition),\n this.notifyError,\n false\n );\n\n // PoleStar\n if (ProvidersOptions.hasPoleStar) {\n this._polestarProviderId = PoleStarProvider.addEventListener(polestarPositionEvent => {\n\n this._lastPolestarFix = TimeUtils.preciseTime();\n const psPositionUsed = this._onAbsolutePosition(polestarPositionEvent);\n\n /**\n * In the case of a degraded position from PoleStar and a good position from GnssWifi,\n * we still need to retrieve the level from PoleStar.\n * To do so, we duplicate lastEvent and add the level from PoleStar to the current\n * position, then we notify with the new position.\n */\n if (!psPositionUsed && this.lastEvent?.level === null) {\n const lastPositionWithLevel = this.lastEvent.clone();\n lastPositionWithLevel.level = polestarPositionEvent.level;\n this.notify(lastPositionWithLevel);\n }\n });\n }\n\n this._mapMatchingHandlerId = MapMatchingHandler.addEventListener();\n }\n\n\n /**\n * @override\n */\n stop() {\n if (this._relativePositionProviderId) {\n GeoRelativePositionProvider.removeEventListener(this._relativePositionProviderId);\n delete this._relativePositionProviderId;\n }\n if (this._gnssWifiProviderId) {\n GnssWifiProvider.removeEventListener(this._gnssWifiProviderId);\n delete this._gnssWifiProviderId;\n }\n if (this._vpsProviderId) {\n VpsProvider.removeEventListener(this._vpsProviderId);\n delete this._vpsProviderId;\n }\n if (this._polestarProviderId) {\n PoleStarProvider.removeEventListener(this._polestarProviderId);\n delete this._polestarProviderId;\n }\n\n MapMatchingHandler.removeEventListener(this._mapMatchingHandlerId);\n }\n\n\n private _shouldTakeIntoAccountNewAbsolutePosition(newPositionEvent: AbsolutePosition, canContainLevel = true) {\n\n const newPosition = newPositionEvent;\n const lastPosition = this.lastEvent || null;\n\n // 1. Verifiy if it is the first known absolute position\n if (!lastPosition) {\n return true;\n }\n\n // 2. Is the new position accuracy is better enough than the last position accuracy\n const isBetterEnough = newPosition.accuracy! * AbsolutePositionProvider.ACCURACY_RELOC_RATIO <= lastPosition.accuracy!;\n if (isBetterEnough) {\n return true;\n }\n\n // 3.a. Is the new position is far from the new one (regarding accuracy)\n // This condition return true if the two positions accuracy circles does not intersect.\n // This is important if the person put the current page in the background during a while. But,\n // could be dangerous if two providers do not provide close positions (ping-pong effect). This\n // is why the 3.b. condition has been added.\n // TODO: add a routine to augment the current position accuracy when the page is in background\n const isFarEnough = lastPosition.distanceTo(newPosition) > lastPosition.accuracy! + newPosition.accuracy!;\n if (isFarEnough) {\n return true;\n }\n\n // 3.b. Added on 16/06/22\n // The goal of this condition is to avoid continuous jumps between positions from two providers\n // (i.e. GnssWifi and PoleStar)\n const isFarEnoughAndAccuracyIsBetter = isFarEnough && newPosition.accuracy! <= lastPosition.accuracy!;\n\n if (isBetterEnough && isFarEnoughAndAccuracyIsBetter) {\n return true;\n }\n\n // 4. Added on 23/06/22\n // The goal of this condition is to take into account levels change when map-matching is not enabled / set\n const isChangingLevel = canContainLevel && !Level.equals(newPosition.level, lastPosition.level);\n if (isChangingLevel) {\n return true;\n }\n\n return false;\n }\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n private _onAbsolutePosition(positionEvent: AbsolutePosition, canContainLevel = true) {\n\n if (!this._shouldTakeIntoAccountNewAbsolutePosition(positionEvent, canContainLevel)\n && !this.useAllAbsolutePositions) {\n return false;\n }\n\n const newPosition = positionEvent.clone();\n const lastPosition = this.lastEvent ? this.lastEvent : null;\n\n if (lastPosition) {\n if (!canContainLevel) {\n newPosition.level = lastPosition.level;\n }\n\n // If the new position does not have a bearing, retrieve the bearing from the last position\n if (newPosition.bearing === null) {\n newPosition.bearing = lastPosition.bearing;\n }\n }\n\n // If the MM is disable or the network is not set yet, use the new position as it is.\n // If the position bearing is null, do not use MM, it is too dangerous.\n if (!MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPosition);\n return true;\n }\n\n return MapMatchingHandler.notifyPositionFromAbsolute(newPosition);\n }\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n _onRelativePosition(relativeEvent: GeoRelativePosition) {\n\n if (!this.lastEvent || this._waitUntilNextVpsPosition) {\n return false;\n }\n\n const lastPosition = this.lastEvent;\n\n const offsetPos = relativeEvent;\n\n const dist = Math.sqrt(offsetPos.x ** 2 + offsetPos.y ** 2);\n const bearing = Math.atan2(offsetPos.x, offsetPos.y);\n const alt = lastPosition.alt !== null ? offsetPos.z : null;\n\n const newPosition = lastPosition.destinationPoint(dist, bearing, alt);\n newPosition.bearing = offsetPos.bearing;\n newPosition.time = offsetPos.time;\n newPosition.accuracy! += offsetPos.accuracy!;\n\n\n if (!MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPosition);\n return true;\n }\n\n return MapMatchingHandler.notifyPositionFromRelative(newPosition);\n }\n\n\n feed(data: AbsolutePosition) {\n\n let newPositionEvent: AbsolutePosition;\n\n if (data instanceof UserPosition) {\n\n if (data.time === null) {\n throw Error('the time of the position is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the position is not defined');\n }\n\n newPositionEvent = data;\n\n } else {\n throw new Error('data is nor an UserPosition or an AbsolutePositionEvent');\n }\n\n // If the MM is disable or the network is not set yet, use the new position as it is.\n if (!AbsolutePositionProvider.USE_MM_FOR_FEED || !MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPositionEvent);\n return;\n }\n\n MapMatchingHandler.notifyPositionFromFeed(newPositionEvent);\n }\n\n getBestPositionEvent(...absolutePositionEvents: (AbsolutePosition | null)[]) {\n return absolutePositionEvents.reduce((best, value) => {\n if (!best) {\n return value;\n }\n if (!value || value.accuracy === null || value.time === null) {\n return best;\n }\n const { accuracy: curAccuracy, time: curTime } = value;\n const { accuracy: bestAccuracy, time: bestTime } = best;\n // 1.3888 corresponds to 1.3888 m/s (5 km/h)\n return curAccuracy < (bestAccuracy! + 1.3888 * (curTime - bestTime!)) ? value : best;\n }, null as null | AbsolutePosition);\n }\n}\n\nexport default new AbsolutePositionProvider();\n","import * as geomag from 'geomag';\n\nimport { deg2rad, rad2deg, Quaternion, Rotations, Quaternion_t } from '@wemap/maths';\nimport { Browser, BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AskImuOnDesktopError from '../../../errors/AskImuOnDesktopError.js';\nimport MissingMagnetometerError from '../../../errors/MissingMagnetometerError.js';\nimport MissingSensorError from '../../../errors/MissingSensorError.js';\nimport AbsolutePositionProvider from '../../position/absolute/AbsolutePositionProvider.js';\nimport { AbsoluteAttitude, AbsolutePosition } from '../../../events/Types.js';\n\n\n// https://stackoverflow.com/a/73369838/2239938\nexport interface DeviceOrientationEventiOS extends DeviceOrientationEvent {\n webkitCompassHeading: number | null;\n webkitCompassAccuracy: number | null;\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n\n\ndeclare global {\n interface Window {\n addEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;\n addEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;\n removeEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;\n removeEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;\n }\n}\n\n\n\n/**\n * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation or deviceorientationabsolute\n * The provider does not work until an AbsolutePosition is given. This is necessary to\n * calculate declination.\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via deviceorientationabsolute)\n * Safari iOS (v12.0): YES (via deviceorientation and event.webkitCompassHeading)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}\n * Firefox Android (v65.0.1): NO {@link https://www.fxsitecompat.com/en-CA/docs/2018/various-device-sensor-apis-are-now-deprecated/}\n *\n * -----------------------------------\n */\nclass AbsoluteAttitudeFromBrowser extends Provider<AbsoluteAttitude> {\n\n // from http://tyrex.inria.fr/mobile/benchmarks-attitude/\n DEFAULT_ACCURACY = deg2rad(15);\n\n absolutePositionProviderId?: number;\n absolutePositionEvent?: AbsolutePosition;\n\n declinationQuaternion?: Quaternion_t;\n magQuaternion?: Quaternion_t;\n magQuaternionTimestamp?: number;\n\n iosPreviousQuat?: Quaternion_t;\n iosIsSkyMode: boolean | null = null;\n\n\n getName = () => 'AbsoluteAttitudeFromBrowser';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n\n\n const subscribe = () => {\n switch (BrowserUtils.getName()) {\n case Browser.CHROME:\n window.addEventListener('deviceorientationabsolute',\n this.onDeviceOrientationChromeEvent, true);\n break;\n\n case Browser.SAFARI:\n case Browser.IOS_WEBVIEW:\n window.addEventListener('deviceorientation',\n this.onDeviceOrientationSafariEvent, true);\n break;\n }\n };\n\n const requestPermission = (DeviceOrientationEvent as unknown as DeviceOrientationEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(this.notifyError);\n } else {\n subscribe();\n }\n\n\n const lastAbsolutePosition = AbsolutePositionProvider.lastEvent;\n if (lastAbsolutePosition) {\n this.onAbsolutePositionEvent(lastAbsolutePosition);\n } else {\n this.absolutePositionProviderId = AbsolutePositionProvider.addEventListener(\n this.onAbsolutePositionEvent,\n this.notifyError,\n false\n );\n }\n\n }\n\n stop() {\n switch (BrowserUtils.getName()) {\n case Browser.CHROME:\n window.removeEventListener('deviceorientationabsolute',\n this.onDeviceOrientationChromeEvent, true);\n break;\n\n case Browser.SAFARI:\n case Browser.IOS_WEBVIEW:\n window.removeEventListener('deviceorientation',\n this.onDeviceOrientationSafariEvent, true);\n break;\n }\n\n AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);\n }\n\n\n onDeviceOrientationChromeEvent = (e: DeviceOrientationEvent) => {\n\n this.magQuaternionTimestamp = e.timeStamp / 1e3;\n\n if (typeof e.alpha !== 'number' || typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientationabsolute'));\n return;\n }\n\n this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees(\n [e.alpha, e.beta, e.gamma]);\n\n this.compute();\n };\n\n\n onDeviceOrientationSafariEvent = (e: DeviceOrientationEventiOS) => {\n\n this.magQuaternionTimestamp = e.timeStamp / 1e3;\n\n if (typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientation'));\n return;\n }\n\n if (typeof e.webkitCompassHeading !== 'number') {\n super.notifyError(new MissingMagnetometerError().from('deviceorientation'));\n return;\n }\n\n /**\n * Trying the best to retrieve a good quaternion from devicemotion event.\n */\n\n let alpha;\n const [qw, qx, qy, qz] = Rotations.eulerToQuaternionZXYDegrees([e.webkitCompassHeading, e.beta, e.gamma]);\n const groundAngle = rad2deg(Math.acos(qw ** 2 - qx ** 2 - qy ** 2 + qz ** 2));\n\n let isSkyMode = null;\n if (groundAngle > 136) {\n isSkyMode = true;\n } else if (groundAngle < 134) {\n isSkyMode = false;\n } else if (this.iosPreviousQuat && this.iosIsSkyMode !== null) {\n /**\n * This condition is true only if :\n * - we are in the [134°; 136°] ground angle range\n * - we know the previous quaternion\n * - one of the both previous condition has been reached during this session\n *\n * In this case, we define a threshold to detect if there is a \"jump\" in the quaternion calculation,\n * then, the mode is switched.\n */\n isSkyMode = Quaternion.distance([qw, qx, qy, qz], this.iosPreviousQuat) < 0.5\n ? this.iosIsSkyMode\n : !this.iosIsSkyMode;\n }\n this.iosPreviousQuat = [qw, qx, qy, qz];\n this.iosIsSkyMode = isSkyMode;\n\n if (typeof (isSkyMode) === 'undefined') {\n // Algorithm uncertainity\n return;\n }\n\n if (isSkyMode) {\n alpha = 180 - e.webkitCompassHeading;\n } else {\n alpha = AbsoluteAttitudeFromBrowser.webkitCompassToHeading(\n e.webkitCompassHeading, e.beta, e.gamma);\n }\n\n this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees([alpha, e.beta, e.gamma]);\n\n this.compute();\n };\n\n\n compute() {\n\n if (!this.declinationQuaternion || !this.magQuaternion || !this.absolutePositionEvent) {\n return;\n }\n\n const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, this.magQuaternion);\n const attitude = new AbsoluteAttitude(trueQuaternion, this.magQuaternionTimestamp, this.DEFAULT_ACCURACY);\n this.notify(attitude);\n }\n\n /**\n * Initialized declination quaternion using current position.\n * This method should be theoretically called every time the user moves.\n * But in reality declination does not change as much.\n */\n onAbsolutePositionEvent = (position: AbsolutePosition) => {\n\n this.absolutePositionEvent = position;\n\n const wmmResult = geomag.field(position.lat, position.lng);\n\n // Declination is given in NED frame and our code use ENU, that is why we have: \"-declination\"\n this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.declination));\n\n AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);\n delete this.absolutePositionProviderId;\n this.compute();\n }\n\n static webkitCompassToHeading(_webkitCompassHeading: number, _beta: number, _gamma: number) {\n const webkitCompassHeading = deg2rad(_webkitCompassHeading);\n const beta = deg2rad(_beta);\n const gamma = deg2rad(_gamma);\n\n const c1 = Math.cos(webkitCompassHeading / 2);\n const c2 = Math.cos(beta / 2);\n const c3 = Math.cos(gamma / 2);\n const s1 = Math.sin(webkitCompassHeading / 2);\n const s2 = Math.sin(beta / 2);\n const s3 = Math.sin(gamma / 2);\n\n const qw = c1 * c2 * c3 - s1 * s2 * s3;\n const qz = s1 * c2 * c3 + c1 * s2 * s3;\n\n return rad2deg(-2 * Math.atan(qz / qw));\n }\n}\n\nexport default new AbsoluteAttitudeFromBrowser();\n","import Provider from '../../Provider.js';\nimport RelativeAttitudeFromInertialProvider from './RelativeAttitudeFromInertialProvider.js';\nimport ArCoreProvider from '../../vision/ArCoreProvider.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Relative attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation\n * The provider does not work until an offset is given.\n */\nclass RelativeAttitudeProvider extends Provider<RelativeAttitude> {\n\n arCoreMonitoringId?: number;\n arCoreProviderId?: number;\n inertialProviderId?: number;\n\n getName = () => 'RelativeAttitude';\n\n availability = () => RelativeAttitudeFromInertialProvider.getAvailability();\n\n start() {\n this.arCoreMonitoringId = ArCoreProvider.addMonitoringListener(\n () => {\n this.listenArCore();\n this.unlistenInertial();\n }, () => {\n this.unlistenArCore();\n this.listenInertial();\n });\n\n if (ArCoreProvider.state === 'started') {\n this.listenArCore();\n } else {\n this.listenInertial();\n }\n }\n\n /**\n * @override\n */\n stop() {\n ArCoreProvider.removeMonitoringListener(this.arCoreMonitoringId);\n this.unlistenArCore();\n this.unlistenInertial();\n }\n\n\n listenInertial = () => {\n this.inertialProviderId = RelativeAttitudeFromInertialProvider.addEventListener(\n this.notify,\n this.notifyError\n );\n }\n\n unlistenInertial = () => {\n RelativeAttitudeFromInertialProvider.removeEventListener(this.inertialProviderId);\n }\n\n listenArCore = () => {\n this.arCoreProviderId = ArCoreProvider.addEventListener(\n event => this.notify(event.relativeAttitude), null, false\n );\n };\n\n unlistenArCore = () => {\n ArCoreProvider.removeEventListener(this.arCoreProviderId);\n }\n}\n\nexport default new RelativeAttitudeProvider();\n","/* eslint-disable max-statements */\nimport { AbsoluteHeading, Attitude } from '@wemap/geo';\nimport { deg2rad, diffAngle, Quaternion, Quaternion_t } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport AbsoluteAttitudeFromBrowserProvider from './AbsoluteAttitudeFromBrowserProvider.js';\nimport RelativeAttitudeProvider from '../relative/RelativeAttitudeProvider.js';\nimport InclinationProvider from '../../inclination/InclinationProvider.js';\nimport HighRotationsProvider from '../../imu/HighRotationsProvider.js';\nimport VpsProvider from '../../vision/vps/VpsProvider.js';\nimport { AbsoluteAttitude, RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame\n */\nclass AbsoluteAttitudeProvider extends Provider<AbsoluteAttitude> {\n\n static REL_ABS_DIVERGENCE_ANGLE_THRESHOLD = deg2rad(25) // in radians;\n static REL_ABS_DIVERGENCE_TIME_THRESHOLD = 2.5; // in seconds\n static REL_ABS_DIVERGENCE_INCLINATION_THRESHOLD = deg2rad(15) // in radians;\n\n private _absAttitudeFromBrowser?: AbsoluteAttitude;\n private _vpsProviderId?: number;\n fromBrowserProviderId?: number;\n highRotationProviderId?: number;\n inclinationProviderId?: number;\n relativeAttitudeProviderId?: number;\n\n _attitudeFromBrowserErrored = false;\n _attitudeFromRelativeErrored = false;\n\n /*\n * RELATIVE\n */\n\n _relativeAttitude: RelativeAttitude | null = null;\n _relativeAccuracy = 0; // in radians/s\n\n _lastForcedHeadingEvent?: AbsoluteAttitude | AbsoluteHeading;\n _relAbsQuat?: Quaternion_t;\n _wasHighRotationInProgress = false;\n _timeFirstDivergence: number | null = null;\n _callbackMagCalibration?: (data: { angle: number }) => void;\n\n getName = () => 'AbsoluteAttitude';\n\n availability() {\n return AvailabilityHelper.some([\n AbsoluteAttitudeFromBrowserProvider.getAvailability(),\n RelativeAttitudeProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.fromBrowserProviderId = AbsoluteAttitudeFromBrowserProvider.addEventListener(\n this._onAttitudeFromBrowser,\n error => {\n this._attitudeFromBrowserErrored = true;\n this._onError(error);\n }\n );\n\n // Vps\n this._vpsProviderId = VpsProvider.addEventListener(\n event => this._onAttitudeFromVps(event.absoluteAttitude),\n error => this.notifyError(error),\n false\n );\n\n this.relativeAttitudeProviderId = RelativeAttitudeProvider.addEventListener(\n this._onRelativeAttitudeEvent,\n error => {\n this._attitudeFromRelativeErrored = true;\n this._onError(error);\n }\n );\n\n this.inclinationProviderId = InclinationProvider.addEventListener();\n\n this.highRotationProviderId = HighRotationsProvider.addEventListener();\n }\n\n stop() {\n AbsoluteAttitudeFromBrowserProvider.removeEventListener(this.fromBrowserProviderId);\n RelativeAttitudeProvider.removeEventListener(this.relativeAttitudeProviderId);\n InclinationProvider.removeEventListener(this.inclinationProviderId);\n HighRotationsProvider.removeEventListener(this.highRotationProviderId);\n VpsProvider.removeEventListener(this._vpsProviderId);\n }\n\n _setCallbackMagCalibration(cb: (data: { angle: number }) => void) {\n this._callbackMagCalibration = cb;\n }\n\n private _onError = (error: Error) => {\n if (this._attitudeFromBrowserErrored && this._attitudeFromRelativeErrored) {\n this.notifyError(error);\n }\n }\n\n\n _forceHeadingForRelative = (absoluteHeadingEvent: AbsoluteAttitude | AbsoluteHeading) => {\n\n if (this.lastEvent && absoluteHeadingEvent.accuracy! > this.lastEvent.accuracy!) {\n return;\n }\n\n const calcForceHeading = (relativeAttitude: RelativeAttitude) => {\n const currentRelativeHeading = relativeAttitude.heading;\n\n this._relAbsQuat = Quaternion.fromAxisAngle(\n [0, 0, 1],\n currentRelativeHeading - absoluteHeadingEvent.heading\n );\n\n this._relativeAccuracy = 0;\n this._lastForcedHeadingEvent = absoluteHeadingEvent;\n };\n\n // If relativeAttitude does not exist yet, wait the next\n if (this._relativeAttitude) {\n calcForceHeading(this._relativeAttitude);\n return;\n }\n\n // If this._relativeAttitude does not exist, wait the first value\n // /!\\ This works only if the relative attitude event is provided rapidly.\n const providerId = RelativeAttitudeProvider.addEventListener(\n event => {\n calcForceHeading(event);\n RelativeAttitudeProvider.removeEventListener(providerId);\n }\n );\n\n };\n\n _onRelativeAttitudeEvent = (event: RelativeAttitude) => {\n\n const { quaternion, accuracy, time } = event;\n\n // Calculate relative accuracy\n if (this._relativeAttitude) {\n this._relativeAccuracy += (time! - this._relativeAttitude.time!) * accuracy!;\n }\n\n // Keep the relative attitude event for the calculation of relAbsQuat\n // /!\\ Keep this even if forced heading is not set /!\\\n this._relativeAttitude = event;\n\n\n if (!this._lastForcedHeadingEvent || !this._relAbsQuat) {\n return;\n }\n\n const accuracyWithRelative = Math.min(\n (this._lastForcedHeadingEvent.accuracy || 0) + this._relativeAccuracy,\n Math.PI\n );\n\n const highRotationInProgress = HighRotationsProvider.isInProgress();\n\n let divergenceDetected = false;\n\n if (this._absAttitudeFromBrowser) {\n\n const {\n accuracy: accuracyWithAbsolute,\n heading: headingFromAbsolute\n } = this._absAttitudeFromBrowser;\n\n if (this._wasHighRotationInProgress && !highRotationInProgress) {\n // Update heading for relative if it the end of high rotations\n // (probably due to a magnetometer calibratiton)\n this._forceHeadingForRelative(this._absAttitudeFromBrowser);\n\n } else if (accuracyWithAbsolute! < accuracyWithRelative) {\n // Update heading for relative if:\n // (1) accuracy from absolute is better than relative\n // (2) heading divergence is greater than REL_ABS_DIVERGENCE_THRESHOLD\n const relativeQuaternion = Quaternion.multiply(this._relAbsQuat, quaternion);\n const relativeAttitude = new Attitude(relativeQuaternion);\n const angle = Math.abs(diffAngle(relativeAttitude.heading, headingFromAbsolute));\n const inclination = InclinationProvider.lastEvent;\n\n\n if (angle > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_ANGLE_THRESHOLD\n && inclination !== null\n && Math.abs(inclination - Math.PI / 4) > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_INCLINATION_THRESHOLD\n ) {\n divergenceDetected = true;\n\n // Be sure before forcing heading\n if (this._timeFirstDivergence !== null\n && time! - this._timeFirstDivergence > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_TIME_THRESHOLD) {\n\n this._forceHeadingForRelative(this._absAttitudeFromBrowser);\n this._callbackMagCalibration?.({ angle });\n this._timeFirstDivergence = null;\n } else if (this._timeFirstDivergence === null) {\n this._timeFirstDivergence = time;\n }\n\n }\n }\n\n }\n\n if (!divergenceDetected) {\n this._timeFirstDivergence = null;\n }\n\n this._wasHighRotationInProgress = highRotationInProgress;\n\n const absoluteQuat = Quaternion.multiply(this._relAbsQuat, quaternion);\n const attitude = new AbsoluteAttitude(absoluteQuat, time, accuracyWithRelative);\n this.notify(attitude);\n }\n\n\n _onAttitudeFromBrowser = (event: AbsoluteAttitude) => {\n this._absAttitudeFromBrowser = event;\n\n if (!this._lastForcedHeadingEvent) {\n this._forceHeadingForRelative(event);\n return;\n }\n\n // Absolute attitude from browser is not used anymore due to magnetometer inaccuracy on pitch and roll\n }\n\n\n _onAttitudeFromVps = (event: AbsoluteAttitude) => {\n this._forceHeadingForRelative(event);\n }\n\n feed(data: AbsoluteHeading | AbsoluteAttitude) {\n\n if (data instanceof AbsoluteHeading) {\n\n if (data.time === null) {\n throw Error('the time of the absolute heading is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the absolute heading is not defined');\n }\n\n this._forceHeadingForRelative(data);\n\n } else if (data instanceof AbsoluteAttitude) {\n\n if (data.time === null) {\n throw Error('the time of the attitude is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the attitude is not defined');\n }\n\n this._forceHeadingForRelative(data);\n\n } else {\n throw new Error('data is nor an AbsoluteHeading or an Attitude object');\n }\n }\n}\n\nexport default new AbsoluteAttitudeProvider();\n","import { std } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport RelativeAttitudeProvider from './relative/RelativeAttitudeProvider.js';\nimport { RelativeAttitude, Turn } from '../../events/Types.js';\n\nclass TurnProvider extends Provider<Turn> {\n\n static SLIDING_WINDOW_TIME = 0.3; // in seconds\n static STD_THRESHOLD = 0.075;\n static CONSIDER_TURN_UNTIL = 1; // in seconds\n\n providerId?: number;\n\n slidingWindow: [number, number][] = [];\n\n getName = () => 'Turn';\n\n availability = () => RelativeAttitudeProvider.getAvailability();\n\n start() {\n this.providerId = RelativeAttitudeProvider.addEventListener(\n this._parseRelativeAttitude,\n this.notifyError\n );\n }\n\n stop() {\n RelativeAttitudeProvider.removeEventListener(this.providerId);\n }\n\n isTurning() {\n if (!this.lastEvent || !RelativeAttitudeProvider.lastEvent) {\n return false;\n }\n\n const diffTime = RelativeAttitudeProvider.lastEvent.time as number - this.lastEvent.timestamp;\n return diffTime < TurnProvider.CONSIDER_TURN_UNTIL;\n }\n\n\n private _parseRelativeAttitude = (relativeAttitudeEvent: RelativeAttitude) => {\n\n const { heading } = relativeAttitudeEvent;\n const timestamp = relativeAttitudeEvent.time as number;\n\n this.slidingWindow = this.slidingWindow.filter(item => item[0] >= timestamp - TurnProvider.SLIDING_WINDOW_TIME);\n this.slidingWindow.push([timestamp, heading]);\n\n const stdVal = std(this.slidingWindow.map(item => item[1]));\n if (stdVal > TurnProvider.STD_THRESHOLD) {\n this.notify({ timestamp });\n }\n\n }\n}\n\nexport default new TurnProvider();\n","import Provider from '../Provider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport StepProvider from './StepProvider.js';\nimport TurnProvider from '../attitude/TurnProvider.js';\nimport { StraightLine } from '../../events/Types.js';\n\nclass StraightLineProvider extends Provider<StraightLine> {\n\n static DEFAULT_STEPS_CONSIDERED_FOR_STRAIGHT_LINE = 2;\n\n _turnProviderId?: number;\n _stepProviderId?: number;\n\n _countSteps = 0;\n _stepsConsideredForStraightLine = StraightLineProvider.DEFAULT_STEPS_CONSIDERED_FOR_STRAIGHT_LINE;\n\n getName = () => 'StraightLine';\n\n availability() {\n return AvailabilityHelper.every([\n TurnProvider.getAvailability(),\n StepProvider.getAvailability()\n ]);\n }\n\n start() {\n this._turnProviderId = TurnProvider.addEventListener(this._onTurn);\n this._stepProviderId = StepProvider.addEventListener(this._onStep);\n }\n\n stop() {\n TurnProvider.removeEventListener(this._turnProviderId);\n StepProvider.removeEventListener(this._stepProviderId);\n }\n\n private _onTurn = () => {\n if (this._countSteps >= this._stepsConsideredForStraightLine) {\n this.notify(false);\n }\n this._countSteps = 0;\n }\n\n private _onStep = () => {\n this._countSteps++;\n\n if (this._countSteps === this._stepsConsideredForStraightLine) {\n this.notify(true);\n }\n\n }\n\n isStraight() {\n return this._countSteps >= this._stepsConsideredForStraightLine;\n }\n\n get numStepsDetectedFromLastTurn() {\n return this._countSteps;\n }\n\n get stepsConsideredForStraightLine() {\n return this._stepsConsideredForStraightLine;\n }\n\n set stepsConsideredForStraightLine(stepsConsideredForStraightLine) {\n this._stepsConsideredForStraightLine = stepsConsideredForStraightLine;\n }\n}\n\nexport default new StraightLineProvider();\n","import {\n AbsoluteHeading, Level, UserPosition, Coordinates, GeoGraph, GeoGraphProjectionHandler, GeoGraphProjection, GeoGraphEdge, GeoGraphVertex\n} from '@wemap/geo';\nimport { deg2rad, diffAngle, diffAngleLines } from '@wemap/maths';\nimport { Itinerary, ItineraryInfoManager } from '@wemap/routers';\nimport { TimeUtils } from '@wemap/utils';\n\nimport AbsoluteAttitudeProvider from '../providers/attitude/absolute/AbsoluteAttitudeProvider.js';\nimport AbsoluteAttitudeFromBrowser from '../providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.js';\nimport TurnProvider from '../providers/attitude/TurnProvider.js';\nimport Constants from '../providers/Constants.js';\nimport AbsolutePositionProvider from '../providers/position/absolute/AbsolutePositionProvider.js';\nimport Provider from '../providers/Provider.js';\nimport StepProvider from '../providers/steps/StepProvider.js';\nimport StraightLineProvider from '../providers/steps/StraightLineProvider.js';\nimport ProvidersOptions from '../ProvidersOptions.js';\nimport { AbsolutePosition } from '../events/Types.js';\n\n\ntype MapMatchingEvent = { graph?: GeoGraph, itinerary?: Itinerary | null };\nclass MapMatchingHandler extends Provider<MapMatchingEvent> {\n\n static DEFAULT_MM_MAX_ANGLE = deg2rad(30); // radians\n static DEFAULT_MM_MAX_DIST = 30; // meters\n static DEFAULT_MM_MIN_DIST = 0; // meters\n static DEFAULT_USE_ITINERARY_START_AS_POSITION = false;\n static DEFAULT_USE_ORIENTATION_MATCHING = true;\n static DEFAULT_MM_HUGE_JUMP_DISTANCE = 3; // meters\n static DEFAULT_DISABLE_MM_CLOSE_TO_A_TURN_DISTANCE = 2; // meters\n static DEFAULT_MIN_STEPS_BETWEEN_ORIENTATION_MATCHING = 3;\n static DEFAULT_MIN_STEPS_FOR_ORIENTATION_MATCHING = 5;\n static DEFAULT_LAST_PROJECTIONS_WINDOW_SIZE = 3;\n static DEFAULT_LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD = deg2rad(3); // radians\n\n _mapMatchingMinDistance = MapMatchingHandler.DEFAULT_MM_MIN_DIST;\n _useItineraryStartAsPosition = MapMatchingHandler.DEFAULT_USE_ITINERARY_START_AS_POSITION;\n _useOrientationMatching = MapMatchingHandler.DEFAULT_USE_ORIENTATION_MATCHING;\n _hugeJumpDistance = MapMatchingHandler.DEFAULT_MM_HUGE_JUMP_DISTANCE;\n _disableMMCloseToATurnDistance = MapMatchingHandler.DEFAULT_DISABLE_MM_CLOSE_TO_A_TURN_DISTANCE;\n _minStepsBetweenOrientationMatching = MapMatchingHandler.DEFAULT_MIN_STEPS_BETWEEN_ORIENTATION_MATCHING;\n _minStepsForOrientationMatching = MapMatchingHandler.DEFAULT_MIN_STEPS_FOR_ORIENTATION_MATCHING;\n _lastProjectionsWindowSize = MapMatchingHandler.DEFAULT_LAST_PROJECTIONS_WINDOW_SIZE;\n _lastProjectionsEdgeAngleThreshold = MapMatchingHandler.DEFAULT_LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD;\n\n _geoGraphProjectionHandler: GeoGraphProjectionHandler;\n _internalProvidersStarted = false;\n _straightLineProviderId?: number;\n _turnProviderId?: number;\n _stepProviderId?: number;\n _projectionsWithAbsAndWithoutRelAttitudeInARow: GeoGraphProjection[] = [];\n _countStepsFromLastMatching = 0;\n _lastProjections: GeoGraphProjection[] = [];\n\n _itineraryInfoManager: ItineraryInfoManager | null = null;\n\n constructor() {\n super();\n\n this._geoGraphProjectionHandler = new GeoGraphProjectionHandler();\n this._geoGraphProjectionHandler.maxDistance = MapMatchingHandler.DEFAULT_MM_MAX_DIST;\n this._geoGraphProjectionHandler.maxAngleBearing = MapMatchingHandler.DEFAULT_MM_MAX_ANGLE;\n }\n\n getName = () => 'MapMatchingHandler';\n\n availability = () => Promise.resolve();\n\n start() {\n if (this.graph) {\n this._startInternalProviders();\n }\n }\n\n stop() {\n this._stopInternalProviders();\n }\n\n _manageStartStop = () => {\n if (this.graph && !this._internalProvidersStarted) {\n this._startInternalProviders();\n } else if (!this.graph && this._internalProvidersStarted) {\n this._stopInternalProviders();\n }\n }\n\n _startInternalProviders() {\n\n if (this.enabled && this._internalProvidersStarted) {\n return;\n }\n\n this._straightLineProviderId = StraightLineProvider.addEventListener();\n this._turnProviderId = TurnProvider.addEventListener();\n this._stepProviderId = StepProvider.addEventListener(() => (this._countStepsFromLastMatching++));\n\n this._internalProvidersStarted = true;\n }\n\n _stopInternalProviders() {\n\n if (this.enabled && !this._internalProvidersStarted) {\n return;\n }\n\n StraightLineProvider.removeEventListener(this._straightLineProviderId);\n TurnProvider.removeEventListener(this._turnProviderId);\n StepProvider.removeEventListener(this._stepProviderId);\n\n this._internalProvidersStarted = false;\n }\n\n get enabled() {\n return ProvidersOptions.useMapMatching;\n }\n\n get graph() {\n return this._geoGraphProjectionHandler.graph;\n }\n\n // TODO: rename to setGraphNetwork()\n set graph(graph) {\n\n this._geoGraphProjectionHandler.graph = graph;\n this._itineraryInfoManager = null;\n this.notify({ ...(graph && { graph })});\n\n this._manageStartStop();\n\n if (this.canUseMapMatching()) {\n // TODO if necessary\n // this._notifyPositionFromNetworkInput(network);\n }\n }\n\n set itinerary(itinerary: Itinerary | null) {\n\n this._geoGraphProjectionHandler.graph = itinerary ? itinerary.toGraph() : null;\n this._itineraryInfoManager = new ItineraryInfoManager(itinerary);\n this.notify({ ...(itinerary && { itinerary })});\n\n this._manageStartStop();\n\n if (this.canUseMapMatching() && itinerary) {\n this._notifyPositionFromItineraryInput(itinerary);\n }\n }\n\n canUseMapMatching() {\n return this.enabled && this.graph;\n }\n\n\n private _notifyPositionFromItineraryInput(itinerary: Itinerary) {\n\n if (!this._useItineraryStartAsPosition || itinerary.from) {\n return;\n }\n\n const lastPosition = AbsolutePositionProvider.lastEvent || null;\n\n // In case of an itinerary, use itinerary start as new position,\n // but add the distance between lastPosition and itinerary start for the accuracy\n const newPosition = UserPosition.fromCoordinates(itinerary.from);\n\n if (lastPosition) {\n newPosition.alt = lastPosition.alt;\n newPosition.time = lastPosition.time;\n newPosition.accuracy = lastPosition.accuracy! + newPosition.distanceTo(lastPosition);\n newPosition.bearing = lastPosition.bearing;\n } else if (itinerary.coords.length >= 2) {\n newPosition.alt = Constants.DEFAULT_ALTITUDE;\n newPosition.time = TimeUtils.preciseTime();\n newPosition.accuracy = 0;\n newPosition.bearing = itinerary.coords[0].bearingTo(itinerary.coords[1]);\n } else {\n return;\n }\n\n // if the distance between itinerary.start and itinerary.nodes[0] is less than MM_MAX_DIST,\n // projection.coords is itinerary.nodes[0]\n const projection = this.getProjection(newPosition, true);\n if (projection) {\n AbsolutePositionProvider.notify(projection.coords);\n // Do not notify for attitude projection because bearing has not been used.\n } else {\n AbsolutePositionProvider.notify(newPosition);\n }\n return;\n }\n\n notifyPositionFromFeed(newPositionEvent: AbsolutePosition) {\n\n const projection = this.getProjection(newPositionEvent, true, false);\n if (!projection) {\n AbsolutePositionProvider.notify(newPositionEvent);\n return;\n }\n\n AbsolutePositionProvider.notify(projection.coords);\n }\n\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n notifyPositionFromAbsolute(newPosition: AbsolutePosition) {\n\n let projectionWithBearing = null;\n if (newPosition.bearing !== null) {\n projectionWithBearing = this.getProjection(newPosition, true, true);\n }\n\n if (!projectionWithBearing) {\n // Verify if the newPosition is far enough from the network to be used by the system.\n // const projectionWithoutBearing = this.getProjection(newPosition, true, false);\n // if (!projectionWithoutBearing) {\n // In this case, the newPosition is far enough and can be used safely.\n AbsolutePositionProvider.notify(newPosition);\n return true;\n // }\n // return true;\n }\n\n // newPosition must not be used after this line\n\n const thisWillBeAHugeJump = projectionWithBearing.distanceFromNearestElement > this._hugeJumpDistance;\n\n // In case of a huge jump, be sure the user is in a straight line\n if (thisWillBeAHugeJump && !StraightLineProvider.isStraight()) {\n return false;\n }\n\n // Detector to avoid big jumps in the wrong direction\n if (thisWillBeAHugeJump && this._detectWrongBigJump(projectionWithBearing)) {\n return false;\n }\n\n AbsolutePositionProvider.notify(projectionWithBearing.coords);\n\n this.tryOrientationMatching(projectionWithBearing);\n return true;\n }\n\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n notifyPositionFromRelative(newPosition: AbsolutePosition) {\n\n if (TurnProvider.isTurning()) {\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections = [];\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n const projection = this.getProjection(newPosition, true, true);\n\n if (projection) {\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections.push(projection);\n if (this._lastProjections.length > this._lastProjectionsWindowSize) {\n this._lastProjections.shift();\n }\n\n const thisWillBeAHugeJump = projection.distanceFromNearestElement > this._hugeJumpDistance;\n\n // In case of a huge jump, be sure the user is in a straight line\n if (thisWillBeAHugeJump && !StraightLineProvider.isStraight()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Detector to avoid big jumps in the wrong direction\n if (thisWillBeAHugeJump && this._detectWrongBigJump(projection)) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Do not use projection if the neareast element is not the same direction than previous\n if (!this._areLastProjectionsInTheSameDirection()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Detector to avoid map-matching close to network turns\n if (this._disableMMCloseToATurnDistance > 0\n && this._hasTurnInCircle(projection.coords, this._disableMMCloseToATurnDistance)) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n AbsolutePositionProvider.notify(projection.coords);\n this.tryOrientationMatching(projection);\n\n return true;\n\n }\n // else {\n\n // Sometimes, the newPosition.bearing diverges due to the Absolute Attitude offset\n // and the Orientation Matching. So, we created this detector to check if projection\n // with bearing from \"AbsoluteAttitudeFromBrowser\" is better than the current bearing.\n // /!\\ This works only if the user is waking in the same direction than the smartphone orientation /!\\\n if (StraightLineProvider.isStraight()) {\n\n const testedPosition = newPosition.clone();\n testedPosition.bearing = AbsoluteAttitudeFromBrowser.lastEvent?.heading || null;\n const projectionWithAbs = this.getProjection(testedPosition, true, true);\n\n if (projectionWithAbs) {\n\n this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);\n if (this._projectionsWithAbsAndWithoutRelAttitudeInARow.length < 3) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n this._lastProjections.push(projectionWithAbs);\n if (this._lastProjections.length > this._lastProjectionsWindowSize) {\n this._lastProjections.shift();\n }\n\n\n if (!this._areLastProjectionsInTheSameDirection()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n AbsolutePositionProvider.notify(projectionWithAbs.coords);\n\n this.tryOrientationMatching(projectionWithAbs);\n return true;\n }\n }\n\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections = [];\n\n // If no projection found with both projection methods, simply use the newPosition.\n AbsolutePositionProvider.notify(newPosition);\n return true;\n\n // }\n\n }\n\n _detectWrongBigJump(projection: GeoGraphProjection<unknown, unknown, UserPosition>) {\n\n if (this._itineraryInfoManager && AbsolutePositionProvider.lastEvent) {\n const infoPrevious = this._itineraryInfoManager.getInfo(AbsolutePositionProvider.lastEvent);\n const infoProjection = this._itineraryInfoManager.getInfo(projection.coords);\n if (infoPrevious\n && infoProjection\n && infoPrevious.traveledDistance > infoProjection.traveledDistance\n && (infoPrevious.traveledDistance - infoProjection.traveledDistance) > projection.origin.accuracy!\n && projection.distanceFromNearestElement > projection.origin.accuracy!\n && projection.origin.distanceTo(AbsolutePositionProvider.lastEvent) < projection.origin.accuracy! + AbsolutePositionProvider.lastEvent.accuracy!) {\n\n return true;\n }\n }\n\n return false;\n }\n\n _areLastProjectionsInTheSameDirection() {\n\n if (this._lastProjections.length === 0) {\n return false;\n }\n\n const firstProjection = this._lastProjections[0];\n return !this._lastProjections.some(projection =>\n !(projection.nearestElement instanceof GeoGraphEdge)\n || !(firstProjection.nearestElement instanceof GeoGraphEdge)\n || (diffAngleLines(projection.nearestElement.bearing, firstProjection.nearestElement.bearing)\n > this._lastProjectionsEdgeAngleThreshold)\n );\n }\n\n\n _nodeHasTurn(node: GeoGraphVertex) {\n const { edges } = node;\n for (let i = 0; i < edges.length; i++) {\n for (let j = i + 1; j < edges.length; j++) {\n const angle = diffAngleLines(edges[i].bearing, edges[j].bearing);\n if (angle > MapMatchingHandler.DEFAULT_MM_MAX_ANGLE) {\n return true;\n }\n }\n }\n return false;\n }\n\n\n _hasTurnInCircle(center: Coordinates, radius: number) {\n const network = this._geoGraphProjectionHandler.graph;\n if (!network) {\n return false;\n }\n\n return network.vertices.filter(vertex =>\n vertex.coords.distanceTo(center) <= radius\n && Level.intersect(vertex.coords.level, center.level)\n ).some(this._nodeHasTurn);\n }\n\n tryOrientationMatching(projection: GeoGraphProjection<unknown, unknown, UserPosition>) {\n\n if (!this._useOrientationMatching) {\n return;\n }\n\n if (this.state !== 'started'\n || this._countStepsFromLastMatching < this._minStepsBetweenOrientationMatching\n || StraightLineProvider.numStepsDetectedFromLastTurn < this._minStepsForOrientationMatching) {\n return;\n }\n\n const { nearestElement, origin } = projection;\n if (!(nearestElement instanceof GeoGraphEdge)) {\n return;\n }\n\n let matchingDirection;\n const matchingDirectionAngle1 = diffAngle(nearestElement.bearing, origin.bearing!);\n const matchingDirectionAngle2 = diffAngle(nearestElement.bearing + Math.PI, origin.bearing!);\n\n if (Math.abs(matchingDirectionAngle1) < Math.abs(matchingDirectionAngle2)) {\n matchingDirection = nearestElement.bearing;\n } else {\n matchingDirection = (nearestElement.bearing + Math.PI) % (2 * Math.PI);\n }\n\n const matchedHeading = new AbsoluteHeading(\n matchingDirection,\n origin.time,\n 0\n // Math.min(Math.abs(matchingDirectionAngle1), Math.abs(matchingDirectionAngle2))\n );\n\n AbsoluteAttitudeProvider._forceHeadingForRelative(matchedHeading);\n\n this._countStepsFromLastMatching = 0;\n }\n\n getProjection(position: UserPosition, useDistance?: boolean, useBearing?: boolean) {\n return this._geoGraphProjectionHandler.getProjection(position, useDistance, useBearing);\n }\n\n get maxDistance() {\n return this._geoGraphProjectionHandler.maxDistance;\n }\n\n set maxDistance(maxDistance) {\n this._geoGraphProjectionHandler.maxDistance = maxDistance;\n }\n\n get minDistance() {\n return this._mapMatchingMinDistance;\n }\n\n set minDistance(minDistance) {\n this._mapMatchingMinDistance = minDistance;\n }\n\n get maxAngleBearing() {\n return this._geoGraphProjectionHandler.maxAngleBearing;\n }\n\n set maxAngleBearing(maxAngleBearing) {\n this._geoGraphProjectionHandler.maxAngleBearing = maxAngleBearing;\n }\n\n get useItineraryStartAsPosition() {\n return this._useItineraryStartAsPosition;\n }\n\n set useItineraryStartAsPosition(useItineraryStartAsPosition) {\n this._useItineraryStartAsPosition = useItineraryStartAsPosition;\n }\n\n get useOrientationMatching() {\n return this._useOrientationMatching;\n }\n\n set useOrientationMatching(useOrientationMatching) {\n this._useOrientationMatching = useOrientationMatching;\n }\n\n get hugeJumpDistance() {\n return this._hugeJumpDistance;\n }\n\n set hugeJumpDistance(hugeJumpDistance) {\n this._hugeJumpDistance = hugeJumpDistance;\n }\n\n get disableMMCloseToATurnDistance() {\n return this._disableMMCloseToATurnDistance;\n }\n\n set disableMMCloseToATurnDistance(disableMMCloseToATurnDistance) {\n this._disableMMCloseToATurnDistance = disableMMCloseToATurnDistance;\n }\n\n get minStepsBetweenOrientationMatching() {\n return this._minStepsBetweenOrientationMatching;\n }\n\n set minStepsBetweenOrientationMatching(minStepsBetweenOrientationMatching) {\n this._minStepsBetweenOrientationMatching = minStepsBetweenOrientationMatching;\n }\n\n get minStepsForOrientationMatching() {\n return this._minStepsForOrientationMatching;\n }\n\n set minStepsForOrientationMatching(minStepsForOrientationMatching) {\n this._minStepsForOrientationMatching = minStepsForOrientationMatching;\n }\n\n get lastProjectionsWindowSize() {\n return this._lastProjectionsWindowSize;\n }\n\n set lastProjectionsWindowSize(lastProjectionsWindowSize) {\n this._lastProjectionsWindowSize = lastProjectionsWindowSize;\n }\n\n get lastProjectionsEdgeAngleThreshold() {\n return this._lastProjectionsEdgeAngleThreshold;\n }\n\n set lastProjectionsEdgeAngleThreshold(lastProjectionsEdgeAngleThreshold) {\n this._lastProjectionsEdgeAngleThreshold = lastProjectionsEdgeAngleThreshold;\n }\n}\n\nexport default new MapMatchingHandler();\n","import { Level, UserPosition } from '@wemap/geo';\n\nclass PositionSmoother {\n\n // Generated positions by second\n static DEFAULT_FREQUENCY = 60;\n\n // flyby (in second)\n static DEFAULT_FLYBY_TIME = 1;\n\n positionsQueue: UserPosition[] = [];\n previousPosition: UserPosition | null = null;\n timeoutNotify?: any; // can be number if web or NodeJS.Timer\n\n\n /**\n * @param frequency in Hz\n */\n constructor(\n public callback?: (position: UserPosition) => void,\n public frequency = PositionSmoother.DEFAULT_FREQUENCY\n ) {}\n\n /**\n * @param flybyTime in seconds\n */\n feed(newPosition: UserPosition, flybyTime = PositionSmoother.DEFAULT_FLYBY_TIME) {\n\n if (!(newPosition instanceof UserPosition)) {\n throw new TypeError('newPosition is not instance of UserPosition');\n }\n\n if (newPosition.time === null) {\n throw new Error('newPosition does not have time property');\n }\n\n let previousPosition;\n if (this.positionsQueue.length !== 0) {\n previousPosition = this.positionsQueue[0];\n this.positionsQueue = [];\n } else {\n previousPosition = this.previousPosition;\n }\n\n if (previousPosition) {\n\n const refTimestamp = newPosition.time;\n const distance = previousPosition.distanceTo(newPosition);\n const azimuth = previousPosition.bearingTo(newPosition);\n\n let i = 1;\n const nSamples = this.frequency * flybyTime + 1;\n\n const newPositionLevel = Level.clone(newPosition.level);\n while (i < nSamples + 1) {\n const smoothedPosition = previousPosition.destinationPoint(distance * i / nSamples, azimuth);\n smoothedPosition.time = refTimestamp + (i - 1) / this.frequency;\n smoothedPosition.level = newPositionLevel;\n smoothedPosition.bearing = newPosition.bearing;\n smoothedPosition.accuracy = Math.max(\n smoothedPosition.accuracy! + (newPosition.accuracy! - smoothedPosition.accuracy!) * i / nSamples,\n 0\n );\n this.positionsQueue.push(smoothedPosition);\n i++;\n }\n\n if (this.timeoutNotify) {\n clearTimeout(this.timeoutNotify);\n }\n } else {\n this.positionsQueue.push(newPosition.clone());\n }\n\n this.previousPosition = newPosition;\n this._notifyNext();\n }\n\n _notifyNext = () => {\n if (!this.positionsQueue.length) return;\n this.callback?.(this.positionsQueue.shift() as UserPosition);\n if (this.positionsQueue.length !== 0) {\n this.timeoutNotify = setTimeout(this._notifyNext, 1e3 / this.frequency);\n } else {\n delete this.timeoutNotify;\n }\n }\n\n clear() {\n clearTimeout(this.timeoutNotify);\n delete this.timeoutNotify;\n this.positionsQueue = [];\n }\n}\n\nexport default PositionSmoother;\n","import { Attitude } from '@wemap/geo';\nimport { deg2rad, diffAngle, Quaternion } from '@wemap/maths';\n\nclass AttitudeSmoother {\n\n static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(180); // in radians/s\n static ROTATION_SPEED_CONVERGENCE = deg2rad(10); // in radians/s\n static HIGH_JUMP_THRESHOLD = deg2rad(20); // in radians/s\n static ROTATION_SPEED_HIGH_JUMP_CONVERGENCE = deg2rad(100); // in radians/s\n static PITCH_UNCERTAINITY_HEADING_THRESHOLD = deg2rad(5); // in radians/s\n\n _previousAttitude?: Attitude;\n\n _smoothing : null | {\n interpAttitude(attitude: Attitude): Attitude,\n toTime: number\n } = null;\n\n constructor(public callback: (attitude: Attitude) => void) {}\n\n feed(newAttitude: Attitude) {\n\n if (newAttitude.time === null) {\n throw new Error('newAttitude does not have time property');\n }\n\n const { _previousAttitude: previousAttitude } = this;\n this._previousAttitude = newAttitude;\n\n if (!previousAttitude) {\n this.callback(newAttitude);\n return;\n }\n\n /*\n * Comparison between two successive Attitude from the \"feed\" function\n */\n if (AttitudeSmoother.isJump(previousAttitude, newAttitude)) {\n\n const fromAttitude = this._smoothing === null\n ? previousAttitude\n : this._smoothing.interpAttitude(previousAttitude);\n\n const fromHeading = fromAttitude.heading;\n const toHeading = newAttitude.heading;\n const diffAngleHeading = diffAngle(toHeading, fromHeading);\n\n const isHighJump = Math.abs(diffAngleHeading) < AttitudeSmoother.HIGH_JUMP_THRESHOLD;\n const rotationSpeedConvergence = isHighJump\n ? AttitudeSmoother.ROTATION_SPEED_CONVERGENCE\n : AttitudeSmoother.ROTATION_SPEED_HIGH_JUMP_CONVERGENCE;\n\n const fromTime = fromAttitude.time!;\n const timeToConsume = Math.abs(diffAngleHeading) / rotationSpeedConvergence;\n const multiplier = diffAngleHeading < 0 ? -1 : 1;\n\n this._smoothing = {\n toTime: fromTime + timeToConsume,\n\n interpAttitude: (attitude: Attitude) => {\n const angle = rotationSpeedConvergence * (attitude.time! - fromTime);\n const interpHeading = fromHeading + angle * multiplier;\n const offsetQuat = Quaternion.fromAxisAngle([0, 0, 1], toHeading - interpHeading);\n const interpQuat = Quaternion.multiply(offsetQuat, attitude.quaternion);\n return new Attitude(interpQuat, attitude.time, attitude.accuracy);\n }\n };\n }\n\n if (this._smoothing !== null) {\n if (newAttitude.time >= this._smoothing.toTime) {\n // This means that is the last epoch for smoothing\n this._smoothing = null;\n } else {\n const interpAttitude = this._smoothing.interpAttitude(newAttitude);\n this.callback(interpAttitude);\n return;\n }\n }\n\n this.callback(newAttitude);\n }\n\n /**\n * @param {Attitude} previousAttitude\n * @param {Attitude} newAttitude\n * @returns {boolean}\n */\n static isJump(previousAttitude: Attitude, newAttitude: Attitude) {\n const fromHeading = previousAttitude.heading;\n const toHeading = newAttitude.heading;\n const diffAngleHeading = diffAngle(toHeading, fromHeading);\n const diffTime = newAttitude.time! - previousAttitude.time!;\n\n /**\n * Heading is calculated from two different formulas in function of the pitch angle.\n * Do not consider a jump if attitude is close to the change of the methods\n * @see MathsRotations#getHeadingFromQuaternion()\n */\n const [qw, qx, qy, qz] = newAttitude.quaternion;\n const distToPitchThreshold = Math.abs(Math.asin(2 * (qw * qx + qy * qz)) - Math.PI / 4);\n if (distToPitchThreshold < AttitudeSmoother.PITCH_UNCERTAINITY_HEADING_THRESHOLD) {\n return false;\n }\n\n return Math.abs(diffAngleHeading) > AttitudeSmoother.ROTATION_SPEED_JUMP_THRESHOLD * diffTime;\n }\n}\n\nexport default AttitudeSmoother;\n","import Provider from '../Provider.js';\nimport AbsoluteAttitudeProvider from '../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport { MagnetometerNeedCalibration } from '../../events/Types.js';\n\nclass MagnetometerCalibrationProvider extends Provider<MagnetometerNeedCalibration> {\n\n getName = () => 'MagnetometerCalibrationProvider';\n\n availability = () => AbsoluteAttitudeProvider.getAvailability();\n\n constructor() {\n super();\n AbsoluteAttitudeProvider._setCallbackMagCalibration(e => this.state === 'started' && this.notify(e));\n }\n\n start() { /* do nothing */ }\n stop() { /* do nothing */ }\n\n}\n\nexport default new MagnetometerCalibrationProvider();\n","class IpResolveServerError extends Error {\n\n static DEFAULT_MESSAGE = 'IP Resolver failed';\n\n constructor(message?: string) {\n super(message || IpResolveServerError.DEFAULT_MESSAGE);\n }\n}\n\nexport default IpResolveServerError;\n","import { UserPosition } from '@wemap/geo';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport IpResolveServerError from '../../../errors/IpResolveServerError.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\n/**\n * GnssWifiProvider is a provider based on navigator.geolocation.\n * This API does not allow us to know if the position returned is provided\n * by Wifi Fingerprinting algorithms or by GNSS. That is why the name is\n * \"GnssWifi\".\n */\nclass IpProvider extends Provider<AbsolutePosition> {\n\n getName = () => 'Ip';\n\n availability = () => Promise.resolve();\n\n async start() {\n\n const response = await fetch('https://ipinfo.io/geo?token=24a7ca2f3b489d');\n if (!response) {\n this.notifyError(new IpResolveServerError());\n return;\n }\n\n const timestamp = TimeUtils.preciseTime() / 1e3;\n\n const latLngStr = (await response.json()).loc.split(',');\n const position = new UserPosition(\n parseFloat(latLngStr[0]),\n parseFloat(latLngStr[1]),\n null,\n null,\n timestamp,\n 100000\n );\n\n this.notify(position);\n }\n\n stop() { /* do nothing */ }\n\n}\n\nexport default new IpProvider();\n","import Provider from '../Provider.js';\nimport ArCore from './ArCoreProvider.js';\nimport { Barcode } from '../../events/Types.js';\n\nclass BarcodePoleStarProvider extends Provider<Barcode> {\n \n providerId?: number;\n\n getName = () => 'Barcode';\n\n availability = () => ArCore.getAvailability();\n\n start() {\n ArCore.enableBarcodeScanner();\n\n this.providerId = ArCore.addEventListener(\n event => event.barcode && this.notify(event.barcode),\n this.notifyError\n );\n }\n\n stop() {\n ArCore.disableBarcodeScanner();\n ArCore.removeEventListener(this.providerId);\n }\n}\n\nexport default new BarcodePoleStarProvider();\n","import Provider from '../Provider.js';\nimport ArCoreProvider from '../vision/ArCoreProvider.js';\nimport { CameraNativeState } from '../../events/Types.js';\n\nclass CameraNativeProvider extends Provider<CameraNativeState> {\n\n providerId?: number;\n\n getName = () => 'CameraNative';\n\n availability = () => Promise.resolve();\n\n start() {\n\n if (ArCoreProvider.state !== 'stopped') {\n this.notify('started');\n }\n this.providerId = ArCoreProvider.addMonitoringListener(\n () => this.notify('started'),\n () => this.notify('stopped')\n );\n }\n\n stop() {\n ArCoreProvider.removeMonitoringListener(this.providerId);\n }\n}\n\nexport default new CameraNativeProvider();\n","import Provider from '../Provider.js';\nimport ArCoreProvider from '../vision/ArCoreProvider.js';\nimport { CameraProjectionMatrix } from '../../events/Types.js';\n\nclass CameraProjectionMatrixProvider extends Provider<CameraProjectionMatrix> {\n\n providerId?: number;\n\n getName = () => 'CameraProjectionMatrix';\n\n availability = () => ArCoreProvider.getAvailability();\n\n start() {\n this.providerId = ArCoreProvider.addEventListener(\n event => event.cameraProjection && this.notify(event.cameraProjection),\n this.notifyError\n );\n }\n\n stop() {\n ArCoreProvider.removeEventListener(this.providerId);\n }\n}\n\nexport default new CameraProjectionMatrixProvider();\n"],"names":["Attitude","UserPosition","Logger","ProvidersLoggerOld","deg2rad","TimeUtils","RelativePosition","ArCoreProvider","AbsoluteAttitudeProvider","GeoRelativePosition","Matrix4","Matrix3","Vector3","Quaternion","Matrix","Vector","BrowserUtils","Browser","ImuProvider","Accelerometer","Gyroscope","Rotations","GyroscopeProvider","RelativeAttitudeFromBrowserProvider","HighRotationsProvider","AccelerometerProvider","GeoConstants","StepProvider","PdrProvider","GeoRelativePositionFromArCoreProvider","InclinationFromAccProvider","InclinationFromRelativeAttitudeProvider","canvasToBase64","base64ToCanvas","convertToGrayscale","reduceImageSize","UserAgentUtils","RelativeAttitudeFromBrowser","Camera","camera","Inclination","AbsolutePositionProvider","GnssWifiProvider","PoleStarProvider","SharedCameras","GeoRelativePositionProvider","VpsProvider","MapMatchingHandler","Level","rad2deg","geomag","RelativeAttitudeProvider","diffAngle","InclinationProvider","AbsoluteAttitudeFromBrowserProvider","AbsoluteHeading","std","TurnProvider","GeoGraphProjectionHandler","StraightLineProvider","ItineraryInfoManager","AbsoluteAttitudeFromBrowser","GeoGraphEdge","diffAngleLines","ArCore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/events/Types.ts","../src/ProvidersOptions.ts","../src/events/ProvidersLoggerOld.ts","../src/errors/ContainsIgnoredProviderError.ts","../src/providers/Provider.ts","../src/events/AvailabilityHelper.ts","../src/errors/AskImuOnDesktopError.ts","../src/errors/MissingSensorError.ts","../src/errors/MissingMagnetometerError.ts","../src/errors/GeolocationApiMissingError.ts","../src/errors/GeolocationPermissionDeniedError.ts","../src/errors/GeolocationPositionUnavailableError.ts","../src/providers/Constants.ts","../src/providers/position/absolute/GnssWifiProvider.ts","../src/errors/MissingArCoreError.ts","../src/errors/MissingNativeInterfaceError.ts","../src/providers/vision/ArCoreProvider.ts","../src/providers/position/relative/GeoRelativePositionFromArCoreProvider.ts","../src/providers/attitude/EkfAttitude.ts","../src/providers/imu/ImuProvider.ts","../src/errors/MissingAccelerometerError.ts","../src/providers/imu/AccelerometerProvider.ts","../src/errors/MissingGyroscopeError.ts","../src/providers/imu/GyroscopeProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromEkfProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromBrowserProvider.ts","../src/providers/imu/HighRotationsProvider.ts","../src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.ts","../src/providers/steps/StepDetectionLadetto.ts","../src/providers/steps/StepDetectionMinMaxPeaks.ts","../src/providers/steps/StepDetectionMinMaxPeaks2.ts","../src/providers/steps/StepDetectionMinMaxPeaks3.ts","../src/providers/steps/StepProvider.ts","../src/providers/position/relative/PdrProvider.ts","../src/providers/position/relative/GeoRelativePositionProvider.ts","../src/providers/inclination/InclinationFromAccProvider.ts","../src/providers/inclination/InclinationFromRelativeAttitudeProvider.ts","../src/providers/inclination/InclinationProvider.ts","../src/providers/vision/vps/VpsMetadata.ts","../src/providers/vision/vps/VpsRequest.ts","../src/providers/vision/vps/VpsResponse.ts","../src/providers/vision/vps/ImageRelocalization.ts","../src/providers/vision/vps/RelativeRotationCalc.ts","../src/errors/MissingPoleStarError.ts","../src/providers/position/absolute/PoleStarProvider.ts","../src/providers/vision/vps/VpsProvider.ts","../src/providers/position/absolute/AbsolutePositionProvider.ts","../src/providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.ts","../src/providers/attitude/relative/RelativeAttitudeProvider.ts","../src/providers/attitude/absolute/AbsoluteAttitudeProvider.ts","../src/providers/attitude/TurnProvider.ts","../src/providers/steps/StraightLineProvider.ts","../src/mapmatching/MapMatchingHandler.ts","../src/smoothers/PositionSmoother.ts","../src/smoothers/AttitudeSmoother.ts","../src/providers/imu/MagnetometerCalibrationProvider.ts","../src/errors/IpResolveServerError.ts","../src/providers/position/absolute/IpProvider.ts","../src/providers/vision/BarcodeProvider.ts","../src/providers/others/CameraNativeProvider.ts","../src/providers/others/CameraProjectionMatrixProvider.ts"],"sourcesContent":["import { Attitude, UserPosition } from \"@wemap/geo\";\nimport { Vector16_t, Vector3_t } from \"@wemap/maths\";\n\nexport type Acceleration = Readonly<{ readonly timestamp: number; readonly values: Vector3_t; }>\nexport type AngularRate = Readonly<{ readonly timestamp: number; readonly values: Vector3_t; }>\nexport type HighRotation = Readonly<{ readonly timestamp: number; }>\nexport type MagnetometerNeedCalibration = Readonly<{ readonly angle: number; }>\nexport class RelativeAttitude extends Attitude { }\nexport class AbsoluteAttitude extends Attitude { }\nexport class AbsolutePosition extends UserPosition { }\nexport type Inclination = number;\nexport type Barcode = string;\nexport type Step = { readonly size: number; readonly number: number; }\nexport type Turn = { readonly timestamp: number; }\nexport type StraightLine = boolean;\nexport type CameraProjectionMatrix = Vector16_t;\nexport type CameraNativeState = 'started' | 'stopped';\n\n","const ProvidersOptions = {\n\n /**\n * Does provider will use map to\n */\n useMapMatching: true,\n\n /**\n * Providers listed here will not be used by the system\n * List of {@link Provider#pname}\n */\n ignoreProviders: [] as string[],\n\n /**\n * Some providers are not used by default (i.e. PoleStar) because they\n * require data from an optional external service or because they drain more\n * battery. They can be added to this list to be used\n * List of {@link Provider#pname}\n */\n optionalProviders: [] as string[],\n\n stopOnError: true,\n\n checkAvailabilityOnStart: true,\n\n get hasPoleStar() {\n return this.optionalProviders.includes('PoleStar');\n }\n};\n\nexport default ProvidersOptions;\n","import Logger from '@wemap/logger';\n\ninterface MyObject { getName(): string }\n\nclass ProvidersLoggerOld {\n\n _enabled = false;\n\n currentId = 0;\n objectsIdMap = new WeakMap<MyObject, number>();\n\n pushEvents: { [key: number]: number } = {};\n pushEventsRef: { [key: number]: MyObject } = {};\n\n interval?: number;\n initDate?: number;\n\n\n get enabled() {\n return this._enabled;\n }\n\n set enabled(_newVal) {\n this._enabled = _newVal;\n }\n\n initializeInterval() {\n\n if (this.interval) {\n return;\n }\n\n this.interval = window.setInterval(() => {\n\n for (const [key, value] of Object.entries(this.pushEvents)) {\n Logger.debug('Received ' + value + ' notifications from '\n + this.pushEventsRef[Number(key)].getName() + ' last second');\n }\n\n this.pushEvents = {};\n this.pushEventsRef = {};\n }, 1000);\n }\n\n getObjectId(object: MyObject) {\n if (!this.objectsIdMap.has(object)) {\n this.objectsIdMap.set(object, ++this.currentId);\n }\n return this.objectsIdMap.get(object) as number;\n }\n\n addEvent(object: MyObject, method: string) {\n\n if (!this.enabled) {\n return;\n }\n\n if (!this.initDate) {\n this.initDate = Date.now();\n }\n\n this.initializeInterval();\n\n const objectId = this.getObjectId(object);\n const objectClassName = object.getName();\n\n Logger.debug(objectClassName + '[' + objectId + '].' + method);\n }\n\n incrementNotifications(object: MyObject) {\n\n if (!this.enabled) {\n return;\n }\n\n const objectId = this.getObjectId(object);\n\n let counter = this.pushEvents[objectId];\n if (!counter) {\n counter = 0;\n this.pushEventsRef[objectId] = object;\n }\n this.pushEvents[objectId] = counter + 1;\n }\n\n}\nexport default new ProvidersLoggerOld();\n","class ContainsIgnoredProviderError extends Error {\n\n static DEFAULT_MESSAGE = 'Contains ignored provider';\n\n constructor(message?: string) {\n super(message || ContainsIgnoredProviderError.DEFAULT_MESSAGE);\n }\n}\n\nexport default ContainsIgnoredProviderError;\n","import ProvidersLoggerOld from '../events/ProvidersLoggerOld.js';\nimport ContainsIgnoredProviderError from '../errors/ContainsIgnoredProviderError.js';\nimport ProvidersOptions from '../ProvidersOptions.js';\nimport { ProviderState } from './ProviderState.js';\nimport { AvailabilityPromise } from '../events/AvailabilityHelper.js';\nimport { NativeCallbackInterface, NativeInterface } from './NativeProviders.js';\n\ndeclare global {\n interface Window {\n __nativeProviders?: NativeInterface;\n __nativeJsProviders?: NativeCallbackInterface;\n }\n}\n\n/**\n * A provider is a meta class to define an entity which can be\n * started / stopped and provides a data of <E>\n */\nabstract class Provider<E> {\n\n static _callbackUniqueId = 0;\n static _uniqueId = 1;\n\n id: number;\n state: ProviderState = 'stopped';\n\n _lastEvent: E | null = null;\n\n _eventsCallbacks: {\n id: number,\n onEvent: ((event: E) => void) | null,\n onError: ((error: Error) => void) | null,\n optional: boolean\n }[] = [];\n\n _monitoringCallbacks: {\n id: number,\n onStarted: (() => void) | null,\n onStopped: (() => void) | null\n }[] = [];\n\n /**\n * Provider constructor\n */\n constructor() {\n this.id = Provider._uniqueId++;\n ProvidersLoggerOld.addEvent(this, 'constructor');\n }\n\n /**\n * Get the provider name\n */\n abstract getName(): string;\n\n\n /**\n * Resolve with an error if the provider is not available\n */\n getAvailability() {\n if (ProvidersOptions.ignoreProviders.includes(this.getName())) {\n return Promise.resolve(new ContainsIgnoredProviderError());\n }\n\n return this.availability();\n }\n\n protected abstract availability(): AvailabilityPromise;\n\n\n protected get hasNativeInterface() {\n return Boolean(this.nativeInterface);\n }\n\n protected get nativeInterface() {\n return typeof window !== 'undefined' && window.__nativeProviders as NativeInterface || null;\n }\n\n protected get nativeJsInterface(): NativeCallbackInterface | null {\n if (typeof window === 'undefined') {\n return null;\n }\n if (!window.__nativeJsProviders) {\n window.__nativeJsProviders = {};\n }\n return window.__nativeJsProviders;\n }\n\n\n get useCameraNatively() {\n return false;\n }\n\n\n addEventListener(\n onEvent: ((events: E) => void) | null = null,\n onError: ((error: Error) => void) | null = null,\n startIfNecessary = true\n ) {\n const id = ++Provider._callbackUniqueId;\n\n /**\n * Build callback\n */\n this._eventsCallbacks.push({\n id,\n onEvent: onEvent || (() => { /* do nothing */ }),\n onError: onError || (() => { /* do nothing */ }),\n optional: !startIfNecessary\n });\n\n\n // The caller just want to have callbacks without starting the provider,\n // the routine can be stopped here\n if (!startIfNecessary) {\n return id;\n }\n\n\n // If the provider is already started do not go further\n if (this.state !== 'stopped') {\n return id;\n }\n this.state = 'starting';\n\n // Check availability on start if defined in options\n let availabilityPromise: AvailabilityPromise = Promise.resolve();\n if (ProvidersOptions.checkAvailabilityOnStart) {\n availabilityPromise = this.getAvailability();\n }\n\n (async () => {\n const error = await availabilityPromise;\n if (error) {\n this.state = 'stopped';\n this.notifyError(error);\n return;\n }\n\n ProvidersLoggerOld.addEvent(this, 'start');\n\n // Call the child start function\n this.start();\n\n this.state = 'started';\n\n this._monitoringCallbacks.forEach(cb => cb.onStarted?.());\n })();\n\n return id;\n }\n\n removeEventListener(callbackUniqueId?: number) {\n\n // Search the caller object in callbacks list\n const callback = this._eventsCallbacks.find(_callback => _callback.id === callbackUniqueId);\n if (!callback) {\n // The callback object is not found. Maybe it is already stopped.\n return;\n }\n\n // Remove the current callback from the list of the callbacks\n this._eventsCallbacks = this._eventsCallbacks.filter(_callback => _callback !== callback);\n\n // If this callback was optional, do not go further to stop the provider\n if (callback.optional) {\n return;\n }\n\n // If there is callbacks that are not optionals for start, do not stop the provider\n if (this._eventsCallbacks.find(_callback => !_callback.optional)) {\n return;\n }\n\n // If the provider is already stopped, do not stop it again.\n // This condition can be true if checkAvailabilityOnStart is true and returns an error\n if (this.state === 'stopped') {\n return;\n }\n\n ProvidersLoggerOld.addEvent(this, 'stop');\n // Call the child stop function\n this.stop();\n\n this.state = 'stopped';\n\n this._monitoringCallbacks.forEach(cb => cb.onStopped?.());\n }\n\n\n addMonitoringListener(onStarted?: (() => void) | null, onStopped?: (() => void) | null) {\n const id = Provider._callbackUniqueId++;\n this._monitoringCallbacks.push({\n id,\n onStarted: onStarted || null,\n onStopped: onStopped || null\n });\n return id;\n }\n\n removeMonitoringListener(callbackUniqueId?: number) {\n this._monitoringCallbacks = this._monitoringCallbacks.filter(\n _callback => _callback.id !== callbackUniqueId\n );\n }\n\n\n protected abstract start(): void\n protected abstract stop(): void\n\n\n /**\n * Notify the subscriber defined in {@link addEventListener}\n */\n notify = (event: E) => {\n // Logging\n ProvidersLoggerOld.incrementNotifications(this);\n\n // Notify callbacks\n this._eventsCallbacks.forEach(cb => cb.onEvent?.(event));\n\n // Keep a trace of the last events.\n this._lastEvent = event;\n }\n\n /**\n * Notify the subscriber defined in {@link addEventListener}\n */\n notifyError = (error: Error) => {\n this._eventsCallbacks.forEach(({\n id, onError\n }) => {\n if (ProvidersOptions.stopOnError) {\n this.removeEventListener(id);\n }\n onError?.(error);\n });\n }\n\n get lastEvent() {\n return this._lastEvent;\n }\n}\n\nexport default Provider;\n","export type AvailabilityPromise = Promise<Error | null | void>;\n\nexport default class AvailabilityHelper {\n\n static async every(availabilityPromises: AvailabilityPromise[]): AvailabilityPromise {\n for (const aPr of availabilityPromises) {\n const error = await aPr;\n if (error) {\n return error;\n }\n }\n return null;\n }\n\n static async some(availabilityPromises: AvailabilityPromise[]): AvailabilityPromise {\n let firstError;\n for (const aPr of availabilityPromises) {\n const error = await aPr;\n if (!error) {\n return null;\n } else if (!firstError) {\n firstError = error;\n }\n }\n return firstError || null;\n }\n\n}\n","class AskImuOnDesktopError extends Error {\n\n static DEFAULT_MESSAGE = 'It seems that you ask for IMU events on a desktop browser';\n\n constructor(message?: string) {\n super(message || AskImuOnDesktopError.DEFAULT_MESSAGE);\n }\n}\n\nexport default AskImuOnDesktopError;\n","class MissingSensorError extends Error {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve events, a sensor is missing';\n\n constructor(message?: string) {\n super(message || MissingSensorError.DEFAULT_MESSAGE);\n }\n\n from(fromMessage: string) {\n this.message += ' from ' + fromMessage;\n return this;\n }\n}\n\nexport default MissingSensorError;\n","import MissingSensorError from './MissingSensorError.js';\n\nclass MissingMagnetometerError extends MissingSensorError {\n constructor(message?: string) {\n super(message);\n }\n}\n\nexport default MissingMagnetometerError;\n","class GeolocationApiMissingError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation api is missing';\n\n constructor(message?: string) {\n super(message || GeolocationApiMissingError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationApiMissingError;\n","class GeolocationPermissionDeniedError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation permission denied';\n\n constructor(message?: string) {\n super(message || GeolocationPermissionDeniedError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationPermissionDeniedError;\n","class GeolocationPositionUnavailableError extends Error {\n\n static DEFAULT_MESSAGE = 'Geolocation position unavailable';\n\n constructor(message?: string) {\n super(message || GeolocationPositionUnavailableError.DEFAULT_MESSAGE);\n }\n}\n\nexport default GeolocationPositionUnavailableError;\n","const Constants = {\n DEFAULT_ALTITUDE: 1.6\n};\n\nexport default Constants;\n","import { UserPosition } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport GeolocationApiMissingError from '../../../errors/GeolocationApiMissingError.js';\nimport Provider from '../../Provider.js';\nimport GeolocationPermissionDeniedError from '../../../errors/GeolocationPermissionDeniedError.js';\nimport GeolocationPositionUnavailableError from '../../../errors/GeolocationPositionUnavailableError.js';\nimport Constants from '../../Constants.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\n\n/**\n * GnssWifiProvider is a provider based on navigator.geolocation.\n * This API does not allow us to know if the position returned is provided\n * by Wifi Fingerprinting algorithms or by GNSS. That is why the name is\n * \"GnssWifi\".\n */\nclass GnssWifiProvider extends Provider<AbsolutePosition> {\n\n static POSITION_OPTIONS = {\n enableHighAccuracy: true,\n timeout: Infinity,\n maximumAge: 0\n };\n\n static DEFAULT_DISCARD_POSITIONS_ABOVE = 50;\n\n discardPositionsAbove = GnssWifiProvider.DEFAULT_DISCARD_POSITIONS_ABOVE;\n\n geoLocationId?: number;\n\n getName = () => 'GnssWifi';\n\n\n availability() {\n return typeof (navigator) === 'object' && navigator.geolocation\n ? Promise.resolve()\n : Promise.resolve(new GeolocationApiMissingError());\n }\n\n start() {\n // Note: added timeout for a workaround on Safari/iOS when user disabled geolocation:\n // watchPosition does not send the error callback without the \"setTimeout\"\n setTimeout(() => {\n this.geoLocationId = navigator.geolocation.watchPosition(\n this.onNewPosition,\n this.onPositionError,\n GnssWifiProvider.POSITION_OPTIONS\n );\n }, 150);\n }\n\n stop() {\n if (typeof this.geoLocationId !== 'undefined') {\n navigator.geolocation.clearWatch(this.geoLocationId);\n }\n }\n\n private onNewPosition = (geolocation: GeolocationPosition) => {\n\n const { coords } = geolocation;\n if (!coords) {\n return;\n }\n\n let bearing;\n if (coords.heading) {\n bearing = deg2rad(coords.heading);\n }\n\n const timestamp = TimeUtils.unixTimestampToPreciseTime(geolocation.timestamp) / 1e3;\n\n const position = new UserPosition(\n coords.latitude,\n coords.longitude,\n Constants.DEFAULT_ALTITUDE,\n null,\n timestamp,\n coords.accuracy,\n bearing);\n\n if (typeof this.discardPositionsAbove === 'number'\n && coords.accuracy > this.discardPositionsAbove\n ) {\n return;\n }\n\n this.notify(position);\n\n };\n\n onPositionError = (error: GeolocationPositionError) => {\n\n Logger.warn(`[Providers] watchPosition error: [${error.code}] ${error.message}`);\n\n let customError;\n switch (error.code) {\n case 1:\n customError = new GeolocationPermissionDeniedError(error.message);\n break;\n case 2:\n customError = new GeolocationPositionUnavailableError(error.message);\n break;\n default:\n customError = new Error(error.message);\n }\n\n this.notifyError(customError);\n };\n}\n\nexport default new GnssWifiProvider();\n","class MissingArCoreError extends Error {\n\n static DEFAULT_MESSAGE = 'ARCore is missing';\n\n constructor(message?: string) {\n super(message || MissingArCoreError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingArCoreError;\n","class MissingNativeInterfaceError extends Error {\n\n static DEFAULT_MESSAGE = 'Native interface is missing. You are maybe trying to '\n + 'execute a code which is not available in a web browser';\n\n constructor(message?: string) {\n super(message || MissingNativeInterfaceError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingNativeInterfaceError;\n","import { RelativePosition } from '@wemap/geo';\nimport { deg2rad, Quaternion_t, Vector16_t, Vector3_t } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../Provider.js';\nimport MissingArCoreError from '../../errors/MissingArCoreError.js';\nimport MissingNativeInterfaceError from '../../errors/MissingNativeInterfaceError.js';\nimport { NativeArCore } from '../NativeProviders.js';\nimport { Barcode, CameraProjectionMatrix, RelativeAttitude} from '../../events/Types.js';\n\n\nexport type Payload = [number, ...[number | string]];\n\nexport type ArCoreEvent = Readonly<{\n readonly relativePosition: RelativePosition,\n readonly relativeAttitude: RelativeAttitude,\n readonly cameraProjection?: CameraProjectionMatrix,\n readonly barcode?: Barcode\n}>;\n\nclass ArCoreProvider extends Provider<ArCoreEvent> {\n\n static Payload = {\n Pose: {\n ref: 2 ** 0,\n size: 7\n },\n Barcode: {\n ref: 2 ** 1,\n size: 1\n },\n ProjMat: {\n ref: 2 ** 2,\n size: 16\n },\n ImageRef: {\n ref: 2 ** 3,\n size: 1\n }\n } as const;\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static RELATIVE_ATTITUDE_DRIFT = deg2rad(3) / 60;\n\n _nativeProvider?: NativeArCore;\n\n previousPosition = [0, 0, 0];\n\n getName = () => 'ArCore';\n\n availability() {\n try {\n const nativeProvider = this.nativeProvider;\n\n if (!nativeProvider.checkAvailability()) {\n return Promise.resolve(new MissingArCoreError());\n }\n\n } catch (e) {\n return Promise.resolve(e as Error);\n }\n\n return Promise.resolve();\n }\n\n start() {\n this.nativeProvider?.start();\n this.pullDataLoop();\n }\n\n stop() {\n this.nativeProvider?.stop();\n }\n\n pullDataLoop = () => {\n\n if (this.state === 'stopped') {\n return;\n }\n\n const payload = JSON.parse(this.nativeProvider.getInfo());\n if (payload.length > 1) {\n this.parsePayload(payload);\n }\n requestAnimationFrame(this.pullDataLoop);\n }\n\n parsePayload(payload: Payload) {\n\n const ref = payload[0];\n let bufferIndex = 1;\n\n let attitude: RelativeAttitude,\n position: RelativePosition,\n cameraProjection,\n barcode;\n\n const time = TimeUtils.preciseTime() / 1e3;\n\n if (ref & ArCoreProvider.Payload.Pose.ref) {\n\n attitude = new RelativeAttitude(\n payload.slice(bufferIndex, bufferIndex + 4) as Quaternion_t,\n time,\n ArCoreProvider.RELATIVE_ATTITUDE_DRIFT,\n );\n\n const newPosition = [\n payload[bufferIndex + 4], payload[bufferIndex + 5], payload[bufferIndex + 6]\n ] as Vector3_t;\n position = new RelativePosition(\n newPosition[0] - this.previousPosition[0],\n newPosition[1] - this.previousPosition[1],\n newPosition[2] - this.previousPosition[2],\n time,\n 1e-4\n );\n this.previousPosition = newPosition;\n\n bufferIndex += ArCoreProvider.Payload.Pose.size;\n }\n\n if (ref & ArCoreProvider.Payload.Barcode.ref) {\n barcode = payload[bufferIndex] as Barcode;\n bufferIndex += ArCoreProvider.Payload.Barcode.size;\n }\n\n if (ref & ArCoreProvider.Payload.ProjMat.ref) {\n cameraProjection = payload.slice(bufferIndex, bufferIndex + ArCoreProvider.Payload.ProjMat.size) as Vector16_t;\n bufferIndex += ArCoreProvider.Payload.ProjMat.size;\n }\n\n this.notify({\n relativePosition: position!,\n relativeAttitude: attitude!,\n ...(barcode && { barcode }),\n ...(cameraProjection && { cameraProjection })\n\n })\n }\n\n\n get nativeProvider() {\n\n if (!this._nativeProvider) {\n\n if (!this.nativeInterface) {\n throw new MissingNativeInterfaceError();\n }\n\n this._nativeProvider = this.nativeInterface.getArCoreProvider();\n if (!this._nativeProvider) {\n throw new MissingArCoreError();\n }\n }\n\n return this._nativeProvider;\n }\n\n\n enableBarcodeScanner() {\n try {\n this.nativeProvider.enableBarcodeScanner();\n } catch (e) {\n this.notifyError(e as Error);\n }\n }\n\n disableBarcodeScanner() {\n try {\n this.nativeProvider.disableBarcodeScanner();\n } catch (e) {\n this.notifyError(e as Error);\n }\n }\n\n get useCameraNatively() {\n return true;\n }\n}\n\nexport default new ArCoreProvider();\n","import { GeoRelativePosition, RelativePosition } from '@wemap/geo';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport ArCoreProvider, { ArCoreEvent } from '../../vision/ArCoreProvider.js';\nimport { AbsoluteAttitude, RelativeAttitude } from '../../../events/Types.js';\n\nclass GeoRelativePositionFromArCoreProvider extends Provider<GeoRelativePosition> {\n\n absoluteAttitudeProviderId?: number;\n arCoreProviderId?: number;\n absoluteAttitudeEvent?: AbsoluteAttitude;\n\n getName = () => 'GeoRelativePositionFromArCore';\n\n availability() {\n return AvailabilityHelper.every([\n ArCoreProvider.getAvailability(),\n AbsoluteAttitudeProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.arCoreProviderId = ArCoreProvider.addEventListener(\n this.onArCoreEvents,\n this.notifyError\n );\n\n this.absoluteAttitudeProviderId = AbsoluteAttitudeProvider.addEventListener(\n event => this.absoluteAttitudeEvent = event,\n this.notifyError\n );\n }\n\n stop() {\n ArCoreProvider.removeEventListener(this.arCoreProviderId);\n AbsoluteAttitudeProvider.removeEventListener(this.absoluteAttitudeProviderId);\n }\n\n onArCoreEvents = (event: ArCoreEvent) => {\n const relativeAttitudeEvent = event.relativeAttitude;\n const relativePositionEvent = event.relativePosition;\n\n if (relativeAttitudeEvent && relativePositionEvent && this.absoluteAttitudeEvent) {\n this.compute(relativePositionEvent, relativeAttitudeEvent, this.absoluteAttitudeEvent);\n }\n }\n\n compute(\n relativePosition: RelativePosition,\n relativeAttitude: RelativeAttitude,\n absoluteAttitude: AbsoluteAttitude\n ) {\n\n const rotation = absoluteAttitude.heading - relativeAttitude.heading;\n\n /**\n * Here, we transform \"relativePosition\" which is defined in ArCore frame to a relative \"position\" defined in ENU frame\n */\n const east = Math.cos(rotation) * relativePosition.x - Math.sin(rotation) * relativePosition.z;\n const north = -Math.sin(rotation) * relativePosition.x - Math.cos(rotation) * relativePosition.z;\n const up = relativePosition.y;\n\n /**\n * Relative position is defined in ENU frame\n */\n const position = new GeoRelativePosition(\n east,\n north,\n up,\n relativePosition.time,\n 0,\n absoluteAttitude.heading\n );\n\n this.notify(position);\n }\n}\n\nexport default new GeoRelativePositionFromArCoreProvider();\n","import { Matrix_t } from '@wemap/maths';\nimport {\n Matrix, Matrix3, Matrix3_t, Matrix4, Matrix4_t,\n Quaternion, Quaternion_t, Vector, Vector3, Vector3_t,\n Vector4_t\n} from '@wemap/maths';\n\ntype RelativeNoises = { acc: number, gyr: number };\ntype AbsoluteNoises = { acc: number, gyr: number, yc: number };\n\ntype RelativeNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t };\ntype AbsoluteNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t, yc: Matrix3_t };\n\nconst DEFAULT_RELATIVE_NOISES = {\n acc: 0.5,\n gyr: 0.3\n};\n\nconst DEFAULT_ABSOLUTE_NOISES = {\n acc: 0.5,\n gyr: 0.3,\n yc: 2\n};\n\nclass EkfAttitude {\n P: Matrix4_t;\n accRef: Vector3_t;\n cRef: Vector3_t;\n noises!: { relative: RelativeNoisesMat, absolute: AbsoluteNoisesMat };\n quaternion: Quaternion_t | null;\n\n constructor(accRef: Vector3_t = [0, 0, 1], ycRef: Vector3_t = [-1, 0, 0]) {\n\n this.accRef = accRef;\n this.cRef = ycRef;\n\n this.P = Matrix4.fromDiagVector(Array(4).fill(0.1 ** 2) as Vector4_t);\n\n this.quaternion = null;\n \n this.noises = {} as never;\n this.setRelativeNoises(DEFAULT_RELATIVE_NOISES);\n this.setAbsoluteNoises(DEFAULT_ABSOLUTE_NOISES);\n }\n\n setRelativeNoises(relativeNoises: RelativeNoises) {\n this.noises.relative = {\n acc: Matrix3.diag(Array(3).fill(relativeNoises.acc ** 2) as Vector3_t),\n gyr: Matrix3.diag(Array(3).fill(relativeNoises.gyr ** 2) as Vector3_t)\n };\n }\n\n\n setAbsoluteNoises(absoluteNoises: AbsoluteNoises) {\n this.noises.absolute = {\n acc: Matrix3.diag(Array(3).fill(absoluteNoises.acc ** 2) as Vector3_t),\n gyr: Matrix3.diag(Array(3).fill(absoluteNoises.gyr ** 2) as Vector3_t),\n yc: Matrix3.diag(Array(3).fill(absoluteNoises.yc ** 2) as Vector3_t)\n };\n }\n\n /**\n * Try to initialize filter.\n * To initialize, we need at least current acceleration (acc)\n */\n tryInitialize(acc: Vector3_t, mag?: Vector3_t) {\n\n const accNormalized = Vector3.normalize(acc);\n\n if (mag) {\n const magNormalized = Vector3.normalize(mag);\n\n const H = Vector3.normalize(Vector3.cross(magNormalized, accNormalized));\n const M = Vector3.cross(accNormalized, H);\n\n const R: Matrix3_t = [\n [H[0], M[0], accNormalized[0]],\n [H[1], M[1], accNormalized[1]],\n [H[2], M[2], accNormalized[2]]\n ];\n\n this.quaternion = Quaternion.fromMatrix3Matlab(R);\n\n } else {\n\n const r = Vector3.dot(accNormalized, this.accRef) + 1;\n const v = Vector3.cross(accNormalized, this.accRef);\n\n let quaternion: Quaternion_t = [r, v[0], v[1], v[2]];\n quaternion = Quaternion.normalize(quaternion);\n\n this.quaternion = quaternion;\n }\n\n return this.quaternion;\n }\n\n update(diffTime: number, acc: Vector3_t, gyr: Vector3_t, mag?: Vector3_t) {\n\n if (!this.quaternion) {\n return this.tryInitialize(acc, mag);\n }\n\n let q = this.quaternion;\n\n /* ------------\n * ESTIMATION\n * ------------*/\n\n const qArray = q;\n const gyrInt = Vector3.multiplyScalar(gyr, 0.5 * diffTime);\n const F = this.computeC([1, gyrInt[0], gyrInt[1], gyrInt[2]]);\n const qAPriori = Matrix4.multiplyVector(F, q);\n const E1 = Matrix3.diag([qArray[0], qArray[0], qArray[0]]);\n const eSkew = Matrix3.skew([qArray[1], qArray[2], qArray[3]]);\n\n const qPart = [-1 * qArray[1], -1 * qArray[2], -1 * qArray[3]];\n const E = Matrix.concatRow([qPart], Matrix3.sum(eSkew, E1));\n\n const Qk = Matrix4.multiplyScalar(\n Matrix.multiply(\n Matrix.multiply(E, this.noises[mag ? 'absolute' : 'relative'].gyr),\n Matrix.transpose(E)\n ) as Matrix4_t,\n (diffTime / 2) ** 2\n );\n\n const pAPriori = Matrix4.sum(\n Matrix4.multiply(\n Matrix4.multiply(F, this.P),\n Matrix4.transpose(F)\n ),\n Qk\n );\n\n /* ------------\n * CORRECTION\n * ------------*/\n\n const accNormalized = Vector3.normalize(acc);\n let dz, K: Matrix_t, H;\n\n if (mag) {\n\n const magNormalized = Vector3.normalize(mag);\n const yc = Vector3.cross(accNormalized, magNormalized);\n const ycNormalized = Vector3.normalize(yc);\n\n const dzYc = Vector3.subtract(ycNormalized, Quaternion.rotateMatlab(qAPriori, this.cRef));\n const dzAcc = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));\n dz = Vector.concat(dzYc, dzAcc);\n\n const HYc = this.jacobianES(qAPriori, this.cRef);\n const HAcc = this.jacobianES(qAPriori, this.accRef);\n H = Matrix.concatRow(HYc, HAcc);\n\n const RYc = Matrix.concatLine(this.noises.absolute.yc, Matrix3.zeros);\n const RAcc = Matrix.concatLine(Matrix3.zeros, this.noises.absolute.acc);\n const R = Matrix.concatRow(RYc, RAcc);\n\n K = Matrix.multiply(\n Matrix.multiply(pAPriori, Matrix.transpose(H)),\n Matrix.inverse(\n Matrix.sum(\n Matrix.multiply(\n Matrix.multiply(H, pAPriori),\n Matrix.transpose(H)\n ),\n R\n )\n ) as Matrix_t\n );\n } else {\n dz = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));\n H = this.jacobianES(qAPriori, this.accRef);\n const R = this.noises.relative.acc;\n\n K = Matrix.multiply(\n Matrix.multiply(pAPriori, Matrix.transpose(H)),\n Matrix3.inverse(\n Matrix3.sum(\n Matrix.multiply(\n Matrix.multiply(H, pAPriori),\n Matrix.transpose(H)\n ) as Matrix3_t,\n R\n )\n ) as Matrix_t\n );\n }\n\n q = Quaternion.sum(\n qAPriori,\n Matrix.multiplyVector(K, dz) as Quaternion_t\n );\n const P = Matrix4.multiply(\n Matrix4.subtract(\n Matrix4.identity,\n Matrix.multiply(K, H) as Matrix4_t\n ),\n pAPriori\n );\n\n q = Quaternion.normalize(q);\n this.quaternion = q;\n this.P = P;\n\n return q;\n }\n\n computeC(b: Vector4_t): Matrix4_t {\n return [\n [b[0], -b[1], -b[2], -b[3]],\n [b[1], b[0], b[3], -b[2]],\n [b[2], -b[3], b[0], b[1]],\n [b[3], b[2], -b[1], b[0]]\n ];\n }\n\n jacobianES(q: Quaternion_t, v: Vector3_t) {\n\n const [qw, qx, qy, qz] = q;\n const [vx, vy, vz] = v;\n\n return [\n [2 * qz * vy - 2 * qy * vz, 2 * qy * vy + 2 * qz * vz, 2 * qx * vy - 2 * qw * vz - 4 * qy * vx, 2 * qw * vy + 2 * qx * vz - 4 * qz * vx],\n [2 * qx * vz - 2 * qz * vx, 2 * qw * vz - 4 * qx * vy + 2 * qy * vx, 2 * qx * vx + 2 * qz * vz, 2 * qy * vz - 2 * qw * vx - 4 * qz * vy],\n [2 * qy * vx - 2 * qx * vy, 2 * qz * vx - 4 * qx * vz - 2 * qw * vy, 2 * qw * vx - 4 * qy * vz + 2 * qz * vy, 2 * qx * vx + 2 * qy * vy]\n ];\n }\n}\n\nexport default EkfAttitude;\n","import { deg2rad, Vector3_t } from '@wemap/maths';\nimport { Browser, BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../Provider.js';\nimport AskImuOnDesktopError from '../../errors/AskImuOnDesktopError.js';\nimport { Acceleration, AngularRate } from '../../events/Types.js';\n\n// https://stackoverflow.com/a/73369838/2239938\ninterface DeviceMotionEventiOS extends DeviceMotionEvent {\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n/**\n * Imu (Inertial Measurement Unit) provider retrieve acceleration data\n * and/or angular rate data from inertial sensors.\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via devicemotion)\n * Safari iOS (v12.0): YES (via devicemotion)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent}\n * Firefox Android (v65.0.1): YES (via devicemotion)\n *\n * -----------------------------------\n */\n\ntype ImuEvent = { readonly acceleration?: Acceleration, readonly angularRate?: AngularRate };\nclass ImuProvider extends Provider<ImuEvent> {\n\n getName = () => 'IMU';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n const subscribe = () => window.addEventListener('devicemotion', this.parseDeviceMotionEvent, true);\n\n const requestPermission = (DeviceMotionEvent as unknown as DeviceMotionEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(this.notifyError);\n } else {\n subscribe();\n }\n }\n\n stop() {\n window.removeEventListener('devicemotion', this.parseDeviceMotionEvent, true);\n }\n\n /**\n * devicemotion callback\n */\n private parseDeviceMotionEvent = (e: DeviceMotionEvent) => {\n\n const timestamp = e.timeStamp / 1e3;\n\n let acc: Vector3_t | undefined;\n if (e.accelerationIncludingGravity) {\n const {\n x, y, z\n } = e.accelerationIncludingGravity;\n\n if (typeof x === 'number' && typeof y === 'number' && typeof z === 'number') {\n acc = [x, y, z];\n\n if (BrowserUtils.getName() === Browser.SAFARI\n || BrowserUtils.getName() === Browser.IOS_WEBVIEW) {\n acc[0] *= -1;\n acc[1] *= -1;\n acc[2] *= -1;\n }\n }\n }\n\n let gyr: [number, number, number] | undefined;\n if (e.rotationRate) {\n const {\n alpha, beta, gamma\n } = e.rotationRate;\n\n if (typeof alpha === 'number' && typeof beta === 'number' && typeof gamma === 'number') {\n gyr = [deg2rad(alpha), deg2rad(beta), deg2rad(gamma)];\n }\n }\n\n\n if (acc || gyr) {\n this.notify({\n ...(acc && { acceleration: { timestamp, values: acc } }),\n ...(gyr && { angularRate: { timestamp, values: gyr } })\n });\n }\n }\n\n}\n\nexport default new ImuProvider();\n","import MissingSensorError from './MissingSensorError.js';\nclass MissingAccelerometerError extends MissingSensorError {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve Acceleration data';\n\n constructor(message?: string) {\n super(message || MissingAccelerometerError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingAccelerometerError;\n","import Provider from '../Provider.js';\nimport ImuProvider from './ImuProvider.js';\nimport MissingAccelerometerError from '../../errors/MissingAccelerometerError.js';\nimport { Acceleration } from '../../events/Types.js';\n\nclass AccelerometerProvider extends Provider<Acceleration> {\n\n private imuProviderId?: number;\n\n getName = () => 'Accelerometer';\n\n availability = () => ImuProvider.getAvailability();\n\n start() {\n this.imuProviderId = ImuProvider.addEventListener(event => {\n event.acceleration\n ? this.notify(event.acceleration)\n : this.notifyError(new MissingAccelerometerError().from('devicemotion'));\n\n }, this.notifyError);\n }\n\n stop() {\n ImuProvider.removeEventListener(this.imuProviderId);\n }\n}\n\nexport default new AccelerometerProvider();\n","import MissingSensorError from './MissingSensorError.js';\nclass MissingGyroscopeError extends MissingSensorError {\n\n static DEFAULT_MESSAGE = 'Impossible to retrieve Angular Rate data';\n\n constructor(message?: string) {\n super(message || MissingSensorError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingGyroscopeError;\n","import Provider from '../Provider.js';\nimport ImuProvider from './ImuProvider.js';\nimport MissingGyroscopeError from '../../errors/MissingGyroscopeError.js';\nimport { AngularRate } from '../../events/Types.js';\n\nclass GyroscopeProvider extends Provider<AngularRate> {\n\n private imuProviderId?: number;\n\n getName = () => 'Gyroscope';\n\n availability = () => ImuProvider.getAvailability();\n\n start() {\n this.imuProviderId = ImuProvider.addEventListener(event => {\n event.angularRate\n ? this.notify(event.angularRate)\n : this.notifyError(new MissingGyroscopeError().from('devicemotion'));\n }, this.notifyError);\n }\n\n stop() {\n ImuProvider.removeEventListener(this.imuProviderId);\n }\n}\n\nexport default new GyroscopeProvider();\n","import { deg2rad, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport EkfAttitude from '../EkfAttitude.js';\nimport Accelerometer from '../../imu/AccelerometerProvider.js';\nimport Gyroscope from '../../imu/GyroscopeProvider.js';\nimport { Acceleration, AngularRate, RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Relative attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation\n * The provider does not work until an offset is given.\n */\nclass RelativeAttitudeFromEkf extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n accelerometerProviderId?: number;\n ekfAttitude = new EkfAttitude();\n gyroscopeEvent?: AngularRate;\n gyroscopeProviderId?: number;\n\n lastTimestamp = 0;\n\n getName = () => 'RelativeAttitudeFromEkf';\n\n availability() {\n return AvailabilityHelper.every([\n Accelerometer.getAvailability(),\n Gyroscope.getAvailability()\n ]);\n }\n\n start() {\n this.accelerometerProviderId = Accelerometer.addEventListener(\n event => this.onAccelerometerEvent(event),\n error => this.notifyError(error)\n );\n\n this.gyroscopeProviderId = Gyroscope.addEventListener(\n event => this.gyroscopeEvent = event,\n error => this.notifyError(error)\n );\n }\n\n stop() {\n Accelerometer.removeEventListener(this.accelerometerProviderId);\n Gyroscope.removeEventListener(this.gyroscopeProviderId);\n }\n\n private onAccelerometerEvent = (accelerationEvent: Acceleration) => {\n\n if (!this.gyroscopeEvent) {\n return;\n }\n\n const {\n values: acceleration, timestamp\n } = accelerationEvent;\n\n // Handle timestamps and dt\n if (this.lastTimestamp === 0) {\n this.lastTimestamp = timestamp;\n return;\n }\n const diffTime = timestamp - this.lastTimestamp;\n this.lastTimestamp = timestamp;\n\n const quaternion = this.ekfAttitude.update(\n diffTime,\n acceleration as Vector3_t,\n this.gyroscopeEvent.values as Vector3_t\n );\n\n if (quaternion) {\n const attitude = new RelativeAttitude(quaternion,\n timestamp,\n RelativeAttitudeFromEkf.DEFAULT_DRIFT\n );\n this.notify(attitude);\n }\n };\n}\n\nexport default new RelativeAttitudeFromEkf();\n","import { deg2rad, Rotations } from '@wemap/maths';\nimport { BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AskImuOnDesktopError from '../../../errors/AskImuOnDesktopError.js';\nimport MissingSensorError from '../../../errors/MissingSensorError.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n// https://stackoverflow.com/a/73369838/2239938\ninterface DeviceOrientationEventiOS extends DeviceOrientationEvent {\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n/**\n * Relative attitude provider gives the device attitude in a custom frame (x-right, y-front, z-up) using\n * browser deviceorientation\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via deviceorientation but deviceorientation.alpha is unreliable! Sometimes it starts at 0°, sometimes at 270°)\n * Safari iOS (v12.0): YES (via deviceorientation)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}\n * Firefox Android (v65.0.1): YES (via deviceorientation)\n *\n * -----------------------------------\n */\n\nclass RelativeAttitudeFromBrowser extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n getName = () => 'RelativeAttitudeFromBrowser';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n const subscribe = () => window.addEventListener('deviceorientation', this.onDeviceOrientationEvent, true);\n\n const requestPermission = (DeviceOrientationEvent as unknown as DeviceOrientationEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(error => this.notifyError(error));\n } else {\n subscribe();\n }\n }\n\n stop() {\n window.removeEventListener('deviceorientation', this.onDeviceOrientationEvent, true);\n }\n\n onDeviceOrientationEvent = (e: DeviceOrientationEvent) => {\n\n if (typeof e.alpha !== 'number' || typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientation'));\n return;\n }\n\n const quaternion = Rotations.eulerToQuaternionZXYDegrees([e.alpha, e.beta, e.gamma]);\n const attitude = new RelativeAttitude(quaternion,\n e.timeStamp / 1e3,\n RelativeAttitudeFromBrowser.DEFAULT_DRIFT\n );\n this.notify(attitude);\n };\n}\n\nexport default new RelativeAttitudeFromBrowser();\n","import { Vector3, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport GyroscopeProvider from './GyroscopeProvider.js';\nimport { AngularRate, HighRotation } from '../../events/Types.js';\n\nclass HighRotationsProvider extends Provider<HighRotation> {\n\n static THRESHOLD = 10; // in radians by second\n static DELAY_CONSIDERATION = 3; // in seconds\n\n gyroscopeProviderId?: number;\n\n getName = () => 'HighRotationsProvider';\n\n availability = () => GyroscopeProvider.getAvailability();\n\n start() {\n this.gyroscopeProviderId = GyroscopeProvider.addEventListener(\n this._parseGyroscopeEvent,\n this.notifyError\n );\n }\n\n stop() {\n GyroscopeProvider.removeEventListener(this.gyroscopeProviderId);\n }\n\n isInProgress() {\n if (!this.lastEvent || !GyroscopeProvider.lastEvent) {\n return false;\n }\n\n const diffTime = GyroscopeProvider.lastEvent.timestamp - this.lastEvent.timestamp;\n return diffTime < HighRotationsProvider.DELAY_CONSIDERATION;\n }\n\n private _parseGyroscopeEvent = (gyroscopeEvent: AngularRate) => {\n\n const { values, timestamp } = gyroscopeEvent;\n const speed = Vector3.norm(values as Vector3_t);\n if (speed > HighRotationsProvider.THRESHOLD) {\n this.notify({ timestamp });\n }\n\n }\n}\n\nexport default new HighRotationsProvider();\n","import { deg2rad } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport RelativeAttitudeFromEkfProvider from './RelativeAttitudeFromEkfProvider.js';\nimport RelativeAttitudeFromBrowserProvider from './RelativeAttitudeFromBrowserProvider.js';\nimport HighRotationsProvider from '../../imu/HighRotationsProvider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n\nclass RelativeAttitudeFromInertial extends Provider<RelativeAttitude> {\n\n /**\n * default relative attitude drift in rad.second-1\n */\n static DEFAULT_DRIFT = deg2rad(5) / 60;\n\n _highRotationsProviderId?: number;\n listenerId?: number;\n provider?: Provider<RelativeAttitude>;\n\n getName = () => 'RelativeAttitudeFromInertial';\n\n availability() {\n return AvailabilityHelper.some([\n RelativeAttitudeFromEkfProvider.getAvailability(),\n RelativeAttitudeFromBrowserProvider.getAvailability()\n ]);\n }\n\n start() {\n\n RelativeAttitudeFromEkfProvider.getAvailability().then(availabilityError => {\n this.provider = !availabilityError ? RelativeAttitudeFromEkfProvider : RelativeAttitudeFromBrowserProvider;\n\n this.listenerId = this.provider.addEventListener(\n event => this._parseEvent(event),\n this.notifyError\n );\n this._highRotationsProviderId = HighRotationsProvider.addEventListener(\n null,\n this.notifyError\n );\n });\n }\n\n _parseEvent(event: RelativeAttitude) {\n const relativeAttitude = event.clone();\n if (HighRotationsProvider.isInProgress()) {\n let accuracy = (relativeAttitude.accuracy || 0) + (RelativeAttitudeFromInertial.DEFAULT_DRIFT * 100);\n accuracy = Math.min(accuracy, Math.PI);\n relativeAttitude.accuracy = accuracy;\n }\n this.notify(relativeAttitude);\n }\n\n stop() {\n if (this.provider) {\n this.provider.removeEventListener(this.listenerId);\n delete this.provider;\n }\n HighRotationsProvider.removeEventListener(this._highRotationsProviderId);\n }\n}\n\nexport default new RelativeAttitudeFromInertial();\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionLadetto {\n\n \n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 1; // in m.s-2\n\n\n frequency = 0;\n\n lastVerticalAcc = 0;\n maxAcceleration = 0;\n lastStepTimestamp = -StepDetectionLadetto.MIN_TIME_BETWEEN_STEPS;\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n let stepDetected = false;\n\n const verticalAcc = linearAcc[2];\n const timeInterval = timestamp - this.lastStepTimestamp;\n\n const upfront = verticalAcc > this.lastVerticalAcc;\n\n if (upfront) {\n if (verticalAcc > this.maxAcceleration) {\n this.maxAcceleration = verticalAcc;\n }\n } else if (this.maxAcceleration > StepDetectionLadetto.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && timeInterval > StepDetectionLadetto.MIN_TIME_BETWEEN_STEPS) {\n this.maxAcceleration = 0;\n\n const diffTime = timestamp - this.lastStepTimestamp;\n this.frequency = Math.min(Math.max((1 / diffTime), StepDetectionLadetto.MIN_FRENQUENCY), StepDetectionLadetto.MAX_FRENQUENCY);\n\n stepDetected = true;\n this.lastStepTimestamp = timestamp;\n } else {\n this.maxAcceleration = 0;\n }\n\n this.lastVerticalAcc = verticalAcc;\n\n return stepDetected;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepTimestamp ? this.lastStepSize * this.frequency : 0;\n }\n}\n\nexport default StepDetectionLadetto;\n","import { Vector3_t } from \"@wemap/maths\";\n\n\nclass StepDetectionMinMaxPeaks {\n\n static WINDOW_TIME = 0.3; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 1.5; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -1; // in m.s-2\n\n frequency = 0;\n lastStepTimestamp = -StepDetectionMinMaxPeaks.MIN_TIME_BETWEEN_STEPS;\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n if (this.lastStepTimestamp && this.lastStepTimestamp + StepDetectionMinMaxPeaks.MIN_TIME_BETWEEN_STEPS > timestamp) {\n return false;\n }\n\n let maxValue = Number.MIN_SAFE_INTEGER;\n let minValue = Number.MAX_SAFE_INTEGER;\n\n const windowTime = StepDetectionMinMaxPeaks.WINDOW_TIME;\n this.slidingWindow.forEach((item, index, object) => {\n if (item.timestamp < timestamp - windowTime) {\n object.splice(index, 1);\n } else {\n maxValue = Math.max(item.verticalAcc, maxValue);\n minValue = Math.min(item.verticalAcc, minValue);\n }\n });\n this.slidingWindow.push({\n timestamp: timestamp,\n verticalAcc: linearAcc[2]\n });\n\n\n if (maxValue > StepDetectionMinMaxPeaks.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && minValue < StepDetectionMinMaxPeaks.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks.MIN_FRENQUENCY), StepDetectionMinMaxPeaks.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n }\n\n return false;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepTimestamp ? this.lastStepSize * this.frequency : 0;\n }\n}\n\nexport default StepDetectionMinMaxPeaks;\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionMinMaxPeaks2 {\n\n static WINDOW_TIME = 0.3; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.4; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 0.75; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -0.3; // in m.s-2\n\n frequency = 0;\n influence = 0.2;\n\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n lastStepTimestamp = -StepDetectionMinMaxPeaks2.MIN_TIME_BETWEEN_STEPS;\n previousVerticalAcc = 0;\n\n compute(timestamp: number, linearAcc: Vector3_t, angularRate: Vector3_t) {\n\n const verticalAcc = this.influence * (linearAcc[2] * 2) + (1 - this.influence) * this.previousVerticalAcc;\n this.previousVerticalAcc = verticalAcc;\n\n\n if (Math.sqrt(angularRate[0] ** 2 + angularRate[1] ** 2 + angularRate[2] ** 2) > 0.75) {\n return false;\n }\n\n if (this.lastStepTimestamp && this.lastStepTimestamp + StepDetectionMinMaxPeaks2.MIN_TIME_BETWEEN_STEPS > timestamp) {\n return false;\n }\n\n let maxValue = Number.MIN_SAFE_INTEGER;\n let minValue = Number.MAX_SAFE_INTEGER;\n\n this.slidingWindow.forEach((item, index, object) => {\n if (item.timestamp < timestamp - StepDetectionMinMaxPeaks2.WINDOW_TIME) {\n object.splice(index, 1);\n } else {\n maxValue = Math.max(item.verticalAcc, maxValue);\n minValue = Math.min(item.verticalAcc, minValue);\n }\n });\n this.slidingWindow.push({\n timestamp: timestamp,\n verticalAcc: verticalAcc\n });\n\n\n if (maxValue > StepDetectionMinMaxPeaks2.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD\n && minValue < StepDetectionMinMaxPeaks2.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks2.MIN_FRENQUENCY), StepDetectionMinMaxPeaks2.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n }\n\n return false;\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepSize && this.frequency ? this.lastStepSize * this.frequency : 0;\n }\n\n mean(data: { verticalAcc: number }[]) {\n let sum = 0.0, mean = 0.0;\n\n for (let i = 0; i < data.length; ++i) {\n sum += data[i].verticalAcc;\n }\n mean = sum / data.length;\n return mean;\n }\n\n stddev(data: { verticalAcc: number }[]) {\n const theMean = this.mean(data);\n let standardDeviation = 0;\n for (let i = 0; i < data.length; ++i) {\n standardDeviation += (data[i].verticalAcc - theMean) ** 2;\n }\n\n return Math.sqrt(standardDeviation / data.length);\n }\n}\n\nexport default StepDetectionMinMaxPeaks2;\n","import { Vector3_t } from \"@wemap/maths\";\n\nclass StepDetectionMinMaxPeaks3 {\n\n static WINDOW_TIME = 0.6; // in seconds\n static MIN_TIME_BETWEEN_STEPS = 0.6; // in seconds\n static MAX_FRENQUENCY = 4; // in Hz\n static MIN_FRENQUENCY = 1; // in Hz\n static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 0.2; // in m.s-2\n static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -0.1; // in m.s-2\n\n frequency = 0;\n influence = 0.05;\n\n slidingWindow: { timestamp: number, verticalAcc: number }[] = [];\n lastStepTimestamp = -StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS;\n previousVerticalAcc = 0;\n previousHorizontalAcc = 0;\n\n\n compute(timestamp: number, linearAcc: Vector3_t) {\n\n const verticalAcc = this.influence * linearAcc[2] + (1 - this.influence) * this.previousVerticalAcc;\n this.previousVerticalAcc = verticalAcc;\n\n // let horizontalAcc = Math.sqrt(linearAcc[0] ** 2 + linearAcc[1] ** 2);\n // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;\n // this.previousHorizontalAcc = horizontalAcc;\n\n // const angularRateNorm = Math.sqrt(angularRate[0] ** 2 + angularRate[1] ** 2 + angularRate[2] ** 2);\n // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;\n // this.previousangularRateNorm = angularRateNorm;\n\n // Update sliding window\n this.slidingWindow = this.slidingWindow.filter(item => item.timestamp >= timestamp - StepDetectionMinMaxPeaks3.WINDOW_TIME\n );\n this.slidingWindow.push({ timestamp, verticalAcc });\n // , horizontalAcc });\n\n // this.horizontalAccStd = this.stddev(this.slidingWindow.map(el => el.horizontalAcc));\n // this.verticalAccStd = this.stddev(this.slidingWindow.map(el => el.verticalAcc));\n\n\n const isTooEarlyForANewStep = this.lastStepTimestamp\n && this.lastStepTimestamp + StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS > timestamp;\n if (isTooEarlyForANewStep) {\n return false;\n }\n\n // Looking for max peak\n let maxValue = Number.MIN_VALUE;\n let maxValueIdx = -1;\n let foundMaxPeakHigherThanThreshold = false;\n this.slidingWindow.forEach((item, idx) => {\n if (item.verticalAcc > maxValue\n && item.verticalAcc >= StepDetectionMinMaxPeaks3.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD) {\n maxValue = item.verticalAcc;\n maxValueIdx = idx;\n foundMaxPeakHigherThanThreshold = true;\n }\n });\n if (!foundMaxPeakHigherThanThreshold) {\n return false;\n }\n\n // Looking for a value lower than a threshold before the max peak\n let hasLowNegativeValueBeforeMaxPeak = false;\n let minValueBeforeMaxPeak = Number.MAX_VALUE;\n for (let i = 0; i < maxValueIdx; i++) {\n const curValue = this.slidingWindow[i].verticalAcc;\n minValueBeforeMaxPeak = Math.min(minValueBeforeMaxPeak, curValue);\n if (curValue < StepDetectionMinMaxPeaks3.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {\n hasLowNegativeValueBeforeMaxPeak = true;\n break;\n }\n }\n if (!hasLowNegativeValueBeforeMaxPeak) {\n return false;\n }\n\n // looking for another minimum after max peak\n const diffMinMax = maxValue - minValueBeforeMaxPeak;\n const targetValue = maxValue - 0.5 * diffMinMax;\n let targetValueFoundAfterMaxPeak = false;\n for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {\n if (this.slidingWindow[i].verticalAcc <= targetValue) {\n targetValueFoundAfterMaxPeak = true;\n break;\n }\n }\n if (!targetValueFoundAfterMaxPeak) {\n return false;\n }\n\n // // looking for another local minimum / maximum after 100ms\n // let localMinimumFound = false;\n // let localMaximumFound = false;\n // let localMaxiumValue = Number.MIN_SAFE_INTEGER;\n // let localMinimumVal = null;\n // const maxPeakTimestamp = this.slidingWindow[maxValueIdx].timestamp;\n // for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {\n // const curVal = this.slidingWindow[i];\n // const prevVal = this.slidingWindow[i - 1];\n\n // if (curVal.timestamp > maxPeakTimestamp + 0.4) {\n // break;\n // }\n\n // if (!localMinimumFound) {\n // // if (curVal.timestamp < maxPeakTimestamp + 0.05) {\n // // // too early\n // // continue;\n // // }\n\n // if (curVal.verticalAcc > prevVal.verticalAcc) {\n // localMinimumFound = true;\n // localMinimumVal = prevVal;\n // }\n // continue;\n // }\n\n // if (!localMaximumFound) {\n\n // // if (curVal.timestamp < localMinimumVal.timestamp + 0.05) {\n // // // too early\n // // continue;\n // // }\n\n // if (curVal.verticalAcc < prevVal.verticalAcc) {\n // localMaximumFound = true;\n // localMaxiumValue = prevVal.verticalAcc;\n // break;\n // }\n // }\n // }\n // const localMinMaxFoundAfterPeak = localMinimumFound && localMaximumFound;\n // // && localMaxiumValue / maxValue < 0.8;\n // // if (!localMinMaxFoundAfterPeak) {\n // // return false;\n // // }\n\n\n // const highRotationDetected = angularRateNorm > 0.75;\n // // if (highRotationDetected) {\n // // return false;\n // // }\n\n const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;\n this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks3.MIN_FRENQUENCY), StepDetectionMinMaxPeaks3.MAX_FRENQUENCY);\n\n this.lastStepTimestamp = timestamp;\n return true;\n\n }\n\n get lastStepSize() {\n\n if (!this.frequency) {\n return 0;\n }\n\n const kParamA = 0.45;\n const kParamB = 0.2;\n return kParamA + kParamB * this.frequency;\n }\n\n get speed() {\n return this.lastStepSize && this.frequency ? this.lastStepSize * this.frequency : 0;\n }\n\n mean(data: number[]) {\n let sum = 0.0, mean = 0.0;\n\n for (let i = 0; i < data.length; ++i) {\n sum += data[i];\n }\n mean = sum / data.length;\n return mean;\n }\n\n stddev(data: number[]) {\n const theMean = this.mean(data);\n let standardDeviation = 0;\n for (let i = 0; i < data.length; ++i) {\n standardDeviation += (data[i] - theMean) ** 2;\n }\n\n return Math.sqrt(standardDeviation / data.length);\n }\n}\n\nexport default StepDetectionMinMaxPeaks3;\n","import { Constants as GeoConstants } from '@wemap/geo';\nimport { Quaternion, Quaternion_t, Vector3_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport { Acceleration, AngularRate, RelativeAttitude, Step } from '../../events/Types.js';\nimport RelativeAttitudeFromInertialProvider from '../attitude/relative/RelativeAttitudeFromInertialProvider.js';\nimport AccelerometerProvider from '../imu/AccelerometerProvider.js';\nimport GyroscopeProvider from '../imu/GyroscopeProvider.js';\nimport StepDetectionLadetto from './StepDetectionLadetto.js';\nimport StepDetectionMinMaxPeaks from './StepDetectionMinMaxPeaks.js';\nimport StepDetectionMinMaxPeaks2 from './StepDetectionMinMaxPeaks2.js';\nimport StepDetectionMinMaxPeaks3 from './StepDetectionMinMaxPeaks3.js';\n\n\ntype StepDetectorAlgorithmName = 'ladetto' | 'minMaxPeaks' | 'minMaxPeaks2' | 'minMaxPeaks3';\n\ntype StepDetectorAlgorithm = {\n compute(timestamp: number, linearAcc: Vector3_t, angularRate?: Vector3_t): boolean;\n lastStepSize: number;\n};\n\nclass StepProvider extends Provider<Step> {\n\n static DEFAULT_STEP_SIZE_MULTIPLIER = 1;\n static DEFAULT_ALGORITHM: StepDetectorAlgorithmName = 'minMaxPeaks3';\n\n accelerometerProviderId?: number;\n attitudeProviderId?: number;\n gyroscopeProviderId?: number;\n angularRateEvent?: AngularRate;\n attitudeEvent?: RelativeAttitude;\n numOfSteps = 0;\n stepDetector!: StepDetectorAlgorithm;\n\n _stepSizeMultiplier = StepProvider.DEFAULT_STEP_SIZE_MULTIPLIER;\n _algorithm: StepDetectorAlgorithmName = StepProvider.DEFAULT_ALGORITHM;\n _accValues: Vector3_t[] = [];\n\n constructor() {\n super();\n this.algorithm = this._algorithm;\n }\n\n getName = () => 'StepDetector';\n\n availability() {\n return AvailabilityHelper.every([\n AccelerometerProvider.getAvailability(),\n GyroscopeProvider.getAvailability(),\n RelativeAttitudeFromInertialProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.numOfSteps = 0;\n\n this.accelerometerProviderId = AccelerometerProvider.addEventListener(\n this.onAccelerometerEvent,\n this.notifyError\n );\n\n this.gyroscopeProviderId = GyroscopeProvider.addEventListener(\n event => this.angularRateEvent = event,\n this.notifyError\n );\n\n this.attitudeProviderId = RelativeAttitudeFromInertialProvider.addEventListener(\n event => this.attitudeEvent = event,\n this.notifyError\n );\n }\n\n stop() {\n AccelerometerProvider.removeEventListener(this.accelerometerProviderId);\n GyroscopeProvider.removeEventListener(this.gyroscopeProviderId);\n RelativeAttitudeFromInertialProvider.removeEventListener(this.attitudeProviderId);\n }\n\n onAccelerometerEvent = (accelerationEvent: Acceleration) => {\n\n if (!this.attitudeEvent || !this.angularRateEvent) {\n return;\n }\n\n const {\n values: acceleration, timestamp\n } = accelerationEvent;\n\n /**\n * Step Detection and Step Size Detection\n */\n const linearAcc = StepProvider.computeLinearAcceleration(\n this.attitudeEvent.quaternion, acceleration);\n const stepDetected = this.stepDetector.compute(timestamp, linearAcc, this.angularRateEvent.values);\n\n if (stepDetected) {\n const size = this.stepDetector.lastStepSize * this._stepSizeMultiplier;\n this.numOfSteps++;\n this.notify({ size, number: this.numOfSteps });\n }\n }\n\n // Linear acceleration in ENU\n static computeLinearAcceleration(quaternion: Quaternion_t, acc: Vector3_t) {\n const linearAcc = Quaternion.rotateMatlab(Quaternion.inverse(quaternion), acc);\n linearAcc[2] -= GeoConstants.EARTH_GRAVITY;\n return linearAcc;\n }\n\n set stepSizeMultiplier(stepSizeMultiplier) {\n this._stepSizeMultiplier = stepSizeMultiplier;\n }\n\n get stepSizeMultiplier() {\n return this._stepSizeMultiplier;\n }\n\n set algorithm(algorithm) {\n switch (algorithm) {\n case 'ladetto':\n this.stepDetector = new StepDetectionLadetto();\n break;\n case 'minMaxPeaks':\n this.stepDetector = new StepDetectionMinMaxPeaks();\n break;\n case 'minMaxPeaks2':\n this.stepDetector = new StepDetectionMinMaxPeaks2();\n break;\n case 'minMaxPeaks3':\n default:\n algorithm = 'minMaxPeaks3';\n this.stepDetector = new StepDetectionMinMaxPeaks3();\n break;\n }\n this._algorithm = algorithm;\n }\n\n get algorithm() {\n return this._algorithm;\n }\n}\n\nexport function createStepProvider(algorithm: StepDetectorAlgorithmName) {\n const stepProvider = new StepProvider();\n stepProvider.algorithm = algorithm;\n return stepProvider;\n}\n\nexport default new StepProvider();\n","import { GeoRelativePosition } from '@wemap/geo';\nimport { deg2rad } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport StepProvider from '../../steps/StepProvider.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport { Step, AbsoluteAttitude } from '../../../events/Types.js';\n\n\nclass PdrProvider extends Provider<GeoRelativePosition> {\n\n private absoluteAttitudeProviderId?: number;\n private stepDetectionProviderId?: number;\n private attitudeEvent?: AbsoluteAttitude;\n\n // https://ieeexplore.ieee.org/document/7346766\n // private misalignment = [1, 0, 0, 0];\n private misalignmentError = deg2rad(3);\n\n getName = () => 'Pdr';\n\n availability() {\n return AvailabilityHelper.every([\n StepProvider.getAvailability(),\n AbsoluteAttitudeProvider.getAvailability()\n ]);\n }\n\n\n start() {\n\n this.stepDetectionProviderId = StepProvider.addEventListener(\n this.onStepEvent,\n this.notifyError\n );\n\n this.absoluteAttitudeProviderId = AbsoluteAttitudeProvider.addEventListener(\n event => (this.attitudeEvent = event),\n this.notifyError\n );\n\n }\n\n stop() {\n StepProvider.removeEventListener(this.stepDetectionProviderId);\n AbsoluteAttitudeProvider.removeEventListener(this.absoluteAttitudeProviderId);\n }\n\n private onStepEvent = (stepEvent: Step) => {\n\n if (!this.attitudeEvent) {\n return;\n }\n\n const stepSize = stepEvent.size;\n\n /**\n * There is three frames because (device heading != walking direction):\n *\n * Device frame (x-Device Right, y-Device Top, z-Device Front)\n * Navigation frame (x-Nav East, y-Nav North, z-Nav Up)\n * Earth local frame (x-East y-North z-Up)\n *\n *\n * For the PDR, in order to find the step direction,\n * we are looking for the rotation between the device frame and the navigation frame.\n * Attitude is the rotation from the device frame to the earth local frame.\n * Misalignment is the rotation from the navigation frame to the earth local frame\n */\n const deviceAttitude = this.attitudeEvent;\n\n /**\n * For optimisation, as we define misalignment to identity, we do not process the quat mulitply formula.\n */\n // const deviceInNavFrame = Quaternion.multiply(deviceAttitude.quaternion, this.misalignment);\n // const deviceDirection = new Attitude(deviceInNavFrame).heading;\n const deviceDirection = deviceAttitude.heading;\n\n /**\n * A bad accuracy from PDR is due to three things:\n * - Attitude accuracy\n * - Misalignement (device heading != walking direction)\n * - Step detection false positives / false negatives\n * Following formula only use attitude accuracy with cone formula\n */\n const deviceDirectionAccuracy = deviceAttitude.accuracy! + this.misalignmentError;\n const accuracy = (stepSize / 2) * Math.sin(deviceDirectionAccuracy / 2);\n const timestamp = deviceAttitude.time;\n\n /**\n * Relative position is defined in ENU frame\n */\n const position = new GeoRelativePosition(\n stepSize * Math.sin(deviceDirection),\n stepSize * Math.cos(deviceDirection),\n 0,\n timestamp,\n accuracy,\n deviceDirection\n );\n\n this.notify(position);\n }\n}\n\nexport default new PdrProvider();\n","import { GeoRelativePosition } from '@wemap/geo';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport GeoRelativePositionFromArCoreProvider from './GeoRelativePositionFromArCoreProvider.js';\nimport PdrProvider from './PdrProvider.js';\n\n\nclass GeoRelativePositionProvider extends Provider<GeoRelativePosition> {\n\n providerId?: number;\n geoRelativeProvider?: Provider<GeoRelativePosition>;\n\n getName = () => 'GeoRelativePosition';\n\n availability() {\n return AvailabilityHelper.some([\n PdrProvider.getAvailability(),\n GeoRelativePositionFromArCoreProvider.getAvailability()\n ]);\n }\n\n async start() {\n const availabilityError = await GeoRelativePositionFromArCoreProvider.getAvailability();\n this.geoRelativeProvider = availabilityError ? PdrProvider : GeoRelativePositionFromArCoreProvider;\n this.providerId = this.geoRelativeProvider.addEventListener(this.notify, this.notifyError);\n }\n\n stop() {\n this.geoRelativeProvider?.removeEventListener(this.providerId);\n delete this.geoRelativeProvider;\n }\n}\n\nexport default new GeoRelativePositionProvider();\n","import Provider from '../Provider.js';\nimport AccelerometerProvider from '../imu/AccelerometerProvider.js';\nimport { Acceleration, Inclination } from '../../events/Types.js';\n\n/**\n * Inclination provider gives the inclination of the device using Imu Sensor\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationFromAccProvider extends Provider<Inclination> {\n\n providerId?: number;\n\n getName = () => 'InclinationFromAcc';\n\n availability = () => AccelerometerProvider.getAvailability();\n\n start() {\n this.providerId = AccelerometerProvider.addEventListener(\n this.onAccelerometerEvent,\n this.notifyError\n );\n }\n\n stop() {\n AccelerometerProvider.removeEventListener(this.providerId);\n }\n\n private onAccelerometerEvent = (accelerometerEvent: Acceleration) => {\n const acc = accelerometerEvent.values;\n\n const screenOrientation = window.orientation || 0;\n\n const sizeAcc = Math.sqrt(acc[0] * acc[0] + acc[1] * acc[1] + acc[2] * acc[2]);\n const accNormalized = [acc[0] / sizeAcc, acc[1] / sizeAcc, acc[2] / sizeAcc];\n\n const q = [accNormalized[2] + 1, accNormalized[1], -accNormalized[0], 0];\n const qSize = Math.sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]);\n const qNormalized = [q[0] / qSize, q[1] / qSize, q[2] / qSize, 0];\n\n let inclination;\n if (screenOrientation === 0) {\n inclination = Math.asin(2 * qNormalized[1] * qNormalized[0]);\n } else if (screenOrientation === 90) {\n inclination = -Math.asin(2 * qNormalized[2] * qNormalized[0]);\n } else if (screenOrientation === -90) {\n inclination = Math.asin(2 * qNormalized[2] * qNormalized[0]);\n } else { // if (screenOrientation === 180) {\n inclination = -Math.asin(2 * qNormalized[1] * qNormalized[0]);\n }\n\n this.notify(inclination);\n };\n}\n\nexport default new InclinationFromAccProvider();\n","import { Quaternion_t } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport RelativeAttitudeFromInertialProvider from '../attitude/relative/RelativeAttitudeFromInertialProvider.js';\nimport { Inclination } from '../../events/Types.js';\n\n\n/**\n * Inclination provider gives the inclination of the device using Relative Attitude\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationFromRelativeAttitudeProvider extends Provider<Inclination> {\n\n providerId?: number;\n\n getName = () => 'InclinationFromRelativeAttitude';\n\n availability = () => RelativeAttitudeFromInertialProvider.getAvailability();\n\n start() {\n this.providerId = RelativeAttitudeFromInertialProvider.addEventListener(\n attitudeEvent => {\n const inclination = this.enuQuatToInclination(attitudeEvent.quaternion);\n this.notify(inclination);\n },\n this.notifyError\n );\n }\n\n stop() {\n RelativeAttitudeFromInertialProvider.removeEventListener(this.providerId);\n }\n\n enuQuatToInclination(q: Quaternion_t) {\n const screenOrientation = window.orientation || 0;\n\n if (screenOrientation === 0) {\n return Math.asin(2 * (q[2] * q[3] + q[1] * q[0]));\n } else if (screenOrientation === 90) {\n return Math.asin(2 * (q[1] * q[3] - q[2] * q[0]));\n } else if (screenOrientation === -90) {\n return Math.asin(2 * (q[2] * q[0] - q[1] * q[3]));\n }\n // else if (screenOrientation === 180)\n return -Math.asin(2 * (q[2] * q[3] + q[1] * q[0]));\n }\n}\n\nexport default new InclinationFromRelativeAttitudeProvider();\n","import Provider from '../Provider.js';\nimport InclinationFromAccProvider from './InclinationFromAccProvider.js';\nimport InclinationFromRelativeAttitudeProvider from './InclinationFromRelativeAttitudeProvider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport { Inclination } from '../../events/Types.js';\n\n/**\n * Inclination provider gives the inclination of the device using Imu Sensor\n * For example, when the top of the device is pointing the sky, inclination = Math.PI/2\n * when the device is layed on a table, inclination = 0\n * This provider use window.orientation to return a result in function of screen orientation\n */\nclass InclinationProvider extends Provider<Inclination> {\n\n provider?: Provider<Inclination>;\n providerId?: number;\n\n getName = () => 'Inclination';\n\n availability() {\n return AvailabilityHelper.some([\n InclinationFromAccProvider.getAvailability(),\n InclinationFromRelativeAttitudeProvider.getAvailability()\n ]);\n }\n\n async start() {\n\n const startInclinationFromAcc = () => {\n this.provider = InclinationFromAccProvider;\n this.providerId = this.provider.addEventListener(\n this.notify,\n this.notifyError\n );\n };\n\n if (await InclinationFromRelativeAttitudeProvider.getAvailability()) {\n this.provider = InclinationFromRelativeAttitudeProvider;\n this.providerId = this.provider.addEventListener(\n this.notify,\n () => {\n InclinationFromRelativeAttitudeProvider.removeEventListener(this.providerId);\n startInclinationFromAcc();\n }\n );\n } else {\n startInclinationFromAcc();\n }\n }\n\n\n stop() {\n if (this.provider) {\n this.provider.removeEventListener(this.providerId);\n }\n }\n}\n\nexport default new InclinationProvider();\n","import { Calibration } from '@wemap/camera';\nimport { Attitude, AttitudeJson, UserPosition, UserPositionJson } from '@wemap/geo';\nimport { Device } from '@wemap/utils';\n\nexport type CoarsePoseJson = {\n attitude?: AttitudeJson,\n position?: UserPositionJson,\n};\n\nexport type CoarsePose = {\n attitude?: Attitude,\n position?: UserPosition,\n};\n\nexport type VpsMetadataJson = {\n size: [number, number], // [width, height]\n calibration?: Calibration,\n coarse?: CoarsePoseJson,\n device?: Device\n}\n\n\nclass VpsMetadata {\n\n constructor(\n public size: { width: number, height: number },\n public calibration: Calibration | null = null,\n public coarse: CoarsePose | null = null,\n public device: Device | null = null,\n ) { }\n\n toJson(): VpsMetadataJson {\n return {\n size: [this.size.width, this.size.height],\n ...(this.calibration && { calibration: this.calibration }),\n ...(this.coarse && {\n coarse: {\n ...(this.coarse.attitude && { attitude: this.coarse.attitude.toJson() }),\n ...(this.coarse.position && { position: this.coarse.position.toJson() })\n }\n }),\n ...(typeof this.device === 'object' && { device: this.device })\n };\n }\n\n\n static fromJson(json: VpsMetadataJson) {\n return new VpsMetadata(\n {\n width: json.size[0],\n height: json.size[1]\n },\n json.calibration,\n {\n ...(json.coarse?.position && { position: UserPosition.fromJson(json.coarse.position) }),\n ...(json.coarse?.attitude && { attitude: Attitude.fromJson(json.coarse.attitude) })\n },\n json.device\n );\n }\n}\n\nexport default VpsMetadata;\n","import { canvasToBase64, base64ToCanvas } from '@wemap/camera';\n\nimport VpsMetadata, { VpsMetadataJson } from './VpsMetadata.js';\n\nexport type VpsRequestJson = VpsMetadataJson & {\n image: string\n}\n\nclass VpsRequest {\n\n constructor(public metadata: VpsMetadata, public image: HTMLCanvasElement) {}\n\n toJson() {\n const base64Image = canvasToBase64(this.image);\n return {\n image: base64Image,\n ...this.metadata.toJson()\n };\n }\n\n static fromJson(json: VpsRequestJson) {\n return new VpsRequest(\n VpsMetadata.fromJson(json),\n base64ToCanvas(json.image)\n );\n }\n}\n\nexport default VpsRequest;\n","import { Attitude, AttitudeJson, UserPosition, UserPositionJson } from '@wemap/geo';\n\nexport type VpsResponseJson = {\n success: boolean,\n attitude?: AttitudeJson,\n position?: UserPositionJson\n}\n\nclass VpsResponse {\n\n constructor(\n public success: boolean,\n public attitude: Attitude | null = null,\n public position: UserPosition | null = null\n ) { }\n\n toJson(): VpsResponseJson {\n return {\n success: this.success,\n attitude: this.attitude?.toJson(),\n position: this.position?.toJson()\n }\n }\n\n static fromJson(json: VpsResponseJson, imageRecordTime: number | null = null) {\n\n let attitude: Attitude | null = null;\n if (json.attitude) {\n attitude = Attitude.fromJson(json.attitude);\n attitude.time = imageRecordTime;\n }\n\n let position: UserPosition | null = null;\n if (json.position) {\n position = UserPosition.fromJson(json.position);\n position.time = imageRecordTime;\n }\n\n return new VpsResponse(json.success, attitude, position);\n }\n}\n\nexport default VpsResponse;\n","import { Calibration, reduceImageSize, convertToGrayscale } from '@wemap/camera';\nimport Logger from '@wemap/logger';\nimport { Quaternion_t } from '@wemap/maths/index.js';\nimport { TimeUtils, UserAgentUtils } from '@wemap/utils';\nimport VpsMetadata, { CoarsePose } from './VpsMetadata.js';\n\nimport VpsRequest from './VpsRequest.js';\nimport VpsResponse from './VpsResponse.js';\n\nclass ImageRelocalization {\n\n static _prepareRequest(\n imageCanvas: HTMLCanvasElement,\n calibration: Calibration | null = null,\n coarsePose: CoarsePose | null = null\n ) {\n convertToGrayscale(imageCanvas);\n const reducedImage = reduceImageSize(imageCanvas, 1280);\n\n const metadata = new VpsMetadata(\n { width: reducedImage.width, height: reducedImage.height },\n calibration,\n coarsePose,\n UserAgentUtils.getDeviceFromUserAgent()\n );\n\n return new VpsRequest(metadata, reducedImage);\n }\n\n \n static async relocalize(\n endpointUrl: string,\n imageCanvas: HTMLCanvasElement,\n calibration: Calibration | null = null,\n coarsePose: CoarsePose | null = null,\n customHeaders: Record<string, string> | null = null\n ) {\n\n const timeBeforeRequest = TimeUtils.preciseTime() / 1e3;\n\n // 1. Prepare the request\n const vpsRequest = this._prepareRequest(imageCanvas, calibration, coarsePose);\n\n // 2. Send the request\n let serverResponse;\n try {\n const body = JSON.stringify(vpsRequest.toJson());\n Logger.debug(`[VPS] Request (${(body.length / 1024).toFixed(0)} kB) sent to server ${endpointUrl}`);\n serverResponse = await fetch(endpointUrl, {\n method: 'POST',\n body,\n headers: Object.assign(\n { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n customHeaders ? customHeaders : {}\n )\n });\n } catch (e) {\n Logger.debug('[VPS] Server respond error');\n return null;\n }\n\n if (serverResponse.status !== 200) {\n Logger.debug('[VPS] Server respond error');\n return null;\n }\n\n // 3. Parse the response\n const json = await serverResponse.json();\n const res = VpsResponse.fromJson(json, timeBeforeRequest);\n Logger.debug(`[VPS] Server respond ${res.success ? 'success' : 'not found'}`);\n return res;\n }\n\n static getHeadingFromQuaternion(quaternion: Quaternion_t) {\n\n const [qw, qx, qy, qz] = quaternion;\n\n const s = Math.sqrt(2) / 2;\n const C = [s * (qw - qx), s * (qw + qx), s * (qy + qz), s * (qz - qy)];\n return -Math.atan2(2 * C[3] * C[0] - 2 * C[2] * C[1], 1 - 2 * C[1] ** 2 - 2 * C[3] ** 2);\n\n // ---- Not optimized version ----\n\n // const eulerAnglesAR = Rotations.quaternionToEulerZXY(\n // Quaternion.multiply(\n // quaternion,\n // Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2)\n // )\n // );\n\n // return -eulerAnglesAR[0];\n }\n}\n\nexport default ImageRelocalization;\n","import { Attitude } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport RelativeAttitudeFromBrowser from '../../attitude/relative/RelativeAttitudeFromBrowserProvider.js';\n\nexport default class RelativeRotationCalc {\n\n _providerId?: number;\n\n _isRunning = false;\n _dataOnStart: Attitude | null = null;\n\n tickStart() {\n this._dataOnStart = null;\n\n if (this._isRunning) {\n // Do not start the provider if tickStart() has already been called without tickEnd()\n return;\n }\n\n this._isRunning = true;\n\n this._providerId = RelativeAttitudeFromBrowser.addEventListener(event => {\n if (!this._dataOnStart) {\n this._dataOnStart = event;\n }\n });\n }\n\n tickEnd() {\n if (!this._isRunning) {\n Logger.warn('You have to call tickStart before tickEnd');\n return null;\n }\n\n this._internalStop();\n\n if (!this._dataOnStart) {\n Logger.warn('Delay was too short between tickStart and tickEnd '\n + 'or RelativeAttitudeProvider cannot be retrieved.');\n return null;\n }\n\n const dataOnEnd = RelativeAttitudeFromBrowser.lastEvent!;\n return Attitude.diff(this._dataOnStart, dataOnEnd);\n }\n\n _internalStop() {\n RelativeAttitudeFromBrowser.removeEventListener(this._providerId);\n delete this._providerId;\n this._isRunning = false;\n }\n\n release() {\n if (this._isRunning) {\n this._internalStop();\n }\n }\n}\n","class MissingPoleStarError extends Error {\n\n static DEFAULT_MESSAGE = 'PoleStar is missing';\n\n constructor(message?: string) {\n super(message || MissingPoleStarError.DEFAULT_MESSAGE);\n }\n}\n\nexport default MissingPoleStarError;\n","import { deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport MissingPoleStarError from '../../../errors/MissingPoleStarError.js';\nimport MissingNativeInterfaceError from '../../../errors/MissingNativeInterfaceError.js';\nimport Constants from '../../Constants.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\nimport { NativePolestarPosition } from '../../NativeProviders.js';\n\nclass PoleStarProvider extends Provider<AbsolutePosition> {\n\n getName = () => 'PoleStar';\n\n constructor() {\n super();\n this.addMethodsToNativeJsProvider();\n }\n\n availability() {\n try {\n this.nativeProvider.checkAvailability();\n return Promise.resolve();\n } catch (e) {\n return Promise.resolve(e as Error);\n }\n }\n\n setApiKey(apiKey: string) {\n this.nativeProvider.setApiKey(apiKey);\n }\n\n start() {\n this.nativeProvider.start();\n }\n\n stop() {\n this.nativeProvider.stop();\n }\n\n get nativeProvider() {\n\n if (!this.nativeInterface) {\n throw new MissingNativeInterfaceError();\n }\n\n const nativeProvider = this.nativeInterface.getPoleStarProvider();\n if (!nativeProvider) {\n throw new MissingPoleStarError();\n }\n\n return nativeProvider;\n }\n\n\n\n addMethodsToNativeJsProvider() {\n\n if (!this.nativeJsInterface) {\n return;\n }\n\n this.nativeJsInterface.polestar = {\n callbackError: (errorMessage: string) => this.notifyError(new Error(errorMessage)),\n callbackPosition: (jsonString: string) => {\n\n const json: NativePolestarPosition = JSON.parse(jsonString);\n\n const timestamp = TimeUtils.unixTimestampToPreciseTime(json.time) / 1e3;\n\n const position = new AbsolutePosition(\n json.lat,\n json.lng,\n Constants.DEFAULT_ALTITUDE,\n json.alt / 5,\n timestamp,\n json.accuracy,\n deg2rad(json.bearing)\n );\n\n this.notify(position);\n }\n };\n\n }\n}\n\nexport default new PoleStarProvider();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport { SharedCameras, Camera } from '@wemap/camera';\nimport { Attitude } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { Quaternion, deg2rad } from '@wemap/maths';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport Inclination from '../../inclination/InclinationProvider.js';\nimport ImageRelocalization from './ImageRelocalization.js';\nimport AbsoluteAttitudeProvider from '../../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport RelativeRotationCalc from './RelativeRotationCalc.js';\nimport GnssWifiProvider from '../../position/absolute/GnssWifiProvider.js';\nimport AbsolutePositionProvider from '../../position/absolute/AbsolutePositionProvider.js';\nimport PoleStarProvider from '../../position/absolute/PoleStarProvider.js';\nimport { AbsoluteAttitude, AbsolutePosition } from '../../../events/Types.js';\nimport { CoarsePose } from './VpsMetadata.js';\n\nexport type VpsEvent = { absoluteAttitude: AbsoluteAttitude, absolutePosition: AbsolutePosition };\nclass VpsProvider extends Provider<VpsEvent> {\n\n static MIN_TIME_BETWEEN_TWO_REQUESTS = 1000; // in ms\n static DEFAULT_MIN_INCLINATION_FOR_REQUEST = deg2rad(60); // in radians\n static DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST = 200; // in ms\n static DEFAULT_USE_COARSE_POSE = true;\n static CAMERA_TO_SMARTPHONE_ROT = Quaternion.fromAxisAngle([1, 0, 0], Math.PI);\n\n _relativeRotationCalc?: RelativeRotationCalc;\n\n _serverError = false;\n _cameraError = false;\n\n _camera: Camera | null = null;\n _endpoint: string | null = null;\n\n _inclinationProviderId?: number;\n\n _minInclinationForRequest = VpsProvider.DEFAULT_MIN_INCLINATION_FOR_REQUEST;\n _waitTimeMinInclinationForRequest = VpsProvider.DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST;\n _useCoarsePose = VpsProvider.DEFAULT_USE_COARSE_POSE;\n\n getName = () => 'Vps';\n\n availability = () => Camera.checkAvailability();\n\n start() {\n\n // 1. Inclination\n this._inclinationProviderId = Inclination.addEventListener();\n\n // 2. Relative Rotation Calc\n this._relativeRotationCalc = new RelativeRotationCalc();\n\n // 3. Add listeners on shared cameras to detect new cameras\n SharedCameras.on('added', this._onCameraDetected);\n SharedCameras.on('removed', this._onCameraRemoved);\n\n // 4. If a camera already exists, use it\n if (SharedCameras.list.length) {\n if (SharedCameras.list.length > 1) {\n Logger.warn('It seems that more than 1 camera has been detected'\n + ' for VPS. Taking the first...');\n }\n this._useCamera(SharedCameras.list[0].camera);\n }\n }\n\n stop() {\n\n Inclination.removeEventListener(this._inclinationProviderId);\n\n this._relativeRotationCalc?.release();\n\n SharedCameras.off('added', this._onCameraDetected);\n SharedCameras.off('removed', this._onCameraRemoved);\n\n this._camera = null;\n }\n\n _onCameraDetected = ({ camera }: { camera: Camera }) => {\n if (this._camera) {\n Logger.warn('It seems that more than 1 camera has been detected'\n + ' for VPS. Taking the first...');\n }\n this._useCamera(camera);\n }\n\n _onCameraRemoved = () => {\n if (this._camera) {\n this._camera.off('started', this._internalStart);\n this._camera.off('stopped', this._internalStop);\n } else {\n Logger.warn('There is no previously detected camera but once has stopped');\n }\n this._camera = null;\n }\n\n _useCamera(camera: Camera) {\n this._camera = camera;\n\n camera.on('started', this._internalStart);\n camera.on('stopped', this._internalStop);\n\n if (camera.state === 'started') {\n this._internalStart();\n }\n }\n\n\n _internalStart = async () => {\n\n if (!this._endpoint) {\n this.notifyError(new Error('VPS endpoint has not been set before calling start()'));\n return;\n }\n\n let lastRequestTime = null;\n const isProviderStopped = () => this.state === 'stopped';\n while (!isProviderStopped()) {\n\n // 1. Handle the time to wait between two requests (MIN_TIME_BETWEEN_TWO_REQUESTS)\n if (lastRequestTime !== null) {\n const diffTime = TimeUtils.preciseTime() - lastRequestTime;\n const timeToWait = Math.max(0, VpsProvider.MIN_TIME_BETWEEN_TWO_REQUESTS - diffTime);\n await new Promise(resolve => setTimeout(resolve, timeToWait));\n }\n lastRequestTime = TimeUtils.preciseTime();\n\n // 2. Check if Vps is not stopped and camera is still started\n if (isProviderStopped()\n || !this._camera\n || this._camera.state !== 'started') {\n break;\n }\n\n // 2.a. Do not send an image if smartphone looks at the floor\n const inclination = Inclination.lastEvent ? Inclination.lastEvent : null;\n if (inclination !== null\n && inclination < this._minInclinationForRequest) {\n await new Promise(resolve => setTimeout(resolve, this._waitTimeMinInclinationForRequest));\n continue;\n }\n\n // 3. Get current image from camera and relocalize it.\n\n // 3.a. Get current image and time it.\n this._relativeRotationCalc?.tickStart();\n const image = await this._camera.currentImage;\n if (!image) {\n continue;\n }\n\n // 3.b. Retrieve coarse position if necessary.\n let coarsePose: CoarsePose | null = null;\n const bestCoarsePosition = AbsolutePositionProvider.getBestPositionEvent(GnssWifiProvider.lastEvent, PoleStarProvider.lastEvent);\n if (this._useCoarsePose && (bestCoarsePosition || AbsoluteAttitudeProvider.lastEvent)) {\n coarsePose = {\n ...(bestCoarsePosition && {position: bestCoarsePosition}),\n ...(AbsoluteAttitudeProvider.lastEvent && {attitude: AbsoluteAttitudeProvider.lastEvent})\n };\n }\n\n // 3.c. Send image and metadata.\n const res = await ImageRelocalization.relocalize(this._endpoint, image, null, coarsePose);\n if (!res || !res.success) {\n continue;\n }\n\n // 4. If relocalization is successful, apply the transforms\n const enuToCameraRot = res.attitude!.quaternion;\n const enuToSmartphoneRot = Quaternion.multiply(\n enuToCameraRot,\n VpsProvider.CAMERA_TO_SMARTPHONE_ROT\n );\n\n const deviceQuaternion = Quaternion.multiply(\n Quaternion.fromAxisAngle([0, 0, 1], deg2rad(window.orientation || 0)),\n enuToSmartphoneRot\n );\n\n const diffAttitude = this._relativeRotationCalc?.tickEnd() || new Attitude([1, 0, 0, 0]);\n const deviceQuaternionWithRelOffset = Quaternion.multiply(\n deviceQuaternion,\n diffAttitude.quaternion\n );\n const attitude = new AbsoluteAttitude(\n deviceQuaternionWithRelOffset,\n res.attitude!.time,\n res.attitude!.accuracy\n );\n\n // [16/06/22] Force VPS accuracy to 5m if the information does not exist\n // this allows to correctly fuse positions from different providers (VPS,\n // GnssWifi, Pole Star...)\n const devicePosition = res.position!.clone();\n if (devicePosition.accuracy === null) {\n devicePosition.accuracy = 5;\n }\n\n // 5. Finally, notify the listeners if the VPS is not stopped\n if (isProviderStopped()) {\n break;\n }\n\n this.notify({\n absoluteAttitude: attitude,\n absolutePosition: devicePosition\n });\n\n }\n }\n\n _internalStop = () => {\n // do nothing\n }\n\n get endpoint() {\n return this._endpoint;\n }\n\n set endpoint(endpoint) {\n this._endpoint = endpoint;\n }\n\n get minInclinationForRequest() {\n return this._minInclinationForRequest;\n }\n\n set minInclinationForRequest(minInclinationForRequest) {\n this._minInclinationForRequest = minInclinationForRequest;\n }\n\n get waitTimeMinInclinationForRequest() {\n return this._waitTimeMinInclinationForRequest;\n }\n\n set waitTimeMinInclinationForRequest(waitTimeMinInclinationForRequest) {\n this._waitTimeMinInclinationForRequest = waitTimeMinInclinationForRequest;\n }\n\n get useCoarsePose() {\n return this._useCoarsePose;\n }\n\n set useCoarsePose(useCoarsePose) {\n this._useCoarsePose = useCoarsePose;\n }\n}\n\nexport default new VpsProvider();\n","import { Level, GeoRelativePosition, UserPosition } from '@wemap/geo';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport MapMatchingHandler from '../../../mapmatching/MapMatchingHandler.js';\nimport GnssWifiProvider from './GnssWifiProvider.js';\nimport GeoRelativePositionProvider from '../relative/GeoRelativePositionProvider.js';\nimport ProvidersOptions from '../../../ProvidersOptions.js';\nimport VpsProvider from '../../vision/vps/VpsProvider.js';\nimport PoleStarProvider from './PoleStarProvider.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\nclass AbsolutePositionProvider extends Provider<AbsolutePosition> {\n\n // Use the new absolute position if its accuracy is at least x times better than the last one.\n static ACCURACY_RELOC_RATIO = 1; // or 1.5\n static USE_MM_FOR_FEED = true;\n\n _polestarProviderId?: number;\n _vpsProviderId?: number;\n _gnssWifiProviderId?: number;\n _relativePositionProviderId?: number;\n _mapMatchingHandlerId?: number;\n\n useAllAbsolutePositions = false;\n _waitUntilNextVpsPosition = false;\n _lastPolestarFix: number | null = null;\n\n getName = () => 'AbsolutePosition';\n\n\n availability() {\n return AvailabilityHelper.some([\n GeoRelativePositionProvider.getAvailability(),\n GnssWifiProvider.getAvailability(),\n ...(ProvidersOptions.hasPoleStar ? [PoleStarProvider.getAvailability()] : []),\n VpsProvider.getAvailability()\n ]);\n }\n\n\n start() {\n GeoRelativePositionProvider.getAvailability()\n .then((error) => {\n if (!error) {\n this._relativePositionProviderId = GeoRelativePositionProvider.addEventListener(\n e => this._onRelativePosition(e)\n );\n } else {\n // do nothing\n }\n });\n\n // GnssWifi\n this._gnssWifiProviderId = GnssWifiProvider.addEventListener(\n event => {\n const clone = event.clone();\n clone.bearing = null;\n this._onAbsolutePosition(clone, false);\n }\n );\n\n // Vps\n this._vpsProviderId = VpsProvider.addEventListener(\n event => this._onAbsolutePosition(event.absolutePosition),\n this.notifyError,\n false\n );\n\n // PoleStar\n if (ProvidersOptions.hasPoleStar) {\n this._polestarProviderId = PoleStarProvider.addEventListener(polestarPositionEvent => {\n\n this._lastPolestarFix = TimeUtils.preciseTime();\n const psPositionUsed = this._onAbsolutePosition(polestarPositionEvent);\n\n /**\n * In the case of a degraded position from PoleStar and a good position from GnssWifi,\n * we still need to retrieve the level from PoleStar.\n * To do so, we duplicate lastEvent and add the level from PoleStar to the current\n * position, then we notify with the new position.\n */\n if (!psPositionUsed && this.lastEvent?.level === null) {\n const lastPositionWithLevel = this.lastEvent.clone();\n lastPositionWithLevel.level = polestarPositionEvent.level;\n this.notify(lastPositionWithLevel);\n }\n });\n }\n\n this._mapMatchingHandlerId = MapMatchingHandler.addEventListener();\n }\n\n\n /**\n * @override\n */\n stop() {\n if (this._relativePositionProviderId) {\n GeoRelativePositionProvider.removeEventListener(this._relativePositionProviderId);\n delete this._relativePositionProviderId;\n }\n if (this._gnssWifiProviderId) {\n GnssWifiProvider.removeEventListener(this._gnssWifiProviderId);\n delete this._gnssWifiProviderId;\n }\n if (this._vpsProviderId) {\n VpsProvider.removeEventListener(this._vpsProviderId);\n delete this._vpsProviderId;\n }\n if (this._polestarProviderId) {\n PoleStarProvider.removeEventListener(this._polestarProviderId);\n delete this._polestarProviderId;\n }\n\n MapMatchingHandler.removeEventListener(this._mapMatchingHandlerId);\n }\n\n\n private _shouldTakeIntoAccountNewAbsolutePosition(newPositionEvent: AbsolutePosition, canContainLevel = true) {\n\n const newPosition = newPositionEvent;\n const lastPosition = this.lastEvent || null;\n\n // 1. Verifiy if it is the first known absolute position\n if (!lastPosition) {\n return true;\n }\n\n // 2. Is the new position accuracy is better enough than the last position accuracy\n const isBetterEnough = newPosition.accuracy! * AbsolutePositionProvider.ACCURACY_RELOC_RATIO <= lastPosition.accuracy!;\n if (isBetterEnough) {\n return true;\n }\n\n // 3.a. Is the new position is far from the new one (regarding accuracy)\n // This condition return true if the two positions accuracy circles does not intersect.\n // This is important if the person put the current page in the background during a while. But,\n // could be dangerous if two providers do not provide close positions (ping-pong effect). This\n // is why the 3.b. condition has been added.\n // TODO: add a routine to augment the current position accuracy when the page is in background\n const isFarEnough = lastPosition.distanceTo(newPosition) > lastPosition.accuracy! + newPosition.accuracy!;\n if (isFarEnough) {\n return true;\n }\n\n // 3.b. Added on 16/06/22\n // The goal of this condition is to avoid continuous jumps between positions from two providers\n // (i.e. GnssWifi and PoleStar)\n const isFarEnoughAndAccuracyIsBetter = isFarEnough && newPosition.accuracy! <= lastPosition.accuracy!;\n\n if (isBetterEnough && isFarEnoughAndAccuracyIsBetter) {\n return true;\n }\n\n // 4. Added on 23/06/22\n // The goal of this condition is to take into account levels change when map-matching is not enabled / set\n const isChangingLevel = canContainLevel && !Level.equals(newPosition.level, lastPosition.level);\n if (isChangingLevel) {\n return true;\n }\n\n return false;\n }\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n private _onAbsolutePosition(positionEvent: AbsolutePosition, canContainLevel = true) {\n\n if (!this._shouldTakeIntoAccountNewAbsolutePosition(positionEvent, canContainLevel)\n && !this.useAllAbsolutePositions) {\n return false;\n }\n\n const newPosition = positionEvent.clone();\n const lastPosition = this.lastEvent ? this.lastEvent : null;\n\n if (lastPosition) {\n if (!canContainLevel) {\n newPosition.level = lastPosition.level;\n }\n\n // If the new position does not have a bearing, retrieve the bearing from the last position\n if (newPosition.bearing === null) {\n newPosition.bearing = lastPosition.bearing;\n }\n }\n\n // If the MM is disable or the network is not set yet, use the new position as it is.\n // If the position bearing is null, do not use MM, it is too dangerous.\n if (!MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPosition);\n return true;\n }\n\n return MapMatchingHandler.notifyPositionFromAbsolute(newPosition);\n }\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n _onRelativePosition(relativeEvent: GeoRelativePosition) {\n\n if (!this.lastEvent || this._waitUntilNextVpsPosition) {\n return false;\n }\n\n const lastPosition = this.lastEvent;\n\n const offsetPos = relativeEvent;\n\n const dist = Math.sqrt(offsetPos.x ** 2 + offsetPos.y ** 2);\n const bearing = Math.atan2(offsetPos.x, offsetPos.y);\n const alt = lastPosition.alt !== null ? offsetPos.z : null;\n\n const newPosition = lastPosition.destinationPoint(dist, bearing, alt);\n newPosition.bearing = offsetPos.bearing;\n newPosition.time = offsetPos.time;\n newPosition.accuracy! += offsetPos.accuracy!;\n\n\n if (!MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPosition);\n return true;\n }\n\n return MapMatchingHandler.notifyPositionFromRelative(newPosition);\n }\n\n\n feed(data: AbsolutePosition) {\n\n let newPositionEvent: AbsolutePosition;\n\n if (data instanceof UserPosition) {\n\n if (data.time === null) {\n throw Error('the time of the position is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the position is not defined');\n }\n\n newPositionEvent = data;\n\n } else {\n throw new Error('data is nor an UserPosition or an AbsolutePositionEvent');\n }\n\n // If the MM is disable or the network is not set yet, use the new position as it is.\n if (!AbsolutePositionProvider.USE_MM_FOR_FEED || !MapMatchingHandler.canUseMapMatching()) {\n this.notify(newPositionEvent);\n return;\n }\n\n MapMatchingHandler.notifyPositionFromFeed(newPositionEvent);\n }\n\n getBestPositionEvent(...absolutePositionEvents: (AbsolutePosition | null)[]) {\n return absolutePositionEvents.reduce((best, value) => {\n if (!best) {\n return value;\n }\n if (!value || value.accuracy === null || value.time === null) {\n return best;\n }\n const { accuracy: curAccuracy, time: curTime } = value;\n const { accuracy: bestAccuracy, time: bestTime } = best;\n // 1.3888 corresponds to 1.3888 m/s (5 km/h)\n return curAccuracy < (bestAccuracy! + 1.3888 * (curTime - bestTime!)) ? value : best;\n }, null as null | AbsolutePosition);\n }\n}\n\nexport default new AbsolutePositionProvider();\n","import * as geomag from 'geomag';\n\nimport { deg2rad, rad2deg, Quaternion, Rotations, Quaternion_t } from '@wemap/maths';\nimport { Browser, BrowserUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport AskImuOnDesktopError from '../../../errors/AskImuOnDesktopError.js';\nimport MissingMagnetometerError from '../../../errors/MissingMagnetometerError.js';\nimport MissingSensorError from '../../../errors/MissingSensorError.js';\nimport AbsolutePositionProvider from '../../position/absolute/AbsolutePositionProvider.js';\nimport { AbsoluteAttitude, AbsolutePosition } from '../../../events/Types.js';\n\n\n// https://stackoverflow.com/a/73369838/2239938\nexport interface DeviceOrientationEventiOS extends DeviceOrientationEvent {\n webkitCompassHeading: number | null;\n webkitCompassAccuracy: number | null;\n requestPermission?: () => Promise<'granted' | 'denied'>;\n}\n\n\n\ndeclare global {\n interface Window {\n addEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;\n addEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;\n removeEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;\n removeEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;\n }\n}\n\n\n\n/**\n * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation or deviceorientationabsolute\n * The provider does not work until an AbsolutePosition is given. This is necessary to\n * calculate declination.\n *\n * -----------------------------------\n * Overview of compatibilities:\n * -----------------------------------\n *\n * Chrome Android (v72.0.3626): YES (via deviceorientationabsolute)\n * Safari iOS (v12.0): YES (via deviceorientation and event.webkitCompassHeading)\n * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}\n * Firefox Android (v65.0.1): NO {@link https://www.fxsitecompat.com/en-CA/docs/2018/various-device-sensor-apis-are-now-deprecated/}\n *\n * -----------------------------------\n */\nclass AbsoluteAttitudeFromBrowser extends Provider<AbsoluteAttitude> {\n\n // from http://tyrex.inria.fr/mobile/benchmarks-attitude/\n DEFAULT_ACCURACY = deg2rad(15);\n\n absolutePositionProviderId?: number;\n absolutePositionEvent?: AbsolutePosition;\n\n declinationQuaternion?: Quaternion_t;\n magQuaternion?: Quaternion_t;\n magQuaternionTimestamp?: number;\n\n iosPreviousQuat?: Quaternion_t;\n iosIsSkyMode: boolean | null = null;\n\n\n getName = () => 'AbsoluteAttitudeFromBrowser';\n\n availability() {\n return BrowserUtils.isMobile\n ? Promise.resolve()\n : Promise.resolve(new AskImuOnDesktopError());\n }\n\n start() {\n\n\n const subscribe = () => {\n switch (BrowserUtils.getName()) {\n case Browser.CHROME:\n window.addEventListener('deviceorientationabsolute',\n this.onDeviceOrientationChromeEvent, true);\n break;\n\n case Browser.SAFARI:\n case Browser.IOS_WEBVIEW:\n window.addEventListener('deviceorientation',\n this.onDeviceOrientationSafariEvent, true);\n break;\n }\n };\n\n const requestPermission = (DeviceOrientationEvent as unknown as DeviceOrientationEventiOS).requestPermission || undefined;\n\n if (requestPermission) {\n requestPermission()\n .then(response => {\n if (response !== 'granted') {\n throw new Error('Permission not granted');\n }\n subscribe();\n })\n .catch(this.notifyError);\n } else {\n subscribe();\n }\n\n\n const lastAbsolutePosition = AbsolutePositionProvider.lastEvent;\n if (lastAbsolutePosition) {\n this.onAbsolutePositionEvent(lastAbsolutePosition);\n } else {\n this.absolutePositionProviderId = AbsolutePositionProvider.addEventListener(\n this.onAbsolutePositionEvent,\n this.notifyError,\n false\n );\n }\n\n }\n\n stop() {\n switch (BrowserUtils.getName()) {\n case Browser.CHROME:\n window.removeEventListener('deviceorientationabsolute',\n this.onDeviceOrientationChromeEvent, true);\n break;\n\n case Browser.SAFARI:\n case Browser.IOS_WEBVIEW:\n window.removeEventListener('deviceorientation',\n this.onDeviceOrientationSafariEvent, true);\n break;\n }\n\n AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);\n }\n\n\n onDeviceOrientationChromeEvent = (e: DeviceOrientationEvent) => {\n\n this.magQuaternionTimestamp = e.timeStamp / 1e3;\n\n if (typeof e.alpha !== 'number' || typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientationabsolute'));\n return;\n }\n\n this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees(\n [e.alpha, e.beta, e.gamma]);\n\n this.compute();\n };\n\n\n onDeviceOrientationSafariEvent = (e: DeviceOrientationEventiOS) => {\n\n this.magQuaternionTimestamp = e.timeStamp / 1e3;\n\n if (typeof e.beta !== 'number' || typeof e.gamma !== 'number') {\n this.notifyError(new MissingSensorError().from('deviceorientation'));\n return;\n }\n\n if (typeof e.webkitCompassHeading !== 'number') {\n super.notifyError(new MissingMagnetometerError().from('deviceorientation'));\n return;\n }\n\n /**\n * Trying the best to retrieve a good quaternion from devicemotion event.\n */\n\n let alpha;\n const [qw, qx, qy, qz] = Rotations.eulerToQuaternionZXYDegrees([e.webkitCompassHeading, e.beta, e.gamma]);\n const groundAngle = rad2deg(Math.acos(qw ** 2 - qx ** 2 - qy ** 2 + qz ** 2));\n\n let isSkyMode = null;\n if (groundAngle > 136) {\n isSkyMode = true;\n } else if (groundAngle < 134) {\n isSkyMode = false;\n } else if (this.iosPreviousQuat && this.iosIsSkyMode !== null) {\n /**\n * This condition is true only if :\n * - we are in the [134°; 136°] ground angle range\n * - we know the previous quaternion\n * - one of the both previous condition has been reached during this session\n *\n * In this case, we define a threshold to detect if there is a \"jump\" in the quaternion calculation,\n * then, the mode is switched.\n */\n isSkyMode = Quaternion.distance([qw, qx, qy, qz], this.iosPreviousQuat) < 0.5\n ? this.iosIsSkyMode\n : !this.iosIsSkyMode;\n }\n this.iosPreviousQuat = [qw, qx, qy, qz];\n this.iosIsSkyMode = isSkyMode;\n\n if (typeof (isSkyMode) === 'undefined') {\n // Algorithm uncertainity\n return;\n }\n\n if (isSkyMode) {\n alpha = 180 - e.webkitCompassHeading;\n } else {\n alpha = AbsoluteAttitudeFromBrowser.webkitCompassToHeading(\n e.webkitCompassHeading, e.beta, e.gamma);\n }\n\n this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees([alpha, e.beta, e.gamma]);\n\n this.compute();\n };\n\n\n compute() {\n\n if (!this.declinationQuaternion || !this.magQuaternion || !this.absolutePositionEvent) {\n return;\n }\n\n const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, this.magQuaternion);\n const attitude = new AbsoluteAttitude(trueQuaternion, this.magQuaternionTimestamp, this.DEFAULT_ACCURACY);\n this.notify(attitude);\n }\n\n /**\n * Initialized declination quaternion using current position.\n * This method should be theoretically called every time the user moves.\n * But in reality declination does not change as much.\n */\n onAbsolutePositionEvent = (position: AbsolutePosition) => {\n\n this.absolutePositionEvent = position;\n\n const wmmResult = geomag.field(position.lat, position.lng);\n\n // Declination is given in NED frame and our code use ENU, that is why we have: \"-declination\"\n this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.declination));\n\n AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);\n delete this.absolutePositionProviderId;\n this.compute();\n }\n\n static webkitCompassToHeading(_webkitCompassHeading: number, _beta: number, _gamma: number) {\n const webkitCompassHeading = deg2rad(_webkitCompassHeading);\n const beta = deg2rad(_beta);\n const gamma = deg2rad(_gamma);\n\n const c1 = Math.cos(webkitCompassHeading / 2);\n const c2 = Math.cos(beta / 2);\n const c3 = Math.cos(gamma / 2);\n const s1 = Math.sin(webkitCompassHeading / 2);\n const s2 = Math.sin(beta / 2);\n const s3 = Math.sin(gamma / 2);\n\n const qw = c1 * c2 * c3 - s1 * s2 * s3;\n const qz = s1 * c2 * c3 + c1 * s2 * s3;\n\n return rad2deg(-2 * Math.atan(qz / qw));\n }\n}\n\nexport default new AbsoluteAttitudeFromBrowser();\n","import Provider from '../../Provider.js';\nimport RelativeAttitudeFromInertialProvider from './RelativeAttitudeFromInertialProvider.js';\nimport ArCoreProvider from '../../vision/ArCoreProvider.js';\nimport { RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Relative attitude provider gives the device attitude in East-North-Up (ENU) frame using\n * browser deviceorientation\n * The provider does not work until an offset is given.\n */\nclass RelativeAttitudeProvider extends Provider<RelativeAttitude> {\n\n arCoreMonitoringId?: number;\n arCoreProviderId?: number;\n inertialProviderId?: number;\n\n getName = () => 'RelativeAttitude';\n\n availability = () => RelativeAttitudeFromInertialProvider.getAvailability();\n\n start() {\n this.arCoreMonitoringId = ArCoreProvider.addMonitoringListener(\n () => {\n this.listenArCore();\n this.unlistenInertial();\n }, () => {\n this.unlistenArCore();\n this.listenInertial();\n });\n\n if (ArCoreProvider.state === 'started') {\n this.listenArCore();\n } else {\n this.listenInertial();\n }\n }\n\n /**\n * @override\n */\n stop() {\n ArCoreProvider.removeMonitoringListener(this.arCoreMonitoringId);\n this.unlistenArCore();\n this.unlistenInertial();\n }\n\n\n listenInertial = () => {\n this.inertialProviderId = RelativeAttitudeFromInertialProvider.addEventListener(\n this.notify,\n this.notifyError\n );\n }\n\n unlistenInertial = () => {\n RelativeAttitudeFromInertialProvider.removeEventListener(this.inertialProviderId);\n }\n\n listenArCore = () => {\n this.arCoreProviderId = ArCoreProvider.addEventListener(\n event => this.notify(event.relativeAttitude), null, false\n );\n };\n\n unlistenArCore = () => {\n ArCoreProvider.removeEventListener(this.arCoreProviderId);\n }\n}\n\nexport default new RelativeAttitudeProvider();\n","/* eslint-disable max-statements */\nimport { AbsoluteHeading, Attitude } from '@wemap/geo';\nimport { deg2rad, diffAngle, Quaternion, Quaternion_t } from '@wemap/maths';\n\nimport Provider from '../../Provider.js';\nimport AvailabilityHelper from '../../../events/AvailabilityHelper.js';\nimport AbsoluteAttitudeFromBrowserProvider from './AbsoluteAttitudeFromBrowserProvider.js';\nimport RelativeAttitudeProvider from '../relative/RelativeAttitudeProvider.js';\nimport InclinationProvider from '../../inclination/InclinationProvider.js';\nimport HighRotationsProvider from '../../imu/HighRotationsProvider.js';\nimport VpsProvider from '../../vision/vps/VpsProvider.js';\nimport { AbsoluteAttitude, RelativeAttitude } from '../../../events/Types.js';\n\n/**\n * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame\n */\nclass AbsoluteAttitudeProvider extends Provider<AbsoluteAttitude> {\n\n static REL_ABS_DIVERGENCE_ANGLE_THRESHOLD = deg2rad(25) // in radians;\n static REL_ABS_DIVERGENCE_TIME_THRESHOLD = 2.5; // in seconds\n static REL_ABS_DIVERGENCE_INCLINATION_THRESHOLD = deg2rad(15) // in radians;\n\n private _absAttitudeFromBrowser?: AbsoluteAttitude;\n private _vpsProviderId?: number;\n fromBrowserProviderId?: number;\n highRotationProviderId?: number;\n inclinationProviderId?: number;\n relativeAttitudeProviderId?: number;\n\n _attitudeFromBrowserErrored = false;\n _attitudeFromRelativeErrored = false;\n\n /*\n * RELATIVE\n */\n\n _relativeAttitude: RelativeAttitude | null = null;\n _relativeAccuracy = 0; // in radians/s\n\n _lastForcedHeadingEvent?: AbsoluteAttitude | AbsoluteHeading;\n _relAbsQuat?: Quaternion_t;\n _wasHighRotationInProgress = false;\n _timeFirstDivergence: number | null = null;\n _callbackMagCalibration?: (data: { angle: number }) => void;\n\n getName = () => 'AbsoluteAttitude';\n\n availability() {\n return AvailabilityHelper.some([\n AbsoluteAttitudeFromBrowserProvider.getAvailability(),\n RelativeAttitudeProvider.getAvailability()\n ]);\n }\n\n start() {\n\n this.fromBrowserProviderId = AbsoluteAttitudeFromBrowserProvider.addEventListener(\n this._onAttitudeFromBrowser,\n error => {\n this._attitudeFromBrowserErrored = true;\n this._onError(error);\n }\n );\n\n // Vps\n this._vpsProviderId = VpsProvider.addEventListener(\n event => this._onAttitudeFromVps(event.absoluteAttitude),\n error => this.notifyError(error),\n false\n );\n\n this.relativeAttitudeProviderId = RelativeAttitudeProvider.addEventListener(\n this._onRelativeAttitudeEvent,\n error => {\n this._attitudeFromRelativeErrored = true;\n this._onError(error);\n }\n );\n\n this.inclinationProviderId = InclinationProvider.addEventListener();\n\n this.highRotationProviderId = HighRotationsProvider.addEventListener();\n }\n\n stop() {\n AbsoluteAttitudeFromBrowserProvider.removeEventListener(this.fromBrowserProviderId);\n RelativeAttitudeProvider.removeEventListener(this.relativeAttitudeProviderId);\n InclinationProvider.removeEventListener(this.inclinationProviderId);\n HighRotationsProvider.removeEventListener(this.highRotationProviderId);\n VpsProvider.removeEventListener(this._vpsProviderId);\n }\n\n _setCallbackMagCalibration(cb: (data: { angle: number }) => void) {\n this._callbackMagCalibration = cb;\n }\n\n private _onError = (error: Error) => {\n if (this._attitudeFromBrowserErrored && this._attitudeFromRelativeErrored) {\n this.notifyError(error);\n }\n }\n\n\n _forceHeadingForRelative = (absoluteHeadingEvent: AbsoluteAttitude | AbsoluteHeading) => {\n\n if (this.lastEvent && absoluteHeadingEvent.accuracy! > this.lastEvent.accuracy!) {\n return;\n }\n\n const calcForceHeading = (relativeAttitude: RelativeAttitude) => {\n const currentRelativeHeading = relativeAttitude.heading;\n\n this._relAbsQuat = Quaternion.fromAxisAngle(\n [0, 0, 1],\n currentRelativeHeading - absoluteHeadingEvent.heading\n );\n\n this._relativeAccuracy = 0;\n this._lastForcedHeadingEvent = absoluteHeadingEvent;\n };\n\n // If relativeAttitude does not exist yet, wait the next\n if (this._relativeAttitude) {\n calcForceHeading(this._relativeAttitude);\n return;\n }\n\n // If this._relativeAttitude does not exist, wait the first value\n // /!\\ This works only if the relative attitude event is provided rapidly.\n const providerId = RelativeAttitudeProvider.addEventListener(\n event => {\n calcForceHeading(event);\n RelativeAttitudeProvider.removeEventListener(providerId);\n }\n );\n\n };\n\n _onRelativeAttitudeEvent = (event: RelativeAttitude) => {\n\n const { quaternion, accuracy, time } = event;\n\n // Calculate relative accuracy\n if (this._relativeAttitude) {\n this._relativeAccuracy += (time! - this._relativeAttitude.time!) * accuracy!;\n }\n\n // Keep the relative attitude event for the calculation of relAbsQuat\n // /!\\ Keep this even if forced heading is not set /!\\\n this._relativeAttitude = event;\n\n\n if (!this._lastForcedHeadingEvent || !this._relAbsQuat) {\n return;\n }\n\n const accuracyWithRelative = Math.min(\n (this._lastForcedHeadingEvent.accuracy || 0) + this._relativeAccuracy,\n Math.PI\n );\n\n const highRotationInProgress = HighRotationsProvider.isInProgress();\n\n let divergenceDetected = false;\n\n if (this._absAttitudeFromBrowser) {\n\n const {\n accuracy: accuracyWithAbsolute,\n heading: headingFromAbsolute\n } = this._absAttitudeFromBrowser;\n\n if (this._wasHighRotationInProgress && !highRotationInProgress) {\n // Update heading for relative if it the end of high rotations\n // (probably due to a magnetometer calibratiton)\n this._forceHeadingForRelative(this._absAttitudeFromBrowser);\n\n } else if (accuracyWithAbsolute! < accuracyWithRelative) {\n // Update heading for relative if:\n // (1) accuracy from absolute is better than relative\n // (2) heading divergence is greater than REL_ABS_DIVERGENCE_THRESHOLD\n const relativeQuaternion = Quaternion.multiply(this._relAbsQuat, quaternion);\n const relativeAttitude = new Attitude(relativeQuaternion);\n const angle = Math.abs(diffAngle(relativeAttitude.heading, headingFromAbsolute));\n const inclination = InclinationProvider.lastEvent;\n\n\n if (angle > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_ANGLE_THRESHOLD\n && inclination !== null\n && Math.abs(inclination - Math.PI / 4) > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_INCLINATION_THRESHOLD\n ) {\n divergenceDetected = true;\n\n // Be sure before forcing heading\n if (this._timeFirstDivergence !== null\n && time! - this._timeFirstDivergence > AbsoluteAttitudeProvider.REL_ABS_DIVERGENCE_TIME_THRESHOLD) {\n\n this._forceHeadingForRelative(this._absAttitudeFromBrowser);\n this._callbackMagCalibration?.({ angle });\n this._timeFirstDivergence = null;\n } else if (this._timeFirstDivergence === null) {\n this._timeFirstDivergence = time;\n }\n\n }\n }\n\n }\n\n if (!divergenceDetected) {\n this._timeFirstDivergence = null;\n }\n\n this._wasHighRotationInProgress = highRotationInProgress;\n\n const absoluteQuat = Quaternion.multiply(this._relAbsQuat, quaternion);\n const attitude = new AbsoluteAttitude(absoluteQuat, time, accuracyWithRelative);\n this.notify(attitude);\n }\n\n\n _onAttitudeFromBrowser = (event: AbsoluteAttitude) => {\n this._absAttitudeFromBrowser = event;\n\n if (!this._lastForcedHeadingEvent) {\n this._forceHeadingForRelative(event);\n return;\n }\n\n // Absolute attitude from browser is not used anymore due to magnetometer inaccuracy on pitch and roll\n }\n\n\n _onAttitudeFromVps = (event: AbsoluteAttitude) => {\n this._forceHeadingForRelative(event);\n }\n\n feed(data: AbsoluteHeading | AbsoluteAttitude) {\n\n if (data instanceof AbsoluteHeading) {\n\n if (data.time === null) {\n throw Error('the time of the absolute heading is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the absolute heading is not defined');\n }\n\n this._forceHeadingForRelative(data);\n\n } else if (data instanceof AbsoluteAttitude) {\n\n if (data.time === null) {\n throw Error('the time of the attitude is not defined');\n }\n if (data.accuracy === null) {\n throw Error('the accuracy of the attitude is not defined');\n }\n\n this._forceHeadingForRelative(data);\n\n } else {\n throw new Error('data is nor an AbsoluteHeading or an Attitude object');\n }\n }\n}\n\nexport default new AbsoluteAttitudeProvider();\n","import { std } from '@wemap/maths';\n\nimport Provider from '../Provider.js';\nimport RelativeAttitudeProvider from './relative/RelativeAttitudeProvider.js';\nimport { RelativeAttitude, Turn } from '../../events/Types.js';\n\nclass TurnProvider extends Provider<Turn> {\n\n static SLIDING_WINDOW_TIME = 0.3; // in seconds\n static STD_THRESHOLD = 0.075;\n static CONSIDER_TURN_UNTIL = 1; // in seconds\n\n providerId?: number;\n\n slidingWindow: [number, number][] = [];\n\n getName = () => 'Turn';\n\n availability = () => RelativeAttitudeProvider.getAvailability();\n\n start() {\n this.providerId = RelativeAttitudeProvider.addEventListener(\n this._parseRelativeAttitude,\n this.notifyError\n );\n }\n\n stop() {\n RelativeAttitudeProvider.removeEventListener(this.providerId);\n }\n\n isTurning() {\n if (!this.lastEvent || !RelativeAttitudeProvider.lastEvent) {\n return false;\n }\n\n const diffTime = RelativeAttitudeProvider.lastEvent.time as number - this.lastEvent.timestamp;\n return diffTime < TurnProvider.CONSIDER_TURN_UNTIL;\n }\n\n\n private _parseRelativeAttitude = (relativeAttitudeEvent: RelativeAttitude) => {\n\n const { heading } = relativeAttitudeEvent;\n const timestamp = relativeAttitudeEvent.time as number;\n\n this.slidingWindow = this.slidingWindow.filter(item => item[0] >= timestamp - TurnProvider.SLIDING_WINDOW_TIME);\n this.slidingWindow.push([timestamp, heading]);\n\n const stdVal = std(this.slidingWindow.map(item => item[1]));\n if (stdVal > TurnProvider.STD_THRESHOLD) {\n this.notify({ timestamp });\n }\n\n }\n}\n\nexport default new TurnProvider();\n","import Provider from '../Provider.js';\nimport AvailabilityHelper from '../../events/AvailabilityHelper.js';\nimport StepProvider from './StepProvider.js';\nimport TurnProvider from '../attitude/TurnProvider.js';\nimport { StraightLine } from '../../events/Types.js';\n\nclass StraightLineProvider extends Provider<StraightLine> {\n\n static DEFAULT_STEPS_CONSIDERED_FOR_STRAIGHT_LINE = 2;\n\n _turnProviderId?: number;\n _stepProviderId?: number;\n\n _countSteps = 0;\n _stepsConsideredForStraightLine = StraightLineProvider.DEFAULT_STEPS_CONSIDERED_FOR_STRAIGHT_LINE;\n\n getName = () => 'StraightLine';\n\n availability() {\n return AvailabilityHelper.every([\n TurnProvider.getAvailability(),\n StepProvider.getAvailability()\n ]);\n }\n\n start() {\n this._turnProviderId = TurnProvider.addEventListener(this._onTurn);\n this._stepProviderId = StepProvider.addEventListener(this._onStep);\n }\n\n stop() {\n TurnProvider.removeEventListener(this._turnProviderId);\n StepProvider.removeEventListener(this._stepProviderId);\n }\n\n private _onTurn = () => {\n if (this._countSteps >= this._stepsConsideredForStraightLine) {\n this.notify(false);\n }\n this._countSteps = 0;\n }\n\n private _onStep = () => {\n this._countSteps++;\n\n if (this._countSteps === this._stepsConsideredForStraightLine) {\n this.notify(true);\n }\n\n }\n\n isStraight() {\n return this._countSteps >= this._stepsConsideredForStraightLine;\n }\n\n get numStepsDetectedFromLastTurn() {\n return this._countSteps;\n }\n\n get stepsConsideredForStraightLine() {\n return this._stepsConsideredForStraightLine;\n }\n\n set stepsConsideredForStraightLine(stepsConsideredForStraightLine) {\n this._stepsConsideredForStraightLine = stepsConsideredForStraightLine;\n }\n}\n\nexport default new StraightLineProvider();\n","import {\n AbsoluteHeading, Level, UserPosition, Coordinates, GeoGraph, GeoGraphProjectionHandler, GeoGraphProjection, GeoGraphEdge, GeoGraphVertex\n} from '@wemap/geo';\nimport { deg2rad, diffAngle, diffAngleLines } from '@wemap/maths';\nimport { Itinerary, ItineraryInfoManager } from '@wemap/routers';\nimport { TimeUtils } from '@wemap/utils';\n\nimport AbsoluteAttitudeProvider from '../providers/attitude/absolute/AbsoluteAttitudeProvider.js';\nimport AbsoluteAttitudeFromBrowser from '../providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.js';\nimport TurnProvider from '../providers/attitude/TurnProvider.js';\nimport Constants from '../providers/Constants.js';\nimport AbsolutePositionProvider from '../providers/position/absolute/AbsolutePositionProvider.js';\nimport Provider from '../providers/Provider.js';\nimport StepProvider from '../providers/steps/StepProvider.js';\nimport StraightLineProvider from '../providers/steps/StraightLineProvider.js';\nimport ProvidersOptions from '../ProvidersOptions.js';\nimport { AbsolutePosition } from '../events/Types.js';\n\n\ntype MapMatchingEvent = { graph?: GeoGraph, itinerary?: Itinerary | null };\nclass MapMatchingHandler extends Provider<MapMatchingEvent> {\n\n static DEFAULT_MM_MAX_ANGLE = deg2rad(30); // radians\n static DEFAULT_MM_MAX_DIST = 30; // meters\n static DEFAULT_MM_MIN_DIST = 0; // meters\n static DEFAULT_USE_ITINERARY_START_AS_POSITION = false;\n static DEFAULT_USE_ORIENTATION_MATCHING = true;\n static DEFAULT_MM_HUGE_JUMP_DISTANCE = 3; // meters\n static DEFAULT_DISABLE_MM_CLOSE_TO_A_TURN_DISTANCE = 2; // meters\n static DEFAULT_MIN_STEPS_BETWEEN_ORIENTATION_MATCHING = 3;\n static DEFAULT_MIN_STEPS_FOR_ORIENTATION_MATCHING = 5;\n static DEFAULT_LAST_PROJECTIONS_WINDOW_SIZE = 3;\n static DEFAULT_LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD = deg2rad(3); // radians\n\n _mapMatchingMinDistance = MapMatchingHandler.DEFAULT_MM_MIN_DIST;\n _useItineraryStartAsPosition = MapMatchingHandler.DEFAULT_USE_ITINERARY_START_AS_POSITION;\n _useOrientationMatching = MapMatchingHandler.DEFAULT_USE_ORIENTATION_MATCHING;\n _hugeJumpDistance = MapMatchingHandler.DEFAULT_MM_HUGE_JUMP_DISTANCE;\n _disableMMCloseToATurnDistance = MapMatchingHandler.DEFAULT_DISABLE_MM_CLOSE_TO_A_TURN_DISTANCE;\n _minStepsBetweenOrientationMatching = MapMatchingHandler.DEFAULT_MIN_STEPS_BETWEEN_ORIENTATION_MATCHING;\n _minStepsForOrientationMatching = MapMatchingHandler.DEFAULT_MIN_STEPS_FOR_ORIENTATION_MATCHING;\n _lastProjectionsWindowSize = MapMatchingHandler.DEFAULT_LAST_PROJECTIONS_WINDOW_SIZE;\n _lastProjectionsEdgeAngleThreshold = MapMatchingHandler.DEFAULT_LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD;\n\n _geoGraphProjectionHandler: GeoGraphProjectionHandler;\n _internalProvidersStarted = false;\n _straightLineProviderId?: number;\n _turnProviderId?: number;\n _stepProviderId?: number;\n _projectionsWithAbsAndWithoutRelAttitudeInARow: GeoGraphProjection[] = [];\n _countStepsFromLastMatching = 0;\n _lastProjections: GeoGraphProjection[] = [];\n\n _itineraryInfoManager: ItineraryInfoManager | null = null;\n\n constructor() {\n super();\n\n this._geoGraphProjectionHandler = new GeoGraphProjectionHandler();\n this._geoGraphProjectionHandler.maxDistance = MapMatchingHandler.DEFAULT_MM_MAX_DIST;\n this._geoGraphProjectionHandler.maxAngleBearing = MapMatchingHandler.DEFAULT_MM_MAX_ANGLE;\n }\n\n getName = () => 'MapMatchingHandler';\n\n availability = () => Promise.resolve();\n\n start() {\n if (this.graph) {\n this._startInternalProviders();\n }\n }\n\n stop() {\n this._stopInternalProviders();\n }\n\n _manageStartStop = () => {\n if (this.graph && !this._internalProvidersStarted) {\n this._startInternalProviders();\n } else if (!this.graph && this._internalProvidersStarted) {\n this._stopInternalProviders();\n }\n }\n\n _startInternalProviders() {\n\n if (this.enabled && this._internalProvidersStarted) {\n return;\n }\n\n this._straightLineProviderId = StraightLineProvider.addEventListener();\n this._turnProviderId = TurnProvider.addEventListener();\n this._stepProviderId = StepProvider.addEventListener(() => (this._countStepsFromLastMatching++));\n\n this._internalProvidersStarted = true;\n }\n\n _stopInternalProviders() {\n\n if (this.enabled && !this._internalProvidersStarted) {\n return;\n }\n\n StraightLineProvider.removeEventListener(this._straightLineProviderId);\n TurnProvider.removeEventListener(this._turnProviderId);\n StepProvider.removeEventListener(this._stepProviderId);\n\n this._internalProvidersStarted = false;\n }\n\n get enabled() {\n return ProvidersOptions.useMapMatching;\n }\n\n get graph() {\n return this._geoGraphProjectionHandler.graph;\n }\n\n set graph(graph) {\n\n this._geoGraphProjectionHandler.graph = graph;\n this._itineraryInfoManager = null;\n this.notify({ ...(graph && { graph })});\n\n this._manageStartStop();\n\n if (this.canUseMapMatching()) {\n // TODO if necessary\n // this._notifyPositionFromNetworkInput(network);\n }\n }\n\n set itinerary(itinerary: Itinerary | null) {\n\n this._geoGraphProjectionHandler.graph = itinerary ? itinerary.toGraph() : null;\n this._itineraryInfoManager = new ItineraryInfoManager(itinerary);\n this.notify({ ...(itinerary && { itinerary })});\n\n this._manageStartStop();\n\n if (this.canUseMapMatching() && itinerary) {\n this._notifyPositionFromItineraryInput(itinerary);\n }\n }\n\n canUseMapMatching() {\n return this.enabled && this.graph;\n }\n\n\n private _notifyPositionFromItineraryInput(itinerary: Itinerary) {\n\n if (!this._useItineraryStartAsPosition || itinerary.from) {\n return;\n }\n\n const lastPosition = AbsolutePositionProvider.lastEvent || null;\n\n // In case of an itinerary, use itinerary start as new position,\n // but add the distance between lastPosition and itinerary start for the accuracy\n const newPosition = UserPosition.fromCoordinates(itinerary.from);\n\n if (lastPosition) {\n newPosition.alt = lastPosition.alt;\n newPosition.time = lastPosition.time;\n newPosition.accuracy = lastPosition.accuracy! + newPosition.distanceTo(lastPosition);\n newPosition.bearing = lastPosition.bearing;\n } else if (itinerary.coords.length >= 2) {\n newPosition.alt = Constants.DEFAULT_ALTITUDE;\n newPosition.time = TimeUtils.preciseTime();\n newPosition.accuracy = 0;\n newPosition.bearing = itinerary.coords[0].bearingTo(itinerary.coords[1]);\n } else {\n return;\n }\n\n // if the distance between itinerary.start and itinerary.nodes[0] is less than MM_MAX_DIST,\n // projection.coords is itinerary.nodes[0]\n const projection = this.getProjection(newPosition, true);\n if (projection) {\n AbsolutePositionProvider.notify(projection.coords);\n // Do not notify for attitude projection because bearing has not been used.\n } else {\n AbsolutePositionProvider.notify(newPosition);\n }\n return;\n }\n\n notifyPositionFromFeed(newPositionEvent: AbsolutePosition) {\n\n const projection = this.getProjection(newPositionEvent, true, false);\n if (!projection) {\n AbsolutePositionProvider.notify(newPositionEvent);\n return;\n }\n\n AbsolutePositionProvider.notify(projection.coords);\n }\n\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n notifyPositionFromAbsolute(newPosition: AbsolutePosition) {\n\n let projectionWithBearing = null;\n if (newPosition.bearing !== null) {\n projectionWithBearing = this.getProjection(newPosition, true, true);\n }\n\n if (!projectionWithBearing) {\n // Verify if the newPosition is far enough from the network to be used by the system.\n // const projectionWithoutBearing = this.getProjection(newPosition, true, false);\n // if (!projectionWithoutBearing) {\n // In this case, the newPosition is far enough and can be used safely.\n AbsolutePositionProvider.notify(newPosition);\n return true;\n // }\n // return true;\n }\n\n // newPosition must not be used after this line\n\n const thisWillBeAHugeJump = projectionWithBearing.distanceFromNearestElement > this._hugeJumpDistance;\n\n // In case of a huge jump, be sure the user is in a straight line\n if (thisWillBeAHugeJump && !StraightLineProvider.isStraight()) {\n return false;\n }\n\n // Detector to avoid big jumps in the wrong direction\n if (thisWillBeAHugeJump && this._detectWrongBigJump(projectionWithBearing)) {\n return false;\n }\n\n AbsolutePositionProvider.notify(projectionWithBearing.coords);\n\n this.tryOrientationMatching(projectionWithBearing);\n return true;\n }\n\n\n /**\n * @returns if input position is used by the system (true = used, false = discarded)\n */\n notifyPositionFromRelative(newPosition: AbsolutePosition) {\n\n if (TurnProvider.isTurning()) {\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections = [];\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n const projection = this.getProjection(newPosition, true, true);\n\n if (projection) {\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections.push(projection);\n if (this._lastProjections.length > this._lastProjectionsWindowSize) {\n this._lastProjections.shift();\n }\n\n const thisWillBeAHugeJump = projection.distanceFromNearestElement > this._hugeJumpDistance;\n\n // In case of a huge jump, be sure the user is in a straight line\n if (thisWillBeAHugeJump && !StraightLineProvider.isStraight()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Detector to avoid big jumps in the wrong direction\n if (thisWillBeAHugeJump && this._detectWrongBigJump(projection)) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Do not use projection if the neareast element is not the same direction than previous\n if (!this._areLastProjectionsInTheSameDirection()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n // Detector to avoid map-matching close to network turns\n if (this._disableMMCloseToATurnDistance > 0\n && this._hasTurnInCircle(projection.coords, this._disableMMCloseToATurnDistance)) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n AbsolutePositionProvider.notify(projection.coords);\n this.tryOrientationMatching(projection);\n\n return true;\n\n }\n // else {\n\n // Sometimes, the newPosition.bearing diverges due to the Absolute Attitude offset\n // and the Orientation Matching. So, we created this detector to check if projection\n // with bearing from \"AbsoluteAttitudeFromBrowser\" is better than the current bearing.\n // /!\\ This works only if the user is waking in the same direction than the smartphone orientation /!\\\n if (StraightLineProvider.isStraight()) {\n\n const testedPosition = newPosition.clone();\n testedPosition.bearing = AbsoluteAttitudeFromBrowser.lastEvent?.heading || null;\n const projectionWithAbs = this.getProjection(testedPosition, true, true);\n\n if (projectionWithAbs) {\n\n this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);\n if (this._projectionsWithAbsAndWithoutRelAttitudeInARow.length < 3) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n this._lastProjections.push(projectionWithAbs);\n if (this._lastProjections.length > this._lastProjectionsWindowSize) {\n this._lastProjections.shift();\n }\n\n\n if (!this._areLastProjectionsInTheSameDirection()) {\n AbsolutePositionProvider.notify(newPosition);\n return true;\n }\n\n AbsolutePositionProvider.notify(projectionWithAbs.coords);\n\n this.tryOrientationMatching(projectionWithAbs);\n return true;\n }\n }\n\n this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];\n this._lastProjections = [];\n\n // If no projection found with both projection methods, simply use the newPosition.\n AbsolutePositionProvider.notify(newPosition);\n return true;\n\n // }\n\n }\n\n _detectWrongBigJump(projection: GeoGraphProjection<unknown, unknown, UserPosition>) {\n\n if (this._itineraryInfoManager && AbsolutePositionProvider.lastEvent) {\n const infoPrevious = this._itineraryInfoManager.getInfo(AbsolutePositionProvider.lastEvent);\n const infoProjection = this._itineraryInfoManager.getInfo(projection.coords);\n if (infoPrevious\n && infoProjection\n && infoPrevious.traveledDistance > infoProjection.traveledDistance\n && (infoPrevious.traveledDistance - infoProjection.traveledDistance) > projection.origin.accuracy!\n && projection.distanceFromNearestElement > projection.origin.accuracy!\n && projection.origin.distanceTo(AbsolutePositionProvider.lastEvent) < projection.origin.accuracy! + AbsolutePositionProvider.lastEvent.accuracy!) {\n\n return true;\n }\n }\n\n return false;\n }\n\n _areLastProjectionsInTheSameDirection() {\n\n if (this._lastProjections.length === 0) {\n return false;\n }\n\n const firstProjection = this._lastProjections[0];\n return !this._lastProjections.some(projection =>\n !(projection.nearestElement instanceof GeoGraphEdge)\n || !(firstProjection.nearestElement instanceof GeoGraphEdge)\n || (diffAngleLines(projection.nearestElement.bearing, firstProjection.nearestElement.bearing)\n > this._lastProjectionsEdgeAngleThreshold)\n );\n }\n\n\n _nodeHasTurn(node: GeoGraphVertex) {\n const { edges } = node;\n for (let i = 0; i < edges.length; i++) {\n for (let j = i + 1; j < edges.length; j++) {\n const angle = diffAngleLines(edges[i].bearing, edges[j].bearing);\n if (angle > MapMatchingHandler.DEFAULT_MM_MAX_ANGLE) {\n return true;\n }\n }\n }\n return false;\n }\n\n\n _hasTurnInCircle(center: Coordinates, radius: number) {\n const network = this._geoGraphProjectionHandler.graph;\n if (!network) {\n return false;\n }\n\n return network.vertices.filter(vertex =>\n vertex.coords.distanceTo(center) <= radius\n && Level.intersect(vertex.coords.level, center.level)\n ).some(this._nodeHasTurn);\n }\n\n tryOrientationMatching(projection: GeoGraphProjection<unknown, unknown, UserPosition>) {\n\n if (!this._useOrientationMatching) {\n return;\n }\n\n if (this.state !== 'started'\n || this._countStepsFromLastMatching < this._minStepsBetweenOrientationMatching\n || StraightLineProvider.numStepsDetectedFromLastTurn < this._minStepsForOrientationMatching) {\n return;\n }\n\n const { nearestElement, origin } = projection;\n if (!(nearestElement instanceof GeoGraphEdge)) {\n return;\n }\n\n let matchingDirection;\n const matchingDirectionAngle1 = diffAngle(nearestElement.bearing, origin.bearing!);\n const matchingDirectionAngle2 = diffAngle(nearestElement.bearing + Math.PI, origin.bearing!);\n\n if (Math.abs(matchingDirectionAngle1) < Math.abs(matchingDirectionAngle2)) {\n matchingDirection = nearestElement.bearing;\n } else {\n matchingDirection = (nearestElement.bearing + Math.PI) % (2 * Math.PI);\n }\n\n const matchedHeading = new AbsoluteHeading(\n matchingDirection,\n origin.time,\n 0\n // Math.min(Math.abs(matchingDirectionAngle1), Math.abs(matchingDirectionAngle2))\n );\n\n AbsoluteAttitudeProvider._forceHeadingForRelative(matchedHeading);\n\n this._countStepsFromLastMatching = 0;\n }\n\n getProjection(position: UserPosition, useDistance?: boolean, useBearing?: boolean) {\n return this._geoGraphProjectionHandler.getProjection(position, useDistance, useBearing);\n }\n\n get maxDistance() {\n return this._geoGraphProjectionHandler.maxDistance;\n }\n\n set maxDistance(maxDistance) {\n this._geoGraphProjectionHandler.maxDistance = maxDistance;\n }\n\n get minDistance() {\n return this._mapMatchingMinDistance;\n }\n\n set minDistance(minDistance) {\n this._mapMatchingMinDistance = minDistance;\n }\n\n get maxAngleBearing() {\n return this._geoGraphProjectionHandler.maxAngleBearing;\n }\n\n set maxAngleBearing(maxAngleBearing) {\n this._geoGraphProjectionHandler.maxAngleBearing = maxAngleBearing;\n }\n\n get useItineraryStartAsPosition() {\n return this._useItineraryStartAsPosition;\n }\n\n set useItineraryStartAsPosition(useItineraryStartAsPosition) {\n this._useItineraryStartAsPosition = useItineraryStartAsPosition;\n }\n\n get useOrientationMatching() {\n return this._useOrientationMatching;\n }\n\n set useOrientationMatching(useOrientationMatching) {\n this._useOrientationMatching = useOrientationMatching;\n }\n\n get hugeJumpDistance() {\n return this._hugeJumpDistance;\n }\n\n set hugeJumpDistance(hugeJumpDistance) {\n this._hugeJumpDistance = hugeJumpDistance;\n }\n\n get disableMMCloseToATurnDistance() {\n return this._disableMMCloseToATurnDistance;\n }\n\n set disableMMCloseToATurnDistance(disableMMCloseToATurnDistance) {\n this._disableMMCloseToATurnDistance = disableMMCloseToATurnDistance;\n }\n\n get minStepsBetweenOrientationMatching() {\n return this._minStepsBetweenOrientationMatching;\n }\n\n set minStepsBetweenOrientationMatching(minStepsBetweenOrientationMatching) {\n this._minStepsBetweenOrientationMatching = minStepsBetweenOrientationMatching;\n }\n\n get minStepsForOrientationMatching() {\n return this._minStepsForOrientationMatching;\n }\n\n set minStepsForOrientationMatching(minStepsForOrientationMatching) {\n this._minStepsForOrientationMatching = minStepsForOrientationMatching;\n }\n\n get lastProjectionsWindowSize() {\n return this._lastProjectionsWindowSize;\n }\n\n set lastProjectionsWindowSize(lastProjectionsWindowSize) {\n this._lastProjectionsWindowSize = lastProjectionsWindowSize;\n }\n\n get lastProjectionsEdgeAngleThreshold() {\n return this._lastProjectionsEdgeAngleThreshold;\n }\n\n set lastProjectionsEdgeAngleThreshold(lastProjectionsEdgeAngleThreshold) {\n this._lastProjectionsEdgeAngleThreshold = lastProjectionsEdgeAngleThreshold;\n }\n}\n\nexport default new MapMatchingHandler();\n","import { Level, UserPosition } from '@wemap/geo';\n\nclass PositionSmoother {\n\n // Generated positions by second\n static DEFAULT_FREQUENCY = 60;\n\n // flyby (in second)\n static DEFAULT_FLYBY_TIME = 1;\n\n positionsQueue: UserPosition[] = [];\n previousPosition: UserPosition | null = null;\n timeoutNotify?: any; // can be number if web or NodeJS.Timer\n\n\n /**\n * @param frequency in Hz\n */\n constructor(\n public callback?: (position: UserPosition) => void,\n public frequency = PositionSmoother.DEFAULT_FREQUENCY\n ) {}\n\n /**\n * @param flybyTime in seconds\n */\n feed(newPosition: UserPosition, flybyTime = PositionSmoother.DEFAULT_FLYBY_TIME) {\n\n if (!(newPosition instanceof UserPosition)) {\n throw new TypeError('newPosition is not instance of UserPosition');\n }\n\n if (newPosition.time === null) {\n throw new Error('newPosition does not have time property');\n }\n\n let previousPosition;\n if (this.positionsQueue.length !== 0) {\n previousPosition = this.positionsQueue[0];\n this.positionsQueue = [];\n } else {\n previousPosition = this.previousPosition;\n }\n\n if (previousPosition) {\n\n const refTimestamp = newPosition.time;\n const distance = previousPosition.distanceTo(newPosition);\n const azimuth = previousPosition.bearingTo(newPosition);\n\n let i = 1;\n const nSamples = this.frequency * flybyTime + 1;\n\n const newPositionLevel = Level.clone(newPosition.level);\n while (i < nSamples + 1) {\n const smoothedPosition = previousPosition.destinationPoint(distance * i / nSamples, azimuth);\n smoothedPosition.time = refTimestamp + (i - 1) / this.frequency;\n smoothedPosition.level = newPositionLevel;\n smoothedPosition.bearing = newPosition.bearing;\n smoothedPosition.accuracy = Math.max(\n smoothedPosition.accuracy! + (newPosition.accuracy! - smoothedPosition.accuracy!) * i / nSamples,\n 0\n );\n this.positionsQueue.push(smoothedPosition);\n i++;\n }\n\n if (this.timeoutNotify) {\n clearTimeout(this.timeoutNotify);\n }\n } else {\n this.positionsQueue.push(newPosition.clone());\n }\n\n this.previousPosition = newPosition;\n this._notifyNext();\n }\n\n _notifyNext = () => {\n if (!this.positionsQueue.length) return;\n this.callback?.(this.positionsQueue.shift() as UserPosition);\n if (this.positionsQueue.length !== 0) {\n this.timeoutNotify = setTimeout(this._notifyNext, 1e3 / this.frequency);\n } else {\n delete this.timeoutNotify;\n }\n }\n\n clear() {\n clearTimeout(this.timeoutNotify);\n delete this.timeoutNotify;\n this.positionsQueue = [];\n }\n}\n\nexport default PositionSmoother;\n","import { Attitude } from '@wemap/geo';\nimport { deg2rad, diffAngle, Quaternion } from '@wemap/maths';\n\nclass AttitudeSmoother {\n\n static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(180); // in radians/s\n static ROTATION_SPEED_CONVERGENCE = deg2rad(10); // in radians/s\n static HIGH_JUMP_THRESHOLD = deg2rad(20); // in radians/s\n static ROTATION_SPEED_HIGH_JUMP_CONVERGENCE = deg2rad(100); // in radians/s\n static PITCH_UNCERTAINITY_HEADING_THRESHOLD = deg2rad(5); // in radians/s\n\n _previousAttitude?: Attitude;\n\n _smoothing : null | {\n interpAttitude(attitude: Attitude): Attitude,\n toTime: number\n } = null;\n\n constructor(public callback: (attitude: Attitude) => void) {}\n\n feed(newAttitude: Attitude) {\n\n if (newAttitude.time === null) {\n throw new Error('newAttitude does not have time property');\n }\n\n const { _previousAttitude: previousAttitude } = this;\n this._previousAttitude = newAttitude;\n\n if (!previousAttitude) {\n this.callback(newAttitude);\n return;\n }\n\n /*\n * Comparison between two successive Attitude from the \"feed\" function\n */\n if (AttitudeSmoother.isJump(previousAttitude, newAttitude)) {\n\n const fromAttitude = this._smoothing === null\n ? previousAttitude\n : this._smoothing.interpAttitude(previousAttitude);\n\n const fromHeading = fromAttitude.heading;\n const toHeading = newAttitude.heading;\n const diffAngleHeading = diffAngle(toHeading, fromHeading);\n\n const isHighJump = Math.abs(diffAngleHeading) < AttitudeSmoother.HIGH_JUMP_THRESHOLD;\n const rotationSpeedConvergence = isHighJump\n ? AttitudeSmoother.ROTATION_SPEED_CONVERGENCE\n : AttitudeSmoother.ROTATION_SPEED_HIGH_JUMP_CONVERGENCE;\n\n const fromTime = fromAttitude.time!;\n const timeToConsume = Math.abs(diffAngleHeading) / rotationSpeedConvergence;\n const multiplier = diffAngleHeading < 0 ? -1 : 1;\n\n this._smoothing = {\n toTime: fromTime + timeToConsume,\n\n interpAttitude: (attitude: Attitude) => {\n const angle = rotationSpeedConvergence * (attitude.time! - fromTime);\n const interpHeading = fromHeading + angle * multiplier;\n const offsetQuat = Quaternion.fromAxisAngle([0, 0, 1], toHeading - interpHeading);\n const interpQuat = Quaternion.multiply(offsetQuat, attitude.quaternion);\n return new Attitude(interpQuat, attitude.time, attitude.accuracy);\n }\n };\n }\n\n if (this._smoothing !== null) {\n if (newAttitude.time >= this._smoothing.toTime) {\n // This means that is the last epoch for smoothing\n this._smoothing = null;\n } else {\n const interpAttitude = this._smoothing.interpAttitude(newAttitude);\n this.callback(interpAttitude);\n return;\n }\n }\n\n this.callback(newAttitude);\n }\n\n /**\n * @param {Attitude} previousAttitude\n * @param {Attitude} newAttitude\n * @returns {boolean}\n */\n static isJump(previousAttitude: Attitude, newAttitude: Attitude) {\n const fromHeading = previousAttitude.heading;\n const toHeading = newAttitude.heading;\n const diffAngleHeading = diffAngle(toHeading, fromHeading);\n const diffTime = newAttitude.time! - previousAttitude.time!;\n\n /**\n * Heading is calculated from two different formulas in function of the pitch angle.\n * Do not consider a jump if attitude is close to the change of the methods\n * @see MathsRotations#getHeadingFromQuaternion()\n */\n const [qw, qx, qy, qz] = newAttitude.quaternion;\n const distToPitchThreshold = Math.abs(Math.asin(2 * (qw * qx + qy * qz)) - Math.PI / 4);\n if (distToPitchThreshold < AttitudeSmoother.PITCH_UNCERTAINITY_HEADING_THRESHOLD) {\n return false;\n }\n\n return Math.abs(diffAngleHeading) > AttitudeSmoother.ROTATION_SPEED_JUMP_THRESHOLD * diffTime;\n }\n}\n\nexport default AttitudeSmoother;\n","import Provider from '../Provider.js';\nimport AbsoluteAttitudeProvider from '../attitude/absolute/AbsoluteAttitudeProvider.js';\nimport { MagnetometerNeedCalibration } from '../../events/Types.js';\n\nclass MagnetometerCalibrationProvider extends Provider<MagnetometerNeedCalibration> {\n\n getName = () => 'MagnetometerCalibrationProvider';\n\n availability = () => AbsoluteAttitudeProvider.getAvailability();\n\n constructor() {\n super();\n AbsoluteAttitudeProvider._setCallbackMagCalibration(e => this.state === 'started' && this.notify(e));\n }\n\n start() { /* do nothing */ }\n stop() { /* do nothing */ }\n\n}\n\nexport default new MagnetometerCalibrationProvider();\n","class IpResolveServerError extends Error {\n\n static DEFAULT_MESSAGE = 'IP Resolver failed';\n\n constructor(message?: string) {\n super(message || IpResolveServerError.DEFAULT_MESSAGE);\n }\n}\n\nexport default IpResolveServerError;\n","import { UserPosition } from '@wemap/geo';\nimport { TimeUtils } from '@wemap/utils';\n\nimport Provider from '../../Provider.js';\nimport IpResolveServerError from '../../../errors/IpResolveServerError.js';\nimport { AbsolutePosition } from '../../../events/Types.js';\n\n/**\n * GnssWifiProvider is a provider based on navigator.geolocation.\n * This API does not allow us to know if the position returned is provided\n * by Wifi Fingerprinting algorithms or by GNSS. That is why the name is\n * \"GnssWifi\".\n */\nclass IpProvider extends Provider<AbsolutePosition> {\n\n getName = () => 'Ip';\n\n availability = () => Promise.resolve();\n\n async start() {\n\n const response = await fetch('https://ipinfo.io/geo?token=24a7ca2f3b489d');\n if (!response) {\n this.notifyError(new IpResolveServerError());\n return;\n }\n\n const timestamp = TimeUtils.preciseTime() / 1e3;\n\n const latLngStr = (await response.json()).loc.split(',');\n const position = new UserPosition(\n parseFloat(latLngStr[0]),\n parseFloat(latLngStr[1]),\n null,\n null,\n timestamp,\n 100000\n );\n\n this.notify(position);\n }\n\n stop() { /* do nothing */ }\n\n}\n\nexport default new IpProvider();\n","import Provider from '../Provider.js';\nimport ArCore from './ArCoreProvider.js';\nimport { Barcode } from '../../events/Types.js';\n\nclass BarcodePoleStarProvider extends Provider<Barcode> {\n \n providerId?: number;\n\n getName = () => 'Barcode';\n\n availability = () => ArCore.getAvailability();\n\n start() {\n ArCore.enableBarcodeScanner();\n\n this.providerId = ArCore.addEventListener(\n event => event.barcode && this.notify(event.barcode),\n this.notifyError\n );\n }\n\n stop() {\n ArCore.disableBarcodeScanner();\n ArCore.removeEventListener(this.providerId);\n }\n}\n\nexport default new BarcodePoleStarProvider();\n","import Provider from '../Provider.js';\nimport ArCoreProvider from '../vision/ArCoreProvider.js';\nimport { CameraNativeState } from '../../events/Types.js';\n\nclass CameraNativeProvider extends Provider<CameraNativeState> {\n\n providerId?: number;\n\n getName = () => 'CameraNative';\n\n availability = () => Promise.resolve();\n\n start() {\n\n if (ArCoreProvider.state !== 'stopped') {\n this.notify('started');\n }\n this.providerId = ArCoreProvider.addMonitoringListener(\n () => this.notify('started'),\n () => this.notify('stopped')\n );\n }\n\n stop() {\n ArCoreProvider.removeMonitoringListener(this.providerId);\n }\n}\n\nexport default new CameraNativeProvider();\n","import Provider from '../Provider.js';\nimport ArCoreProvider from '../vision/ArCoreProvider.js';\nimport { CameraProjectionMatrix } from '../../events/Types.js';\n\nclass CameraProjectionMatrixProvider extends Provider<CameraProjectionMatrix> {\n\n providerId?: number;\n\n getName = () => 'CameraProjectionMatrix';\n\n availability = () => ArCoreProvider.getAvailability();\n\n start() {\n this.providerId = ArCoreProvider.addEventListener(\n event => event.cameraProjection && this.notify(event.cameraProjection),\n this.notifyError\n );\n }\n\n stop() {\n ArCoreProvider.removeEventListener(this.providerId);\n }\n}\n\nexport default new CameraProjectionMatrixProvider();\n"],"names":["Attitude","UserPosition","Logger","ProvidersLoggerOld","deg2rad","TimeUtils","RelativePosition","ArCoreProvider","AbsoluteAttitudeProvider","GeoRelativePosition","Matrix4","Matrix3","Vector3","Quaternion","Matrix","Vector","BrowserUtils","Browser","ImuProvider","Accelerometer","Gyroscope","Rotations","GyroscopeProvider","RelativeAttitudeFromBrowserProvider","HighRotationsProvider","AccelerometerProvider","GeoConstants","StepProvider","PdrProvider","GeoRelativePositionFromArCoreProvider","InclinationFromAccProvider","InclinationFromRelativeAttitudeProvider","canvasToBase64","base64ToCanvas","convertToGrayscale","reduceImageSize","UserAgentUtils","RelativeAttitudeFromBrowser","Camera","camera","Inclination","AbsolutePositionProvider","GnssWifiProvider","PoleStarProvider","SharedCameras","GeoRelativePositionProvider","VpsProvider","MapMatchingHandler","Level","rad2deg","geomag","RelativeAttitudeProvider","diffAngle","InclinationProvider","AbsoluteAttitudeFromBrowserProvider","AbsoluteHeading","std","TurnProvider","GeoGraphProjectionHandler","StraightLineProvider","ItineraryInfoManager","AbsoluteAttitudeFromBrowser","GeoGraphEdge","diffAngleLines","ArCore"],"mappings":"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"}
|