5.5.22 · D4Embedded Systems & Real-Time Software

Exercises — Software-in-the-Loop (SIL) simulation — all software, simulated hardware

3,632 words17 min readBack to topic

Level 1 — Recognition

L1.1 — What is "in the loop"?

Recall Solution

Answer: (b). The "loop" is the closed-loop feedback path. Look at the figure below: the two boxes are the Software (SUT) on the left and the Plant model on the right. Follow the red arrow — that is the command the software sends out. Then follow the black arrow back — that is the sensor value the plant returns, which becomes the software's next input. Because the output loops back to become the next input, the data-flow forms a closed circle — that circle is the "loop," not any for-loop in the code.

Figure — Software-in-the-Loop (SIL) simulation — all software, simulated hardware

Figure L1.1: the closed SIL feedback loop. Red = the command signal (the key object); black = the returned sensor signal that closes the cycle.

(a) is a distractor: any program has for loops. (c) describes the developer's workflow, not the runtime signal path.

L1.2 — Match the component

Recall Solution

1→B, 2→C, 3→A, 4→D.

  • SUT (1→B): the real code you will ship.
  • Plant model (2→C): equations replacing motors/sensors.
  • Cosim framework (3→A): the orchestrator that steps both clocks.
  • HAL (4→D): Hardware Abstraction Layer — the seam that lets the same core logic run on PC (SIL) or MCU (production) by swapping only this layer.

L1.3 — Which stage catches which bug?

Recall Solution

No. A linear model has no saturation limit, so the actuator command is never clamped — the windup condition (command pinned at max while error keeps integrating) never occurs. You need a high-fidelity model with a if speed > max_rpm: speed = max_rpm limit.


Level 2 — Application

L2.1 — One Euler tick by hand

Recall Solution

What we do: evaluate the derivative at the current state, then step forward. Why Euler and not something fancier? Euler is the cheapest solver — one derivative evaluation per step. For a first look it's fine; its cost is accuracy, addressed in L3.

L2.2 — Two ticks, watch the state carry

Recall Solution

Why re-evaluate the derivative? The whole point of "in-the-loop" is that the new state feeds the next step. Notice the increment shrank (): the model is approaching its steady value . That lag toward the steady value is exactly the dynamic behaviour a medium-fidelity model (defined in the box above — the first-order rule) exists to reveal, and a low-fidelity speed = K*u model would miss entirely.

L2.3 — The braking scenario

Recall Solution

Why convert units first? The model's terms are in metres and seconds (SI). Mixing km/h into a formula that expects m/s would silently scale the physics wrong — a classic SIL unit bug the low-fidelity check exists to catch. The conversion factor: and , so Therefore . This is a repeating decimal ; we carry the exact fraction through the arithmetic and only round the final answers to 3 decimals at the very end (writing or is a rounded display of an exact fraction, never a value we feed back in).

Deceleration . Why update distance with the old velocity ? This is Euler's rule — it uses the state at the start of the interval. (If you had rounded to first and fed that back, you'd read and — the danger is not the display digits but rounding before the next computation.)


Level 3 — Analysis

L3.1 — Why does big blow up?

Recall Solution

The per-step multiplier is ; each step multiplies by . The red curve in the figure is the one that diverges — that is the case to fear.

Figure — Software-in-the-Loop (SIL) simulation — all software, simulated hardware

Figure L3.1: three Euler runs of the same decaying state. X-axis = simulated time (s); Y-axis = state . Black solid = stable decay; black dashed = oscillating-but-shrinking; red = diverging. Watch how only the red run grows in magnitude away from zero.

Walking every range of , boundaries included:

  • Degenerate boundary (): no step is taken at all, so never changes — the state is frozen. This is trivially "stable" but useless: with zero time advance the simulation makes no progress. We list it for completeness, because it is the exact edge where the step size vanishes.
  • (): smooth monotone decay toward 0 — the correct physics (black solid).
  • Boundary (): the state snaps to exactly 0 in a single step and stays there. Harmless but non-physical (real decay is gradual, never instant).
  • (): sign flips each step but magnitude shrinks — a decaying oscillation (black dashed). Non-physical wobble, but it doesn't blow up.
  • Boundary (): marginal stability flips forever at constant magnitude, never settling. This is the knife-edge between stable and unstable.
  • (): magnitude grows every step — true divergence (red curve). This is the "numerical instability" the parent note warns about.

Why this matters for SIL: picking too large to "run faster" can make the plant model report physics that never happen, so you'd debug a simulation artifact, not your code.

L3.2 — Reading the fidelity budget

Recall Solution

