GCC Code Coverage Report


Directory: ./
File: firmware/controllers/closed_loop_controller.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 18 0 18
Functions: 100.0% 2 0 2
Branches: 100.0% 14 0 14
Decisions: 100.0% 8 - 8

Line Branch Decision Exec Source
1 /**
2 * @file closed_loop_controller.h
3 */
4
5 #pragma once
6
7 #include <rusefi/expected.h>
8
9 template <typename TInput, typename TOutput>
10 class ClosedLoopController {
11 public:
12 211 void update() {
13
1/1
✓ Branch 2 taken 211 times.
211 expected<TOutput> outputValue = getOutput();
14
1/1
✓ Branch 1 taken 211 times.
211 setOutput(outputValue);
15 211 }
16
17 private:
18 211 expected<TOutput> getOutput() {
19
1/1
✓ Branch 2 taken 211 times.
211 expected<TInput> setpoint = getSetpoint();
20 // If we don't know the setpoint, return failure.
21
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 209 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 209 times.
211 if (!setpoint) {
22 2 return unexpected;
23 }
24
25
1/1
✓ Branch 2 taken 209 times.
209 expected<TInput> observation = observePlant();
26 // If we couldn't observe the plant, return failure.
27
2/2
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 158 times.
2/2
✓ Decision 'true' taken 51 times.
✓ Decision 'false' taken 158 times.
209 if (!observation) {
28 51 return unexpected;
29 }
30
31
1/1
✓ Branch 2 taken 158 times.
158 expected<TOutput> openLoopResult = getOpenLoop(setpoint.Value);
32 // If we couldn't compute open loop, return failure.
33
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 157 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 157 times.
158 if (!openLoopResult) {
34 1 return unexpected;
35 }
36
37
1/1
✓ Branch 2 taken 157 times.
157 expected<TOutput> closedLoopResult = getClosedLoop(setpoint.Value, observation.Value);
38 // If we couldn't compute closed loop, return failure.
39
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 156 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 156 times.
157 if (!closedLoopResult) {
40 1 return unexpected;
41 }
42
43 156 return openLoopResult.Value + closedLoopResult.Value;
44 }
45
46 // Get the setpoint: where should the controller put the plant?
47 virtual expected<TInput> getSetpoint() = 0;
48
49 // Get the current observation: what is the current state of the world?
50 virtual expected<TInput> observePlant() = 0;
51
52 // Get the open-loop output: output state based on only the setpoint
53 virtual expected<TOutput> getOpenLoop(TInput setpoint) = 0;
54
55 // Get the closed-loop output: output state based on setpoint and observation
56 virtual expected<TOutput> getClosedLoop(TInput setpoint, TInput observation) = 0;
57
58 // Set the output: Drive whatever output system will perturb the plant in the real world
59 virtual void setOutput(expected<TOutput> outputValue) = 0;
60 };
61