Below is a numbered list detailing the basic process of performing state estimation using a Kalman Filter, Square Root Information Filter, or Unscented Kalman Filter. For each step in the process, the options available in FreeFlyer script are listed, and a script example is given for each option.
There are a variety of Sample Mission Plans (included with your FreeFlyer installation) that demonstrate various applications of these topics. Continue to the Orbit Determination Samples page to view descriptions and images of these examples or jump to one of the Mission Plans listed below.

For information on creating and configuring a KalmanFilterOD, SquareRootInformationFilterOD, or UnscentedKalmanFilterOD object see Setting up a Kalman Filter, Setting up a Square Root Information Filter, or Setting up an Unscented Kalman Filter, respectively.
1.Process Observations at the Current Epoch
There are several options available when processing observations.
a.Handle observations defined in files
i.For tracking data files that have been registered with the Kalman Filter, Square Root Information Filter, or Unscented Kalman Filter, the filter is able to count the number of observations at the current epoch and process them individually in a For loop, as seen in the example below.
n = KalmanFilterOD1.NumberOfObservationsAtCurrentEpoch();
For i = 0 to n1;
KalmanFilterOD1.ProcessNextObservation();
End;

ii.You can also process data from tracking data files that are not registered with the Kalman Filter, Square Root Information Filter, or Unscented Kalman Filter. The next Observation can be retrieved and then passed to the Filter for processing. For example:
FFGroundObsFile1.GetNextObservation(GroundStationObs1);
KalmanFilterOD1.ProcessObservation(GroundStationObs1);

b.Handle observations instantiated and initialized from script
i.If you're working with a file format that isn't natively supported by FreeFlyer, you can read the observation data in manually and pass it to the Filter, as seen below:
PointSolutionObs1.X.ObservedValue = 3410.686122056;
PointSolutionObs1.Y.ObservedValue = 5950.923165257;
PointSolutionObs1.Z.ObservedValue = 1788.614088631;
PointSolutionObs1.VX.ObservedValue = 1.892964574;
PointSolutionObs1.VY.ObservedValue = 1.072030460;
PointSolutionObs1.VZ.ObservedValue = 7.176379907;
PointSolutionObs1.SetObjectBeingObserved(FilterSC);
PointSolutionObs1.SetObserver(FilterSC.GNSSReceivers[0]);
KalmanFilterOD1.ProcessObservation(PointSolutionObs1);

ii.You can also process observations that aren't read in from an external file. These observations may be data you're simulating in the current Mission Plan using the SimulateTrackingData method, as shown in the example below.
TruthSC.SimulateTrackingData(PointSolutionObs1);
KalmanFilterOD1.ProcessObservation(PointSolutionObs1);


2.Evaluate Processing Status
There are a variety of ways that you can evaluate the status of the measurement processing during the run.
a.You can determine if measurements were edited by the Filter by examining the measurement ProcessingStatus property:
Report PointSolutionObs1.X.ProcessingStatus;

b.Examine the State Update for each of the properties your filter is estimating:
Report FilterSC.OD.Cartesian.X.StateUpdate, FilterSC.OD.Cartesian.Y.StateUpdate, FilterSC.OD.Cartesian.Z.StateUpdate,
FilterSC.OD.Cartesian.VX.StateUpdate, FilterSC.OD.Cartesian.VY.StateUpdate, FilterSC.OD.Cartesian.VZ.StateUpdate;

c.Inspect Measurement pre and postupdate residuals:
Report PointSolutionObs1.X.PreUpdateResidual, PointSolutionObs1.X.PostUpdateResidual;

d.Examine the Filter Covariance or Information Matrix:
Report KalmanFilterOD1.Covariance.Diagonal;
Report KalmanFilterOD1.Covariance.Matrix;
SquareRootInformationFilterOD SRIF;
Report SRIF.Covariance.SquareRootInformationMatrix;

e. Examine the Kalman Gain:
Report KalmanFilterOD1.LastKalmanGain;


