rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes
BoostController Class Reference

#include <boost_control.h>

Inheritance diagram for BoostController:
Inheritance graph
[legend]
Collaboration diagram for BoostController:
Collaboration graph
[legend]

Public Member Functions

void init (IPwm *const pmw, const ValueProvider3D *const openLoopMap, const ValueProvider3D *const closedLoopTargetMap, const ValueProvider2D &cltMultiplierProvider, const ValueProvider2D &iatMultiplierProvider, const ValueProvider2D &cltAdderProvider, const ValueProvider2D &iatAdderProvider, pid_s *const pidParams)
 
void onFastCallback () override
 
void setDefaultConfiguration () override
 
void resetLua ()
 
void onConfigurationChange (engine_configuration_s const *previousConfig) override
 
expected< floatobservePlant () override
 
expected< floatgetSetpoint () override
 
expected< percent_tgetOpenLoop (float target) override
 
expected< percent_tgetClosedLoop (float target, float manifoldPressure) override
 
void setOutput (expected< percent_t > outputValue) override
 
- Public Member Functions inherited from EngineModule
virtual void initNoConfiguration ()
 
virtual void onSlowCallback ()
 
virtual void onEngineStop ()
 
virtual void onIgnitionStateChanged (bool)
 
virtual bool needsDelayedShutoff ()
 
virtual void onEnginePhase (float, efitick_t, angle_t, angle_t)
 
- Public Member Functions inherited from ClosedLoopController< float, percent_t >
void update ()
 

Private Member Functions

percent_t getClosedLoopImpl (float target, float manifoldPressure)
 
float getBoostControlDutyCycleWithTemperatureCorrections (const float rpm, const float driverIntent) const
 
std::optional< floatgetBoostControlTargetTemperatureAdder () const
 
std::optional< floatgetBoostTemperatureCorrection (const SensorType sensorType, const ValueProvider2D &correctionCurve) const
 

Private Attributes

Pid m_pid
 
const ValueProvider3Dm_openLoopMap = nullptr
 
const ValueProvider3Dm_closedLoopTargetMap = nullptr
 
const ValueProvider2Dm_cltBoostCorrMap = nullptr
 
const ValueProvider2Dm_iatBoostCorrMap = nullptr
 
const ValueProvider2Dm_cltBoostAdderMap = nullptr
 
const ValueProvider2Dm_iatBoostAdderMap = nullptr
 
IPwmm_pwm = nullptr
 

Additional Inherited Members

- Data Fields inherited from boost_control_s
bool isTpsInvalid: 1 {}
 
bool m_shouldResetPid: 1 {}
 
bool isBelowClosedLoopThreshold: 1 {}
 
bool isNotClosedLoop: 1 {}
 
bool isZeroRpm: 1 {}
 
bool hasInitBoost: 1 {}
 
bool rpmTooLow: 1 {}
 
bool tpsTooLow: 1 {}
 
bool mapTooLow: 1 {}
 
bool isPlantValid: 1 {}
 
bool isBoostControlled: 1 {}
 
bool unusedBit_11_11: 1 {}
 
bool unusedBit_11_12: 1 {}
 
bool unusedBit_11_13: 1 {}
 
bool unusedBit_11_14: 1 {}
 
bool unusedBit_11_15: 1 {}
 
bool unusedBit_11_16: 1 {}
 
bool unusedBit_11_17: 1 {}
 
bool unusedBit_11_18: 1 {}
 
bool unusedBit_11_19: 1 {}
 
bool unusedBit_11_20: 1 {}
 
bool unusedBit_11_21: 1 {}
 
bool unusedBit_11_22: 1 {}
 
bool unusedBit_11_23: 1 {}
 
bool unusedBit_11_24: 1 {}
 
bool unusedBit_11_25: 1 {}
 
bool unusedBit_11_26: 1 {}
 
bool unusedBit_11_27: 1 {}
 
bool unusedBit_11_28: 1 {}
 
bool unusedBit_11_29: 1 {}
 
bool unusedBit_11_30: 1 {}
 
bool unusedBit_11_31: 1 {}
 
