{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Laplace IOD based range calculation for IOD Gooding\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Satellite Dictionary\n", "sat_list = { \n", " 'oneweb': {\n", " 'norad_id': 48042, # For Space-Track TLE queries\n", " 'cospar_id': '0200901', # For laser ranging data queries\n", " 'sic_id': '6179', # For writing in CPF files\n", " 'mass': 200.0, # kg; TODO: compute proper value\n", " 'cross_section': 1.0, # m2; TODO: compute proper value\n", " 'cd': 2.0, # Drag coefficient; TODO: compute proper value\n", " 'cr': 1.0 # Radiation coefficient; TODO: compute proper value\n", " },\n", " 'starlink45185': {\n", " 'norad_id': 45185,\n", " 'cospar_id': '2001208',\n", " 'sic_id': '5986', # TODO: correct it\n", " 'mass': 260.0, # kg\n", " 'cross_section': 5.0, # m2\n", " 'cd': 1.0, # TODO: compute proper value\n", " 'cr': 1.0 # TODO: compute proper value\n", " },\n", " 'ISS': {\n", " 'norad_id': 25544,\n", " 'cospar_id': '1704205',\n", " 'sic_id': '6203',\n", " 'mass': 419725.0, # kg\n", " 'cross_section': 0.10, # m2,\n", " 'cd': 2.0, # TODO: compute proper value\n", " 'cr': 1.0 # TODO: compute proper value\n", " },\n", " 'starlink53058': {\n", " 'norad_id': 53058,\n", " 'cospar_id': '1801410',\n", " 'sic_id': '6204',\n", " 'mass': 260.0, # kg\n", " 'cross_section': 5.0, # m2\n", " 'cd': 1.0, # TODO: compute proper value\n", " 'cr': 1.0 # TODO: compute proper value\n", " }\n", "}\n", "\n", "sc_name = 'oneweb' # Change the name to select a different satellite in the dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Orbit determination parameters" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime, timedelta\n", "import numpy as np\n", "from math import radians, pi, degrees, sin, cos, sqrt, acos\n", "\n", "################################################\n", "odDate = datetime(2023, 4, 7) # Beginning of the OD, CHANGE EACH TIME!!\n", "################################################\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting Up Orekit Models\n", "Initializing Orekit and JVM" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import orekit\n", "orekit.initVM()\n", "\n", "import warnings # To surpress warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "# Modified from https://gitlab.orekit.org/orekit-labs/python-wrapper/blob/master/python_files/pyhelpers.py\n", "from java.io import File\n", "from org.orekit.data import DataProvidersManager, DirectoryCrawler, DataContext\n", "from orekit import JArray\n", "\n", "orekit_data_dir = 'orekit-data'\n", "#DM = DataProvidersManager.getInstance() \n", "DM = DataContext.getDefault().getDataProvidersManager()\n", "datafile = File(orekit_data_dir)\n", "if not datafile.exists():\n", " print('Directory :', datafile.absolutePath, ' not found')\n", "\n", "crawler = DirectoryCrawler(datafile)\n", "DM.clearProviders()\n", "DM.addProvider(crawler)\n", "\n", "# Orekit packages\n", "from org.orekit.propagation.analytical.tle import TLE, TLEPropagator, SGP4\n", "from org.orekit.propagation import SpacecraftState\n", "from org.orekit.utils import Constants, IERSConventions, PVCoordinatesProvider, PVCoordinates\n", "from org.orekit.frames import FramesFactory, ITRFVersion, TopocentricFrame, LocalOrbitalFrame, LOFType\n", "from org.orekit.models.earth import ReferenceEllipsoid\n", "from org.orekit.bodies import CelestialBodyFactory, OneAxisEllipsoid, GeodeticPoint\n", "from org.orekit.time import AbsoluteDate, TimeScalesFactory\n", "from org.orekit.attitudes import NadirPointing\n", "from org.orekit.orbits import CartesianOrbit, PositionAngle, KeplerianOrbit, OrbitType, Orbit\n", "from org.orekit.propagation.conversion import DormandPrince853IntegratorBuilder, NumericalPropagatorBuilder, TLEPropagatorBuilder, FiniteDifferencePropagatorConverter\n", "from org.orekit.estimation.measurements import EstimatedMeasurement, GroundStation, ObservableSatellite, PV, ObservableSatellite, AngularRaDec\n", "from org.orekit.estimation.leastsquares import BatchLSEstimator\n", "from org.orekit.estimation.iod import IodLaplace\n", "from orekit import JArray_double\n", "from orekit.pyhelpers import absolutedate_to_datetime, datetime_to_absolutedate, JArray\n", "\n", "from org.hipparchus.ode.nonstiff import DormandPrince853Integrator\n", "from org.orekit.propagation.conversion import DormandPrince853IntegratorBuilder, NumericalPropagatorBuilder\n", "from org.orekit.propagation.numerical import NumericalPropagator\n", "from org.orekit.forces.gravity.potential import GravityFieldFactory\n", "from org.orekit.forces.gravity import HolmesFeatherstoneAttractionModel, ThirdBodyAttraction, Relativity, OceanTides, SolidTides\n", "from org.orekit.forces.drag import DragForce, DragSensitive, IsotropicDrag \n", "from org.orekit.forces.radiation import SolarRadiationPressure, IsotropicRadiationClassicalConvention, IsotropicRadiationSingleCoefficient\n", "from org.orekit.models.earth.atmosphere import JB2008, NRLMSISE00, DTM2000\n", "from org.orekit.models.earth.atmosphere.data import CssiSpaceWeatherData, MarshallSolarActivityFutureEstimation\n", "\n", "# Hipparchus packages\n", "from org.hipparchus.linear import QRDecomposer\n", "from org.hipparchus.optim.nonlinear.vector.leastsquares import GaussNewtonOptimizer, LevenbergMarquardtOptimizer\n", "from org.hipparchus.geometry.euclidean.threed import Vector3D\n", "from java.util import ArrayList, Arrays\n", "\n", "# Misc packages\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "from math import radians, pi, degrees, sin, cos, sqrt, acos\n", "import seaborn as sns\n", "import numpy as np\n", "import datetime" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Setting up Orekit frames and models" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "tod = FramesFactory.getTOD(IERSConventions.IERS_2010, False) # Taking tidal effects into account when interpolating EOP parameters\n", "gcrf = FramesFactory.getGCRF()\n", "itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, False)\n", "eci = gcrf\n", "ECI = eci\n", "ecef = itrf\n", "TEME = FramesFactory.getTEME()\n", "\n", "R_earth = Constants.WGS84_EARTH_EQUATORIAL_RADIUS\n", "Mu_earth = Constants.WGS84_EARTH_MU\n", "F_earth = Constants.WGS84_EARTH_FLATTENING\n", "earth = OneAxisEllipsoid(R_earth, F_earth, itrf) # Define earth body for later use.\n", "\n", "wgs84Ellipsoid = ReferenceEllipsoid.getWgs84(ecef)\n", "\n", "moon = CelestialBodyFactory.getMoon()\n", "sun = CelestialBodyFactory.getSun()\n", "\n", "nadirPointing = NadirPointing(eci, wgs84Ellipsoid) # Set the attitude to nadir pointing\n", "\n", "UTC = TimeScalesFactory.getUTC()\n", "mjd_utc_epoch = AbsoluteDate(1858, 11, 17, 0, 0, 0.0, UTC)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# IOD Solution from Observations " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observations are first fetched and transfer to a data frame. Then the Preliminary Orbit Determination with Laplace method takes place. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1mGathered IOD data: \n", "\u001b[0m\n", "48042 21 025AS 4171 G 20230407233818603 17 25 1022717+832681 37 S\n", "48042 21 025AS 4171 G 20230407233825285 17 25 0938235+844641 37 S\n", "48042 21 025AS 4171 G 20230407233835331 17 25 0746692+860423 37 S\n", "48042 21 025AS 4171 G 20230407233845376 17 25 0524323+855897 37 S\n", "48042 21 025AS 4171 G 20230407233855424 17 25 0346237+844327 37 S\n", "48042 21 025AS 4171 G 20230407233903209 17 25 0302927+832370 37 S\n" ] }, { "data": { "text/html": [ "
\n", " | NoradID | \n", "UTC Date | \n", "Ra (deg) | \n", "Dec (deg) | \n", "
---|---|---|---|---|
0 | \n", "48042 | \n", "2023-04-07 23:38:18.603 | \n", "155.67925 | \n", "83.446833 | \n", "
1 | \n", "48042 | \n", "2023-04-07 23:38:25.285 | \n", "144.55875 | \n", "84.773500 | \n", "
2 | \n", "48042 | \n", "2023-04-07 23:38:35.331 | \n", "116.67300 | \n", "86.070500 | \n", "
3 | \n", "48042 | \n", "2023-04-07 23:38:45.376 | \n", "81.08075 | \n", "85.982833 | \n", "
4 | \n", "48042 | \n", "2023-04-07 23:38:55.424 | \n", "56.55925 | \n", "84.721167 | \n", "
5 | \n", "48042 | \n", "2023-04-07 23:39:03.209 | \n", "45.73175 | \n", "83.395000 | \n", "