3. LKF#
- class LKF(propagator: Propagator, measurements: List[Dict], settings: FilterSettings, traj_name: str | None = None, traj_dir: str | None = None, overwrite_traj: bool = True)#
Bases:
FilterODImplements a Linearized Kalman Filter (LKF) for spacecraft orbit determination.
Applies the Linearized Kalman Filter (LKF) method to estimate a spacecraft’s state using sequential measurements while propagating uncertainty through a dynamic model. The LKF is particularly useful when the state evolution and measurement models are nonlinear, but can be linearized using a State Transition Matrix (STM).
The filter follows a predict-update cycle, where:
The prediction step propagates the state and covariance forward in time.
The update step refines the state using measurement updates via the Kalman gain.
The LKF is recursive, meaning it updates the estimate as new measurements become available, making it computationally efficient compared to batch methods.
- Parameters:
propagator (
Propagator) – An instance of the Propagator class that provides the spacecraft trajectory and STM.settings (
FilterSettings) – An instance of the FilterSettings class containing filter configuration, including: * Initial state covariance matrix. * Process noise model and parameters.measurements (
list) –A list of measurement observations, where each entry includes:
Measurement time.
Residuals between observed and predicted values.
Measurement covariance matrix.
Measurement Jacobian (sensitivity matrix).
Additional metadata (e.g., instrument, measurement type).
traj_name (
str, optional) – The name of the trajectory file to be created (default is None).traj_dir (
str, optional) – Directory to save the trajectory file (default is current working directory).overwrite_traj (
bool, optional) – If True, overwrite the existing trajectory file (default is True).
See also
scarabaeus.FilterODBase class for orbit determination filters.
scarabaeus.SolutionODStores estimated state history and covariance evolution.
scarabaeus.CovarianceMatrixDefines measurement noise covariance.
scarabaeus.StateNoiseCompensationRepresents process noise in the system dynamics.
Notes
The LKF assumes Gaussian noise models for both system dynamics and measurement errors.
Process noise can be included to account for unmodeled dynamics in state propagation.
The filter can operate across multiple trajectory legs, adjusting the state size at event epochs.
Unlike batch least-squares, the Kalman filter updates estimates sequentially, allowing real-time implementation.
References
Tapley, B. D., Schutz, B. E., & Born, G. H. (2004). Statistical orbit determination. Elsevier.
Methods
compute([meas_corr, printOutput, ...])Performs the state estimation using the Linearized Kalman Filter.
iterate([traj_name, traj_dir, ...])Perform iterative orbit determination with automatic convergence checking.
map_covariance_definition_node(...[, ...])Adjusts the covariance matrix to match a new state vector definition.
map_deviation_definition_node(...[, ...])Adjusts the deviation vector to align with a new state vector definition.
map_stm_definition_node(counter_events, old_STM)Adjusts the State Transition Matrix (STM) to match a new state definition.
observability_test([print_obs, threshold, ...])Performs an observability analysis on the system by computing the information matrix.
reinitialize([state_deviation, ...])Reinitialize the filter for iterative estimation.
smoother([printOutput])Rauch-Tung-Striebel backward smoother.
Split the partial derivatives matrix into estimated and consider parameters.
split_stm_phi_psi(STM)Split the State Transition Matrix (STM) into Phi and Psi components.
unwrap_residuals(postfit_residuals, ...)Organizes postfit residuals into a dictionary categorized by dataset.
Validates consistency in state vector definitions across sequential estimation legs.
- compute(meas_corr: list = None, printOutput: bool = True, underweighting_factor: float = 1.0) SolutionOD#
Performs the state estimation using the Linearized Kalman Filter.
Iterates through the measurement epochs, performing prediction and update steps. The predicted state is corrected based on new measurements using the Kalman gain.
- Parameters:
meas_corr (
list, optional) – List of correction factors for measurement covariance. Defaults toNone.printOutput (
bool, optional) – IfTrue, prints the progress of the filter. Defaults toTrue.underweighting_factor (
float, optional) – A scaling factor to modify the measurement covariance (used for robustness). Defaults to1.0.
- Returns:
An object containing the estimated state deviation history and covariance evolution.
- Return type:
- iterate(traj_name: str | None = None, traj_dir: str | None = None, overwrite_traj: bool = True, max_iterations: int = 10, convergence_threshold: float = 1e-06, verbose: bool = True, if_sequential_smooth: bool = False)#
Perform iterative orbit determination with automatic convergence checking.
Runs the filter iteratively, applying state corrections from each solution to the next iteration until convergence or maximum iterations is reached.
- Parameters:
traj_name (
str, optional) – Base name for trajectory files. Iteration number will be appended. If None, auto-generates names. Defaults to None.traj_dir (
str, optional) – Directory for trajectory files. Defaults to None (current directory).overwrite_traj (
bool, optional) – Whether to overwrite existing trajectories. Defaults to True.max_iterations (
int, optional) – Maximum number of iterations. Defaults to 10.convergence_threshold (
float, optional) – RMS deviation threshold for convergence. Defaults to 1e-6.verbose (
bool, optional) – If True, prints iteration progress. Defaults to True.if_sequential_smooth (
bool, optional) – If True, applies sequential smoothing after filtering. Defaults to False.
- Returns:
solution (
SolutionOD) – Final filter solution from the last iteration.iteration_count (
int) – Number of iterations performed.converged (
bool) – Whether convergence was achieved.
Examples
>>> # Automatic iteration with convergence checking >>> lkf = LKF(propagator, covariance, measurements) >>> solution, n_iters, converged = lkf.iterate( ... max_iterations=5, ... convergence_threshold=1e-6 ... ) >>> print(f"Converged in {n_iters} iterations: {converged}")
- map_covariance_definition_node(counter_events: int, old_covariance: ndarray, flag_augment: bool = True) ndarray#
Adjusts the covariance matrix to match a new state vector definition.
- Parameters:
counter_events (
int) – Index of the current sequence event for state transition.old_covariance (
numpy.ndarray) – Previous covariance matrix to be updated.flag_augment (
bool, optional) – IfTrue, expands the covariance matrix; otherwise, reduces it. Defaults toTrue.
- Returns:
updated_covar – Updated covariance matrix reflecting the new state definition.
- Return type:
- map_deviation_definition_node(counter_events: int, old_deviation: ndarray, flag_augment: bool = True) ndarray#
Adjusts the deviation vector to align with a new state vector definition.
- Parameters:
counter_events (
int) – Index of the current sequence event for state transition.old_deviation (
numpy.ndarray) – Previous state deviation vector.flag_augment (
bool, optional) – IfTrue, expands the deviation vector; otherwise, reduces it. Defaults toTrue.
- Returns:
updated_dev – Updated deviation vector reflecting the new state definition.
- Return type:
- map_stm_definition_node(counter_events: int, old_STM: ndarray, flag_augment: bool = True) ndarray#
Adjusts the State Transition Matrix (STM) to match a new state definition.
- Parameters:
counter_events (
int) – Index of the current sequence event for state transition.old_STM (
numpy.ndarray) – Previous STM to be updated.flag_augment (
bool, optional) – IfTrue, expands the STM; otherwise, reduces it. Defaults toTrue.
- Returns:
updated_stm – Updated State Transition Matrix reflecting the new state definition.
- Return type:
- observability_test(print_obs=False, threshold=0.1, meas_corr=None)#
Performs an observability analysis on the system by computing the information matrix.
Checks whether the system’s observability matrix has full rank and determines the positive definiteness of the information matrix.
- Parameters:
- Returns:
info_matrix, obs_matrix – A tuple with the following values corresponding to their respective indices:
[0]= info_matrixnumpy.ndarrayThe computed information matrix.
[1]= obs_matrixnumpy.ndarrayThe observability matrix constructed from measurement partials.
- Return type:
tuple[numpy.ndarray,numpy.ndarray]
- reinitialize(state_deviation: ndarray | None = None, state_vector: StateArray | None = None, traj_name: str | None = None, traj_dir: str | None = None, overwrite_traj: bool = True) None#
Reinitialize the filter for iterative estimation.
Updates the state vector by applying deviations from a previous filter iteration, re-propagates the trajectory, and rebuilds measurement datasets. This method enables iterative orbit determination where each iteration refines the reference trajectory using corrections from the previous filter solution.
- Parameters:
state_deviation (
np.ndarray, optional) – State deviation vector from previous filter iteration (e.g., from solution.map_state_deviation_to_epoch()). If provided, this deviation is added to the current state vector. Shape should be (n,) or (n, 1). Defaults to None.state_vector (
StateArray, optional) – New state vector to use. If None, uses the current propagator’s state vector. If state_deviation is provided, it will be applied to this state vector. Defaults to None.traj_name (
str, optional) – Name for the new trajectory BSP file. If None, auto-generates a name. Defaults to None.traj_dir (
str, optional) – Directory to write the new trajectory. If None, uses current directory. Defaults to None.overwrite_traj (
bool, optional) – If True, overwrites existing trajectory file with the same name. Defaults to True.
- Returns:
Updates self.trajectory and self.measurement_data in place.
- Return type:
- Raises:
ValueError – If state_deviation is provided but state_vector cannot be determined.
Notes
This method modifies the FilterOD object in place by: 1. Applying state deviation to the state vector (if provided) 2. Re-propagating the trajectory with the updated state 3. Rebuilding measurement datasets 4. Re-initializing filter attributes (sequence, ground stations, etc.)
The body objects are NOT modified - the same spacecraft body is used across iterations for simplicity. Each iteration operates on the same SPICE ID.
Examples
>>> # Manual iteration control >>> lkf = LKF(propagator, covariance, measurements) >>> >>> # Iteration 1 >>> solution_it1 = lkf.compute() >>> deviation_it1 = solution_it1.map_state_deviation_to_epoch() >>> >>> # Iteration 2 >>> lkf.reinitialize(state_deviation=deviation_it1) >>> solution_it2 = lkf.compute() >>> >>> # Iteration 3 >>> deviation_it2 = solution_it2.map_state_deviation_to_epoch() >>> lkf.reinitialize(state_deviation=deviation_it2) >>> solution_it3 = lkf.compute()
See also
iterateAutomatic iterative estimation with convergence checking.
_apply_state_deviationApplies deviation to state vector components.
_initializeBuilds trajectory and measurement datasets.
- smoother(printOutput: bool = True) SolutionOD#
Rauch-Tung-Striebel backward smoother.
Performs backward smoothing on the filtered solution and stores results in the filter object for SolutionOD to extract.
- Parameters:
printOutput (
bool, optional) – If True, prints progress during smoothing. Defaults to True.- Returns:
Solution object containing smoothed state deviations, covariances, and postfit residuals.
- Return type:
- split_partials_hx_hc(H: ndarray) tuple[ndarray, ndarray]#
Split the partial derivatives matrix into estimated and consider parameters.
This method partitions a matrix of partial derivatives based on whether parameters are being estimated or only considered (not estimated but whose uncertainties affect the solution).
- Parameters:
H (
np.ndarray) – Matrix of partial derivatives with shape (m, n) where m is the number of measurements and n is the total number of parameters (estimated + consider).- Returns:
- A tuple containing:
Hx (np.ndarray): Partial derivatives with respect to estimated parameters. Shape (m, n_est) where n_est is the number of estimated parameters.
Hc (np.ndarray): Partial derivatives with respect to consider parameters. Shape (m, n_con) where n_con is the number of consider parameters. Returns empty array (m, 0) if no consider parameters exist.
- Return type:
tuple[np.ndarray, np.ndarray]
- Raises:
IndexError – If idx_est or idx_con indices are invalid for the given matrix H.
- split_stm_phi_psi(STM: ndarray) tuple[ndarray, ndarray, ndarray]#
Split the State Transition Matrix (STM) into Phi and Psi components.
Extracts the estimated state parameters (Phi) and consider parameters (Psi) from the State Transition Matrix based on the configured estimation and consider parameter indices.
- Parameters:
STM (
np.ndarray) – The State Transition Matrix to be split.- Returns:
- A tuple containing:
Phi (np.ndarray): The STM submatrix corresponding to estimated parameters. If no consider parameters are configured, returns the full STM.
Psi (np.ndarray): The STM submatrix corresponding to consider parameters. If no consider parameters are configured, returns an empty array with shape (STM.shape[0], 0).
- Phi_c (np.ndarray, optional): The STM submatrix corresponding to consider
parameters only. Returned only if consider parameters exist.
- Return type:
tuple[np.ndarray, np.ndarray, np.ndarray]