scaled_channel< int16_t, 2, 1 > luaTargetAdd = (int16_t)0
 
uint8_t alignmentFill_at_6 [2] = {}
 
float luaTargetMult = (float)0
 
scaled_channel< int16_t, 30, 1 > boostControlTarget = (int16_t)0
 
uint8_t alignmentFill_at_14 [2] = {}
 
float openLoopPart = (float)0
 
scaled_channel< int16_t, 10, 1 > openLoopYAxis = (int16_t)0
 
uint8_t alignmentFill_at_22 [2] = {}
 
float luaOpenLoopAdd = (float)0
 
scaled_channel< int8_t, 2, 1 > boostControllerClosedLoopPart = (int8_t)0
 
uint8_t alignmentFill_at_29 [1] = {}
 
scaled_channel< int16_t, 100, 1 > boostOutput = (int16_t)0
 

Detailed Description

Definition at line 17 of file boost_control.h.

Member Function Documentation

◆ getBoostControlDutyCycleWithTemperatureCorrections()

float BoostController::getBoostControlDutyCycleWithTemperatureCorrections ( const float  rpm,
const float  driverIntent 
) const
private

Definition at line 196 of file boost_control.cpp.

199 {
200 float result = m_openLoopMap->getValue(rpm, driverIntent);
201 std::optional<float> cltBoostMultiplier = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostCorrMap);
202 if (cltBoostMultiplier.has_value()) {
203 result *= cltBoostMultiplier.value();
204 }
205 std::optional<float> iatBoostMultiplier = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostCorrMap);
206 if (iatBoostMultiplier.has_value()) {
207 result *= iatBoostMultiplier.value();
208 }
209 return result;
210}
const ValueProvider2D * m_cltBoostCorrMap
const ValueProvider2D * m_iatBoostCorrMap
std::optional< float > getBoostTemperatureCorrection(const SensorType sensorType, const ValueProvider2D &correctionCurve) const
const ValueProvider3D * m_openLoopMap
virtual float getValue(float xColumn, float yRow) const =0
static ProxySensor driverIntent(SensorType::DriverThrottleIntent)

Referenced by getOpenLoop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getBoostControlTargetTemperatureAdder()

std::optional< float > BoostController::getBoostControlTargetTemperatureAdder ( ) const
private

Definition at line 212 of file boost_control.cpp.

212 {
214 const std::optional<float> iatBoostAdder = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostAdderMap);
215 if (iatBoostAdder.has_value()) {
216 if (result.has_value()) {
217 result.value() += iatBoostAdder.value();
218 } else {
219 result = iatBoostAdder;
220 }
221 }
222 return result;
223}
const ValueProvider2D * m_iatBoostAdderMap
const ValueProvider2D * m_cltBoostAdderMap

Referenced by getSetpoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getBoostTemperatureCorrection()

std::optional< float > BoostController::getBoostTemperatureCorrection ( const SensorType  sensorType,
const ValueProvider2D correctionCurve 
) const
private

Definition at line 225 of file boost_control.cpp.

228 {
229 const SensorResult temperature = Sensor::get(sensorType);
230 if (temperature.Valid) {
231 const std::optional<float> boostCorrection = correctionCurve.getValue(temperature.Value);
232 if (boostCorrection.has_value()) {
233 return std::make_optional<float>(boostCorrection.value());
234 }
235 }
236 return {};
237}
virtual SensorResult get() const =0
virtual std::optional< float > getValue(float x) const =0
expected< float > SensorResult
Definition sensor.h:46

Referenced by getBoostControlDutyCycleWithTemperatureCorrections(), and getBoostControlTargetTemperatureAdder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getClosedLoop()

expected< percent_t > BoostController::getClosedLoop ( float  target,
float  manifoldPressure 
)
overridevirtual

Implements ClosedLoopController< float, percent_t >.

Definition at line 240 of file boost_control.cpp.

