I am currently working on a orbit determination project and I’ve been using the UnscentedKalmanEstimatorBuilder to create an UnscentedKalmanEstimator. Then I process several measurements with it and get the final propagator, which is working perfectly. In addition, I am processing the measurements using the .processMeasurements([measurements]), where measurements is the Java list containing all the sensor measurements in chronological order.
However, I’ve been recently trying to use the Rauch-Tung-Striebel smoothing to try to improve the results, as in orbital determination it is considered a wise practice to smooth the filtering process. What I’ve done is the following:
I have set the observer to the Kalman filter implemented by Mark Rutten as follows:
Finally, I collect the smoothed output using the .backwardsSmooth() method of the smoother:
test_smoothed = smoother.backwardsSmooth()
The issue is the following: After doing all this, estimated_propagator contains a Propagator, which is totally fine as that is what I want as my objective is then propagate that orbit and compare it with the ground-truth orbit. But in test_smoothed I get a list of PhysicalEstimatedState and I do not know how to get the propagator from that list. As estimated_propagator is the UnscentedKalmanEstimator propagator from the orbit determination without the smoother, I want to get the final smoothed propagator from the smoother to compare how each of the two methodologies perform.
Hope I made myself clear enough. Another aspect to take into account is that I am implementing all of this using Python.
Hi! Sorry but if anyone knows anything it would be of tremendous help (maybe @markrutten knows best as he was the one who developed it). Sorry for insisting and thanks a lot in advance guys!
Hi @a.malaver . Thanks for tagging me … I don’t look at the forum as often as I should.
You’re correct, there aren’t any propagators generated as part of the smoothing process. There are typically very limited uses for the smoothed results, e.g. filter/smoother consistency, and those uses employ the smoothed covariance and the physical state, rather than propagating from them.
I think that, theoretically, the propagator you want to use (assuming that you’re predicting forward in time) is what you have access to after processing your last measurement. That is the propagator most accurately representing all of your measurements. In that sense (predicting forward in time) smoothing can’t give you a more accurate estimate.
But I shouldn’t be holding you back just because I disagree philosophically! Let me remind myself how we do this inside the filter, and I can sketch out some code. It will be java, though, you’ll have to do the translation to python, and I suspect it will involve low-level parameter-driver stuff which isn’t pretty.
@a.malaver I haven’t used Mark’s RTS smoother yet, but from the sound of what you’re saying you’ll have to create your own propagator at each step using the individual orbit components (pos, vel) and any propagator parameters you’ve included in your KF (it sounds like you’re doing serious OD, which means you’ll want drag and solar). The code to do that is:
# Initialize the propagator builder
numPropBuilder = NumericalPropagatorBuilder(orbit, integratorBuilder, PositionAngleType.MEAN, 1.0)
numPropBuilder.setMass(mass)
# force == drag, solar, gravity, ocean tides, etc.
# For high-level propagator, have to add each force separately
numPropBuilder.addForceModel(force)
I would recommend writing a python function that accepts pos/vel/drag/solar values as inputs and then returns a NumericalPropagator with all your forces added in.
P.S. My own code was built with 12.2. There might be some slight changes in how the NumericalPropagatorBuilder and NumericalPropagator classes work in v13.