gnss_solutions
Version:
Javascript GNSS solution analysis library
467 lines (466 loc) • 15.8 kB
TypeScript
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;
}