import { PartialDeep } from 'type-fest'; import { SensorId } from '../sensors/types'; export { type AnchorState, type AnchorStateConfig, DEFAULT_ANCHOR_STATE_CONFIG } from './anchor-state'; export type FusionEventPayloads = { 'fused-position': { position: FusedPosition; }; 'heading-update': { heading: number; }; 'anchor-set': { anchor: PositionAnchor; }; 'anchor-expired': { anchor: PositionAnchor; }; error: { error: Error | GeolocationPositionError; }; }; export type PositionMetadata = { /** Confidence score 0-1 (0 = no confidence, 1 = 100% certain) */ confidence: number; }; /** * Represents a position update from a position source with an associated confidence score. * This interface is explicitly defined to include core geolocation fields, avoiding TypeScript interface extension errors. */ export type PositionUpdate = { /** Latitude in degrees */ latitude: number; /** Longitude in degrees */ longitude: number; /** Accuracy in meters */ accuracy?: number; /** Altitude in meters above the WGS84 ellipsoid (if available) */ altitude?: number | null; /** Altitude accuracy in meters (if available) */ altitudeAccuracy?: number | null; /** Heading in degrees (if available) */ heading?: number | null; /** Angular velocity in degrees per second (gyroscope z-axis rotation rate) */ angularVelocity?: number | null; /** Speed in meters per second (if available) */ speed?: number | null; /** Floor level from device (used to resolve floor) */ floorLevel?: number | null; /** Timestamp in milliseconds */ timestamp?: number; } & PositionMetadata; export type PartialPositionUpdate = PartialDeep & PositionMetadata; /** * Contribution from a single sensor to the fused position. */ export interface SensorContribution { /** Sensor identifier */ sensorId: SensorId; /** Weight applied to this sensor (normalized 0-1, 0 for heading-only sensors) */ weight: number; /** Original position update from the sensor (may be partial) */ position: PartialPositionUpdate; } /** * A fused position combining multiple sensor updates. */ export interface FusedPosition extends PositionUpdate { sensorId: 'fusion'; /** Individual contributions from each sensor */ contributions: SensorContribution[]; /** Whether position is calibrated via an anchor (VPS/AI Localizer) */ isCalibrated: boolean; /** Accumulated displacement from anchor in meters (only present when isCalibrated is true) */ displacement?: DisplacementVector; } /** * A displacement vector in meters. */ export interface DisplacementVector { /** Displacement in meters along east-west axis (positive = east) */ dx: number; /** Displacement in meters along north-south axis (positive = north) */ dy: number; } /** * A relative displacement update from a motion sensor (e.g., PDR). * Displacement is in meters, relative to the last known position. * Used for dead reckoning from a calibrated anchor position. */ export interface RelativePositionUpdate { /** Displacement in meters along east-west axis (positive = east) */ dx: number; /** Displacement in meters along north-south axis (positive = north) */ dy: number; /** Heading in degrees (0-360) at time of displacement */ heading?: number; /** Timestamp in milliseconds */ timestamp: number; /** Confidence score 0-1 */ confidence: number; } /** * Configuration for the multi-sensor EKF fusion engine. */ export interface FusionEngineConfig { /** * Duration in ms where anchor is exclusive (GPS rejected). * @default 5000 (5 seconds) */ anchorOnlyPeriodMs: number; /** * Half-life for state uncertainty growth in milliseconds. * The state uncertainty doubles every halfLifeMs when no measurements arrive. * Lower values = faster decay of old position estimates. * @default 10000 (10 seconds) */ halfLifeMs: number; /** * Maximum age of position updates to consider in milliseconds. * Updates older than this cause filter reset. * @default 5000 (5 seconds) */ maxAgeMs: number; } /** * Default fusion engine configuration. */ export declare const DEFAULT_FUSION_ENGINE_CONFIG: FusionEngineConfig; /** * Position anchor from a calibration source (VPS, AI Localizer). * Anchors represent absolute ground truth positions that other sensors * can reference for relative positioning. */ export interface PositionAnchor { /** Absolute latitude in degrees */ latitude: number; /** Absolute longitude in degrees */ longitude: number; /** Heading/bearing from calibration source in degrees */ heading?: number; /** Floor level from calibration source */ floorLevel?: number; /** Sensor that set this anchor */ sensorId: SensorId; /** When anchor was established (timestamp in ms) */ timestamp: number; /** How long anchor remains valid in milliseconds */ ttl: number; /** * Initial confidence of this anchor (0-1). * Used for transition decay: anchor confidence decreases over time. * @default 1.0 */ confidence?: number; } /** * Default anchor TTL (time-to-live) in milliseconds. * @default 30000 (30 seconds) */ export declare const DEFAULT_ANCHOR_TTL = 30000; /** * Meters per degree of latitude (approximately constant). * Used for converting displacement in meters to lat/lon degrees. */ export declare const METERS_PER_DEGREE_LAT = 111320;