3.Using the Smoother (optional)
For more information on the available Smoother algorithms for each of the Filters and their configuration options, see Setting up a Smoother.
When using the Fixed Point algorithm, the "smoothed state" is updated automatically every time that the Kalman Filter processes an Observation.
When using the Fixed Lag or Fixed Lag  Full Span algorithm or the Square Root Information Smoother, since these algorithms are more numerically intensive the "smoothed state" is only updated when the user manually calls the Smoother.CalculateSmoothedState() method. This is to avoid performing the smoother calculations every step, but the user can force those calculations, if desired, by calling the CalculateSmoothedState method each time an Observation is processed at the script level.
The Smoother.CalculateSmoothedState() method does NOT need to be called when running in Fixed Point mode, though it is harmless to do so and has no effect.
Since the Smoother algorithms run backwards in time, the epoch of the "smoothed state" is always the epoch of the first observation in the Smoother data buffer. The start of the span of the smoother data buffer is determined as the latest epoch of:
•The epoch of the first Observation processed by the Kalman filter
•The epoch of the first observation following a gap of data as defined by the "Gap Duration for Reset" property
•The epoch of the first observation following a manual call to the Smoother.Reset() method
•(For Fixed Lag) The epoch of the observation processed n number of points in the past, where n is defined by the "Number of Point in Interval" property.
•(For Fixed Lag  Full Span) The epoch of first observation processed by the Kalman filter. 
When operating the Kalman Filter using the simple "KalmanFilterOD.StepOD()" method, it isn't directly obvious if the Filter has processed any observations, and hence it isn't automatically known if the "smoothed state" has been updated. To determine this, the user can inspect the Smoother.SmootherStateHasBeenUpdated property. This will return a value of 1 if the smoothed state was updated over the last call to the Kalman Filter, and 0 otherwise.
The epoch of the "smoothed state" is accessible through the Smoother.Epoch property. The "smoothed state" itself, including the "smoothed covariance", is accessible through the objects being estimated, as shown below:
KalmanFilterOD1.Smoother.CalculateSmoothedState();
SmoothedSC.Epoch = KalmanFilterOD1.Smoother.Epoch;
SmoothedSC.X = EstimatedSC.OD.Cartesian.X.SmoothedValue;
SmoothedSC.Y = EstimatedSC.OD.Cartesian.Y.SmoothedValue;
SmoothedSC.Z = EstimatedSC.OD.Cartesian.Z.SmoothedValue;
SmoothedSC.VX = EstimatedSC.OD.Cartesian.VX.SmoothedValue;
SmoothedSC.VY = EstimatedSC.OD.Cartesian.VY.SmoothedValue;
SmoothedSC.VZ = EstimatedSC.OD.Cartesian.VZ.SmoothedValue;
SmoothedSC.Epoch = KalmanFilterOD1.Smoother.Epoch;
SmoothedSC.EquinoctialA = EstimatedSC.OD.Equinoctial.A.SmoothedValue
SmoothedSC.EquinoctialH = EstimatedSC.OD.Equinoctial.H.SmoothedValue
SmoothedSC.EquinoctialK = EstimatedSC.OD.Equinoctial.K.SmoothedValue
SmoothedSC.EquinoctialP = EstimatedSC.OD.Equinoctial.P.SmoothedValue
SmoothedSC.EquinoctialQ = EstimatedSC.OD.Equinoctial.Q.SmoothedValue
SmoothedSC.EquinoctialLongitude = EstimatedSC.OD.Equinoctial.Longitude.SmoothedValue
Step TruthSC to (TruthSC.Epoch == KalmanFilterOD1.Smoother.Epoch);
Plot TruthSC.ElapsedTime, TruthSC.AlongTrackSeparation(SmoothedSC),
TruthSC.CrossTrackSeparation(SmoothedSC),
TruthSC.RadialSeparation(SmoothedSC);
Report KalmanFilterOD1.Smoother.Epoch.ConvertToCalendarDate(), EstimatedSC.OD.Covariance.SmoothedDiagonal;
EstimatedSC.OD.Covariance.MapSmoothedErrorEllipsoid(EstimatedSC.ProximityZones[0], 3);

Additionally, incremental smoothed states can optionally be stored in an Ephemeris object for later output or inspection. This includes the smoothed Cartesian state vectors and can optionally include the smoothed covariance, as shown below:
FilteredSC.OD.SetEphemerisForSmoother(SmoothedEphem, 1);
SquareRootInformationFilterOD1.Smoother.CalculateSmoothedState();
Put SmoothedEphem to FFephem "smoothedSolution.ephem";
SmoothedSC.SetPropagatorType(TypeOf(Ephemeris));
(SmoothedSC.Propagator AsType Ephemeris).LoadEphemeris("smoothedSolution.ephem");

4.Propagate Objects
After processing the observations at the current epoch and generating any desired output in order to inspect the current processing state, you can propagate to future measurements.
a.Propagate all OD objects by the Kalman Filter, Square Root Information Filter, or Unscented Kalman Filter Step Size
KalmanFilterOD1.StepOD();

b.Propagate all OD objects to a userspecified epoch
KalmanFilterOD1.StepToEpoch(epoch);

c.Propagate all OD objects to the next Epoch of Data from any of the Registered Tracking Data files
KalmanFilterOD1.StepToNextObservation();

d.Step objects individually
Step GPS;
Step TruthSC;
Step EstimatedSC to (EstimatedSC.Epoch == TruthSC.Epoch);


