Get measurements used from Unscented Kalman Filter

Hello everyone,

I’ve been working on OD using both the Unscented Kalman Filter and the Batch Least Squares :smile:.

I was trying to print a summary of the estimation algorithm, including the information about the measurements. What I did in the case of the BLS is to get the last estimation using the getLastEstimations() method, but I was unable to find anything similar for the UKF.

I was doing this to be able to obtain from the propagator all the measurements considered, and to specify the number of measurements of each kind (radar, laser, optical…) that were considered in the OD. Although it is easy for the BLS, it does not seem that straightforward for the UKF :sad_but_relieved_face:.

The only “similar” output that I was able to find is the number of measurements:
getCurrentMeasurementNumber(). However, it does not provide me the crucial information I need, which is something like the following:

Measurement Statistics:
  Total number of unique ObservedMeasurement objects evaluated: 371.
  Total number of residual components considered: 491.
     Breakdown by type (based on residual components):
       RangeRate (m/s): 44.
       Range (m): 207.
       RA (rad): 76.
       Dec (rad): 76.
       Azimuth (rad): 44.
       Elevation (rad): 44.

Thank you so much in advance :heart:,
Antonio Malaver.

It’s a pain to get the measurement data, but it can be done. You need to:

  1. Use the KalmanObserver class to go into the evaluation process at each step
  2. Pull the relevant calculated/measured values out of the module KalmanModel

You can then pull your measurement value out of KalmanModel using the method:

model.getCorrectedMeasurement().getObservedMeasurement().getObservedValue()

which will give you a Java double array. Some other useful functions are:

model.getCorrectedMeasurement().getDate() // Measurement date
model.getCorrectedMeasurement().getObservedMeasurement().getTheoreticalStandardDeviation() // Measurement standard deviation
model.getPhysicalKalmanGain() // Kalman gain matrix
model.getCorrectedMeasurement().getEstimatedValue() // corrected orbital parameter values
model.getEstimatedPropagationParameters().getDrivers() // corrected propagation parameter values (i.e. drag, solar)
model.getPhysicalEstimatedCovarianceMatrix() // corrected covariance values

I haven’t found a function that will give you the initial predicted value, but you can get it by working backwards from the observed measurement and the corrected filter value

# Get predicted covariance by working backwards from corrected (helps prevent
# asymmetries/numeric error to work backwards from Orekit value)
ident = MatrixUtils.createRealIdentityMatrix(6 + numEstimatedParams)
h_mat = model.getPhysicalMeasurementJacobian()
b = ident.subtract(kalmanGain.multiply(h_mat))
self.predictedCovariance = MatrixUtils.inverse(b).multiply(correctedCovariance)

# Get predicted measurement by working backward from corrected
a = self.correctedMeasurement.subtract(kalmanGain.multiply(observedMeasurement))
self.predictedMeasurement = MatrixUtils.inverse(b).multiply(a)

Pulled this from some of my working code (python) so you’ll probably have to adapt it a bit. But hope it helps.

P.S. I was just using the basic KF, not the UKF, so there might be some adaption required there. But hopefully not.

1 Like

Hello!

Thank you so much for your detailed answer.

I’ve been trying to implement an Observer for the UKF creating a python class that contains a KalmanObserver this way:

# Create an Unscented Kalman Filter observer to be able to retrieve information from each iteration.
class my_observer(KalmanObserver):
    """
    A KalmanObserver that collects all KalmanEstimation objects processed by a Kalman filter.
    """
     # Store full KalmanEstimation objects, just in case more information is needed.
    def __init__(self):
        super().__init__()
        self.kalman_estimations = []
        
    def evaluationPerformed(self, estimation: KalmanEstimation):
        """
        This method is called by the Kalman filter after each measurement evaluation.
        'estimation' is an org.orekit.estimation.sequential.KalmanEstimation object.
        """
        self.kalman_estimations.append(estimation)
    
    def getKalmanEstimations(self) -> list:
        """
        Returns the list of KalmanEstimation objects that were processed.
        """
        return self.kalman_estimations

    def reset(self):
        """
        Resets the collected estimations. Useful if reusing the observer.
        """
        self.kalman_estimations = []

