UNPKG

gnss_solutions

Version:

Javascript GNSS solution analysis library

467 lines (466 loc) 15.8 kB
import { OnlineHistogram, OnlineStatistics } from "./accumulators"; import { ECEFSolution, LLASolution, SolutionStatus } from "./coords"; import * as err from "./errors"; import { Event, TimeRange } from "pondjs"; export declare class UnitializedVariableException extends err.CustomException { constructor(); } export declare class IndexOutOfBoundsExceptions extends err.CustomException { constructor(); } export declare class MissingDataException extends err.CustomException { constructor(); } /** * A solution status event wraps a SolutionStatus representation of a position * solution from a sample GNSS receiver, and additionally keeps track of a * measured error against a truth reference if available at the same time. It * represents a sample solution event at a particular instance of time, and * stores a flat map for a particular instance in time, using the result schema * defined by Swift's gnss-testing repository: * https://github.com/swift-nav/gnss-testing/blob/master/DESIGN.md#swift-solution-csv * * Example: * ``` * import { ECEFSolution, SolutionStatus } from "./coords"; * const time = new Date('2016-06-05'); * const ecef = new coords.ECEFSolution(ctest.earthA, 0, 0); * const soln = new coords.SolutionStatus(time, ecef.toLLA(), 0, 3, 0.5); * const event = new tab.SolutionStatusEvent(soln); * console.log(event.toJSON()); => * {"epoch(gpst)": new Date("2016-06-05T00:00:00.000Z"), * "fix_mode": "integer_rtk", * "latency(sec)": 0.5, * "num_sats": 3, * "abs_error_2d(m)": NaN, * "abs_error_3d(m)": NaN, * "abs_error_v(m)": NaN, * "est_error_2d(m)": NaN, * "est_error_3d(m)": NaN, * "est_error_v(m)": NaN, * "baseline_x(m)": NaN, * "baseline_y(m)": NaN, * "baseline_z(m)": NaN, * "rover_pos_x(m)":6378137, * "rover_pos_y(m)":0, * "rover_pos_z(m)":0, * "rover_pos_lat(deg)":0, * "rover_pos_lon(deg)":0, * "rover_pos_height(m)":0} * ``` */ export declare class SolutionStatusEvent extends Event { soln: SolutionStatus; absError3d: number; absErrorH: number; absErrorV: number; /** * Construct a SolutionStatusEvent. * * @param {SolutionStatus} soln - A sample solution * @param {number} absError3d - Optional, measured spherical error (m) * @param {number} absErrorH - Optional, measured horizontal error (m) * @param {Number} absErrorV - Optional, measured vertical error (m) * @return {SolutionStatusEvent} The constructed solution status event. */ constructor(soln: SolutionStatus, absError3d?: number, absErrorH?: number, absErrorV?: number); /** * Checks to see if a solution is (approximately) at the same time. * * @param {SolutionStatus} ref - Another position solution * @return {boolean} */ sameTime(ref: SolutionStatus): boolean; /** * Compare this solution status event a reference position. * * @param {SolutionStatus} ref - The reference position. * @return {SolutionStatusEvent} */ compareTo(ref: SolutionStatus): SolutionStatusEvent; /** * Get a JSON-string presentation of this solution event. * * @return {string} */ toString(): string; /** * Get a JSON presentation of this solution event, using the gnss-testing * solution schema. * * @return {Object} */ toJSON(): Object; /** * Helper method for constructing a SolutionStatusEvent from a pond.js * Event. A timeseries queried at a particular time returns an Event, from * which we have to reconstruct the subclassed SolutionStatusEvent. * * @param {Event} event - Plain Old Event * @return {SolutionStatusEvent} */ static fromEvent(event: Event): SolutionStatusEvent; } /** * Generate a random static solution hovering around a point. * * @param {ECEFSolution} sol - Center point in ECEF * @param {Date} t - Time for solution * @return {SolutionStatusEvent} - Random static solution */ export declare function getRandomStaticSoln(sol: ECEFSolution, t: Date): SolutionStatus; /** * A solution table is an abstract class used to store solution events. It is * intended to be subclassed to have different kinds of implementations. * * @param {string} name - Name of the table * @param {boolean} warnOnOOO - Warn on out-of-order updates. */ export declare abstract class SolutionTable { name: string; index: any; warnOnOOO: any; boolean: any; constructor(name: string, warnOnOOO?: boolean); /** * Get most recent element. * * @return {SolutionStatusEvent} */ tail(): SolutionStatusEvent; /** * Checks to see if the current time is in the table. * * Optimizes for online use cases and will actually warn if calling any * expensive lookups for events that are likely in the backing store's index * but earlier than the latest event. * * @param {Date} time - Time * @return {boolean} Return true if time is in the index, false otherwise. */ hasTime(time: Date): boolean; /** * Get SolutionStatusEvent at a particular index, between 0 and the size * of the index. * * @throws IndexOutOfBoundsExceptions * @param {Number} pos - position within the index * @return {SolutionStatusEvent} */ atPos(pos: number): SolutionStatusEvent; /** * Get SolutionStatusEvent at a particular point in time. * * This retrieval method merges all the solution events at a particular * time. The backing table actually stores all updates at a particular time, * but the backing timeseries API doesn't give an option to conditionally * retrieve items at an instance of time. * * @param {date} Time - (degrees) * @return {SolutionStatusEvent} */ atTime(time: Date): SolutionStatusEvent; /** * Return an array of SolutionStatusEvents. * * @return {Array<SolutionStatusEvent>} */ toArray(): Array<SolutionStatusEvent>; /** * Return an array of Objects. * * @return {Array<Object>} */ toObjectArray(): Array<Object>; /** * Return the number of events store in the table. * * @return {number} Size, in elements, of the current timeseries. */ size(): number; /** * What's the duration of data in this table? * * @return {number} - Duration in seconds. */ getDuration(): number; /** * Add a ECEF offset to the sample coordinates. * * @param {Array<number>} Offset - ECEF offset to apply to sample coordinates. */ addSampleEcefOffset(offset: Array<number>): void; /** * LatLon-based horizontal error. * * @return {any} */ getAbsError2dTs(): any; /** * ECEF-frame 3d error. * * @return {any} */ getAbsError3dTs(): any; /** * Convenience method for filling in all the errors. * * @return {any} */ getErrorsTs(): any; /** * Produce percentiles of errors. * * @return {Object} */ getPercentileErrors(): Object; /** * Calculate fixing percentage for different RTK fixing modes. * * @return {any} */ getFixingPercentage(freq: number): Object; /** * Calculates solution frequency, in Hertz. * * @return {any} */ getSolutionFrequency(): void; /** * Summarize a metrics map of performance, per the evaluation schema defined * at * https://github.com/swift-nav/gnss-testing/blob/master/schemas/evaluation.json */ getSummarizePerformance(): void; /** * Get the TimeRange of the data in this table. * * @return {TimeRange} */ getTimeRange(): TimeRange; /** * Return this table as a JSON object * * @return {Object} */ toJSON(): Object; } /** * Solution state table for pre-processed solution events. * */ export declare class BatchSolutionTable extends SolutionTable { constructor(name: string, events: [SolutionStatusEvent]); /** * Merging * * @return {any} */ join(reference: BatchSolutionTable): void; /** * Adds geodetic reference coordinates to a sample. * * @param {Number} lat - latitude (degrees) */ addRefLlh(refPos: LLASolution): void; /** * Add ECEF reference coordinates to a sample. * * @param {Number} lat - latitude (degrees) */ addRefEcef(refPos: ECEFSolution): void; } /** * Online solution state table. * * A columnar timeseries table that supports streaming, immutable updates. It * intended to store a flat map of results, for a particular instance in time, * using the result schema defined by Swift's gnss-testing repository: * https://github.com/swift-nav/gnss-testing/blob/master/DESIGN.md#swift-solution-csv * * Additionally, stores some accumulated statistical state about solutions that * have been seen so far: a histogram of solution fix modes and *approximate* * CDFs of the spherical, horizontal, and vertical error (implemented using a * T-Digest). * * Example usage: * ``` * let table1 = new tab.OnlineSolutionTable("test_table1"); * * // Construct a sample solution point * const time1 = new Date('2016-06-05'); * const ecef1 = new coords.ECEFSolution(ctest.earthA, 0, 0); * table1 = table1.addSampleSoln(new coords.SolutionStatus(time1, ecef1)); * * // Construct a reference point at the same time and update reference errors * const ecef2 = new coords.ECEFSolution(ctest.earthA, 0, ctest.earthA); * table1 = table1.updateReferenceSoln( * new coords.SolutionStatus(time1, ecef2, ecef2.toLLA())); * * // Retrieve and print error at a particular time, and aggregated errors: * let result = table1.atTime(time1).toJSON(); * console.log(result['abs_error_2d']); => // A number * console.log(table1.getPercentileErrors()); // A map * ``` * */ export declare class OnlineSolutionTable extends SolutionTable { collection: any; modeCounter: OnlineHistogram; absError3dCDF: OnlineStatistics; absErrorHCDF: OnlineStatistics; absErrorVCDF: OnlineStatistics; bufferedReferenceSolution: SolutionStatus; utc: boolean; /** * Construct online solution state table. * * @param {string} name - Human-readable name * @return {OnlineSolutionTable} The constructed solution table. */ constructor(name: string); /** * Initialize state: backing timeseries and accumulators. * * @return {OnlineSolutionTable} */ _init(): OnlineSolutionTable; /** * Sets the backing collection and timeseries, which are immutable objects. * * @param {Collection} coll - Collection to set * @return {OnlineSolutionTable} */ _setCollection(coll: any): OnlineSolutionTable; /** * Update timeseries with a solution status event, which includes positions in * different coordinate systems and measured errors at a particular instance * in-time. This is an internal method. * * @param {SolutionStatusEvent} event * @return {OnlineSolutionTable} */ _update(event: SolutionStatusEvent): OnlineSolutionTable; /** * Update the timeseries with a new sample solution. Returns a new table. * * @param {SolutionStatus} soln - Sample solution * @return {OnlineSolutionTable} */ addSampleSoln(soln: SolutionStatus): OnlineSolutionTable; /** * Add reference coordinates to a sample. * * @param {SolutionStatus} ref - Reference solution * @return {OnlineSolutionTable} */ updateReferenceSoln(ref: SolutionStatus): OnlineSolutionTable; /** * Crop solution table to range. Returns a new OnlineSolutionTable, discarding * accumulated aggregated statistics state of the original range. * * @param {TimeRange} range - TimeRange * @return {OnlineSolutionTable} */ crop(range: TimeRange): OnlineSolutionTable; /** * Select OnlineSolutionTable between begin and end. * * @param {number} begin - The position to begin slicing * @param {number} end - The position to end slicing * @return {OnlineSolutionTable} */ slice(begin: number, end: number): OnlineSolutionTable; /** * Select OnlineSolutionTable max. * * @param {string} column - The column to find the max of. * @return {number} */ max(column: string): number; /** * Internal, generic function for collecting summary statistics from internal * statistics accumulators. * * @param {Function} fn - One of the class methods on OnlineStatistics. * @return {Object} - Object of values keyed error type (one of * abs_error_2d, abs_error_3d, abs_error_h). */ _collectAggValue(fn: (obj: OnlineStatistics) => Object | number): Object; /** * Returns the max errors. Queries are O(1), using backing online accumulator. * * @return {Object} - Object of max values keyed error type (one of * abs_error_2d, abs_error_3d, abs_error_h). */ maxErrors(): Object; /** * Select OnlineSolutionTable min. * * @param {string} column - The column to find the min of. * @return {number} */ min(column: string): number; /** * Returns the min errors. Queries are O(1), using backing online accumulator. * * @return {Object} - Object of min values keyed error type (one of * abs_error_2d, abs_error_3d, abs_error_h). */ minErrors(): Object; /** * Produce approximate cumulative distribution function (CDF) errors. * * Returns a map result that looks like (bogus values): * * { abs_error_2d: { '10': 637, ... , '90': 630, '95': 635, '99': 637 }, * ... } * * @return {Object} Nested Object of error types, with percentile values keyed * by a string percentile value. */ getErrorsCDF(): Object; /** * Produce approximate percentiles of errors. * * Returns a map result that looks like (bogus values): * * { abs_error_2d: { '50': 637, '90': 637, '99': 637 }, * abs_error_v: { '50': 500, '90': 500, '99': 500 }, * abs_error_3d: { '50': -265, '90': -265, '99': -265 }} * * @param {Array<number>} percentiles - List of percentiles, with each * element between 0 and 1. Defaults to [0.50, 0.90, 0.99]. * @return {Object} Nested Object of error types, with percentile values keyed * by a string percentile value. */ getPercentileErrors(percentiles?: number[]): Object; /** * Calculate exact fixing percentage for different RTK fixing modes. * * Uses a presumed solution frequency to bound solution availability: given a * frequency of solutions and the duration of the timeseries, you have the * total number of expected solution events. This normalizes the raw count of * observed solution modes stored. * * @param {number} freq - Solution frequency * @return {Object} */ getFixingPercentage(freq: number): Object; /** * Calculate exact fixing percentage for different RTK fixing modes, assuming * a timerange that may be longer than the timerange actually in the * table. See getFixingPercentage for remaining details. * * @param {number} freq - Solution frequency * @param {TimeRange} range - TimeRange for checking availability. * @return {Object} */ getRangedFixingPercentage(freq: number, range: TimeRange): Object; /** * Calculate the total number of samples in the table. * * @return {number} - Number of samples. */ getSamples(): number; }