Hi Everyone,
I am playing with a script about the visibility of 2 Walker constellations from 2 ground stations using PropagatorsParallelizer. I have found the other script about PropagatorsParallelizer very helpful and was able to get my script running on my laptop. However, when I am launching the same script from my new desktop, I am hitting the following JavaError:
Traceback (most recent call last):
File “Test_TTC_Walker.py”, line 166, in
_ = parallelizer.propagate(extrap_date, final_date)
orekit.JavaError: <super: <class ‘JavaError’>, >
Java stacktrace:
java.lang.RuntimeException: TypeError
at org.orekit.propagation.sampling.PythonMultiSatStepHandler.handleStep(Native Method)
at org.orekit.propagation.PropagatorsParallelizer.propagate(PropagatorsParallelizer.java:180)
I did import the same conda env from my laptop to my desktop. Attached please find my code
Thanks!
Wenhao
import orekit
vm = orekit.initVM()
from orekit.pyhelpers import setup_orekit_curdir, absolutedate_to_datetime
setup_orekit_curdir()
from org.orekit.propagation.analytical.tle import TLE, TLEPropagator
from org.orekit.propagation.analytical import KeplerianPropagator
from org.orekit.propagation.events import ElevationDetector, EventsLogger
from org.orekit.propagation.events.handlers import ContinueOnEvent
from org.orekit.propagation import PropagatorsParallelizer, SpacecraftState, PythonAdditionalStateProvider
from org.orekit.propagation.sampling import PythonMultiSatStepHandler
from org.orekit.orbits import CartesianOrbit, KeplerianOrbit, OrbitType, PositionAngle
from org.orekit.frames import FramesFactory, TopocentricFrame
from org.orekit.utils import Constants, IERSConventions
from org.orekit.bodies import OneAxisEllipsoid, GeodeticPoint
from org.orekit.time import TimeScalesFactory, AbsoluteDate
from java.util import Arrays
from orekit import JArray_double
from math import pi, degrees, radians
import numpy as np
import datetime
import pandas as pd
config = pd.DataFrame()
config['constellation'] = [0, 1]
config['name'] = ['OneWeb', 'Galileo']
config['total'] = [588, 24]
config['plane'] = [12, 3]
config['f'] = [1, 1]
config['type'] = ['Star', 'Delta']
# https://celestrak.com/NORAD/elements/oneweb.txt: ONEWEB-0012 (LEO). Note that for Walker Star constellation, should use a seed satellite from "plane 1". Not sure if this choice is correct. However, it does not affect the conclusion from this simulation.
# https://celestrak.com/NORAD/elements/galileo.txt: GSAT0101 (MEO)
config['tle_line1_seed'] = ['1 44057U 19010A 21242.77040566 .00019687 00000-0 46314-1 0 9997',
'1 37846U 11060A 21242.30456699 -.00000070 00000-0 00000-0 0 9997']
config['tle_line2_seed'] = ['2 44057 87.4890 245.4230 0000321 339.7858 20.3264 13.23573112120926',
'2 37846 56.8763 29.2664 0001970 60.7596 299.2674 1.70475360 61250']
dt_utc_now = datetime.datetime.utcnow()
initial_date = AbsoluteDate(dt_utc_now.year,
dt_utc_now.month,
dt_utc_now.day,
dt_utc_now.hour,
dt_utc_now.minute,
0.0 + dt_utc_now.second,
TimeScalesFactory.getUTC())
extrap_date = initial_date
final_date = extrap_date.shiftedBy(3600. * 24 * 2) # 48hours
inertial_frame = FramesFactory.getEME2000()
earth_frame = FramesFactory.getITRF(IERSConventions.IERS_2010, True)
earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
earth_frame)
def TLEToKeplerian(prop, frame, date, mu):
return KeplerianOrbit(OrbitType.KEPLERIAN.convertType(CartesianOrbit(prop.getPVCoordinates(date, frame), inertial_frame, date, mu)))
tle_seed = [TLE(config['tle_line1_seed'][i], config['tle_line2_seed'][i]) for i in range(len(config))]
config['prop_seed'] = [TLEPropagator.selectExtrapolator(tle) for tle in tle_seed]
config['orbit_kep_seed'] = config['prop_seed'].apply(lambda x: TLEToKeplerian(x, inertial_frame, extrap_date, Constants.WGS84_EARTH_MU))
ephemeris = pd.DataFrame(columns=['constellation', 'name', 'shell', 'plane', 'orbit'])
for i in range(len(config)):
# These parameters are common among all satellites within a Walker constellation
sma = config['orbit_kep_seed'][i].getA()
eccentricity = config['orbit_kep_seed'][i].getE()
inclination = config['orbit_kep_seed'][i].getI()
pa = config['orbit_kep_seed'][i].getPerigeeArgument()
# This is common among all satellites within a same plane. Offset by 2 * pi / p between planes for Walker Delta, and by pi / p for Walker star
raan = config['orbit_kep_seed'][i].getRightAscensionOfAscendingNode()
# This is offset by f * 2 * pi / t from west to east between planes, and by p * 2 * pi / t between neighboring satellites within a plane
true_anomaly = config['orbit_kep_seed'][i].getTrueAnomaly() # In Walker pattern, true anomaly is equally distributed
is_walker_delta = (config['type'][i].lower() == "delta")
n_sat_per_plane = int(config['total'][i] / config['plane'][i])
for p in range(config['plane'][i]):
if is_walker_delta:
raan_tmp = float(raan + 2 * pi / config['plane'][i] * p)
else:
raan_tmp = float(raan + pi / config['plane'][i] * p)
offset_true_anomaly = config['f'][i] * 2 * pi / config['total'][i] * p # Offset of true anomaly for the current plane w.r.t to the seed plane
true_anomaly_tmp = [float(true_anomaly + offset_true_anomaly + j * config['plane'][i] * 2 * pi / config['total'][i]) for j in range(n_sat_per_plane)]
ephemeris_tmp = pd.DataFrame()
ephemeris_tmp['orbit'] = [KeplerianOrbit(sma, eccentricity, inclination, pa, raan_tmp, true_anomaly_tmp[j],
PositionAngle.TRUE, inertial_frame, extrap_date, Constants.WGS84_EARTH_MU) \
for j in range(n_sat_per_plane)]
ephemeris_tmp['constellation'] = config['constellation'][i]
ephemeris_tmp['shell'] = i
ephemeris_tmp['name'] = config['name'][i]
ephemeris_tmp['plane'] = p
ephemeris = ephemeris.append(ephemeris_tmp, ignore_index=True)
ephemeris['spacecraftID'] = range(len(ephemeris))
_ = ephemeris.set_index('spacecraftID')
lat_lon_data = pd.DataFrame()
lat_lon_data['constellation'] = ephemeris['constellation']
lat_lon_data['name'] = ephemeris['name']
lat_lon_data['shell'] = ephemeris['shell']
lat_lon_data['plane'] = ephemeris['plane'].apply(lambda x: float(x))
lat_lon_data['point'] = ephemeris['orbit'].apply(lambda x: earth.transform(x.getPVCoordinates(inertial_frame).getPosition(), inertial_frame, extrap_date))
lat_lon_data['latitude'] = lat_lon_data['point'].apply(lambda x: degrees(x.getLatitude()))
lat_lon_data['longitude'] = lat_lon_data['point'].apply(lambda x: degrees(x.getLongitude()))
_ = lat_lon_data.drop('point', axis=1)
config_gs = pd.DataFrame()
lat = [34.252047, 40.957778]
lon = [109.018003, 100.291667]
alt = [418., 1079.] # https://www.advancedconverter.com/map-tools/find-altitude-by-coordinates
name_gs = ['WeiNan', 'DongFeng']
min_elev = [5, 30] # Min elevation angle in degree
config_gs['station'] = [GeodeticPoint(radians(lat[i]), radians(lon[i]), alt[i]) for i in range(len(lat))]
config_gs['frame'] = config_gs['station'].apply(lambda x: TopocentricFrame(earth, x, 'Esrange'))
config_gs['logger'] = config_gs['station'].apply(lambda x: EventsLogger())
config_gs['detector_elev'] = [config_gs['logger'][i].monitorDetector(ElevationDetector(config_gs['frame'][i]).withConstantElevation(radians(min_elev[i])).withHandler(ContinueOnEvent())) for i in range(len(config_gs))]
config_gs['name'] = name_gs
ephemeris['propagator'] = ephemeris['orbit'].apply(lambda x: KeplerianPropagator(x))
def addSpaceCraftID(row):
row['propagator'].resetInitialState(row['propagator'].getInitialState().addAdditionalState('spacecraftID', [float(row['spacecraftID'])]))
_ = ephemeris.apply(addSpaceCraftID, axis = 1)
# Add event detecctor to each individal propagator
for i in range(len(lat)):
ephemeris['propagator'].apply(lambda x: x.addEventDetector(config_gs['detector_elev'][i]))
class SimpleStepHandler(PythonMultiSatStepHandler):
def init(self, s, t):
pass
def handleStep(self, interpolators, isLast):
pass
step_handler = SimpleStepHandler()
parallelizer = PropagatorsParallelizer(Arrays.asList(ephemeris['propagator']), step_handler)
extrap_date = initial_date
final_date = extrap_date.shiftedBy(3600. * 1) # 1hr propagation takes roughly one minute on my little laptop
_ = parallelizer.propagate(extrap_date, final_date)