2015-07-10 06:01:56 -07:00
|
|
|
/**
|
2019-03-31 13:56:13 -07:00
|
|
|
* @file alternator_controller.cpp
|
2016-02-25 14:01:37 -08:00
|
|
|
* @brief alternator controller - some newer vehicles control alternator with ECU
|
2015-07-10 06:01:56 -07:00
|
|
|
*
|
|
|
|
* @date Apr 6, 2014
|
|
|
|
* @author Dmitry Sidin
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
2019-11-19 23:18:17 -08:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ALTERNATOR_CONTROL
|
2019-03-31 13:56:13 -07:00
|
|
|
#include "alternator_controller.h"
|
2022-01-31 18:51:32 -08:00
|
|
|
#include "efi_pid.h"
|
2019-03-31 13:56:13 -07:00
|
|
|
#include "local_version_holder.h"
|
2019-07-09 13:08:49 -07:00
|
|
|
#include "periodic_task.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-07-05 16:00:44 -07:00
|
|
|
#if defined(HAS_OS_ACCESS)
|
|
|
|
#error "Unexpected OS ACCESS HERE"
|
2019-11-19 23:18:17 -08:00
|
|
|
#endif /* HAS_OS_ACCESS */
|
2019-07-05 16:00:44 -07:00
|
|
|
|
2019-01-09 05:50:51 -08:00
|
|
|
static SimplePwm alternatorControl("alt");
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-09-21 18:14:50 -07:00
|
|
|
static percent_t currentAltDuty;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2016-09-15 20:01:48 -07:00
|
|
|
static bool shouldResetPid = false;
|
2016-02-25 14:01:37 -08:00
|
|
|
|
2023-11-13 01:22:08 -08:00
|
|
|
void AlternatorController::init() {
|
2023-11-10 10:12:01 -08:00
|
|
|
alternatorPid.initPidClass(&engineConfiguration->alternatorControl);
|
2017-04-10 19:07:51 -07:00
|
|
|
}
|
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
expected<float> AlternatorController::observePlant() {
|
|
|
|
auto vBatt = Sensor::get(SensorType::BatteryVoltage);
|
|
|
|
// if somehow battery voltage isn't valid
|
|
|
|
if (!vBatt)
|
|
|
|
return unexpected;
|
|
|
|
return vBatt.Value;
|
|
|
|
}
|
2019-02-10 20:54:41 -08:00
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
expected<float> AlternatorController::getSetpoint() {
|
2024-07-15 13:41:29 -07:00
|
|
|
const float rpm = Sensor::getOrZero(SensorType::Rpm);
|
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
// check if the engine is not running
|
2024-07-15 13:41:29 -07:00
|
|
|
bool alternatorShouldBeEnabledAtCurrentRpm = rpm > engineConfiguration->cranking.rpm;
|
2023-11-10 10:12:01 -08:00
|
|
|
|
|
|
|
if (!engineConfiguration->isAlternatorControlEnabled || !alternatorShouldBeEnabledAtCurrentRpm) {
|
|
|
|
return unexpected;
|
2021-12-05 15:33:50 -08:00
|
|
|
}
|
2023-11-10 10:12:01 -08:00
|
|
|
|
2024-07-15 13:41:29 -07:00
|
|
|
const float load = getEngineState()->fuelingLoad;
|
|
|
|
return interpolate3d(
|
|
|
|
config->alternatorVoltageTargetTable,
|
|
|
|
config->alternatorVoltageTargetLoadBins, load,
|
|
|
|
config->alternatorVoltageTargetRpmBins, rpm
|
|
|
|
);;
|
2023-11-10 10:12:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
expected<percent_t> AlternatorController::getOpenLoop(float target) {
|
|
|
|
UNUSED(target);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
expected<percent_t> AlternatorController::getClosedLoop(float targetVoltage, float vBattVoltage) {
|
|
|
|
percent_t altDuty = alternatorPid.getOutput(targetVoltage, vBattVoltage, FAST_CALLBACK_PERIOD_MS / 1000.0f);
|
2016-01-22 10:02:51 -08:00
|
|
|
|
2021-12-05 15:33:50 -08:00
|
|
|
// this block could be executed even in on/off alternator control mode
|
|
|
|
// but at least we would reflect latest state
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
2022-03-24 05:58:55 -07:00
|
|
|
alternatorPid.postState(engine->outputChannels.alternatorStatus);
|
2018-11-16 04:40:06 -08:00
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
2017-02-12 17:05:02 -08:00
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
// see "idle air Bump for AC" comment
|
|
|
|
int acDutyBump = engine->module<AcController>().unmock().acButtonState ? engineConfiguration->acRelayAlternatorDutyAdder : 0;
|
|
|
|
altDuty += acDutyBump;
|
|
|
|
return altDuty;
|
|
|
|
}
|
2021-05-07 06:38:41 -07:00
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
void AlternatorController::setOutput(expected<percent_t> outputValue) {
|
|
|
|
if (outputValue) {
|
|
|
|
currentAltDuty = outputValue.Value;
|
|
|
|
alternatorControl.setSimplePwmDutyCycle(PERCENT_TO_DUTY(outputValue.Value));
|
|
|
|
} else {
|
2021-12-05 15:33:50 -08:00
|
|
|
// Shut off output if not needed
|
|
|
|
alternatorControl.setSimplePwmDutyCycle(0);
|
2023-11-10 10:12:01 -08:00
|
|
|
// we need to avoid accumulating iTerm while the alternator is not working
|
|
|
|
pidReset();
|
2021-12-05 15:33:50 -08:00
|
|
|
}
|
2023-11-10 10:12:01 -08:00
|
|
|
}
|
2016-01-31 16:01:34 -08:00
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
void AlternatorController::pidReset() {
|
|
|
|
alternatorPid.reset();
|
|
|
|
}
|
2016-02-25 14:01:37 -08:00
|
|
|
|
2023-11-10 10:12:01 -08:00
|
|
|
void AlternatorController::onFastCallback() {
|
|
|
|
if (!isBrainPinValid(engineConfiguration->alternatorControlPin)) {
|
|
|
|
return;
|
2021-12-05 15:33:50 -08:00
|
|
|
}
|
2023-11-10 10:12:01 -08:00
|
|
|
#if ! EFI_UNIT_TEST
|
|
|
|
if (shouldResetPid) {
|
|
|
|
pidReset();
|
|
|
|
shouldResetPid = false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ClosedLoopController::update();
|
2021-12-05 15:33:50 -08:00
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
void setAltPFactor(float p) {
|
2015-11-11 20:01:18 -08:00
|
|
|
engineConfiguration->alternatorControl.pFactor = p;
|
2021-04-21 09:53:13 -07:00
|
|
|
efiPrintf("setAltPid: %.2f", p);
|
2023-11-10 10:12:01 -08:00
|
|
|
engine->module<AlternatorController>()->pidReset();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2023-11-10 10:11:25 -08:00
|
|
|
void AlternatorController::onConfigurationChange(engine_configuration_s const * previousConfiguration) {
|
2024-05-03 22:10:42 -07:00
|
|
|
shouldResetPid = !previousConfiguration || !alternatorPid.isSame(&previousConfiguration->alternatorControl);
|
2016-09-15 20:01:48 -07:00
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void initAlternatorCtrl() {
|
2023-11-13 01:22:08 -08:00
|
|
|
engine->module<AlternatorController>()->init();
|
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
if (!isBrainPinValid(engineConfiguration->alternatorControlPin))
|
2015-07-10 06:01:56 -07:00
|
|
|
return;
|
|
|
|
|
2022-09-07 19:59:40 -07:00
|
|
|
startSimplePwm(&alternatorControl,
|
2019-01-09 05:50:51 -08:00
|
|
|
"Alternator control",
|
|
|
|
&engine->executor,
|
2016-09-13 21:03:14 -07:00
|
|
|
&enginePins.alternatorPin,
|
2021-05-07 06:38:41 -07:00
|
|
|
engineConfiguration->alternatorPwmFrequency, 0);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
2016-01-20 20:03:03 -08:00
|
|
|
|
|
|
|
#endif /* EFI_ALTERNATOR_CONTROL */
|