fome-fw/firmware/controllers/alternatorController.cpp

186 lines
5.9 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file alternatorController.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
2017-01-03 03:05:22 -08:00
* @author Andrey Belomutskiy, (c) 2012-2017
2015-07-10 06:01:56 -07:00
*/
#include "main.h"
#include "engine.h"
#include "rpm_calculator.h"
#include "alternatorController.h"
#include "voltage.h"
#include "pid.h"
2016-01-22 10:02:51 -08:00
#include "LocalVersionHolder.h"
2015-07-10 06:01:56 -07:00
2016-01-20 20:03:03 -08:00
#if EFI_ALTERNATOR_CONTROL || defined(__DOXYGEN__)
2017-01-02 11:03:17 -08:00
#include "pwm_generator.h"
#include "pin_repository.h"
#include "tunerstudio_configuration.h"
2016-01-20 20:03:03 -08:00
2015-07-10 06:01:56 -07:00
EXTERN_ENGINE
;
static Logging *logger;
2016-09-17 18:02:45 -07:00
int alternatorPidResetCounter = 0;
2016-02-25 14:01:37 -08:00
2015-07-10 06:01:56 -07:00
static SimplePwm alternatorControl;
2016-01-20 20:03:03 -08:00
static pid_s *altPidS = &persistentState.persistentConfiguration.engineConfiguration.alternatorControl;
static Pid altPid(altPidS, 1, 90);
2015-07-10 06:01:56 -07:00
static THD_WORKING_AREA(alternatorControlThreadStack, UTILITY_THREAD_STACK_SIZE);
static float currentAltDuty;
2016-01-22 10:02:51 -08:00
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
extern TunerStudioOutputChannels tsOutputChannels;
#endif
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) {
altPid.reset();
altPid.minResult = engineConfiguration->bc.alternatorPidMin;
altPid.maxResult = engineConfiguration->bc.alternatorPidMax;
}
2015-07-10 06:01:56 -07:00
static msg_t AltCtrlThread(int param) {
2016-01-22 10:02:51 -08:00
UNUSED(param);
2015-07-10 06:01:56 -07:00
chRegSetThreadName("AlternatorController");
while (true) {
2016-01-22 10:02:51 -08:00
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
2016-09-15 20:01:48 -07:00
if (shouldResetPid) {
2017-04-10 19:07:51 -07:00
pidReset();
2016-09-17 18:02:45 -07:00
alternatorPidResetCounter++;
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
int dt = maxI(10, engineConfiguration->alternatorDT);
2016-01-21 20:02:49 -08:00
chThdSleepMilliseconds(dt);
2015-07-10 06:01:56 -07:00
2017-02-12 17:05:02 -08:00
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
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
tsOutputChannels.debugFloatField1 = currentAltDuty;
altPid.postState(&tsOutputChannels);
tsOutputChannels.debugIntField3 = alternatorPidResetCounter;
}
#endif /* !EFI_UNIT_TEST */
2016-01-31 16:01:34 -08:00
// todo: migrate this to FSIO
2016-07-02 16:01:27 -07:00
bool alternatorShouldBeEnabledAtCurrentRpm = engine->rpmCalculator.rpmValue > 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();
2016-01-31 16:01:34 -08:00
continue;
}
2016-02-25 14:01:37 -08:00
float vBatt = getVBatt(PASS_ENGINE_PARAMETER_F);
float targetVoltage = engineConfiguration->targetVBatt;
2016-02-27 22:03:22 -08:00
if (boardConfiguration->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) {
2016-02-25 14:01:37 -08:00
tsOutputChannels.debugIntField1 = newState;
}
continue;
}
2017-01-22 14:03:31 -08:00
currentAltDuty = altPid.getValue(targetVoltage, vBatt);
2015-07-10 06:01:56 -07:00
if (boardConfiguration->isVerboseAlternator) {
2016-06-30 20:01:36 -07:00
scheduleMsg(logger, "alt duty: %f/vbatt=%f/p=%f/i=%f/d=%f int=%f", currentAltDuty, vBatt,
2015-07-10 06:01:56 -07:00
altPid.getP(), altPid.getI(), altPid.getD(), altPid.getIntegration());
}
2016-01-22 10:02:51 -08:00
2015-07-10 06:01:56 -07:00
alternatorControl.setSimplePwmDutyCycle(currentAltDuty / 100);
}
#if defined __GNUC__
return -1;
#endif
}
void showAltInfo(void) {
scheduleMsg(logger, "alt=%s @%s t=%dms", boolToString(engineConfiguration->isAlternatorControlEnabled),
hwPortname(boardConfiguration->alternatorControlPin),
engineConfiguration->alternatorDT);
2015-11-11 20:01:18 -08:00
scheduleMsg(logger, "p=%f/i=%f/d=%f offset=%f", engineConfiguration->alternatorControl.pFactor,
2016-02-05 12:02:36 -08:00
0, 0, engineConfiguration->alternatorControl.offset); // todo: i & d
2015-07-10 06:01:56 -07:00
scheduleMsg(logger, "vbatt=%f/duty=%f/target=%f", getVBatt(PASS_ENGINE_PARAMETER_F), currentAltDuty,
engineConfiguration->targetVBatt);
}
void setAltPFactor(float p) {
2015-11-11 20:01:18 -08:00
engineConfiguration->alternatorControl.pFactor = p;
2015-07-10 06:01:56 -07:00
scheduleMsg(logger, "setAltPid: %f", p);
2017-04-10 19:07:51 -07:00
pidReset();
2015-07-10 06:01:56 -07:00
showAltInfo();
}
static void applyAlternatorPinState(PwmConfig *state, int stateIndex) {
efiAssertVoid(stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex");
efiAssertVoid(state->multiWave.waveCount == 1, "invalid idle waveCount");
OutputPin *output = state->outputPins[0];
int value = state->multiWave.waves[0].pinStates[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);
}
void setDefaultAlternatorParameters(void) {
engineConfiguration->alternatorOffAboveTps = 120;
boardConfiguration->alternatorControlPin = GPIO_UNASSIGNED;
boardConfiguration->alternatorControlPinMode = OM_DEFAULT;
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;
2015-07-10 06:01:56 -07:00
engineConfiguration->alternatorDT = 100;
}
2016-09-15 20:01:48 -07:00
void onConfigurationChangeAlternatorCallback(engine_configuration_s *previousConfiguration) {
2017-04-10 12:16:00 -07:00
shouldResetPid = !altPid.isSame(&previousConfiguration->alternatorControl) ||
engineConfiguration->bc.alternatorPidMin != previousConfiguration->bc.alternatorPidMin ||
engineConfiguration->bc.alternatorPidMax != previousConfiguration->bc.alternatorPidMax;
2016-09-15 20:01:48 -07:00
}
2015-07-10 06:01:56 -07:00
void initAlternatorCtrl(Logging *sharedLogger) {
logger = sharedLogger;
addConsoleAction("altinfo", showAltInfo);
if (boardConfiguration->alternatorControlPin == GPIO_UNASSIGNED)
return;
2016-02-27 22:03:22 -08:00
if (boardConfiguration->onOffAlternatorLogic) {
2017-04-21 15:11:36 -07:00
enginePins.alternatorPin.initPin("on/off alternator", boardConfiguration->alternatorControlPin);
2016-02-25 14:01:37 -08:00
} else {
startSimplePwmExt(&alternatorControl, "Alternator control", boardConfiguration->alternatorControlPin,
2016-09-13 21:03:14 -07:00
&enginePins.alternatorPin,
2016-07-16 23:03:46 -07:00
engineConfiguration->alternatorPwmFrequency, 0.1, applyAlternatorPinState);
2016-02-25 14:01:37 -08:00
}
2015-07-10 06:01:56 -07:00
chThdCreateStatic(alternatorControlThreadStack, sizeof(alternatorControlThreadStack), LOWPRIO,
(tfunc_t) AltCtrlThread, NULL);
}
2016-01-20 20:03:03 -08:00
#endif /* EFI_ALTERNATOR_CONTROL */