However, I get the following error (which does not tell much about the problem, to be honest…) 'instantiating java class', <class 'mosaicpy.estimation.kalman_observer.my_observer'>

Thank you so much :smile:

Hi @a.malaver,

I think you need to subclass PythonKalmanObserver and not the Java interface directly.
You’ll probably need to use PythonKalmanEstimation at some point but I’m not sure where, I guess @baubin will know :slight_smile:

Hope this helps,
Maxime

1 Like

Yes, I searched the forum for similar problems and, yes, I found someone using the PythonKalmanObserver and it solved it immediately!

I am almost done, with the above code implemented, to create my own observer. However, I run into the following problem:

When I create the list containing all the kalman_estimations, every object within the list has the same final information. I have done some debugging and this is because the UnscentedKalmanModel retrieved by the estimator has the same hash for each of them, forcing each object in the list to be updated at each iteration, even though each step contains different information.

Here is the debugging information, with 3 steps of updating the observer and the information in each KalmanEstimation:

estimation
<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>
special variables
function variables
boxfn_ =
<capsule object "boxfn" at 0x7f175f54c210>
class =
<Class: class org.orekit.estimation.sequential.UnscentedKalmanModel>
class_ =
<Class: interface org.orekit.estimation.sequential.KalmanEstimation>
correctedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@68d519ce>
correctedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4809888.210021667, 906093.5858677439, 5298013.383610573), V(-2957.84567869847, -6679.41408934435, -1674.5918654910718)}, attitude=org.orekit.attitudes.Attitude@2057ec0f, mass=47.0, additional={}, additionalDot={}}>]
currentDate =
<AbsoluteDate: 2023-04-01T00:10:49.999999999999973568Z>
currentMeasurementNumber =
1
estimatedMeasurementsParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@147e7abc>
estimatedOrbitalParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@54a51a94>
estimatedPropagationParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@3766b5f7>
physicalEstimatedCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{1469.032072375,1754.91515328,-396.906658575,-1.0813102202,0.5031929689,2.18867555,0.0000007142,-0.0000424832},{1754.91515328,4263.1512058,-849.02349523,-4.2793288171,0.027897845,4.9524047053,0.0000004184,-0.0000298045},{-396.906658575,-849.02349523,1605.33553357,1.4634487642,0.2767296627,-2.0178387895,-0.0000004963,0.0000330227},{-1.0813102202,-4.2793288171,1.4634487642,0.0054504787,0.0004197359,-0.0053211428,-0.0000000013,0.0000000732},{0.5031929689,0.027897845,0.2767296627,0.0004197359,0.0018406879,-0.0008400315,-0.0000000026,0.0000000395},{2.18867555,4.9524047053,-2.0178387895,-0.0053211428,-0.0008400315,0.007185812,0.0000000014,-0.0000000582},{0.0000007142,0.0000004184,-0.0000004963,-0.0000000013,-0.0000000026,0.0000000014,0.0001000001,0.0},{-0.0000424832,-0.0000298045,0.0000330227,0.0000000732,0.0000000395,-0.0000000582,0.0,0.0001000001}}>
physicalEstimatedState =
<RealVector: {-4,809,888.210021667; 906,093.5858677439; 5,298,013.383610573; -2,957.8456786985; -6,679.4140893444; -1,674.5918654911; 2.0499996376; 1.2500000072}>
physicalInnovationCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{167885261.91000482}}>
physicalKalmanGain =
<RealMatrix: Array2DRowRealMatrix{{0.4874866714},{1.1149056895},{0.2857933123},{-0.0008604377},{0.0001375693},{0.0009374759},{-0.0},{0.0}}>
physicalMeasurementJacobian =
None
physicalStateTransitionMatrix =
None
predictedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@6be8a8c1>
predictedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4849606.989191166, 815254.8091994971, 5274727.902953899), V(-2887.7400984625915, -6690.622772512179, -1750.9742579320182)}, attitude=org.orekit.attitudes.Attitude@2435bc84, mass=47.0, additional={}, additionalDot={}}>]
wrapfn_ =
<capsule object "wrapfn" at 0x7f175f54c1e0>
_jobject =
<capsule object "jobject" at 0x7f174c919740>