Where does the 6% abstraction error come from? (the WHY, derived, not asserted): The ADC (analog-to-digital converter) needs 2 clock cycles to finish a conversion; at a 1 kHz control rate the control period is ... but here the delay is quoted relative to a loop period, giving a fractional delay of a cycle. A pure time delay of cycles is, to first order, the same as removing phase margin from the loop: it subtracts a phase angle of phase margin at the loop's crossover (here crossover sits near one-seventh of the sample rate, a typical well-tuned value). Now use the standard second-order overshoot-vs-phase-margin relation — the textbook approximation that overshoot percentage near a nominal margin, i.e. losing phase margin adds overshoot roughly one-for-one in the band. Losing of margin therefore adds on the order of extra overshoot. So the "" is a derived engineering estimate from the known 2-cycle delay, not a chart pulled from nowhere — and crucially, SIL never models this delay, so it cannot see this term at all.

Worst-case bound: possible prediction error — larger than the margin, so SIL alone is not trustworthy for this spec. Which term first? The abstraction error (6%) dominates and is the one SIL structurally cannot see. It's an unmodeled effect (ADC conversion delay), so no amount of solver tuning fixes it. That is exactly the "necessary-but-not-sufficient" limit: move this spec's check to PIL/HIL where real timing appears, and shrink discretization only if it's cheap.


Level 4 — Synthesis

L4.1 — Where does the HAL cut?

Recall Solution

First, note what each symbol means: pid(error) is a pure-computation controller — input is the tracking error, output is the command; it touches no hardware, so it is core logic and stays put. The offending line is instead the direct memory-mapped register read *(volatile int*)0x4001A004. It is hardware-specific and cannot exist on a host PC. Refactor — pull it behind a HAL call:

int hal_read_sensor(void);   // SIL: returns plant-model value
                             // MCU: reads 0x4001A004
int control_step(void) {
    int raw = hal_read_sensor();       // core logic untouched
    int cmd = pid(setpoint - raw);     // pid() unchanged, still pure
    return cmd;
}

Now control_step is platform-independent: . In SIL the framework links a hal_read_sensor that returns the plant model's sensor value; on the target it links the register version. This mirrors Unit Testing for Embedded Systems, where the same seam lets you inject stub inputs.

L4.2 — Design a two-stage plan

Recall Solution
  • (i) Sign error → SIL. This is pure algorithm logic. Feed a known rotating input through the plant model; a sign flip makes the fused angle diverge from ground truth immediately, cheaply, in software.
  • (ii) EMI-spike crash → HIL. An EMI outlier is an abstraction-error effect — real electrical noise with heavy-tailed spikes that a clean Gaussian SIL model won't produce. Real analog front-end + wiring (HIL) is where such glitches actually appear. Plan: SIL first (catch the cheap logic bug), then HIL (catch the physical-world bug). This is the parent note's "necessary but not sufficient" doctrine applied.

Level 5 — Mastery

L5.1 — Euler vs RK4 cost/accuracy trade-off

Recall Solution

Why these thresholds (the WHY): the local error per step scales like , where is the method's order — Euler is order , RK4 is order . To hit the same small error target :

  • Euler: error , so — a loose bound, forcing many small steps; the "" captures needing 10 steps across one time constant to resolve it.
  • RK4: error , which shrinks dramatically faster, so the same is met with a much larger step — the "" (about 2 steps per time constant).

The ratio between allowed step sizes is the payoff of RK4's higher order. Now the counting:

Euler: → steps → evals . RK4: → steps → evals . Decision: RK4 is cheaper here — 48000 < 60000 evals — and more accurate, because its larger stable step outweighs its 4× per-step cost. The lesson: "Euler is fast" is a per-step claim; total cost = steps × cost/step, and a stiffer accuracy demand can flip the winner.

L5.2 — Is SIL sufficient here? Judgment call

Recall Solution

Argument: SIL's prediction error is bounded by (model + discretization + abstraction) error, and the abstraction term covers exactly the effects you didn't model — sensor EMI spikes, MCU timing jitter, voltage sag — so 100000 passing scenarios only prove correctness within your model's world, never outside it. Zero SIL failures cannot bound the un-modeled term. Correct move: SIL proves algorithm correctness; escalate through Hardware-in-the-Loop (HIL) and a Real-Time Operating Systems (RTOS)-scheduled real-time run to validate timing and physical robustness before any ship decision.


Recall Quick self-test (cloze)

In SIL, the artifact under test is the software (SUT), while the plant model is a trusted stand-in. Forward Euler computes every new-state value from old-state values only. For decay with time constant , Euler diverges when ==, and is marginally stable exactly at . The one error term SIL structurally cannot see is abstraction error== (unmodeled effects). Euler step for in L2.1 ::: rad/s RK4 vs Euler total evals in L5.1 ::: 48000 vs 60000 — RK4 cheaper


Parent: Software-in-the-Loop (SIL) simulation — all software, simulated hardware (index 5.5.22) · See also: Hardware-in-the-Loop (HIL) · Unit Testing for Embedded Systems · Real-Time Operating Systems (RTOS) · Sensor Fusion Algorithms