| 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 |