estimation
<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>
special variables
function variables
boxfn_ =
<capsule object "boxfn" at 0x7f175f54c210>
class =
<Class: class org.orekit.estimation.sequential.UnscentedKalmanModel>
class_ =
<Class: interface org.orekit.estimation.sequential.KalmanEstimation>
correctedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@2a55856e>
correctedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4882642.827990354, 737843.6882867012, 5254116.316045545), V(-2828.58653891186, -6701.321966992971, -1815.6600410707083)}, attitude=org.orekit.attitudes.Attitude@251e8482, mass=47.0, additional={}, additionalDot={}}>]
currentDate =
<AbsoluteDate: 2023-04-01T00:11:14.999999999999973568Z>
currentMeasurementNumber =
2
estimatedMeasurementsParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@147e7abc>
estimatedOrbitalParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@54a51a94>
estimatedPropagationParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@3766b5f7>
physicalEstimatedCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{963.1294316566,569.1509904731,-617.8553298606,-0.078291023,0.3490887269,1.1009717904,0.0000007046,-0.0000412203},{569.1509904731,1649.2818913612,-1455.6482063983,-2.209003615,-0.317230873,2.7106194,0.0000004092,-0.0000301127},{-617.8553298606,-1455.6482063983,1302.1549864199,1.846591736,0.2108954312,-2.4173255276,-0.0000004461,0.0000312228},{-0.078291023,-2.209003615,1.846591736,0.0037876847,0.0007451724,-0.0035334743,-0.0000000014,0.0000000727},{0.3490887269,-0.317230873,0.2108954312,0.0007451724,0.001811916,-0.001226435,-0.0000000027,0.0000000406},{1.1009717904,2.7106194,-2.4173255276,-0.0035334743,-0.001226435,0.0052273039,0.0000000014,-0.0000000573},{0.0000007046,0.0000004092,-0.0000004461,-0.0000000014,-0.0000000027,0.0000000014,0.0001000002,0.0},{-0.0000412203,-0.0000301127,0.0000312228,0.0000000727,0.0000000406,-0.0000000573,0.0,0.0001000002}}>
physicalEstimatedState =
<RealVector: {-4,882,642.827990354; 737,843.6882867012; 5,254,116.316045545; -2,828.5865389119; -6,701.321966993; -1,815.6600410707; 2.049999659; 1.2499995141}>
physicalInnovationCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{2108.1397451797}}>
physicalKalmanGain =
<RealMatrix: Array2DRowRealMatrix{{0.4649053081},{1.1133833969},{0.313813627},{-0.000868169},{0.000113706},{0.0009234479},{-0.0},{0.0000000006}}>
physicalMeasurementJacobian =
None
physicalStateTransitionMatrix =
None
predictedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@17e172dc>
predictedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4882232.466400848, 738826.4470820124, 5254393.312364081), V(-2829.352852413342, -6701.221601273944, -1814.8449340983143)}, attitude=org.orekit.attitudes.Attitude@7e64aff7, mass=47.0, additional={}, additionalDot={}}>]
wrapfn_ =
<capsule object "wrapfn" at 0x7f175f54c1e0>
_jobject =
<capsule object "jobject" at 0x7f174c919410>

