What is a linear system anyway?

‘Linear systems’ get their name because they exhibit a linear response to changes in input. “What’s a linear response?” I hear you ask, we can say that a system is linear if it obeys two rules:

Together those two are called superposition. It sounds simple but these properties are what allow us to tackle such systems with elegant control solutions. The goal of this post is to explain the intuition behind one, and I’ll be using a boiler to do so because it’s a classic example.

The boiler

Imagine we’re trying to control the water temperature inside a boiler. We have control over the strength of a flame that can be used to heat up the water. How can we use the flame to achieve a target water temperature?

Let’s see what can we state about the boiler:

The easy way

It follows that for any target temperature2, there’s a given flame strength that will be able to hold that target by balancing the heat loss. Why not set the flame to that strength, and wait for the water to reach temp? We can put together an equation to solve for the required strength:

τdTdt=−(T(t)−Tambient)+K⋅f(t)\tau \frac{dT}{dt} = -\big(T(t) - T_{ambient}\big) + K\cdot f(t)

Don’t be intimidated! The equation represents several simple concepts:

Solving where dT/dt=0dT/dt=0 (the steady state) gives exactly the flame strength we were after:

fsteady=Ttarget−TambientKf_{steady} = \frac{T_{target} - T_{ambient}}{K}

For example, let’s say our boiler’s cool water starts at Tambient=15°CT_{ambient}=15°C, but we want Ttarget=45°CT_{target}=45°C, and for this particular boiler K=30°C/uK=30°C/u. Then:

fsteady=45−1530=1uf_{steady} = \frac{45-15}{30} = 1u

So holding the flame at strength 11 unit is what keeps the water sitting at 45°C once things settle down.

If we set the flame to fsteadyf_{steady} and just wait, T(t)T(t) climbs towards TtargetT_{target} and eventually settles there:

Mystery Tau, look at it we shall ♪

Eagle eyed readers might have noticed that I labelled time in multiples of τ\tau, which I did because τ\tau is the time constant. The time constant of a linear system is the fundamental time unit that dictates how quickly it responds. More specifically a time constant is the time it takes for the system to reach approximately 63.2%63.2\% of its climb to the steady-state value.

“Why 63.2%?” I hear you ask, it’s because a linear system’s approach to the target follows an exponential curve. As we heat up and approach the target, the heat loss also increases (because it’s proportional to how far above ambient the water is), while the amount of heat we’re adding remains fixed. All that means is our approach slows as we get closer and closer. The path it follows is exactly (with T(0)=TambientT(0) = T_{ambient}):

T(t)=T(0)+(Ttarget−T(0))⋅(1−e−t/τ)T(t) = T(0) + (T_{target}-T(0)) \cdot \big(1 - e^{-t/\tau}\big)

In other words, the distance to the target closes at an exponentially decaying rate, so we call this an exponential approach.

Why is my shower still cold?!

Right so that’s a little slow… perhaps we could reach the target faster by starting with a stronger flame to heat the water up more quickly, and then smoothly transition to fsteadyf_{steady} as we approach the target?

Let’s try it… below you can see that the stronger start moves more heat in early, so the resulting temperature (left axis) reaches TtargetT_{target} sooner. The flame driving it (right axis) starts high and tapers back down to fsteadyf_{steady} as we approach the target:

Here I’ve used twice the starting flame strength initially, reducing it to fsteadyf_{steady} by the end. You can see that we’re reaching that 63.2%63.2\% mark in half the time.

Let’s crank this flame up to eleven!

This leads to two natural questions: “How strong should we set the initial flame?” and “Over what time period should we transition between the two?” It turns out these two questions are very intertwined.

We know that τ\tau is a kind of measure of the response rate of the system, but imagine we want the boiler to respond more quickly on some shorter time constant τfast\tau_{fast}. Assuming our boiler has τ=66s\tau = 66s, let’s push it 11 times faster: τfast=τ11=6s\tau_{fast} = \frac{\tau}{11} = 6s. If we bring back the first equation, we can solve for the initial state where T(0)=TambientT(0) = T_{ambient}. Remember that we’re closing a 30°C30°C gap, and K=30°C/uK = 30°C/u:

dT=Ttarget−T(0),dt=τfastτ⋅dTdt=−(T(t)−Tambient)+K⋅f(t)66s⋅30°C6s=0+30°C/u⋅f(0)∴f(0)=11u\begin{align*} dT &= T_{target} - T(0),\qquad dt = \tau_{fast} \\ \tau \cdot \frac{dT}{dt} &= -\big(T(t) - T_{ambient}\big) + K\cdot f(t) \\ & \\ 66s \cdot \frac{30°C}{6s} &= 0 + 30°C/u\cdot f(0) \\ \therefore f(0) &= 11u \end{align*}

An eleven times shorter time constant and eleven times the flame! 5

And that’s no coincidence, remember that: Ttarget−Tambient=K⋅fsteadyT_{target} - T_{ambient} = K \cdot f_{steady}. 6 It turns out we can do some rearranging to find that the starting flame strength is defined by a ratio of the two time constants:

f(0)=dTdt⋅τK=Ttarget−Tambientτfast⋅τK=K⋅fsteadyτfast⋅τK=fsteady⋅ττfast\begin{align*} f(0) &= \frac{dT}{dt} \cdot \frac{\tau}{K} \\ &= \frac{T_{target} - T_{ambient}}{\tau_{fast}} \cdot \frac{\tau}{K} \\ &= \frac{K \cdot f_{steady}}{\tau_{fast}} \cdot \frac{\tau}{K} \\ &= f_{steady} \cdot \frac{\tau}{\tau_{fast}} \end{align*}

This is super cool! It means our rule generalizes to: “Want to go XX times as fast? Then use XX times the flame, faded out with 1Xτ\frac{1}{X}\tau”

So where does that leave us?

As we’ve learned, the time constant represents the exponential approach to the target temperature, and we want our strong initial flame to fade out matching that approach, so it needs an exponential decay.7 Plugging that in we can write down the entire continuous flame function that describes every flame strength from now until the water settles:

f(t)=fsteady+(f(0)−fsteady)⋅e−t/τfast=fsteady+fsteady⋅(ττfast−1)⋅e−t/τfast\begin{align*} f(t) &= f_{steady} + (f(0) - f_{steady}) \cdot e^{-t/\tau_{fast}} \\ &= f_{steady} + f_{steady} \cdot \left(\frac{\tau}{\tau_{fast}} - 1\right) \cdot e^{-t/\tau_{fast}} \end{align*}

Think about what we just did. Split the flame function8 down the middle:

f(t)=fsteady⏟holds the target+fsteady⋅(ττfast−1)⋅e−t/τfast⏟boost that fades awayf(t) = \underbrace{f_{steady}}_{\text{holds the target}} + \underbrace{f_{steady} \cdot \left(\frac{\tau}{\tau_{fast}} - 1\right) \cdot e^{-t/\tau_{fast}}}_{\text{boost that fades away}}

A steady part that holds the target forever, and an extra part that dies off once we’ve arrived (that’s scaling!). Then just… add them together (that’s superposition!).

That’s all there is to it. To solve a linear system9, we start by identifying the ideal steady state conditions, and then tune the aggressiveness (τfast\tau_{fast}) to accelerate the path there.