ootk
Version:
Orbital Object Toolkit including Multiple Propagators, Initial Orbit Determination, and Maneuver Calculations.
105 lines • 4.54 kB
JavaScript
/**
* @author @thkruz Theodore Kruczek
* @license AGPL-3.0-or-later
* @copyright (c) 2025 Kruczek Labs LLC
*
* Orbital Object ToolKit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* Orbital Object ToolKit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with
* Orbital Object ToolKit. If not, see <http://www.gnu.org/licenses/>.
*/
import { array2d, DEG2RAD, J2000, Matrix, RadecTopocentric, RIC, Vector, Vector3D, } from '../main.js';
import { Observation } from './Observation.js';
import { normalizeAngle, observationDerivative, observationNoiseFromSigmas } from './ObservationUtils.js';
// / Optical observation data.
export class ObservationOptical extends Observation {
site_;
observation;
noise_;
// / Create a new [ObservationOptical] object.
constructor(site_, observation, noise_ = ObservationOptical.defaultNoise) {
super();
this.site_ = site_;
this.observation = observation;
this.noise_ = noise_;
}
// / Inertial site location.
get site() {
return this.site_;
}
// / Noise matrix.
get noise() {
return this.noise_;
}
/**
* Default noise matrix _(right-ascension, declination)_.
* Based on the Maui Optical Site noise model.
*/
static defaultNoise = ObservationOptical.noiseFromSigmas(0.0037 * DEG2RAD, 0.003 * DEG2RAD);
get epoch() {
return this.observation.epoch;
}
toVector() {
return Vector.fromList([this.observation.rightAscension, this.observation.declination]);
}
clos(propagator) {
const position = propagator.propagate(this.epoch).position;
const offset = position.subtract(this.site.position);
const actual = this.observation.lineOfSight().normalize();
const expected = offset.normalize();
const slantRange = offset.magnitude();
const theta = actual.angle(expected);
if (isNaN(theta)) {
return 0.0;
}
return 2.0 * slantRange * Math.sin(theta * 0.5);
}
ricDiff(propagator) {
const r0 = this.site;
const r1 = propagator.propagate(this.epoch);
const r2 = this.observation.position(this.site, r1.position.distance(r0.position));
return RIC.fromJ2000(new J2000(this.epoch, r2, Vector3D.origin), r1).position;
}
sample(random, sigma = 1.0) {
const resultEl = this.sampleVector(random, sigma).elements;
return new ObservationOptical(this.site, new RadecTopocentric(this.epoch, resultEl[0], resultEl[1]), this.noise);
}
jacobian(propPairs) {
const result = array2d(2, 6, 0.0);
for (let i = 0; i < 6; i++) {
const step = propPairs.step(i);
const [high, low] = propPairs.get(i);
const sl = low.propagate(this.epoch);
const sh = high.propagate(this.epoch);
const ol = RadecTopocentric.fromStateVector(sl, this.site);
const oh = RadecTopocentric.fromStateVector(sh, this.site);
result[0][i] = observationDerivative(oh.rightAscension, ol.rightAscension, step, true);
result[1][i] = observationDerivative(oh.declination, ol.declination, step, true);
}
return new Matrix(result);
}
residual(propagator) {
const result = array2d(2, 1, 0.0);
const state = propagator.propagate(this.epoch);
const radec = RadecTopocentric.fromStateVector(state, this.site);
result[0][0] = normalizeAngle(this.observation.rightAscension, radec.rightAscension);
result[1][0] = normalizeAngle(this.observation.declination, radec.declination);
return new Matrix(result);
}
/**
* Create a noise matrix from right ascension and declination standard deviantions.
* @param raSigma Right ascension standard deviation
* @param decSigma Declination standard deviation
* @returns Noise matrix
*/
static noiseFromSigmas(raSigma, decSigma) {
return observationNoiseFromSigmas([raSigma, decSigma]);
}
}
//# sourceMappingURL=ObservationOptical.js.map