I was recently implementing covariance interpolation from an OEM, referencing the solution in Covariance Matrix Interpolation from OEM . The end goal of this is getting Pc parity between a SpaceTrack CDM (Ephem/Ephem) and the actual ephems that were used in that CDM.
The issue I am seeing, is that the interpolated covariance (when the input OEM covariance is in RTN) is coming out different than the CDM and also does not match with the non-interpolated values on either side of the TCA from the ephem. This seems to be only for the Radial component. My process is as follows:
I loaded in the two OEM ephems (OEM Parser → propagator), and used an ExtremumApproachDetector to get the TCA and miss distance/velocity - this matched with the CDM. I then set up a covariance interpolator similar to the link above and use it to build an Ephemeris() object. Then finally extract the interpolated covariance through the .getCovariance() method. Code as follows:
# Covariance interpolator
covariance_kep_hermite = StateCovarianceKeplerianHermiteInterpolator(
OrbitHermiteInterpolator(<EME2000>),
LOFType.QSW
)
# New propagator
ephem_propagator = Ephemeris(
<ArrayList(SpacecraftState)>, # Tabulated states from the OEM
SpacecraftStateInterpolator(5, <EME2000 Frame>), # States are in J2000
<ArrayList(StateCovariance)>, # RTN covariance built with LOFType.QSW, while J2000 covariance build as such with <EME2000>/OrbitType/PositionAngleType
covariance_kep_hermite
)
# Extract covariance at TCA
tca_java = AbsoluteDate('2026-01-23T00:58:50.750', TimeScalesFactory.getUTC())
interp_cov = ephem_propagator.getCovariance(tca_java)
# Convert interpolated covariance back into RTN/RIC to compare against CDM & OEM
interp_orbit = ephem_propagator.propagateOrbit(tca_java)
interp_cov_ric = interp_cov.changeCovarianceFrame(interp_orbit, LOFType.QSW)
This is where things get weird. My first ephem (testsat-1.oem) has states and covariance both in J2000. The interpolated covariance here matches almost exactly with the CDM. However my second ephem (testsat-2.oem) had states in J2000 and covariance in RTN. Here I can see the diagonal RIC covariance values on either side of the interpolated point and the Radial value is nowhere near the interpolated one. Note that both ephems have 1 minute steps. Here are the results:
# interp_cov_ric is from the previous block. cdm_cov is the CR_R, CT_T, CN_N values. Units are the covariance units of m^2
# testsat-1.oem -> states & covar in J2000
interp_cov_ric = [3999.9587648430606, 852573168.0795757, 2012.599168118526]
cdm_cov = [3999.885341602069, 852565808.4392604, 2007.709022392526]
# testsat-2.oem -> states in J2000, covar in RTN
interp_cov_ric = [13007.472576136963, 13170728.940087868, 27.1341201964874]
cdm_cov = [6224.041894496001, 13170283.90046027, 26.96531832610106]
# testsat-2.oem RTN diagonal covar at step BEFORE interpolated point (...00:58:42):
oem_cov_rtn_pre = [6231.1060419000005, 13161702.127, 26.870291514]
# testsat-2.oem RTN diagonal covar at step AFTER interpolated point (...00:59:42):
oem_cov_rtn_post = [6188.1730422, 13220598.384, 27.384216506999998]
Is there something wrong in my implementation that is approximately doubling the Radial covariance? The interpolator should be using the two points (as default) on either side of the interpolated one, but its value is nowhere near.
Attaching abridged ephems for reference (they produce the same results)
testsat-1.oem (7.0 KB)
testsat-2.oem (6.1 KB)