estimation
<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>
special variables
function variables
boxfn_ =
<capsule object "boxfn" at 0x7f175f54c210>
class =
<Class: class org.orekit.estimation.sequential.UnscentedKalmanModel>
class_ =
<Class: interface org.orekit.estimation.sequential.KalmanEstimation>
correctedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@782de78d>
correctedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951460.925757221, 570621.226827021, 5206514.180406753), V(-2698.6759547956926, -6718.777757827543, -1953.9683336802937)}, attitude=org.orekit.attitudes.Attitude@6288be90, mass=47.0, additional={}, additionalDot={}}>]
currentDate =
<AbsoluteDate: 2023-04-01T00:11:39.999999999999973568Z>
currentMeasurementNumber =
3
estimatedMeasurementsParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@147e7abc>
estimatedOrbitalParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@54a51a94>
estimatedPropagationParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@3766b5f7>
physicalEstimatedCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{588.6494770659,-221.4862632737,102.73500299,0.8824912159,0.4828962382,-0.2451292693,0.0000000914,-0.0000125589},{-221.4862632737,147.8494244366,-86.8088275989,-0.4665348014,-0.0525944903,0.2213159953,-0.0000008122,0.0000244736},{102.73500299,-86.8088275989,53.8729988993,0.2544008331,-0.0120793554,-0.1391303443,0.0000005965,-0.0000169315},{0.8824912159,-0.4665348014,0.2544008331,0.0017920451,0.0005019511,-0.000704305,-0.0,0.000000011},{0.4828962382,-0.0525944903,-0.0120793554,0.0005019511,0.0017776953,-0.0008818685,-0.0000000025,0.0000000319},{-0.2451292693,0.2213159953,-0.1391303443,-0.000704305,-0.0008818685,0.0011506374,-0.0000000005,0.0000000319},{0.0000000914,-0.0000008122,0.0000005965,-0.0,-0.0000000025,-0.0000000005,0.0001000003,0.0},{-0.0000125589,0.0000244736,-0.0000169315,0.000000011,0.0000000319,0.0000000319,0.0,0.0001000003}}>
physicalEstimatedState =
<RealVector: {-4,951,460.925757221; 570,621.226827021; 5,206,514.180406753; -2,698.6759547957; -6,718.7777578275; -1,953.9683336803; 2.0500000764; 1.2499801591}>
physicalInnovationCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{5.0593681}}>
physicalKalmanGain =
<RealMatrix: Array2DRowRealMatrix{{-8.5939763981},{-17.1344598064},{14.9550025551},{0.0192581288},{0.0031349731},{-0.027943905},{-0.0000000133},{0.0000006178}}>
physicalMeasurementJacobian =
None
physicalStateTransitionMatrix =
None
predictedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@3c672ff>
predictedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951730.162427472, 570084.4293433991, 5206982.698692701), V(-2698.0726258780537, -6718.679543720881, -1954.8437752196219)}, attitude=org.orekit.attitudes.Attitude@77a1d751, mass=47.0, additional={}, additionalDot={}}>]
wrapfn_ =
<capsule object "wrapfn" at 0x7f175f54c1e0>
_jobject =
<capsule object "jobject" at 0x7f174c919bf0>

