ootk 5.1.0 → 6.0.0-rc.2
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/.claude/PROMPT.md +13 -0
- package/.claude/hooks/post-tool-use.ts +33 -0
- package/.claude/hooks/user-prompt-submit.ts +138 -0
- package/.claude/settings.local.json +13 -0
- package/.claude/skill-rules.json +11 -0
- package/.claude/skills/ootk-dev/SKILL.md +16 -0
- package/ADVANCED_FEATURES_GUIDE.md +1025 -0
- package/CHANGELOG.md +42 -3
- package/README.md +77 -45
- package/dist/body/Celestial.d.ts +2 -2
- package/dist/body/Celestial.js +2 -2
- package/dist/body/Celestial.js.map +1 -1
- package/dist/body/Earth.d.ts +4 -4
- package/dist/body/Earth.js +2 -2
- package/dist/body/Earth.js.map +1 -1
- package/dist/body/Moon.d.ts +3 -3
- package/dist/body/Moon.js +7 -7
- package/dist/body/Moon.js.map +1 -1
- package/dist/body/NutationAngles.d.ts +2 -2
- package/dist/body/NutationAngles.js +1 -1
- package/dist/body/PrecessionAngles.d.ts +2 -2
- package/dist/body/PrecessionAngles.js +1 -1
- package/dist/body/Sun.d.ts +2 -2
- package/dist/body/Sun.js +3 -3
- package/dist/body/Sun.js.map +1 -1
- package/dist/body/index.d.ts +5 -5
- package/dist/body/index.js +5 -5
- package/dist/body/index.js.map +1 -1
- package/dist/conjunction/ConjunctionAssessment.d.ts +156 -0
- package/dist/conjunction/ConjunctionAssessment.js +281 -0
- package/dist/conjunction/ConjunctionAssessment.js.map +1 -0
- package/dist/conjunction/ConjunctionEvent.d.ts +104 -0
- package/dist/conjunction/ConjunctionEvent.js +156 -0
- package/dist/conjunction/ConjunctionEvent.js.map +1 -0
- package/dist/conjunction/ProbabilityOfCollision.d.ts +102 -0
- package/dist/conjunction/ProbabilityOfCollision.js +240 -0
- package/dist/conjunction/ProbabilityOfCollision.js.map +1 -0
- package/dist/conjunction/index.d.ts +19 -0
- package/dist/conjunction/index.js +20 -0
- package/dist/conjunction/index.js.map +1 -0
- package/dist/coordinate/ClassicalElements.d.ts +7 -7
- package/dist/coordinate/ClassicalElements.js +7 -7
- package/dist/coordinate/ClassicalElements.js.map +1 -1
- package/dist/coordinate/EquinoctialElements.d.ts +5 -5
- package/dist/coordinate/EquinoctialElements.js +4 -4
- package/dist/coordinate/EquinoctialElements.js.map +1 -1
- package/dist/coordinate/FormatTle.d.ts +2 -2
- package/dist/coordinate/FormatTle.js +2 -2
- package/dist/coordinate/FormatTle.js.map +1 -1
- package/dist/coordinate/Geodetic.d.ts +4 -4
- package/dist/coordinate/Geodetic.js +7 -7
- package/dist/coordinate/Geodetic.js.map +1 -1
- package/dist/coordinate/Hill.d.ts +4 -4
- package/dist/coordinate/Hill.js +3 -3
- package/dist/coordinate/Hill.js.map +1 -1
- package/dist/coordinate/ITRF.d.ts +5 -5
- package/dist/coordinate/ITRF.js +6 -5
- package/dist/coordinate/ITRF.js.map +1 -1
- package/dist/coordinate/J2000.d.ts +5 -5
- package/dist/coordinate/J2000.js +5 -5
- package/dist/coordinate/J2000.js.map +1 -1
- package/dist/coordinate/RIC.d.ts +4 -4
- package/dist/coordinate/RIC.js +3 -3
- package/dist/coordinate/RIC.js.map +1 -1
- package/dist/coordinate/RelativeState.d.ts +5 -5
- package/dist/coordinate/RelativeState.js +2 -2
- package/dist/coordinate/RelativeState.js.map +1 -1
- package/dist/coordinate/StateVector.d.ts +2 -2
- package/dist/coordinate/StateVector.js +2 -2
- package/dist/coordinate/StateVector.js.map +1 -1
- package/dist/coordinate/TEME.d.ts +4 -4
- package/dist/coordinate/TEME.js +4 -4
- package/dist/coordinate/TEME.js.map +1 -1
- package/dist/coordinate/Tle.d.ts +5 -5
- package/dist/coordinate/Tle.js +9 -9
- package/dist/coordinate/Tle.js.map +1 -1
- package/dist/coordinate/index.d.ts +12 -12
- package/dist/coordinate/index.js +12 -12
- package/dist/coordinate/index.js.map +1 -1
- package/dist/coordinate/tle-format-data.d.ts +1 -1
- package/dist/coordinate/tle-format-data.js +1 -1
- package/dist/covariance/CovarianceSample.d.ts +5 -5
- package/dist/covariance/CovarianceSample.js +5 -5
- package/dist/covariance/CovarianceSample.js.map +1 -1
- package/dist/covariance/StateCovariance.d.ts +2 -2
- package/dist/covariance/StateCovariance.js +2 -2
- package/dist/covariance/StateCovariance.js.map +1 -1
- package/dist/covariance/index.d.ts +2 -2
- package/dist/covariance/index.js +2 -2
- package/dist/covariance/index.js.map +1 -1
- package/dist/data/DataHandler.d.ts +4 -4
- package/dist/data/DataHandler.js +5 -5
- package/dist/data/DataHandler.js.map +1 -1
- package/dist/data/values/Egm96Data.d.ts +1 -1
- package/dist/data/values/Egm96Data.js +3 -3
- package/dist/data/values/Egm96Data.js.map +1 -1
- package/dist/data/values/HpAtmosphereData.d.ts +2 -2
- package/dist/data/values/HpAtmosphereData.js +3 -3
- package/dist/data/values/HpAtmosphereData.js.map +1 -1
- package/dist/data/values/HpAtmosphereResult.d.ts +2 -2
- package/dist/data/values/HpAtmosphereResult.js +1 -1
- package/dist/data/values/Iau1980Data.d.ts +1 -1
- package/dist/data/values/Iau1980Data.js +2 -2
- package/dist/data/values/Iau1980Data.js.map +1 -1
- package/dist/data/values/LeapSecond.d.ts +1 -1
- package/dist/data/values/LeapSecond.js +1 -1
- package/dist/data/values/LeapSecondData.d.ts +2 -2
- package/dist/data/values/LeapSecondData.js +2 -2
- package/dist/data/values/LeapSecondData.js.map +1 -1
- package/dist/data/values/egm96.d.ts +2 -2
- package/dist/data/values/egm96.js +1 -1
- package/dist/data/values/hpAtmosphere.d.ts +2 -2
- package/dist/data/values/hpAtmosphere.js +1 -1
- package/dist/data/values/iau1980.d.ts +2 -2
- package/dist/data/values/iau1980.js +1 -1
- package/dist/enums/AngularDiameterMethod.d.ts +1 -1
- package/dist/enums/AngularDiameterMethod.js +1 -1
- package/dist/enums/AngularDistanceMethod.d.ts +1 -1
- package/dist/enums/AngularDistanceMethod.js +1 -1
- package/dist/enums/OrbitRegime.d.ts +1 -1
- package/dist/enums/OrbitRegime.js +1 -1
- package/dist/enums/PassType.d.ts +1 -1
- package/dist/enums/PassType.js +1 -1
- package/dist/enums/Sgp4OpsMode.d.ts +1 -1
- package/dist/enums/Sgp4OpsMode.js +1 -1
- package/dist/enums/index.d.ts +7 -7
- package/dist/enums/index.js +7 -7
- package/dist/enums/index.js.map +1 -1
- package/dist/fetch/horizons-constants.d.ts +43 -0
- package/dist/fetch/horizons-constants.js +50 -0
- package/dist/fetch/horizons-constants.js.map +1 -0
- package/dist/fetch/horizons-interfaces.d.ts +37 -0
- package/dist/fetch/horizons-interfaces.js +2 -0
- package/dist/fetch/horizons-interfaces.js.map +1 -0
- package/dist/fetch/horizons.d.ts +86 -0
- package/dist/fetch/horizons.js +237 -0
- package/dist/fetch/horizons.js.map +1 -0
- package/dist/force/AtmosphericDrag.d.ts +3 -3
- package/dist/force/AtmosphericDrag.js +2 -2
- package/dist/force/AtmosphericDrag.js.map +1 -1
- package/dist/force/EarthGravity.d.ts +3 -3
- package/dist/force/EarthGravity.js +2 -2
- package/dist/force/EarthGravity.js.map +1 -1
- package/dist/force/Force.d.ts +3 -3
- package/dist/force/Force.js +1 -10
- package/dist/force/Force.js.map +1 -1
- package/dist/force/ForceModel.d.ts +3 -3
- package/dist/force/ForceModel.js +7 -7
- package/dist/force/ForceModel.js.map +1 -1
- package/dist/force/Gravity.d.ts +3 -3
- package/dist/force/Gravity.js +2 -2
- package/dist/force/Gravity.js.map +1 -1
- package/dist/force/SolarRadiationPressure.d.ts +3 -3
- package/dist/force/SolarRadiationPressure.js +4 -4
- package/dist/force/SolarRadiationPressure.js.map +1 -1
- package/dist/force/ThirdBodyGravity.d.ts +3 -3
- package/dist/force/ThirdBodyGravity.js +2 -2
- package/dist/force/ThirdBodyGravity.js.map +1 -1
- package/dist/force/Thrust.d.ts +3 -3
- package/dist/force/Thrust.js +2 -2
- package/dist/force/Thrust.js.map +1 -1
- package/dist/force/index.d.ts +1 -1
- package/dist/force/index.js +1 -1
- package/dist/force/index.js.map +1 -1
- package/dist/interfaces/BaseObjectParams.d.ts +2 -2
- package/dist/interfaces/BaseObjectParams.js +1 -1
- package/dist/interfaces/ClassicalElementsParams.d.ts +2 -2
- package/dist/interfaces/ClassicalElementsParams.js +1 -1
- package/dist/interfaces/EquinoctialElementsParams.d.ts +2 -2
- package/dist/interfaces/EquinoctialElementsParams.js +1 -1
- package/dist/interfaces/GroundPositionParams.d.ts +2 -2
- package/dist/interfaces/GroundPositionParams.js +1 -1
- package/dist/interfaces/RfSensorParams.d.ts +2 -2
- package/dist/interfaces/SatelliteParams.d.ts +2 -2
- package/dist/interfaces/SensorParams.d.ts +2 -2
- package/dist/interfaces/StarObjectParams.d.ts +1 -1
- package/dist/interfaces/TimeVariables.d.ts +1 -1
- package/dist/interfaces/index.d.ts +9 -9
- package/dist/interpolator/ChebyshevCoefficients.d.ts +2 -2
- package/dist/interpolator/ChebyshevCoefficients.js +2 -2
- package/dist/interpolator/ChebyshevCoefficients.js.map +1 -1
- package/dist/interpolator/ChebyshevInterpolator.d.ts +4 -4
- package/dist/interpolator/ChebyshevInterpolator.js +3 -3
- package/dist/interpolator/ChebyshevInterpolator.js.map +1 -1
- package/dist/interpolator/CubicSpline.d.ts +2 -2
- package/dist/interpolator/CubicSpline.js +1 -1
- package/dist/interpolator/CubicSplineInterpolator.d.ts +4 -4
- package/dist/interpolator/CubicSplineInterpolator.js +4 -4
- package/dist/interpolator/CubicSplineInterpolator.js.map +1 -1
- package/dist/interpolator/FieldInterpolator.d.ts +3 -3
- package/dist/interpolator/FieldInterpolator.js +2 -12
- package/dist/interpolator/FieldInterpolator.js.map +1 -1
- package/dist/interpolator/Interpolator.d.ts +2 -2
- package/dist/interpolator/Interpolator.js +2 -2
- package/dist/interpolator/Interpolator.js.map +1 -1
- package/dist/interpolator/LagrangeInterpolator.d.ts +3 -3
- package/dist/interpolator/LagrangeInterpolator.js +3 -3
- package/dist/interpolator/LagrangeInterpolator.js.map +1 -1
- package/dist/interpolator/StateInterpolator.d.ts +4 -4
- package/dist/interpolator/StateInterpolator.js +2 -10
- package/dist/interpolator/StateInterpolator.js.map +1 -1
- package/dist/interpolator/VerletBlendInterpolator.d.ts +5 -5
- package/dist/interpolator/VerletBlendInterpolator.js +5 -5
- package/dist/interpolator/VerletBlendInterpolator.js.map +1 -1
- package/dist/main.d.ts +20 -20
- package/dist/main.js +21 -20
- package/dist/main.js.map +1 -1
- package/dist/maneuver/TwoBurnOrbitTransfer.d.ts +3 -3
- package/dist/maneuver/TwoBurnOrbitTransfer.js +3 -3
- package/dist/maneuver/TwoBurnOrbitTransfer.js.map +1 -1
- package/dist/maneuver/Waypoint.d.ts +5 -5
- package/dist/maneuver/Waypoint.js +7 -7
- package/dist/maneuver/Waypoint.js.map +1 -1
- package/dist/objects/BaseObject.d.ts +3 -3
- package/dist/objects/BaseObject.js +2 -2
- package/dist/objects/BaseObject.js.map +1 -1
- package/dist/objects/DetailedSatellite.d.ts +4 -4
- package/dist/objects/DetailedSatellite.js +4 -4
- package/dist/objects/DetailedSatellite.js.map +1 -1
- package/dist/objects/DetailedSensor.d.ts +5 -5
- package/dist/objects/DetailedSensor.js +2 -2
- package/dist/objects/DetailedSensor.js.map +1 -1
- package/dist/objects/GroundObject.d.ts +4 -4
- package/dist/objects/GroundObject.js +3 -3
- package/dist/objects/GroundObject.js.map +1 -1
- package/dist/objects/LandObject.d.ts +3 -3
- package/dist/objects/LandObject.js +2 -2
- package/dist/objects/LandObject.js.map +1 -1
- package/dist/objects/Marker.d.ts +2 -2
- package/dist/objects/Marker.js +2 -2
- package/dist/objects/Marker.js.map +1 -1
- package/dist/objects/RfSensor.d.ts +2 -2
- package/dist/objects/RfSensor.js +2 -2
- package/dist/objects/RfSensor.js.map +1 -1
- package/dist/objects/Satellite.d.ts +12 -12
- package/dist/objects/Satellite.js +14 -14
- package/dist/objects/Satellite.js.map +1 -1
- package/dist/objects/Sensor.d.ts +6 -6
- package/dist/objects/Sensor.js +5 -5
- package/dist/objects/Sensor.js.map +1 -1
- package/dist/objects/Star.d.ts +3 -3
- package/dist/objects/Star.js +3 -3
- package/dist/objects/Star.js.map +1 -1
- package/dist/objects/index.d.ts +10 -10
- package/dist/objects/index.js +10 -10
- package/dist/objects/index.js.map +1 -1
- package/dist/observation/Observation.d.ts +11 -11
- package/dist/observation/Observation.js +1 -52
- package/dist/observation/Observation.js.map +1 -1
- package/dist/observation/ObservationOptical.d.ts +6 -6
- package/dist/observation/ObservationOptical.js +4 -4
- package/dist/observation/ObservationOptical.js.map +1 -1
- package/dist/observation/ObservationRadar.d.ts +6 -6
- package/dist/observation/ObservationRadar.js +4 -4
- package/dist/observation/ObservationRadar.js.map +1 -1
- package/dist/observation/ObservationUtils.d.ts +2 -2
- package/dist/observation/ObservationUtils.js +2 -2
- package/dist/observation/ObservationUtils.js.map +1 -1
- package/dist/observation/PropagatorPairs.d.ts +2 -2
- package/dist/observation/PropagatorPairs.js +1 -1
- package/dist/observation/RAE.d.ts +6 -6
- package/dist/observation/RAE.js +6 -6
- package/dist/observation/RAE.js.map +1 -1
- package/dist/observation/RadecGeocentric.d.ts +6 -6
- package/dist/observation/RadecGeocentric.js +5 -5
- package/dist/observation/RadecGeocentric.js.map +1 -1
- package/dist/observation/RadecTopocentric.d.ts +6 -6
- package/dist/observation/RadecTopocentric.js +9 -7
- package/dist/observation/RadecTopocentric.js.map +1 -1
- package/dist/observation/index.d.ts +5 -5
- package/dist/observation/index.js +5 -5
- package/dist/observation/index.js.map +1 -1
- package/dist/operations/BoxMuller.d.ts +2 -2
- package/dist/operations/BoxMuller.js +2 -2
- package/dist/operations/BoxMuller.js.map +1 -1
- package/dist/operations/EulerAngles.d.ts +2 -2
- package/dist/operations/EulerAngles.js +2 -2
- package/dist/operations/EulerAngles.js.map +1 -1
- package/dist/operations/Matrix.d.ts +2 -2
- package/dist/operations/Matrix.js +2 -2
- package/dist/operations/Matrix.js.map +1 -1
- package/dist/operations/Quaternion.d.ts +2 -2
- package/dist/operations/Quaternion.js +2 -2
- package/dist/operations/Quaternion.js.map +1 -1
- package/dist/operations/Random.d.ts +1 -1
- package/dist/operations/Random.js +1 -1
- package/dist/operations/RandomGaussianSource.d.ts +2 -2
- package/dist/operations/RandomGaussianSource.js +3 -3
- package/dist/operations/RandomGaussianSource.js.map +1 -1
- package/dist/operations/Vector.d.ts +2 -2
- package/dist/operations/Vector.js +2 -2
- package/dist/operations/Vector.js.map +1 -1
- package/dist/operations/Vector3D.d.ts +5 -4
- package/dist/operations/Vector3D.js +5 -4
- package/dist/operations/Vector3D.js.map +1 -1
- package/dist/operations/index.d.ts +4 -4
- package/dist/operations/index.js +4 -4
- package/dist/operations/index.js.map +1 -1
- package/dist/operations/operations.d.ts +5 -5
- package/dist/operations/operations.js +5 -5
- package/dist/operations/operations.js.map +1 -1
- package/dist/optimize/ChebyshevCompressor.d.ts +3 -3
- package/dist/optimize/ChebyshevCompressor.js +4 -4
- package/dist/optimize/ChebyshevCompressor.js.map +1 -1
- package/dist/optimize/DownhillSimplex.d.ts +2 -2
- package/dist/optimize/DownhillSimplex.js +2 -2
- package/dist/optimize/DownhillSimplex.js.map +1 -1
- package/dist/optimize/GoldenSection.d.ts +2 -2
- package/dist/optimize/GoldenSection.js +1 -1
- package/dist/optimize/PolynomialRegression.d.ts +2 -2
- package/dist/optimize/PolynomialRegression.js +4 -4
- package/dist/optimize/PolynomialRegression.js.map +1 -1
- package/dist/optimize/PolynomicalRegressionResult.d.ts +1 -1
- package/dist/optimize/PolynomicalRegressionResult.js +1 -1
- package/dist/optimize/SimpleLinearRegression.d.ts +1 -1
- package/dist/optimize/SimpleLinearRegression.js +1 -1
- package/dist/optimize/SimplexEntry.d.ts +1 -1
- package/dist/optimize/SimplexEntry.js +2 -2
- package/dist/optimize/SimplexEntry.js.map +1 -1
- package/dist/orbit_determination/BatchLeastSquaresOD.d.ts +5 -5
- package/dist/orbit_determination/BatchLeastSquaresOD.js +8 -8
- package/dist/orbit_determination/BatchLeastSquaresOD.js.map +1 -1
- package/dist/orbit_determination/BatchLeastSquaresResult.d.ts +3 -3
- package/dist/orbit_determination/BatchLeastSquaresResult.js +1 -1
- package/dist/orbit_determination/GaussIOD.d.ts +98 -0
- package/dist/orbit_determination/GaussIOD.js +291 -0
- package/dist/orbit_determination/GaussIOD.js.map +1 -0
- package/dist/orbit_determination/GibbsIOD.d.ts +2 -2
- package/dist/orbit_determination/GibbsIOD.js +4 -4
- package/dist/orbit_determination/GibbsIOD.js.map +1 -1
- package/dist/orbit_determination/GoodingIOD.d.ts +58 -8
- package/dist/orbit_determination/GoodingIOD.js +225 -35
- package/dist/orbit_determination/GoodingIOD.js.map +1 -1
- package/dist/orbit_determination/HerrickGibbsIOD.d.ts +2 -2
- package/dist/orbit_determination/HerrickGibbsIOD.js +2 -2
- package/dist/orbit_determination/HerrickGibbsIOD.js.map +1 -1
- package/dist/orbit_determination/LambertIOD.d.ts +2 -2
- package/dist/orbit_determination/LambertIOD.js +2 -2
- package/dist/orbit_determination/LambertIOD.js.map +1 -1
- package/dist/orbit_determination/ModifiedGoodingIOD.d.ts +3 -3
- package/dist/orbit_determination/ModifiedGoodingIOD.js +8 -8
- package/dist/orbit_determination/ModifiedGoodingIOD.js.map +1 -1
- package/dist/orbit_determination/index.d.ts +7 -7
- package/dist/orbit_determination/index.js +7 -7
- package/dist/orbit_determination/index.js.map +1 -1
- package/dist/propagator/DormandPrince54Propagator.d.ts +2 -2
- package/dist/propagator/DormandPrince54Propagator.js +2 -2
- package/dist/propagator/DormandPrince54Propagator.js.map +1 -1
- package/dist/propagator/KeplerPropagator.d.ts +6 -6
- package/dist/propagator/KeplerPropagator.js +6 -7
- package/dist/propagator/KeplerPropagator.js.map +1 -1
- package/dist/propagator/Propagator.d.ts +5 -5
- package/dist/propagator/Propagator.js +5 -5
- package/dist/propagator/Propagator.js.map +1 -1
- package/dist/propagator/RkCheckpoint.d.ts +2 -2
- package/dist/propagator/RkCheckpoint.js +1 -1
- package/dist/propagator/RkResult.d.ts +2 -2
- package/dist/propagator/RkResult.js +1 -1
- package/dist/propagator/RungeKutta4Propagator.d.ts +6 -6
- package/dist/propagator/RungeKutta4Propagator.js +5 -5
- package/dist/propagator/RungeKutta4Propagator.js.map +1 -1
- package/dist/propagator/RungeKutta89Propagator.d.ts +2 -2
- package/dist/propagator/RungeKutta89Propagator.js +2 -2
- package/dist/propagator/RungeKutta89Propagator.js.map +1 -1
- package/dist/propagator/RungeKuttaAdaptive.d.ts +6 -6
- package/dist/propagator/RungeKuttaAdaptive.js +52 -9
- package/dist/propagator/RungeKuttaAdaptive.js.map +1 -1
- package/dist/propagator/Sgp4Propagator.d.ts +7 -7
- package/dist/propagator/Sgp4Propagator.js +4 -4
- package/dist/propagator/Sgp4Propagator.js.map +1 -1
- package/dist/propagator/index.d.ts +3 -3
- package/dist/propagator/index.js +3 -3
- package/dist/propagator/index.js.map +1 -1
- package/dist/sgp4/index.d.ts +2 -2
- package/dist/sgp4/index.js +2 -2
- package/dist/sgp4/index.js.map +1 -1
- package/dist/sgp4/sgp4.d.ts +3 -3
- package/dist/sgp4/sgp4.js +11 -5
- package/dist/sgp4/sgp4.js.map +1 -1
- package/dist/smoothing/ExponentialSmoothing.d.ts +2 -2
- package/dist/smoothing/ExponentialSmoothing.js +1 -1
- package/dist/time/Epoch.d.ts +2 -2
- package/dist/time/Epoch.js +2 -2
- package/dist/time/Epoch.js.map +1 -1
- package/dist/time/EpochGPS.d.ts +3 -3
- package/dist/time/EpochGPS.js +3 -3
- package/dist/time/EpochGPS.js.map +1 -1
- package/dist/time/EpochTAI.d.ts +2 -2
- package/dist/time/EpochTAI.js +2 -2
- package/dist/time/EpochTAI.js.map +1 -1
- package/dist/time/EpochTDB.d.ts +2 -2
- package/dist/time/EpochTDB.js +2 -2
- package/dist/time/EpochTDB.js.map +1 -1
- package/dist/time/EpochTT.d.ts +2 -2
- package/dist/time/EpochTT.js +2 -2
- package/dist/time/EpochTT.js.map +1 -1
- package/dist/time/EpochUTC.d.ts +7 -7
- package/dist/time/EpochUTC.js +9 -9
- package/dist/time/EpochUTC.js.map +1 -1
- package/dist/time/EpochWindow.d.ts +2 -2
- package/dist/time/EpochWindow.js +1 -1
- package/dist/time/TimeStamped.d.ts +2 -2
- package/dist/time/TimeStamped.js +1 -1
- package/dist/time/index.d.ts +8 -8
- package/dist/time/index.js +8 -8
- package/dist/time/index.js.map +1 -1
- package/dist/transforms/TransformCache.d.ts +1 -1
- package/dist/transforms/TransformCache.js +1 -1
- package/dist/transforms/conversions.d.ts +2 -2
- package/dist/transforms/conversions.js +2 -2
- package/dist/transforms/conversions.js.map +1 -1
- package/dist/transforms/index.d.ts +2 -2
- package/dist/transforms/index.js +2 -2
- package/dist/transforms/index.js.map +1 -1
- package/dist/transforms/transforms.d.ts +1 -1
- package/dist/transforms/transforms.js +1 -1
- package/dist/transforms/transforms.js.map +1 -1
- package/dist/types/types.d.ts +8 -3
- package/dist/types/types.js +6 -1
- package/dist/types/types.js.map +1 -1
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.js +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/create-covariance-from-tle.d.ts +1 -1
- package/dist/utils/create-covariance-from-tle.js +1 -1
- package/dist/utils/create-covariance-from-tle.js.map +1 -1
- package/dist/utils/functions.d.ts +4 -4
- package/dist/utils/functions.js +9 -4
- package/dist/utils/functions.js.map +1 -1
- package/dist/utils/index.d.ts +5 -5
- package/dist/utils/index.js +5 -5
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/jacobian.d.ts +2 -2
- package/dist/utils/jacobian.js +1 -1
- package/dist/utils/jacobian.js.map +1 -1
- package/dist/utils/linearDistance.d.ts +1 -1
- package/docs/README.md +132 -0
- package/docs/getting-started.md +792 -0
- package/docs/lambert-satellite-integration-guide.md +766 -0
- package/docs/user-guide.md +1935 -0
- package/jest.config.mjs +28 -0
- package/package.json +3 -4
- package/src/body/Celestial.ts +2 -2
- package/src/body/Earth.ts +4 -4
- package/src/body/Moon.ts +7 -7
- package/src/body/NutationAngles.ts +2 -2
- package/src/body/PrecessionAngles.ts +2 -2
- package/src/body/Sun.ts +4 -4
- package/src/body/index.ts +6 -5
- package/src/conjunction/ConjunctionAssessment.ts +417 -0
- package/src/conjunction/ConjunctionEvent.ts +149 -0
- package/src/conjunction/ProbabilityOfCollision.ts +300 -0
- package/src/conjunction/index.ts +24 -0
- package/src/coordinate/ClassicalElements.ts +16 -11
- package/src/coordinate/EquinoctialElements.ts +7 -7
- package/src/coordinate/FormatTle.ts +2 -2
- package/src/coordinate/Geodetic.ts +8 -8
- package/src/coordinate/Hill.ts +4 -4
- package/src/coordinate/ITRF.ts +6 -6
- package/src/coordinate/J2000.ts +7 -7
- package/src/coordinate/RIC.ts +4 -4
- package/src/coordinate/RelativeState.ts +5 -5
- package/src/coordinate/StateVector.ts +8 -3
- package/src/coordinate/TEME.ts +6 -6
- package/src/coordinate/Tle.ts +9 -9
- package/src/coordinate/index.ts +13 -12
- package/src/coordinate/tle-format-data.ts +1 -1
- package/src/covariance/CovarianceSample.ts +13 -13
- package/src/covariance/StateCovariance.ts +2 -2
- package/src/covariance/index.ts +3 -2
- package/src/data/DataHandler.ts +6 -6
- package/src/data/values/Egm96Data.ts +3 -3
- package/src/data/values/HpAtmosphereData.ts +3 -3
- package/src/data/values/HpAtmosphereResult.ts +2 -2
- package/src/data/values/Iau1980Data.ts +2 -2
- package/src/data/values/LeapSecond.ts +1 -1
- package/src/data/values/LeapSecondData.ts +2 -2
- package/src/data/values/egm96.ts +2 -2
- package/src/data/values/hpAtmosphere.ts +2 -2
- package/src/data/values/iau1980.ts +2 -2
- package/src/enums/AngularDiameterMethod.ts +1 -1
- package/src/enums/AngularDistanceMethod.ts +1 -1
- package/src/enums/OrbitRegime.ts +1 -1
- package/src/enums/PassType.ts +1 -1
- package/src/enums/Sgp4OpsMode.ts +1 -1
- package/src/enums/index.ts +8 -7
- package/src/fetch/horizons-constants.ts +53 -0
- package/src/fetch/horizons-interfaces.ts +38 -0
- package/src/fetch/horizons.ts +300 -0
- package/src/force/AtmosphericDrag.ts +3 -3
- package/src/force/EarthGravity.ts +3 -3
- package/src/force/Force.ts +3 -5
- package/src/force/ForceModel.ts +9 -9
- package/src/force/Gravity.ts +3 -3
- package/src/force/SolarRadiationPressure.ts +4 -4
- package/src/force/ThirdBodyGravity.ts +3 -3
- package/src/force/Thrust.ts +3 -3
- package/src/force/index.ts +2 -1
- package/src/interfaces/BaseObjectParams.ts +2 -2
- package/src/interfaces/ClassicalElementsParams.ts +2 -2
- package/src/interfaces/EquinoctialElementsParams.ts +2 -2
- package/src/interfaces/GroundPositionParams.ts +2 -2
- package/src/interfaces/RfSensorParams.ts +2 -2
- package/src/interfaces/SatelliteParams.ts +2 -2
- package/src/interfaces/SensorParams.ts +3 -3
- package/src/interfaces/StarObjectParams.ts +1 -1
- package/src/interfaces/TimeVariables.ts +1 -1
- package/src/interfaces/index.ts +10 -9
- package/src/interpolator/ChebyshevCoefficients.ts +2 -2
- package/src/interpolator/ChebyshevInterpolator.ts +4 -4
- package/src/interpolator/CubicSpline.ts +2 -2
- package/src/interpolator/CubicSplineInterpolator.ts +4 -4
- package/src/interpolator/FieldInterpolator.ts +3 -5
- package/src/interpolator/Interpolator.ts +2 -2
- package/src/interpolator/LagrangeInterpolator.ts +3 -3
- package/src/interpolator/StateInterpolator.ts +4 -6
- package/src/interpolator/VerletBlendInterpolator.ts +5 -5
- package/src/main.ts +41 -20
- package/src/maneuver/TwoBurnOrbitTransfer.ts +3 -3
- package/src/maneuver/Waypoint.ts +8 -8
- package/src/objects/BaseObject.ts +3 -3
- package/src/objects/DetailedSatellite.ts +9 -9
- package/src/objects/DetailedSensor.ts +5 -5
- package/src/objects/GroundObject.ts +9 -9
- package/src/objects/LandObject.ts +3 -3
- package/src/objects/Marker.ts +2 -2
- package/src/objects/RfSensor.ts +2 -2
- package/src/objects/Satellite.ts +21 -21
- package/src/objects/Sensor.ts +7 -7
- package/src/objects/Star.ts +3 -3
- package/src/objects/index.ts +11 -10
- package/src/observation/Observation.ts +11 -23
- package/src/observation/ObservationOptical.ts +7 -7
- package/src/observation/ObservationRadar.ts +7 -7
- package/src/observation/ObservationUtils.ts +2 -2
- package/src/observation/PropagatorPairs.ts +2 -2
- package/src/observation/RAE.ts +9 -9
- package/src/observation/RadecGeocentric.ts +9 -9
- package/src/observation/RadecTopocentric.ts +13 -10
- package/src/observation/index.ts +6 -5
- package/src/operations/BoxMuller.ts +2 -2
- package/src/operations/EulerAngles.ts +2 -2
- package/src/operations/Matrix.ts +2 -2
- package/src/operations/Quaternion.ts +2 -2
- package/src/operations/Random.ts +1 -1
- package/src/operations/RandomGaussianSource.ts +3 -3
- package/src/operations/Vector.ts +2 -2
- package/src/operations/Vector3D.ts +6 -4
- package/src/operations/index.ts +5 -4
- package/src/operations/operations.ts +6 -5
- package/src/optimize/ChebyshevCompressor.ts +5 -5
- package/src/optimize/DownhillSimplex.ts +2 -2
- package/src/optimize/GoldenSection.ts +2 -2
- package/src/optimize/PolynomialRegression.ts +4 -4
- package/src/optimize/PolynomicalRegressionResult.ts +1 -1
- package/src/optimize/SimpleLinearRegression.ts +1 -1
- package/src/optimize/SimplexEntry.ts +2 -2
- package/src/orbit_determination/BatchLeastSquaresOD.ts +10 -10
- package/src/orbit_determination/BatchLeastSquaresResult.ts +3 -3
- package/src/orbit_determination/GaussIOD.ts +393 -0
- package/src/orbit_determination/GibbsIOD.ts +4 -4
- package/src/orbit_determination/GoodingIOD.ts +458 -160
- package/src/orbit_determination/HerrickGibbsIOD.ts +2 -2
- package/src/orbit_determination/LambertIOD.ts +2 -2
- package/src/orbit_determination/ModifiedGoodingIOD.ts +33 -22
- package/src/orbit_determination/index.ts +8 -7
- package/src/propagator/DormandPrince54Propagator.ts +2 -2
- package/src/propagator/KeplerPropagator.ts +7 -8
- package/src/propagator/Propagator.ts +6 -6
- package/src/propagator/RkCheckpoint.ts +2 -2
- package/src/propagator/RkResult.ts +2 -2
- package/src/propagator/RungeKutta4Propagator.ts +6 -6
- package/src/propagator/RungeKutta89Propagator.ts +2 -2
- package/src/propagator/RungeKuttaAdaptive.ts +62 -12
- package/src/propagator/Sgp4Propagator.ts +7 -7
- package/src/propagator/index.ts +4 -3
- package/src/sgp4/index.ts +3 -2
- package/src/sgp4/sgp4.ts +6 -6
- package/src/smoothing/ExponentialSmoothing.ts +2 -2
- package/src/time/Epoch.ts +3 -3
- package/src/time/EpochGPS.ts +5 -5
- package/src/time/EpochTAI.ts +2 -2
- package/src/time/EpochTDB.ts +2 -2
- package/src/time/EpochTT.ts +2 -2
- package/src/time/EpochUTC.ts +10 -10
- package/src/time/EpochWindow.ts +2 -2
- package/src/time/TimeStamped.ts +2 -2
- package/src/time/index.ts +9 -8
- package/src/transforms/TransformCache.ts +1 -1
- package/src/transforms/conversions.ts +2 -2
- package/src/transforms/index.ts +3 -2
- package/src/transforms/transforms.ts +4 -4
- package/src/types/types.ts +8 -3
- package/src/utils/constants.ts +2 -2
- package/src/utils/create-covariance-from-tle.ts +1 -1
- package/src/utils/functions.ts +10 -5
- package/src/utils/index.ts +6 -5
- package/src/utils/jacobian.ts +2 -2
- package/src/utils/linearDistance.ts +1 -1
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
# Lambert Integration Guide: Generating State Vectors Without SGP4
|
|
2
|
+
|
|
3
|
+
This guide demonstrates how to use Lambert's problem solution to generate state vectors and integrate them with OOTK's orbit propagation capabilities, bypassing SGP4.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Overview](#overview)
|
|
8
|
+
2. [Quick Start](#quick-start)
|
|
9
|
+
3. [Lambert Solver Basics](#lambert-solver-basics)
|
|
10
|
+
4. [Integration Workflows](#integration-workflows)
|
|
11
|
+
5. [Complete Examples](#complete-examples)
|
|
12
|
+
6. [Advanced Usage](#advanced-usage)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
**Lambert's Problem** finds the orbit connecting two position vectors at specific times. This is useful for:
|
|
19
|
+
- Orbit determination from observation data
|
|
20
|
+
- Transfer orbit design
|
|
21
|
+
- Maneuver planning
|
|
22
|
+
- Rendezvous calculations
|
|
23
|
+
- Generating state vectors from position-only observations
|
|
24
|
+
|
|
25
|
+
### Key Classes
|
|
26
|
+
|
|
27
|
+
- **LambertIOD**: Solves Lambert's problem, returns J2000 state vectors
|
|
28
|
+
- **J2000**: ECI state vector (position + velocity)
|
|
29
|
+
- **ClassicalElements**: Orbital elements (a, e, i, Ω, ω, ν)
|
|
30
|
+
- **Satellite**: TLE-based satellite object (requires SGP4 data)
|
|
31
|
+
- **RungeKutta89Propagator**: High-precision numerical propagator
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install ootk
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Basic Lambert Solution
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { LambertIOD, EpochUTC, Vector3D, Kilometers } from 'ootk';
|
|
47
|
+
|
|
48
|
+
// Create Lambert solver (default: Earth's gravitational parameter)
|
|
49
|
+
const lambert = new LambertIOD();
|
|
50
|
+
|
|
51
|
+
// Define two positions in ECI coordinates (km)
|
|
52
|
+
const p1 = new Vector3D<Kilometers>(6778, 0, 0);
|
|
53
|
+
const p2 = new Vector3D<Kilometers>(0, 6778, 0);
|
|
54
|
+
|
|
55
|
+
// Define epochs
|
|
56
|
+
const t1 = EpochUTC.fromDateTime(new Date('2024-01-01T00:00:00.000Z'));
|
|
57
|
+
const t2 = EpochUTC.fromDateTime(new Date('2024-01-01T01:30:00.000Z'));
|
|
58
|
+
|
|
59
|
+
// Solve Lambert's problem
|
|
60
|
+
const stateVector = lambert.estimate(p1, p2, t1, t2, {
|
|
61
|
+
posigrade: true, // Use short path
|
|
62
|
+
nRev: 0 // Zero-revolution transfer
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (stateVector) {
|
|
66
|
+
console.log('Position:', stateVector.position);
|
|
67
|
+
console.log('Velocity:', stateVector.velocity);
|
|
68
|
+
console.log('Epoch:', stateVector.epoch);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Lambert Solver Basics
|
|
75
|
+
|
|
76
|
+
### Constructor
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
const lambert = new LambertIOD(mu?: number);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
- `mu`: Gravitational parameter (km³/s²)
|
|
84
|
+
- Default: `Earth.mu` (398600.4418 km³/s²)
|
|
85
|
+
- Moon: `Moon.mu` (4902.8 km³/s²)
|
|
86
|
+
- Other bodies: Provide custom value
|
|
87
|
+
|
|
88
|
+
### Main Method: `estimate()`
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
estimate(
|
|
92
|
+
p1: Vector3D<Kilometers>,
|
|
93
|
+
p2: Vector3D<Kilometers>,
|
|
94
|
+
t1: EpochUTC,
|
|
95
|
+
t2: EpochUTC,
|
|
96
|
+
options?: { posigrade?: boolean; nRev?: number }
|
|
97
|
+
): J2000 | null
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Parameters:**
|
|
101
|
+
- `p1`, `p2`: Position vectors (km) in ECI/J2000 frame
|
|
102
|
+
- `t1`, `t2`: Epoch times (EpochUTC objects)
|
|
103
|
+
- `posigrade`:
|
|
104
|
+
- `true` = short path (transfer angle < 180°)
|
|
105
|
+
- `false` = long path (transfer angle > 180°)
|
|
106
|
+
- `nRev`: Number of complete revolutions (0, 1, 2, ...)
|
|
107
|
+
|
|
108
|
+
**Returns:**
|
|
109
|
+
- `J2000` state vector at epoch `t1` (null if solution fails)
|
|
110
|
+
|
|
111
|
+
### Understanding the Output
|
|
112
|
+
|
|
113
|
+
The returned `J2000` object contains:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
{
|
|
117
|
+
epoch: EpochUTC, // Time of the state
|
|
118
|
+
position: Vector3D<Kilometers>, // Position (km)
|
|
119
|
+
velocity: Vector3D<KilometersPerSecond> // Velocity (km/s)
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Key Methods:**
|
|
124
|
+
```typescript
|
|
125
|
+
stateVector.toClassicalElements() // Convert to orbital elements
|
|
126
|
+
stateVector.magnitude // Position magnitude
|
|
127
|
+
stateVector.velocity.magnitude // Speed
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Integration Workflows
|
|
133
|
+
|
|
134
|
+
### Workflow 1: Direct Use with Numerical Propagators (Recommended)
|
|
135
|
+
|
|
136
|
+
**Best for:** High-precision orbit propagation without TLE constraints
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { LambertIOD, RungeKutta89Propagator, ForceModel, EpochUTC } from 'ootk';
|
|
140
|
+
|
|
141
|
+
// 1. Solve Lambert's problem
|
|
142
|
+
const lambert = new LambertIOD();
|
|
143
|
+
const j2000State = lambert.estimate(p1, p2, t1, t2);
|
|
144
|
+
|
|
145
|
+
if (!j2000State) {
|
|
146
|
+
throw new Error('Lambert solution failed');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 2. Set up force model for propagation
|
|
150
|
+
const forceModel = new ForceModel();
|
|
151
|
+
forceModel.setEarthGravity(8, 8); // 8x8 gravity harmonics
|
|
152
|
+
forceModel.setAtmosphericDrag(); // Optional: add drag
|
|
153
|
+
forceModel.setSolarRadiationPressure(); // Optional: add SRP
|
|
154
|
+
|
|
155
|
+
// 3. Create propagator with Lambert-derived state
|
|
156
|
+
const propagator = new RungeKutta89Propagator(j2000State, forceModel);
|
|
157
|
+
|
|
158
|
+
// 4. Propagate to future epochs
|
|
159
|
+
const futureEpoch = EpochUTC.fromDateTime(new Date('2024-01-02T00:00:00.000Z'));
|
|
160
|
+
const futureState = propagator.propagate(futureEpoch);
|
|
161
|
+
|
|
162
|
+
console.log('Future position:', futureState.position);
|
|
163
|
+
console.log('Future velocity:', futureState.velocity);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Advantages:**
|
|
167
|
+
- No TLE conversion artifacts
|
|
168
|
+
- Full control over perturbation forces
|
|
169
|
+
- Higher precision for short-term propagation
|
|
170
|
+
- Direct state vector manipulation
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### Workflow 2: Convert to Satellite Object
|
|
175
|
+
|
|
176
|
+
**Best for:** Using Satellite class features (ground tracks, visibility, etc.)
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import {
|
|
180
|
+
LambertIOD,
|
|
181
|
+
ClassicalElements,
|
|
182
|
+
Tle,
|
|
183
|
+
Satellite
|
|
184
|
+
} from 'ootk';
|
|
185
|
+
|
|
186
|
+
// 1. Solve Lambert's problem
|
|
187
|
+
const lambert = new LambertIOD();
|
|
188
|
+
const j2000State = lambert.estimate(p1, p2, t1, t2);
|
|
189
|
+
|
|
190
|
+
if (!j2000State) {
|
|
191
|
+
throw new Error('Lambert solution failed');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 2. Convert to classical orbital elements
|
|
195
|
+
const elements = j2000State.toClassicalElements();
|
|
196
|
+
|
|
197
|
+
console.log('Semi-major axis:', elements.semimajorAxis, 'km');
|
|
198
|
+
console.log('Eccentricity:', elements.eccentricity);
|
|
199
|
+
console.log('Inclination:', elements.inclination, 'deg');
|
|
200
|
+
|
|
201
|
+
// 3. Generate TLE from classical elements
|
|
202
|
+
const tle = Tle.fromClassicalElements(elements);
|
|
203
|
+
|
|
204
|
+
// 4. Create Satellite object
|
|
205
|
+
const satellite = new Satellite({
|
|
206
|
+
tle1: tle.line1,
|
|
207
|
+
tle2: tle.line2,
|
|
208
|
+
name: 'Lambert-derived Satellite'
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// 5. Use Satellite methods
|
|
212
|
+
const futureState = satellite.toJ2000(new Date('2024-01-02T00:00:00.000Z'));
|
|
213
|
+
const lla = satellite.lla(new Date('2024-01-02T00:00:00.000Z'));
|
|
214
|
+
|
|
215
|
+
console.log('Latitude:', lla.lat, 'deg');
|
|
216
|
+
console.log('Longitude:', lla.lon, 'deg');
|
|
217
|
+
console.log('Altitude:', lla.alt, 'km');
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Note:** This workflow uses SGP4 for propagation after TLE conversion.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### Workflow 3: Hybrid Approach
|
|
225
|
+
|
|
226
|
+
**Best for:** Combining Lambert IOD with TLE-based satellites
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { LambertIOD, Satellite, RungeKutta89Propagator, ForceModel } from 'ootk';
|
|
230
|
+
|
|
231
|
+
// Scenario: Plan a transfer from one satellite to another
|
|
232
|
+
|
|
233
|
+
// 1. Get current states from existing satellites
|
|
234
|
+
const satellite1 = new Satellite({ tle1, tle2 });
|
|
235
|
+
const satellite2 = new Satellite({ tle1: target_tle1, tle2: target_tle2 });
|
|
236
|
+
|
|
237
|
+
const currentDate = new Date();
|
|
238
|
+
const transferDate = new Date(currentDate.getTime() + 3600000); // +1 hour
|
|
239
|
+
|
|
240
|
+
const state1 = satellite1.toJ2000(currentDate);
|
|
241
|
+
const state2 = satellite2.toJ2000(transferDate);
|
|
242
|
+
|
|
243
|
+
// 2. Solve for transfer orbit using Lambert
|
|
244
|
+
const lambert = new LambertIOD();
|
|
245
|
+
const transferOrbit = lambert.estimate(
|
|
246
|
+
state1.position,
|
|
247
|
+
state2.position,
|
|
248
|
+
state1.epoch,
|
|
249
|
+
state2.epoch,
|
|
250
|
+
{ posigrade: true, nRev: 0 }
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
if (!transferOrbit) {
|
|
254
|
+
throw new Error('No transfer solution found');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// 3. Calculate delta-V required
|
|
258
|
+
const deltaV1 = transferOrbit.velocity.subtract(state1.velocity);
|
|
259
|
+
console.log('Delta-V magnitude:', deltaV1.magnitude, 'km/s');
|
|
260
|
+
|
|
261
|
+
// 4. Propagate transfer orbit with high precision
|
|
262
|
+
const forceModel = new ForceModel();
|
|
263
|
+
forceModel.setEarthGravity(20, 20);
|
|
264
|
+
const propagator = new RungeKutta89Propagator(transferOrbit, forceModel);
|
|
265
|
+
|
|
266
|
+
const arrivalState = propagator.propagate(state2.epoch);
|
|
267
|
+
const deltaV2 = state2.velocity.subtract(arrivalState.velocity);
|
|
268
|
+
|
|
269
|
+
console.log('Arrival delta-V:', deltaV2.magnitude, 'km/s');
|
|
270
|
+
console.log('Total delta-V:', deltaV1.magnitude + deltaV2.magnitude, 'km/s');
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Complete Examples
|
|
276
|
+
|
|
277
|
+
### Example 1: Orbit Determination from Two Observations
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import {
|
|
281
|
+
LambertIOD,
|
|
282
|
+
EpochUTC,
|
|
283
|
+
Vector3D,
|
|
284
|
+
Kilometers,
|
|
285
|
+
ClassicalElements
|
|
286
|
+
} from 'ootk';
|
|
287
|
+
|
|
288
|
+
// Observation data from radar/optical tracking
|
|
289
|
+
const observation1 = {
|
|
290
|
+
time: new Date('2024-01-01T12:00:00.000Z'),
|
|
291
|
+
position: new Vector3D<Kilometers>(6778.137, 0.0, 0.0) // ECI coordinates
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const observation2 = {
|
|
295
|
+
time: new Date('2024-01-01T13:30:00.000Z'),
|
|
296
|
+
position: new Vector3D<Kilometers>(-2000.0, 6400.0, 1500.0)
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Convert times to EpochUTC
|
|
300
|
+
const epoch1 = EpochUTC.fromDateTime(observation1.time);
|
|
301
|
+
const epoch2 = EpochUTC.fromDateTime(observation2.time);
|
|
302
|
+
|
|
303
|
+
// Solve for the orbit
|
|
304
|
+
const lambert = new LambertIOD();
|
|
305
|
+
const orbit = lambert.estimate(
|
|
306
|
+
observation1.position,
|
|
307
|
+
observation2.position,
|
|
308
|
+
epoch1,
|
|
309
|
+
epoch2,
|
|
310
|
+
{ posigrade: true, nRev: 0 }
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
if (orbit) {
|
|
314
|
+
// Extract orbital elements
|
|
315
|
+
const elements = orbit.toClassicalElements();
|
|
316
|
+
|
|
317
|
+
console.log('=== Determined Orbit ===');
|
|
318
|
+
console.log('Epoch:', orbit.epoch.toISOString());
|
|
319
|
+
console.log('Position (km):', orbit.position.x, orbit.position.y, orbit.position.z);
|
|
320
|
+
console.log('Velocity (km/s):', orbit.velocity.x, orbit.velocity.y, orbit.velocity.z);
|
|
321
|
+
console.log('\n=== Classical Elements ===');
|
|
322
|
+
console.log('Semi-major axis:', elements.semimajorAxis.toFixed(3), 'km');
|
|
323
|
+
console.log('Eccentricity:', elements.eccentricity.toFixed(6));
|
|
324
|
+
console.log('Inclination:', elements.inclination.toFixed(3), 'deg');
|
|
325
|
+
console.log('RAAN:', elements.rightAscension.toFixed(3), 'deg');
|
|
326
|
+
console.log('Arg of Perigee:', elements.argOfPerigee.toFixed(3), 'deg');
|
|
327
|
+
console.log('True Anomaly:', elements.trueAnomaly.toFixed(3), 'deg');
|
|
328
|
+
|
|
329
|
+
// Calculate orbital period
|
|
330
|
+
const period = elements.period;
|
|
331
|
+
console.log('Orbital Period:', (period / 60).toFixed(2), 'minutes');
|
|
332
|
+
} else {
|
|
333
|
+
console.error('Lambert solution failed - check input geometry');
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Example 2: Multi-Revolution Transfer
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { LambertIOD, EpochUTC, Vector3D, Kilometers } from 'ootk';
|
|
341
|
+
|
|
342
|
+
// LEO to GEO transfer with one complete revolution
|
|
343
|
+
const leoPosition = new Vector3D<Kilometers>(6778, 0, 0); // ~400 km altitude
|
|
344
|
+
const geoPosition = new Vector3D<Kilometers>(42164, 0, 0); // GEO altitude
|
|
345
|
+
|
|
346
|
+
const t1 = EpochUTC.fromDateTime(new Date('2024-01-01T00:00:00.000Z'));
|
|
347
|
+
const t2 = EpochUTC.fromDateTime(new Date('2024-01-01T12:00:00.000Z'));
|
|
348
|
+
|
|
349
|
+
const lambert = new LambertIOD();
|
|
350
|
+
|
|
351
|
+
// Compare different revolution options
|
|
352
|
+
for (let nRev = 0; nRev <= 2; nRev++) {
|
|
353
|
+
const solution = lambert.estimate(leoPosition, geoPosition, t1, t2, {
|
|
354
|
+
posigrade: true,
|
|
355
|
+
nRev
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
if (solution) {
|
|
359
|
+
const elements = solution.toClassicalElements();
|
|
360
|
+
console.log(`\n=== ${nRev}-Revolution Transfer ===`);
|
|
361
|
+
console.log('Departure V:', solution.velocity.magnitude.toFixed(3), 'km/s');
|
|
362
|
+
console.log('Semi-major axis:', elements.semimajorAxis.toFixed(1), 'km');
|
|
363
|
+
console.log('Eccentricity:', elements.eccentricity.toFixed(4));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Example 3: Rendezvous Planning with Time Window
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
import {
|
|
372
|
+
LambertIOD,
|
|
373
|
+
Satellite,
|
|
374
|
+
EpochUTC,
|
|
375
|
+
Vector3D,
|
|
376
|
+
Kilometers,
|
|
377
|
+
KilometersPerSecond
|
|
378
|
+
} from 'ootk';
|
|
379
|
+
|
|
380
|
+
// ISS TLE (example - use current TLE in practice)
|
|
381
|
+
const iss = new Satellite({
|
|
382
|
+
name: 'ISS',
|
|
383
|
+
tle1: '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9005',
|
|
384
|
+
tle2: '2 25544 51.6400 208.9163 0006317 69.9862 25.2906 15.54225995 67973'
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Chaser spacecraft initial state
|
|
388
|
+
const chaserStart = new Date('2024-01-01T00:00:00.000Z');
|
|
389
|
+
const chaserState = new Vector3D<Kilometers>(6778, 100, 50); // Slightly offset
|
|
390
|
+
const chaserVelocity = new Vector3D<KilometersPerSecond>(0, 7.5, 0.1);
|
|
391
|
+
|
|
392
|
+
// Find optimal transfer time (test multiple windows)
|
|
393
|
+
const lambert = new LambertIOD();
|
|
394
|
+
const transferTimes = [1800, 3600, 5400, 7200]; // 30, 60, 90, 120 minutes
|
|
395
|
+
|
|
396
|
+
let bestSolution = null;
|
|
397
|
+
let minDeltaV = Infinity;
|
|
398
|
+
|
|
399
|
+
for (const dt of transferTimes) {
|
|
400
|
+
const rendezvousTime = new Date(chaserStart.getTime() + dt * 1000);
|
|
401
|
+
const issState = iss.toJ2000(rendezvousTime);
|
|
402
|
+
|
|
403
|
+
const solution = lambert.estimate(
|
|
404
|
+
chaserState,
|
|
405
|
+
issState.position,
|
|
406
|
+
EpochUTC.fromDateTime(chaserStart),
|
|
407
|
+
issState.epoch,
|
|
408
|
+
{ posigrade: true, nRev: 0 }
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
if (solution) {
|
|
412
|
+
const deltaV = solution.velocity.subtract(chaserVelocity).magnitude;
|
|
413
|
+
|
|
414
|
+
console.log(`Transfer time: ${dt/60} min, Delta-V: ${deltaV.toFixed(3)} km/s`);
|
|
415
|
+
|
|
416
|
+
if (deltaV < minDeltaV) {
|
|
417
|
+
minDeltaV = deltaV;
|
|
418
|
+
bestSolution = { solution, dt, issState };
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (bestSolution) {
|
|
424
|
+
console.log(`\n=== Optimal Rendezvous ===`);
|
|
425
|
+
console.log('Transfer time:', bestSolution.dt / 60, 'minutes');
|
|
426
|
+
console.log('Required delta-V:', minDeltaV.toFixed(3), 'km/s');
|
|
427
|
+
console.log('Intercept position:', bestSolution.issState.position);
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Example 4: Moon Transfer Trajectory
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import { LambertIOD, EpochUTC, Vector3D, Kilometers, Moon } from 'ootk';
|
|
435
|
+
|
|
436
|
+
// Use Moon's gravitational parameter for cislunar trajectory
|
|
437
|
+
const lambert = new LambertIOD(Moon.mu);
|
|
438
|
+
|
|
439
|
+
// Earth-Moon transfer positions (simplified)
|
|
440
|
+
const earthDeparture = new Vector3D<Kilometers>(6778, 0, 0); // LEO
|
|
441
|
+
const moonArrival = new Vector3D<Kilometers>(384400, 0, 0); // ~Moon distance
|
|
442
|
+
|
|
443
|
+
const t1 = EpochUTC.fromDateTime(new Date('2024-01-01T00:00:00.000Z'));
|
|
444
|
+
const t2 = EpochUTC.fromDateTime(new Date('2024-01-04T00:00:00.000Z')); // 3-day transfer
|
|
445
|
+
|
|
446
|
+
const solution = lambert.estimate(earthDeparture, moonArrival, t1, t2, {
|
|
447
|
+
posigrade: true,
|
|
448
|
+
nRev: 0
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
if (solution) {
|
|
452
|
+
const elements = solution.toClassicalElements();
|
|
453
|
+
|
|
454
|
+
console.log('=== Trans-Lunar Injection ===');
|
|
455
|
+
console.log('Departure velocity:', solution.velocity.magnitude.toFixed(3), 'km/s');
|
|
456
|
+
console.log('Escape velocity at LEO:', (Math.sqrt(2 * 398600.4418 / 6778)).toFixed(3), 'km/s');
|
|
457
|
+
console.log('Transfer orbit apogee:',
|
|
458
|
+
(elements.semimajorAxis * (1 + elements.eccentricity)).toFixed(0), 'km');
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Advanced Usage
|
|
465
|
+
|
|
466
|
+
### Path Selection: Short vs Long
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
import { LambertIOD, J2000 } from 'ootk';
|
|
470
|
+
|
|
471
|
+
const lambert = new LambertIOD();
|
|
472
|
+
|
|
473
|
+
// Method 1: Manual selection
|
|
474
|
+
const shortPath = lambert.estimate(p1, p2, t1, t2, { posigrade: true });
|
|
475
|
+
const longPath = lambert.estimate(p1, p2, t1, t2, { posigrade: false });
|
|
476
|
+
|
|
477
|
+
// Method 2: Automatic optimal path selection
|
|
478
|
+
const interceptor = new J2000(t1, p1, v1); // Current state
|
|
479
|
+
const target = new J2000(t2, p2, v2); // Target state
|
|
480
|
+
|
|
481
|
+
const useShort = LambertIOD.useShortPath(interceptor, target);
|
|
482
|
+
const optimalSolution = lambert.estimate(p1, p2, t1, t2, {
|
|
483
|
+
posigrade: useShort
|
|
484
|
+
});
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Error Handling
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
const solution = lambert.estimate(p1, p2, t1, t2);
|
|
491
|
+
|
|
492
|
+
if (!solution) {
|
|
493
|
+
// Solution failed - possible reasons:
|
|
494
|
+
// 1. Positions are too close (collinear)
|
|
495
|
+
// 2. Time of flight too short/long for geometry
|
|
496
|
+
// 3. Numerical convergence failure
|
|
497
|
+
// 4. Hyperbolic trajectory (|x| >= 1)
|
|
498
|
+
|
|
499
|
+
console.error('Lambert solution failed');
|
|
500
|
+
|
|
501
|
+
// Diagnostics
|
|
502
|
+
const distance = p2.subtract(p1).magnitude;
|
|
503
|
+
const timeOfFlight = (t2.toDateTime().getTime() - t1.toDateTime().getTime()) / 1000;
|
|
504
|
+
|
|
505
|
+
console.log('Distance between positions:', distance, 'km');
|
|
506
|
+
console.log('Time of flight:', timeOfFlight, 'seconds');
|
|
507
|
+
|
|
508
|
+
// Try increasing time or adjusting positions
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Iterative Optimization for Specific Constraints
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
import { LambertIOD, EpochUTC, Vector3D, Kilometers } from 'ootk';
|
|
516
|
+
|
|
517
|
+
// Find transfer time for specific delta-V budget
|
|
518
|
+
function findTransferTime(
|
|
519
|
+
p1: Vector3D<Kilometers>,
|
|
520
|
+
p2: Vector3D<Kilometers>,
|
|
521
|
+
t1: EpochUTC,
|
|
522
|
+
currentVelocity: Vector3D<KilometersPerSecond>,
|
|
523
|
+
maxDeltaV: number,
|
|
524
|
+
maxTimeHours: number
|
|
525
|
+
): { transferTime: number; solution: J2000 } | null {
|
|
526
|
+
|
|
527
|
+
const lambert = new LambertIOD();
|
|
528
|
+
const startMs = t1.toDateTime().getTime();
|
|
529
|
+
|
|
530
|
+
// Binary search for optimal time
|
|
531
|
+
let low = 300; // 5 minutes minimum
|
|
532
|
+
let high = maxTimeHours * 3600;
|
|
533
|
+
|
|
534
|
+
while (high - low > 60) { // 1-minute precision
|
|
535
|
+
const mid = Math.floor((low + high) / 2);
|
|
536
|
+
const t2 = EpochUTC.fromDateTime(new Date(startMs + mid * 1000));
|
|
537
|
+
|
|
538
|
+
const solution = lambert.estimate(p1, p2, t1, t2, { posigrade: true });
|
|
539
|
+
|
|
540
|
+
if (solution) {
|
|
541
|
+
const deltaV = solution.velocity.subtract(currentVelocity).magnitude;
|
|
542
|
+
|
|
543
|
+
if (deltaV <= maxDeltaV) {
|
|
544
|
+
high = mid; // Can do it faster
|
|
545
|
+
} else {
|
|
546
|
+
low = mid; // Need more time
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
low = mid;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const finalT2 = EpochUTC.fromDateTime(new Date(startMs + high * 1000));
|
|
554
|
+
const finalSolution = lambert.estimate(p1, p2, t1, finalT2, { posigrade: true });
|
|
555
|
+
|
|
556
|
+
if (finalSolution) {
|
|
557
|
+
return { transferTime: high, solution: finalSolution };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Combining with Force Models
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
import {
|
|
568
|
+
LambertIOD,
|
|
569
|
+
RungeKutta89Propagator,
|
|
570
|
+
ForceModel,
|
|
571
|
+
EpochUTC
|
|
572
|
+
} from 'ootk';
|
|
573
|
+
|
|
574
|
+
// 1. Get initial estimate from Lambert
|
|
575
|
+
const lambert = new LambertIOD();
|
|
576
|
+
const initialOrbit = lambert.estimate(p1, p2, t1, t2);
|
|
577
|
+
|
|
578
|
+
if (!initialOrbit) {
|
|
579
|
+
throw new Error('No solution');
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// 2. Set up high-fidelity force model
|
|
583
|
+
const forceModel = new ForceModel();
|
|
584
|
+
forceModel.setEarthGravity(20, 20); // High-order gravity
|
|
585
|
+
forceModel.setThirdBody(true); // Sun/Moon perturbations
|
|
586
|
+
forceModel.setAtmosphericDrag(2.2, 0.01); // Drag (Cd, area/mass)
|
|
587
|
+
forceModel.setSolarRadiationPressure(1.2, 0.02); // SRP
|
|
588
|
+
|
|
589
|
+
// 3. Propagate with perturbations
|
|
590
|
+
const propagator = new RungeKutta89Propagator(initialOrbit, forceModel);
|
|
591
|
+
const highFidelityState = propagator.propagate(t2);
|
|
592
|
+
|
|
593
|
+
// 4. Check accuracy against target
|
|
594
|
+
const positionError = highFidelityState.position.subtract(p2).magnitude;
|
|
595
|
+
console.log('Position error:', positionError, 'km');
|
|
596
|
+
|
|
597
|
+
// 5. Optional: Iterate to refine solution
|
|
598
|
+
if (positionError > 1.0) { // More than 1 km error
|
|
599
|
+
// Re-solve Lambert with adjusted target
|
|
600
|
+
const correctedTarget = p2.add(
|
|
601
|
+
highFidelityState.position.subtract(p2).scale(0.5)
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
const refinedOrbit = lambert.estimate(p1, correctedTarget, t1, t2);
|
|
605
|
+
// Continue iteration...
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## Best Practices
|
|
612
|
+
|
|
613
|
+
### 1. Choose the Right Workflow
|
|
614
|
+
|
|
615
|
+
| Use Case | Recommended Approach |
|
|
616
|
+
|----------|---------------------|
|
|
617
|
+
| High-precision orbit propagation | J2000 + RungeKutta89Propagator |
|
|
618
|
+
| Quick orbit estimation | J2000 + ClassicalElements |
|
|
619
|
+
| Ground track visualization | J2000 → TLE → Satellite |
|
|
620
|
+
| Transfer planning | Lambert + direct delta-V calculation |
|
|
621
|
+
| Real-time operations | Cache Lambert solutions |
|
|
622
|
+
|
|
623
|
+
### 2. Validate Solutions
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
// Always check for null returns
|
|
627
|
+
const solution = lambert.estimate(p1, p2, t1, t2);
|
|
628
|
+
if (!solution) {
|
|
629
|
+
// Handle failure gracefully
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Verify solution makes physical sense
|
|
634
|
+
const elements = solution.toClassicalElements();
|
|
635
|
+
if (elements.eccentricity >= 1.0) {
|
|
636
|
+
console.warn('Hyperbolic trajectory detected');
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (elements.semimajorAxis < 6378) {
|
|
640
|
+
console.error('Orbit intersects Earth!');
|
|
641
|
+
}
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### 3. Time of Flight Considerations
|
|
645
|
+
|
|
646
|
+
- **Too short**: May not have physical solution
|
|
647
|
+
- **Too long**: Multiple revolution solutions possible
|
|
648
|
+
- **Rule of thumb**: Time should be 0.1 to 10 orbital periods
|
|
649
|
+
|
|
650
|
+
### 4. Numerical Stability
|
|
651
|
+
|
|
652
|
+
The Lambert solver uses:
|
|
653
|
+
- Householder's method (3rd order convergence)
|
|
654
|
+
- Tolerance: 1e-13
|
|
655
|
+
- Max iterations: 50
|
|
656
|
+
|
|
657
|
+
Most solutions converge in < 10 iterations.
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Troubleshooting
|
|
662
|
+
|
|
663
|
+
### Problem: Lambert returns null
|
|
664
|
+
|
|
665
|
+
**Causes:**
|
|
666
|
+
1. Positions nearly collinear
|
|
667
|
+
2. Time of flight incompatible with geometry
|
|
668
|
+
3. Numerical convergence issues
|
|
669
|
+
|
|
670
|
+
**Solutions:**
|
|
671
|
+
```typescript
|
|
672
|
+
// Check input validity
|
|
673
|
+
const r1 = p1.magnitude;
|
|
674
|
+
const r2 = p2.magnitude;
|
|
675
|
+
const c = p2.subtract(p1).magnitude; // Chord
|
|
676
|
+
|
|
677
|
+
// Triangle inequality must hold
|
|
678
|
+
if (c >= r1 + r2 || c <= Math.abs(r1 - r2)) {
|
|
679
|
+
console.error('Invalid geometry');
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Try different time of flight
|
|
683
|
+
const minTOF = Math.PI * Math.sqrt(Math.pow((r1 + r2 + c) / 2, 3) / mu);
|
|
684
|
+
console.log('Minimum TOF:', minTOF, 'seconds');
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Problem: Large delta-V requirements
|
|
688
|
+
|
|
689
|
+
**Cause:** Inefficient transfer geometry
|
|
690
|
+
|
|
691
|
+
**Solution:**
|
|
692
|
+
```typescript
|
|
693
|
+
// Try multiple revolution transfers
|
|
694
|
+
for (let nRev = 0; nRev <= 2; nRev++) {
|
|
695
|
+
const sol = lambert.estimate(p1, p2, t1, t2, { nRev });
|
|
696
|
+
if (sol) {
|
|
697
|
+
console.log(`${nRev} revs: ${sol.velocity.magnitude} km/s`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Or adjust transfer time
|
|
702
|
+
const adjustedT2 = new EpochUTC(t2.toDateTime().getTime() + 3600000);
|
|
703
|
+
const betterSol = lambert.estimate(p1, p2, t1, adjustedT2);
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Problem: TLE conversion artifacts
|
|
707
|
+
|
|
708
|
+
**Cause:** Classical elements → TLE conversion limitations
|
|
709
|
+
|
|
710
|
+
**Solution:**
|
|
711
|
+
Use numerical propagators directly instead of Satellite class:
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
// Instead of:
|
|
715
|
+
const tle = Tle.fromClassicalElements(elements);
|
|
716
|
+
const sat = new Satellite({ tle1: tle.line1, tle2: tle.line2 });
|
|
717
|
+
|
|
718
|
+
// Use:
|
|
719
|
+
const propagator = new RungeKutta89Propagator(j2000State, forceModel);
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## Performance Tips
|
|
725
|
+
|
|
726
|
+
1. **Reuse Lambert instances**: Constructor is lightweight
|
|
727
|
+
2. **Cache solutions**: Lambert solve is ~microseconds, but caching helps for repeated queries
|
|
728
|
+
3. **Use appropriate propagators**:
|
|
729
|
+
- Keplerian: Fastest, no perturbations
|
|
730
|
+
- RK4: Medium speed, fixed step
|
|
731
|
+
- RK89: Adaptive step, best accuracy
|
|
732
|
+
- SGP4: For TLE-based satellites only
|
|
733
|
+
|
|
734
|
+
4. **Parallel processing**: Lambert solutions are independent
|
|
735
|
+
|
|
736
|
+
```typescript
|
|
737
|
+
const transfers = await Promise.all(
|
|
738
|
+
targets.map(target =>
|
|
739
|
+
Promise.resolve(lambert.estimate(start, target, t1, t2))
|
|
740
|
+
)
|
|
741
|
+
);
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## References
|
|
747
|
+
|
|
748
|
+
- Lambert solver: `/home/user/ootk/src/orbit_determination/LambertIOD.ts:1`
|
|
749
|
+
- J2000 class: `/home/user/ootk/src/coordinate/J2000.ts:1`
|
|
750
|
+
- RungeKutta89: `/home/user/ootk/src/propagator/RungeKutta89Propagator.ts:1`
|
|
751
|
+
- ClassicalElements: `/home/user/ootk/src/coordinate/ClassicalElements.ts:1`
|
|
752
|
+
- Examples: `/home/user/ootk/examples/iod.ts:1`
|
|
753
|
+
|
|
754
|
+
---
|
|
755
|
+
|
|
756
|
+
## Summary
|
|
757
|
+
|
|
758
|
+
Lambert integration provides a powerful alternative to SGP4 for state vector generation:
|
|
759
|
+
|
|
760
|
+
✅ **Direct state vector generation** from position observations
|
|
761
|
+
✅ **Transfer orbit design** without TLE requirements
|
|
762
|
+
✅ **High-precision propagation** using numerical integrators
|
|
763
|
+
✅ **Flexible force modeling** for perturbation analysis
|
|
764
|
+
✅ **Seamless integration** with existing OOTK components
|
|
765
|
+
|
|
766
|
+
For most applications involving precise orbit determination or maneuver planning, using Lambert with numerical propagators provides superior accuracy compared to TLE-based SGP4 propagation.
|