fome-fw/firmware/controllers/algo/idle_controller.cpp

105 lines
3.3 KiB
C++
Raw Normal View History

2014-08-29 07:52:33 -07:00
/**
2014-10-22 14:03:06 -07:00
* @file idle_controller.cpp
2014-08-29 07:52:33 -07:00
* @brief Simple Idle Air Valve control algorithm
*
* This algorithm is trying to get current RPM to the desired 'target' value
* by changing Idle Air Valve solenoid duty cycle. Depending on how far current RPM
* is from the target RPM, the incremental change would be smaller or bigger.
*
*
* todo: DEFAULT_IDLE_DUTY should be a field on the IdleValveState, not a constant
*
* @date May 22, 2013
2015-01-12 15:04:10 -08:00
* @author Andrey Belomutskiy, (c) 2012-2015
2014-08-29 07:52:33 -07:00
*/
2014-10-22 14:03:06 -07:00
#include "main.h"
2014-08-29 07:52:33 -07:00
#include "idle_controller.h"
#include "efilib.h"
2014-10-22 14:03:06 -07:00
#include "rpm_calculator.h"
2014-12-21 22:03:40 -08:00
#include "tps.h"
2014-08-29 07:52:33 -07:00
static int lastGoodValue = DEFAULT_IDLE_DUTY;
2014-12-21 22:03:40 -08:00
EXTERN_ENGINE
;
2014-11-22 13:03:22 -08:00
2015-01-01 11:03:23 -08:00
IdleValveState::IdleValveState() {
value = DEFAULT_IDLE_DUTY;
timeOfLastIdleChange = 0;
2015-02-26 15:09:02 -08:00
time = 0;
targetRpmRangeLeft = targetRpmRangeRight = 0;
2015-01-01 11:03:23 -08:00
}
void IdleValveState::init(DECLARE_ENGINE_PARAMETER_F) {
2015-04-03 17:08:31 -07:00
setTargetRpm(engineConfiguration->targetIdleRpm);
2014-08-29 07:52:33 -07:00
}
2015-04-03 17:08:31 -07:00
void IdleValveState::setTargetRpm(int targetRpm) {
targetRpmRangeLeft = (int) (targetRpm * 0.93);
targetRpmRangeRight = (int) (targetRpm * 1.07);
2014-08-29 07:52:33 -07:00
}
/**
* @brief sets new idle valve duty cycle: checks the bounds and reports new value
*/
2015-01-01 11:03:23 -08:00
static percent_t setNewValue(IdleValveState *idle, int currentRpm, efitimems_t now, const char * msg, percent_t newValue) {
newValue = maxF(newValue, MIN_IDLE);
newValue = minF(newValue, MAX_IDLE);
2014-08-29 07:52:33 -07:00
if (idle->value != newValue) {
idleDebug(msg, currentRpm);
idle->timeOfLastIdleChange = now;
}
idle->value = newValue;
return newValue;
}
2015-01-01 11:03:23 -08:00
static percent_t changeValue(IdleValveState *idle, int currentRpm, int now, const char * msg, percent_t delta DECLARE_ENGINE_PARAMETER_S) {
2014-12-21 22:03:40 -08:00
if (getTPS(PASS_ENGINE_PARAMETER_F) > 5.0) {
// We are not supposed to be in idle mode. Don't touch anything
idleDebug("TPS Lockout, TPS=", getTPS(PASS_ENGINE_PARAMETER_F));
return idle->value;
}
2015-01-01 11:03:23 -08:00
percent_t newValue = idle->value + delta;
2014-08-29 07:52:33 -07:00
return setNewValue(idle, currentRpm, now, msg, newValue);
}
/**
2014-12-31 21:04:10 -08:00
* now - current time in milliseconds
2014-08-29 07:52:33 -07:00
*/
2015-01-01 11:03:23 -08:00
percent_t IdleValveState::getIdle(int currentRpm, efitimems_t now DECLARE_ENGINE_PARAMETER_S) {
2014-08-29 07:52:33 -07:00
if (currentRpm == 0 || isCranking()) {
2015-01-01 11:03:23 -08:00
return setNewValue(this, currentRpm, now, "cranking value: ", DEFAULT_IDLE_DUTY);
2014-08-29 07:52:33 -07:00
}
2015-01-01 11:03:23 -08:00
if (currentRpm < 0.7 * targetRpmRangeLeft) {
return setNewValue(this, currentRpm, now, "RPMs are seriously low: ", lastGoodValue);
2014-08-29 07:52:33 -07:00
}
2015-01-01 11:03:23 -08:00
if (now - timeOfLastIdleChange < IDLE_PERIOD) {
2014-08-29 07:52:33 -07:00
// too soon to adjust anything - exiting
2015-01-01 11:03:23 -08:00
return value;
2014-08-29 07:52:33 -07:00
}
2015-01-01 11:03:23 -08:00
if (currentRpm > targetRpmRangeLeft && currentRpm < targetRpmRangeRight) {
2014-08-29 07:52:33 -07:00
// current RPM is good enough
// todo: need idle signal input
//lastGoodValue = idle->value;
2015-01-01 11:03:23 -08:00
return value;
2014-08-29 07:52:33 -07:00
}
2015-01-01 11:03:23 -08:00
if (currentRpm >= targetRpmRangeRight + 100)
return changeValue(this, currentRpm, now, "idle control: rpm is too high: ", -IDLE_DECREASE_STEP PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
2015-01-01 11:03:23 -08:00
if (currentRpm >= targetRpmRangeRight)
return changeValue(this, currentRpm, now, "idle control: rpm is a bit too high: ", -IDLE_DECREASE_SMALL_STEP PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
// we are here if RPM is low, let's see how low
2015-01-01 11:03:23 -08:00
if (currentRpm < targetRpmRangeLeft - 100) {
return changeValue(this, currentRpm, now, "idle control: RPMs are low: ", IDLE_INCREASE_STEP PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
}
2015-01-01 11:03:23 -08:00
return changeValue(this, currentRpm, now, "idle control: RPMs are a bit low: ", IDLE_INCREASE_SMALL_STEP PASS_ENGINE_PARAMETER);
2014-08-29 07:52:33 -07:00
}