self.kalman_estimations
[<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>, <KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>]
special variables
function variables
0 =
<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>
special variables
function variables
boxfn_ =
<capsule object "boxfn" at 0x7f175f54c210>
class =
<Class: class org.orekit.estimation.sequential.UnscentedKalmanModel>
class_ =
<Class: interface org.orekit.estimation.sequential.KalmanEstimation>
correctedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@782de78d>
correctedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951460.925757221, 570621.226827021, 5206514.180406753), V(-2698.6759547956926, -6718.777757827543, -1953.9683336802937)}, attitude=org.orekit.attitudes.Attitude@6288be90, mass=47.0, additional={}, additionalDot={}}>]
currentDate =
<AbsoluteDate: 2023-04-01T00:11:39.999999999999973568Z>
currentMeasurementNumber =
3
estimatedMeasurementsParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@147e7abc>
estimatedOrbitalParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@54a51a94>
estimatedPropagationParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@3766b5f7>
physicalEstimatedCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{588.6494770659,-221.4862632737,102.73500299,0.8824912159,0.4828962382,-0.2451292693,0.0000000914,-0.0000125589},{-221.4862632737,147.8494244366,-86.8088275989,-0.4665348014,-0.0525944903,0.2213159953,-0.0000008122,0.0000244736},{102.73500299,-86.8088275989,53.8729988993,0.2544008331,-0.0120793554,-0.1391303443,0.0000005965,-0.0000169315},{0.8824912159,-0.4665348014,0.2544008331,0.0017920451,0.0005019511,-0.000704305,-0.0,0.000000011},{0.4828962382,-0.0525944903,-0.0120793554,0.0005019511,0.0017776953,-0.0008818685,-0.0000000025,0.0000000319},{-0.2451292693,0.2213159953,-0.1391303443,-0.000704305,-0.0008818685,0.0011506374,-0.0000000005,0.0000000319},{0.0000000914,-0.0000008122,0.0000005965,-0.0,-0.0000000025,-0.0000000005,0.0001000003,0.0},{-0.0000125589,0.0000244736,-0.0000169315,0.000000011,0.0000000319,0.0000000319,0.0,0.0001000003}}>
physicalEstimatedState =
<RealVector: {-4,951,460.925757221; 570,621.226827021; 5,206,514.180406753; -2,698.6759547957; -6,718.7777578275; -1,953.9683336803; 2.0500000764; 1.2499801591}>
physicalInnovationCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{5.0593681}}>
physicalKalmanGain =
<RealMatrix: Array2DRowRealMatrix{{-8.5939763981},{-17.1344598064},{14.9550025551},{0.0192581288},{0.0031349731},{-0.027943905},{-0.0000000133},{0.0000006178}}>
physicalMeasurementJacobian =
None
physicalStateTransitionMatrix =
None
predictedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@3c672ff>
predictedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951730.162427472, 570084.4293433991, 5206982.698692701), V(-2698.0726258780537, -6718.679543720881, -1954.8437752196219)}, attitude=org.orekit.attitudes.Attitude@77a1d751, mass=47.0, additional={}, additionalDot={}}>]
wrapfn_ =
<capsule object "wrapfn" at 0x7f175f54c1e0>
_jobject =
<capsule object "jobject" at 0x7f174c919ad0>
1 =
<KalmanEstimation: org.orekit.estimation.sequential.UnscentedKalmanModel@1c4d7c0a>
special variables
function variables
boxfn_ =
<capsule object "boxfn" at 0x7f175f54c210>
class =
<Class: class org.orekit.estimation.sequential.UnscentedKalmanModel>
class_ =
<Class: interface org.orekit.estimation.sequential.KalmanEstimation>
correctedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@782de78d>
correctedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951460.925757221, 570621.226827021, 5206514.180406753), V(-2698.6759547956926, -6718.777757827543, -1953.9683336802937)}, attitude=org.orekit.attitudes.Attitude@6288be90, mass=47.0, additional={}, additionalDot={}}>]
currentDate =
<AbsoluteDate: 2023-04-01T00:11:39.999999999999973568Z>
currentMeasurementNumber =
3
estimatedMeasurementsParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@147e7abc>
estimatedOrbitalParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@54a51a94>
estimatedPropagationParameters =
<ParameterDriversList: org.orekit.utils.ParameterDriversList@3766b5f7>
physicalEstimatedCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{588.6494770659,-221.4862632737,102.73500299,0.8824912159,0.4828962382,-0.2451292693,0.0000000914,-0.0000125589},{-221.4862632737,147.8494244366,-86.8088275989,-0.4665348014,-0.0525944903,0.2213159953,-0.0000008122,0.0000244736},{102.73500299,-86.8088275989,53.8729988993,0.2544008331,-0.0120793554,-0.1391303443,0.0000005965,-0.0000169315},{0.8824912159,-0.4665348014,0.2544008331,0.0017920451,0.0005019511,-0.000704305,-0.0,0.000000011},{0.4828962382,-0.0525944903,-0.0120793554,0.0005019511,0.0017776953,-0.0008818685,-0.0000000025,0.0000000319},{-0.2451292693,0.2213159953,-0.1391303443,-0.000704305,-0.0008818685,0.0011506374,-0.0000000005,0.0000000319},{0.0000000914,-0.0000008122,0.0000005965,-0.0,-0.0000000025,-0.0000000005,0.0001000003,0.0},{-0.0000125589,0.0000244736,-0.0000169315,0.000000011,0.0000000319,0.0000000319,0.0,0.0001000003}}>
physicalEstimatedState =
<RealVector: {-4,951,460.925757221; 570,621.226827021; 5,206,514.180406753; -2,698.6759547957; -6,718.7777578275; -1,953.9683336803; 2.0500000764; 1.2499801591}>
physicalInnovationCovarianceMatrix =
<RealMatrix: Array2DRowRealMatrix{{5.0593681}}>
physicalKalmanGain =
<RealMatrix: Array2DRowRealMatrix{{-8.5939763981},{-17.1344598064},{14.9550025551},{0.0192581288},{0.0031349731},{-0.027943905},{-0.0000000133},{0.0000006178}}>
physicalMeasurementJacobian =
None
physicalStateTransitionMatrix =
None
predictedMeasurement =
<EstimatedMeasurement: org.orekit.estimation.measurements.EstimatedMeasurement@3c672ff>
predictedSpacecraftStates =
JArray<object>[<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(-4951730.162427472, 570084.4293433991, 5206982.698692701), V(-2698.0726258780537, -6718.679543720881, -1954.8437752196219)}, attitude=org.orekit.attitudes.Attitude@77a1d751, mass=47.0, additional={}, additionalDot={}}>]
wrapfn_ =
<capsule object "wrapfn" at 0x7f175f54c1e0>
_jobject =
<capsule object "jobject" at 0x7f174c919590>
len() =
2

