fome-fw/firmware/controllers/actuators/alternator_controller.cpp

178 lines
5.6 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -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
*/
#include "global.h"
2019-11-19 23:18:17 -08:00
#if EFI_TUNER_STUDIO
2020-05-25 10:02:05 -07:00
#include "tunerstudio_outputs.h"
2019-11-19 23:18:17 -08:00
#endif /* EFI_TUNER_STUDIO */
2019-04-12 19:07:03 -07:00
#if EFI_ALTERNATOR_CONTROL
2015-07-10 06:01:56 -07:00
#include "engine.h"
#include "rpm_calculator.h"
#include "alternator_controller.h"
2015-07-10 06:01:56 -07:00
#include "voltage.h"
#include "pid.h"
#include "local_version_holder.h"
#include "periodic_task.h"
2015-07-10 06:01:56 -07:00
2020-04-26 14:40:12 -07:00
#include "pwm_generator_logic.h"
2017-01-02 11:03:17 -08:00
#include "pin_repository.h"
2019-11-19 23:18:17 -08:00
2016-01-20 20:03:03 -08:00
#if defined(HAS_OS_ACCESS)
#error "Unexpected OS ACCESS HERE"
2019-11-19 23:18:17 -08:00
#endif /* HAS_OS_ACCESS */
EXTERN_ENGINE;
2015-07-10 06:01:56 -07:00
static Logging *logger;
static SimplePwm alternatorControl("alt");
static PidIndustrial alternatorPid(&persistentState.persistentConfiguration.engineConfiguration.alternatorControl);
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-02-25 14:01:37 -08:00
static bool currentPlainOnOffState = false;
2016-09-15 20:01:48 -07:00
static bool shouldResetPid = false;
2016-02-25 14:01:37 -08:00
2017-04-10 19:07:51 -07:00
static void pidReset(void) {
2019-09-03 16:12:04 -07:00
alternatorPid.reset();
2017-04-10 19:07:51 -07:00
}
class AlternatorController : public PeriodicTimerController {
int getPeriodMs() override {
return GET_PERIOD_LIMITED(&engineConfiguration->alternatorControl);
}
2019-02-10 20:54:41 -08:00
void PeriodicTask() override {
2019-04-12 19:07:03 -07:00
#if ! EFI_UNIT_TEST
2016-09-15 20:01:48 -07:00
if (shouldResetPid) {
2017-04-10 19:07:51 -07:00
pidReset();
2017-02-12 17:05:02 -08:00
shouldResetPid = false;
2016-09-15 20:01:48 -07:00
}
2016-01-22 10:02:51 -08:00
#endif
// todo: move this to pid_s one day
alternatorPid.antiwindupFreq = engineConfiguration->alternator_antiwindupFreq;
alternatorPid.derivativeFilterLoss = engineConfiguration->alternator_derivativeFilterLoss;
2017-02-12 18:04:18 -08:00
if (engineConfiguration->debugMode == DBG_ALTERNATOR_PID) {
2017-02-12 17:05:02 -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
2019-09-03 16:12:04 -07:00
alternatorPid.postState(&tsOutputChannels);
#endif /* EFI_TUNER_STUDIO */
2017-02-12 17:05:02 -08:00
}
2016-01-31 16:01:34 -08:00
// todo: migrate this to FSIO
2020-09-03 16:29:15 -07:00
bool alternatorShouldBeEnabledAtCurrentRpm = GET_RPM() > engineConfiguration->cranking.rpm;
2016-01-31 16:01:34 -08:00
engine->isAlternatorControlEnabled = CONFIG(isAlternatorControlEnabled) && alternatorShouldBeEnabledAtCurrentRpm;
if (!engine->isAlternatorControlEnabled) {
2016-07-02 16:01:27 -07:00
// we need to avoid accumulating iTerm while engine is not running
2017-04-10 19:07:51 -07:00
pidReset();
2019-02-10 20:54:41 -08:00
return;
2016-01-31 16:01:34 -08:00
}
2017-05-15 20:33:22 -07:00
float vBatt = getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE);
2016-02-25 14:01:37 -08:00
float targetVoltage = engineConfiguration->targetVBatt;
if (CONFIG(onOffAlternatorLogic)) {
2016-02-25 14:01:37 -08:00
float h = 0.1;
bool newState = (vBatt < targetVoltage - h) || (currentPlainOnOffState && vBatt < targetVoltage);
2016-09-13 21:03:14 -07:00
enginePins.alternatorPin.setValue(newState);
2016-02-25 14:01:37 -08:00
currentPlainOnOffState = newState;
2017-02-12 18:04:18 -08:00
if (engineConfiguration->debugMode == DBG_ALTERNATOR_PID) {
2019-04-12 19:07:03 -07:00
#if EFI_TUNER_STUDIO
2016-02-25 14:01:37 -08:00
tsOutputChannels.debugIntField1 = newState;
#endif /* EFI_TUNER_STUDIO */
2016-02-25 14:01:37 -08:00
}
2019-02-10 20:54:41 -08:00
return;
2016-02-25 14:01:37 -08:00
}
2019-09-03 16:12:04 -07:00
currentAltDuty = alternatorPid.getOutput(targetVoltage, vBatt);
if (CONFIG(isVerboseAlternator)) {
2018-01-23 09:05:14 -08:00
scheduleMsg(logger, "alt duty: %.2f/vbatt=%.2f/p=%.2f/i=%.2f/d=%.2f int=%.2f", currentAltDuty, vBatt,
2019-09-03 16:12:04 -07:00
alternatorPid.getP(), alternatorPid.getI(), alternatorPid.getD(), alternatorPid.getIntegration());
2015-07-10 06:01:56 -07:00
}
2016-01-22 10:02:51 -08:00
2019-07-12 05:00:07 -07:00
alternatorControl.setSimplePwmDutyCycle(PERCENT_TO_DUTY(currentAltDuty));
2015-07-10 06:01:56 -07:00
}
2019-02-10 20:54:41 -08:00
};
2015-07-10 06:01:56 -07:00
2019-02-10 20:54:41 -08:00
static AlternatorController instance;
2015-07-10 06:01:56 -07:00
void showAltInfo(void) {
scheduleMsg(logger, "alt=%s @%s t=%dms", boolToString(engineConfiguration->isAlternatorControlEnabled),
hwPortname(CONFIG(alternatorControlPin)),
2019-02-10 19:47:49 -08:00
engineConfiguration->alternatorControl.periodMs);
2018-01-23 09:05:14 -08:00
scheduleMsg(logger, "p=%.2f/i=%.2f/d=%.2f offset=%.2f", engineConfiguration->alternatorControl.pFactor,
2016-02-05 12:02:36 -08:00
0, 0, engineConfiguration->alternatorControl.offset); // todo: i & d
2018-01-23 09:05:14 -08:00
scheduleMsg(logger, "vbatt=%.2f/duty=%.2f/target=%.2f", getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE), currentAltDuty,
2015-07-10 06:01:56 -07:00
engineConfiguration->targetVBatt);
}
void setAltPFactor(float p) {
2015-11-11 20:01:18 -08:00
engineConfiguration->alternatorControl.pFactor = p;
2018-01-23 09:05:14 -08:00
scheduleMsg(logger, "setAltPid: %.2f", p);
2017-04-10 19:07:51 -07:00
pidReset();
2015-07-10 06:01:56 -07:00
showAltInfo();
}
static void applyAlternatorPinState(int stateIndex, PwmConfig *state) /* pwm_gen_callback */ {
2018-07-25 20:03:04 -07:00
efiAssertVoid(CUSTOM_ERR_6643, stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex");
efiAssertVoid(CUSTOM_IDLE_WAVE_CNT, state->multiChannelStateSequence.waveCount == 1, "invalid idle waveCount");
2015-07-10 06:01:56 -07:00
OutputPin *output = state->outputPins[0];
int value = state->multiChannelStateSequence.getChannelState(/*channelIndex*/0, stateIndex);
2016-09-12 17:02:56 -07:00
/**
* 'engine->isAlternatorControlEnabled' would be false is RPM is too low
*/
2016-01-31 16:01:34 -08:00
if (!value || engine->isAlternatorControlEnabled)
2015-07-10 06:01:56 -07:00
output->setValue(value);
}
2019-08-29 20:50:20 -07:00
void setDefaultAlternatorParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
2015-07-10 06:01:56 -07:00
engineConfiguration->alternatorOffAboveTps = 120;
engineConfiguration->targetVBatt = 14;
2016-02-05 12:02:36 -08:00
engineConfiguration->alternatorControl.offset = 0;
2015-11-11 20:01:18 -08:00
engineConfiguration->alternatorControl.pFactor = 30;
2019-02-10 19:47:49 -08:00
engineConfiguration->alternatorControl.periodMs = 100;
2015-07-10 06:01:56 -07:00
}
2016-09-15 20:01:48 -07:00
void onConfigurationChangeAlternatorCallback(engine_configuration_s *previousConfiguration) {
2019-09-03 16:12:04 -07:00
shouldResetPid = !alternatorPid.isSame(&previousConfiguration->alternatorControl);
2016-09-15 20:01:48 -07:00
}
void initAlternatorCtrl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-07-10 06:01:56 -07:00
logger = sharedLogger;
addConsoleAction("altinfo", showAltInfo);
if (CONFIG(alternatorControlPin) == GPIO_UNASSIGNED)
2015-07-10 06:01:56 -07:00
return;
if (CONFIG(onOffAlternatorLogic)) {
enginePins.alternatorPin.initPin("Alternator control", CONFIG(alternatorControlPin));
2016-02-25 14:01:37 -08:00
} else {
startSimplePwmExt(&alternatorControl,
"Alternator control",
&engine->executor,
CONFIG(alternatorControlPin),
2016-09-13 21:03:14 -07:00
&enginePins.alternatorPin,
engineConfiguration->alternatorPwmFrequency, 0.1, (pwm_gen_callback*)applyAlternatorPinState);
2016-02-25 14:01:37 -08:00
}
2019-02-10 20:54:41 -08:00
instance.Start();
2015-07-10 06:01:56 -07:00
}
2016-01-20 20:03:03 -08:00
#endif /* EFI_ALTERNATOR_CONTROL */