I built a 2D orbit simulator that estimates a spacecraft state from noisy ground station measurements using an Extended Kalman Filter (EKF). The estimate drives an LQR state feedback controller with a fixed acceleration limit. I evaluate the filter with Monte Carlo runs using NEES and NIS consistency checks, and I track control effort and saturation.
This project couples orbit determination and feedback control in one loop. The dynamics use a simple planar two body gravity model so the focus stays on measurement availability, noise modeling, and estimator consistency.
R.
u = −K x̂ with saturation. Initialize weights with Bryson’s rule, then tune the balance between response speed and control effort.
EKF with nonlinear propagation (ode45), Jacobians evaluated at the current estimate, covariance propagation with acceleration process noise, stacked measurement updates, and a measurement size that changes with station visibility.
LQR designed about a nominal circular orbit using a linear state space model, gain synthesis, Bryson’s rule weight selection, and saturation to a fixed maximum acceleration used in this demo.
Separate truth noise from the noise assumed by the filter, include time varying station visibility, run Monte Carlo trials, and log errors, innovations, and control saturation.
The truth model propagates nonlinear two body dynamics and injects disturbances as additive acceleration noise. Disturbances and actuation share the same acceleration interface so the truth inputs can be compared directly to the model used inside the EKF.
The truth trajectory is propagated with numerical integration and sampled at a fixed update period for EKF updates.
Each visible station returns range, range rate, and angle. Visibility changes over time, so the measurement size changes. When no stations are visible, the filter only predicts forward and uncertainty grows. When measurements return, uncertainty shrinks again.
Propagate the nonlinear state estimate forward with the dynamics. Evaluate the dynamics Jacobian at the most recent corrected estimate.
Propagate covariance using the linearized transition and an acceleration noise mapping. Use NEES and NIS trends across Monte Carlo trials to tune noise levels.
Stack measurements from all visible stations, build a block diagonal R, and apply the EKF update.
Stacking: If m stations are visible, the measurement vector has length 3m. The ordering must stay consistent across y, H, and R.
Linearization: If the Jacobians do not match the model used in propagation, the EKF becomes unreliable fast. I evaluate Jacobians at the corrected estimate each step.
Dropouts: Visibility gaps are common, especially during lower orbits. During gaps, uncertainty grows. After gaps, measurements pull the estimate back toward the truth.
Noise assumptions: Truth noise is separate from the noise assumed by the filter so mismatch can be tested and its impact on NEES and NIS can be measured.
The controller is designed by linearizing about a nominal circular orbit of radius r₀. The state is expressed as small in plane perturbations with a two axis control input.
With mean motion n = sqrt(μ / r₀³), one common in plane linearization is:
LQR minimizes state error and control effort and returns a stabilizing gain K.
I initialize Q and R with Bryson’s rule and tune the trade between tracking and effort with a scalar multiplier. The commanded acceleration is saturated to a fixed limit used for this demo, 0.01 g.
I compare designs using time response and integrated control effort under the same acceleration limit. Once saturation engages, performance is limited by available acceleration rather than by the feedback gain.
I evaluate filter consistency using NEES for state error and NIS for innovation error, and compare them to chi square bounds. These checks reveal underconfident or overconfident covariance tuning across many trials.
I randomize the initial truth state around the filter initial estimate using the initial covariance, then run repeated trials. This exposes failure modes that a single run can hide.
The controller command is saturated to a fixed acceleration capability, 0.01 g in this demo. This keeps comparisons consistent across controller designs.
This page documents a coupled estimation and control loop with time varying measurement availability. The algorithms were developed in MATLAB. This site presents results and links to supporting materials.
The demo applies continuous acceleration, which helps compare controllers but does not match many real spacecraft thrusters. A more realistic actuation layer would convert commands into discrete firings with a minimum impulse bit and would track propellant use and delta V. Deadband logic would also reduce chatter driven by estimator noise.
LQR is a strong baseline, but it only handles limits through saturation. A more operational setup adds an outer layer that trades performance against propellant and delta V, and that enforces constraints directly.
Orbit determination with nonlinear filtering, station geometry, stacked measurement updates, and NEES/NIS testing.
Linearized orbital perturbation model, LQR synthesis and tuning, and performance comparison against a manual controller.
Interested in discussing GN&C roles or this project? I'd love to chat.
Please reach out by email or LinkedIn below.