As can be clearly seen, the information in each step is different, as they only contain the measures that have been evaluated up to that step. However, as the hash is the same and does not vary, they are updated at each iteration in the list, containing the same information as the current iteration.

I am thinking of solving this problem by simply extracting all the information from the KalmanEstimator at each step, but I would prefer to have a list with the estimators with the data they had at that particular step.

I hope I explained it in detail :smile:

Thank you very much.

Sorry @baubin and @MaximeJ, I am new in this forum and I did not know that I should @ you, guys!

I am sorry :cold_face:

I’m afraid you have to literally go into each individual step and store the data from each step in an overarching list.

class KalmanOdObserver(PythonKalmanObserver):
    """
    This class allows us to examine and store the kalman filter
    values for the individual steps
    """

    def __init__(self, estimatedParams: ParameterDriversList):

        # Save the log information
        self.__forward_log = []  # log of forward kalman values
        
        ... # whatever stuff you want to store

        # Initialize the PythonKalmanObserver
        super(KalmanOdObserver, self).__init__()

    def evaluationPerformed(self, estimation: KalmanModel) -> None:
        """
        examines and stores a single step

         Args:
             estimation (KalmanModel): Kalman values for this time step
        """

        # Downcast to KalmanModel to get more of the kalman-filter specific values
        # for the timestep
        model = KalmanModel.cast_(estimation)

        # Leaving this code here in case someone wants these values later
        # observed = model.getCorrectedMeasurement().getObservedMeasurement().getObservedValue()
        # predicted = model.getPredictedSpacecraftStates()[0].getPVCoordinates().getPosition()

        # If the filter gets rid of this measurement, then this will be true
        if model.getPhysicalMeasurementJacobian() is not None:

            # Create the step data storage object
            step = KalmanForwardStep(model, self.numEstimatedParams)

            # Update the forward_log
            self.__forward_log.append(step)

I just sort of assumed you were working in Java, or I would have mentioned the “you have to use PythonKalmanObserver” step.

1 Like

Thank you so much @babuin! It is a strange thing that each iteration updates all the information of all the elements I am storing, but thankfully now I know what to do. :smiley:

1 Like