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 |