240 {
241 boostControllerClosedLoopPart = getClosedLoopImpl(target, manifoldPressure);
242
244
245 boostControlTarget = target;
246
247 return (float)boostControllerClosedLoopPart;
248}
percent_t getClosedLoopImpl(float target, float manifoldPressure)
TunerStudioOutputChannels outputChannels
Definition engine.h:109
void postState(pid_status_s &pidStatus) const
Definition efi_pid.cpp:144
static EngineAccessor engine
Definition engine.h:413
scaled_channel< int16_t, 30, 1 > boostControlTarget
scaled_channel< int8_t, 2, 1 > boostControllerClosedLoopPart
Here is the call graph for this function:

◆ getClosedLoopImpl()

percent_t BoostController::getClosedLoopImpl ( float  target,
float  manifoldPressure 
)
private

Definition at line 166 of file boost_control.cpp.

166 {
167 // If we're in open loop only mode, make no closed loop correction.
169 if (isNotClosedLoop) {
170 return 0;
171 }
172
173 // Reset PID if requested
174 if (m_shouldResetPid) {
175 m_pid.reset();
176 m_shouldResetPid = false;
177 }
178
179 // If the engine isn't running, don't correct.
181 if (isZeroRpm) {
182 m_pid.reset();
183 return 0;
184 }
185
188 // We're below the CL threshold, inhibit CL for now
189 m_pid.reset();
190 return 0;
191 }
192
193 return m_pid.getOutput(target, manifoldPressure, FAST_CALLBACK_PERIOD_MS / 1000.0f);
194}
virtual void reset()
Definition efi_pid.cpp:103
float getOutput(float target, float input)
Definition efi_pid.cpp:56
static float getOrZero(SensorType type)
Definition sensor.h:83
static constexpr engine_configuration_s * engineConfiguration

Referenced by getClosedLoop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getOpenLoop()

expected< percent_t > BoostController::getOpenLoop ( float  target)
overridevirtual

Implements ClosedLoopController< float, percent_t >.

Definition at line 123 of file boost_control.cpp.

123 {
124 // Boost control open loop doesn't care about target - only TPS/RPM
125 UNUSED(target);
126
129
130 isTpsInvalid = !driverIntent.Valid;
131
132 if (isTpsInvalid) {
133 return unexpected;
134 }
135
136 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_openLoopMap != nullptr, "boost open loop", unexpected);
137 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_cltBoostCorrMap != nullptr, "boost CLT multiplier", unexpected);
138 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_iatBoostCorrMap != nullptr, "boost IAT multiplier", unexpected);
139
142
143#if EFI_ENGINE_CONTROL
144 // Add any blends if configured
145 for (size_t i = 0; i < efi::size(config->boostOpenLoopBlends); i++) {
146 auto result = calculateBlend(config->boostOpenLoopBlends[i], rpm, driverIntent.Value);
147
148 engine->outputChannels.boostOpenLoopBlendParameter[i] = result.BlendParameter;
151 engine->outputChannels.boostOpenLoopBlendYAxis[i] = result.TableYAxis;
152
153 openLoop += result.Value;
154 }
155#endif // EFI_ENGINE_CONTROL
156
157 // Add gear-based adder
159 float gearAdder = engineConfiguration->gearBasedOpenLoopBoostAdder[static_cast<int>(gear) + 1];
160 openLoop += gearAdder;
161
162 openLoopPart = openLoop;
163 return openLoop;
164}
float getBoostControlDutyCycleWithTemperatureCorrections(const float rpm, const float driverIntent) const
static constexpr persistent_config_s * config
BlendResult calculateBlend(blend_table_s &cfg, float rpm, float load)
expected< float > readGppwmChannel(gppwm_channel_e channel)
UNUSED(samplingTimeSeconds)
@ OBD_PCM_Processor_Fault
float percent_t
scaled_channel< int16_t, 10, 1 > openLoopYAxis
scaled_channel< int8_t, 2, 1 > gearBasedOpenLoopBoostAdder[TCU_GEAR_COUNT]
scaled_channel< int16_t, 10, 1 > boostOpenLoopBlendParameter[BOOST_BLEND_COUNT]
scaled_channel< uint8_t, 2, 1 > boostOpenLoopBlendBias[BOOST_BLEND_COUNT]
int8_t boostOpenLoopBlendOutput[BOOST_BLEND_COUNT]
scaled_channel< int16_t, 10, 1 > boostOpenLoopBlendYAxis[BOOST_BLEND_COUNT]
Here is the call graph for this function:

◆ getSetpoint()

expected< float > BoostController::getSetpoint ( )
overridevirtual

Implements ClosedLoopController< float, percent_t >.

Definition at line 79 of file boost_control.cpp.

79 {
80 // If we're in open loop only mode, disregard any target computation.
81 // Open loop needs to work even in case of invalid closed loop config
83 if (isNotClosedLoop) {
86 }
87
89
92
93 if (isTpsInvalid) {
94 return unexpected;
95 }
96
97 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_closedLoopTargetMap != nullptr, "boost closed loop target", unexpected);
98
99 float target = m_closedLoopTargetMap->getValue(rpm, driverIntent.Value);
100#if EFI_ENGINE_CONTROL
101 // Add any blends if configured
102 for (size_t i = 0; i < efi::size(config->boostClosedLoopBlends); i++) {
103 auto result = calculateBlend(config->boostClosedLoopBlends[i], rpm, driverIntent.Value);
104
105 engine->outputChannels.boostClosedLoopBlendParameter[i] = result.BlendParameter;
108 engine->outputChannels.boostClosedLoopBlendYAxis[i] = result.TableYAxis;
109
110 target += result.Value;
111 }
112#endif //EFI_ENGINE_CONTROL
113
114 target *= luaTargetMult;
115 target += luaTargetAdd;
116 const std::optional<float> temperatureAdder = getBoostControlTargetTemperatureAdder();
117 if (temperatureAdder.has_value()) {
118 target += temperatureAdder.value();
119 }
120 return target;
121}
const ValueProvider3D * m_closedLoopTargetMap
std::optional< float > getBoostControlTargetTemperatureAdder() const
@ DriverThrottleIntent
scaled_channel< int16_t, 2, 1 > luaTargetAdd
scaled_channel< int16_t, 10, 1 > boostClosedLoopBlendYAxis[BOOST_BLEND_COUNT]
scaled_channel< int16_t, 10, 1 > boostClosedLoopBlendParameter[BOOST_BLEND_COUNT]
scaled_channel< uint8_t, 2, 1 > boostClosedLoopBlendBias[BOOST_BLEND_COUNT]
scaled_channel< int16_t, 10, 1 > boostClosedLoopBlendOutput[BOOST_BLEND_COUNT]
Here is the call graph for this function:

◆ init()

void BoostController::init ( IPwm *const  pmw,
const ValueProvider3D *const  openLoopMap,
const ValueProvider3D *const  closedLoopTargetMap,
const ValueProvider2D cltMultiplierProvider,
const ValueProvider2D iatMultiplierProvider,
const ValueProvider2D cltAdderProvider,
const ValueProvider2D iatAdderProvider,
pid_s *const  pidParams 
)

Definition at line 29 of file boost_control.cpp.

38 {
39 m_pwm = pwm;
40 m_openLoopMap = openLoopMap;
41 m_closedLoopTargetMap = closedLoopTargetMap;
42 m_cltBoostCorrMap = &cltMultiplierProvider;
43 m_iatBoostCorrMap = &iatMultiplierProvider;
44 m_cltBoostAdderMap = &cltAdderProvider;
45 m_iatBoostAdderMap = &iatAdderProvider;
46
47 m_pid.initPidClass(pidParams);
48 resetLua();
49
50 hasInitBoost = true;
51}
void initPidClass(pid_s *parameters)
Definition efi_pid.cpp:24

Referenced by initBoostCtrl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ observePlant()

expected< float > BoostController::observePlant ( )
overridevirtual

Implements ClosedLoopController< float, percent_t >.

Definition at line 69 of file boost_control.cpp.

69 {
70 expected<float> map = Sensor::get(SensorType::Map);
71 if (!map.Valid && engineConfiguration->boostType != CLOSED_LOOP) {
72 // if we're in open loop only let's somewhat operate even without valid Map sensor
73 map = 0;
74 }
75 isPlantValid = map.Valid;
76 return map;
77}
Here is the call graph for this function:

◆ onConfigurationChange()

void BoostController::onConfigurationChange ( engine_configuration_s const *  previousConfig)
overridevirtual

Reimplemented from EngineModule.

Definition at line 59 of file boost_control.cpp.

59 {
60#if EFI_PROD_CODE
62#endif
63
64 if (!previousConfig || !m_pid.isSame(&previousConfig->boostPid)) {
65 m_shouldResetPid = true;
66 }
67}
void initBoostCtrl()
bool isSame(const pid_s *parameters) const
Definition efi_pid.cpp:39
Here is the call graph for this function:

◆ onFastCallback()

void BoostController::onFastCallback ( )
overridevirtual

Reimplemented from EngineModule.

Definition at line 276 of file boost_control.cpp.

276 {
277 if (!hasInitBoost) {
278 return;
279 }
280
281 m_pid.iTermMin = -20;
282 m_pid.iTermMax = 20;
283
287
289
290 if (!isBoostControlled) {
291 // Passing unexpected will use the safe duty cycle configured by the user
292 setOutput(unexpected);
293 } else {
295 }
296}
void setOutput(expected< percent_t > outputValue) override
float iTermMax
Definition efi_pid.h:69
float iTermMin
Definition efi_pid.h:68
Here is the call graph for this function:

◆ resetLua()

void BoostController::resetLua ( )

Definition at line 53 of file boost_control.cpp.

53 {
54 luaTargetAdd = 0;
55 luaTargetMult = 1;
57}

Referenced by init().

Here is the caller graph for this function:

◆ setDefaultConfiguration()

void BoostController::setDefaultConfiguration ( )
overridevirtual

◆ setOutput()

void BoostController::setOutput ( expected< percent_t outputValue)
overridevirtual

Implements ClosedLoopController< float, percent_t >.

Definition at line 254 of file boost_control.cpp.

254 {
255 // this clamping is just for happier gauge #6339
256 boostOutput = clampPercentValue(output.value_or(engineConfiguration->boostControlSafeDutyCycle));
257
259 // If not enabled, force 0% output
260 boostOutput = 0;
261 }
262
263 float duty = PERCENT_TO_DUTY(boostOutput);
264
267 } else {
268#if EFI_ELECTRONIC_THROTTLE_BODY
269 // inject wastegate position into DC controllers, pretty weird workflow to be honest
270 // todo: should it be DC controller pulling?
272#endif // EFI_ELECTRONIC_THROTTLE_BODY
273 }
274}
bool isBoostControlSolenoidMode()
void setEtbWastegatePosition(percent_t pos)
virtual void setSimplePwmDutyCycle(float dutyCycle)=0
scaled_channel< int16_t, 100, 1 > boostOutput
static float duty

Referenced by onFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

Field Documentation

◆ m_closedLoopTargetMap

const ValueProvider3D* BoostController::m_closedLoopTargetMap = nullptr
private

Definition at line 60 of file boost_control.h.

Referenced by getSetpoint(), and init().

◆ m_cltBoostAdderMap

const ValueProvider2D* BoostController::m_cltBoostAdderMap = nullptr
private

Definition at line 63 of file boost_control.h.

Referenced by getBoostControlTargetTemperatureAdder(), and init().

◆ m_cltBoostCorrMap

const ValueProvider2D* BoostController::m_cltBoostCorrMap = nullptr
private

◆ m_iatBoostAdderMap

const ValueProvider2D* BoostController::m_iatBoostAdderMap = nullptr
private

Definition at line 64 of file boost_control.h.

Referenced by getBoostControlTargetTemperatureAdder(), and init().

◆ m_iatBoostCorrMap

const ValueProvider2D* BoostController::m_iatBoostCorrMap = nullptr
private

◆ m_openLoopMap

const ValueProvider3D* BoostController::m_openLoopMap = nullptr
private

◆ m_pid

Pid BoostController::m_pid
private

◆ m_pwm

IPwm* BoostController::m_pwm = nullptr
private

Definition at line 65 of file boost_control.h.

Referenced by init(), and setOutput().


The documentation for this class was generated from the following files: