Why Your Controller Works in Discrete Time but Fails in Continuous Simulation

A spacecraft attitude controller may look stable in a fixed-step simulation, but behave differently when placed inside an adaptive solver. This problem investigates why the controller, the physics, and the gains can remain the same, while the response changes because the timing assumption changed.

Problem Setup

Spacecraft Attitude Problem

The spacecraft is represented by a simple rotational model. Its attitude is described using orientation angle \( \theta \), angular velocity \( \omega \), and control torque \( \tau \).

The goal is to rotate the spacecraft toward a target attitude without excessive overshoot or oscillation.

$$ \dot{\theta} = \omega $$ $$ \dot{\omega} = \tau $$

In this simplified model, the moment of inertia is taken as unity so that the torque command directly produces angular acceleration. This keeps the focus on the simulation timing problem rather than spacecraft inertia modelling.

Controller Design

PD Attitude Controller

The controller uses attitude error and angular velocity to calculate torque. The proportional term pulls the spacecraft toward the target. The derivative term provides damping.

$$ \tau = K_p(\theta_{target} - \theta) - K_d\omega $$
$$ \theta_{k+1} = \theta_k + \omega_k \Delta t $$ $$ \omega_{k+1} = \omega_k + \tau_k \Delta t $$ $$ \tau_k = K_p(\theta_{target} - \theta_k) - K_d\omega_k $$

In the fixed-step version, the response looks stable because both the controller and the state update at the same known timestep.

\(K_p\) decides how strongly the spacecraft reacts to attitude error. \(K_d\) decides how strongly the controller resists angular velocity.

In a fixed-step simulation, this controller is evaluated at a regular time interval. That means the damping behaviour is predictable. The hidden assumption is that the controller has a known update rate.

Simulation Cases

What This Problem Investigates

This problem compares three ways of simulating the same spacecraft attitude controller. The gains are unchanged. The spacecraft dynamics are unchanged. Only the timing assumption changes.

The third case represents the engineering fix. Real flight software does not update whenever the numerical solver feels like stepping. It updates on a clock.

Where It Breaks

Where the Timing Assumption Breaks

The controller implicitly assumes a known control update rate:

$$ \text{Control update rate} = \frac{1}{\Delta t} $$

With adaptive stepping, \( \Delta t \) is no longer constant.

$$ \Delta t \neq \text{constant} $$

That means control may be applied too late, too frequently, or at irregular intervals. The derivative term no longer behaves with the same damping effect.

Interactive Demo

Run the Same Controller Three Ways

Select a simulation mode, adjust the gains, and run the response. The purpose is to observe how timing affects attitude response, angular velocity, torque command, and effective timestep.

Choose simulation mode:





What You Observe

Fixed Step vs Adaptive Solver Behaviour

Behaviour Fixed Step Adaptive Solver
Rise time Smooth Irregular
Damping Consistent Varies
Stability Stable May oscillate
Control effort Predictable Spiky
Why It Happens

Why Adaptive Stepping Can Mislead the Controller

An adaptive solver such as ODE45 changes its timestep to solve the differential equation efficiently and accurately. If the motion changes quickly, the solver may take smaller steps. If the motion is smooth, it may take larger steps.

That behaviour is good for solving physics. The problem appears when a discrete controller is placed inside the solver without modelling its update timing.

A digital controller normally assumes a fixed update rate. It reads the state, calculates a command, sends the command, waits for the next control cycle, and repeats. That is a sampled-data system.

Read sensors → Estimate state → Compute control command → Send actuator command → Wait until next control cycle

If the controller is evaluated at irregular solver-selected times, then the controller is no longer behaving like real flight software. The damping term can become inconsistent, the response may overshoot more, and the torque command may become irregular.

Inside the Solver

What the Adaptive Solver Is Actually Doing

An adaptive solver does not step randomly. It adjusts its timestep based on how fast the solution is changing.

When dynamics are fast → small timestep When dynamics are smooth → large timestep

Notice how the timestep shrinks during rapid motion and expands when the system settles. This behaviour is ideal for solving physics — but it breaks assumptions of a fixed-rate controller.

Engineering Fix

The Fix Is Not Simply “Change the Gains”

Poor behaviour does not always mean the controller gains are wrong. Sometimes the simulation architecture is wrong.

Option A — Fixed-step simulation

Use a fixed simulation timestep when the controller is intended to run at a fixed update rate.

Option B — Sample-and-hold inside continuous propagation

Let the plant evolve continuously, but update the controller only at fixed clock intervals. Between controller updates, hold the previous torque command constant.

Option C — Fully continuous controller

Treat the controller as a continuous-time law:

$$ \tau(t) = K_p(\theta_{target} - \theta(t)) - K_d\dot{\theta}(t) $$

This is mathematically valid, but it is not the same as real digital flight software unless the real controller is also continuous.

Reality Check

Why This Controller Still Fails in Real Systems

Even after fixing the simulation timing, the controller is still based on a simplified assumption: that torque can be applied instantly and without limits.

In a real spacecraft, control is implemented through actuators such as reaction wheels or control moment gyros. These introduce constraints that fundamentally change how the controller behaves.

Actuator Limits

The commanded torque cannot exceed actuator capability:

$$ |\tau| \leq \tau_{max} $$

If the controller demands more torque than available, the system saturates. This removes damping and can lead to overshoot or oscillation.

Momentum Buildup

Reaction wheels accumulate angular momentum over time:

$$ H = I_w \omega_w $$

Without momentum dumping, the actuator eventually reaches its limit and can no longer produce control torque.

Sensor and Estimation Delay

The controller does not receive the true state instantly. There is always delay due to sensing and estimation:

$$ \theta_{measured}(t) = \theta(t - \Delta t_{delay}) $$

This delay reduces effective damping and can destabilize otherwise stable gains.

Key Engineering Insight

A controller that works in ideal simulation may fail once actuator limits and delays are introduced.

This is why controller design must always be validated against physical constraints, not just numerical behaviour.

Python Implementation

Reproducing This Behaviour in Python

The same mismatch appears when using adaptive solvers like solve_ivp in Python.


import numpy as np
from scipy.integrate import solve_ivp

Kp = 5
Kd = 2
theta_target = 1

def dynamics(t, state):
    theta, omega = state
    tau = Kp*(theta_target - theta) - Kd*omega
    return [omega, tau]

t_span = (0, 20)
y0 = [0, 0]

sol = solve_ivp(dynamics, t_span, y0, method='RK45')

This produces behaviour similar to the adaptive simulation shown earlier. The controller is evaluated at solver-selected time points, not at a fixed rate.

Takeaway

What This Problem Shows

A controller that works in simulation is not automatically a good controller. It only works under the assumptions used by that simulation.

Controller

Same \(K_p\), same \(K_d\), same target attitude.

Plant

Same attitude dynamics: \( \dot{\theta} = \omega \), \( \dot{\omega} = \tau \).

Difference

The timing assumption changes.

The engineering lesson is simple but important:

Controller design is inseparable from simulation timing.