auto-sync
This commit is contained in:
parent
4a0f7298d2
commit
9a1f56ff73
|
@ -24,10 +24,13 @@ static int lastGoodValue = DEFAULT_IDLE_DUTY;
|
|||
EXTERN_ENGINE
|
||||
;
|
||||
|
||||
void idleInit(IdleValveState *idle DECLARE_ENGINE_PARAMETER_S) {
|
||||
idle->value = DEFAULT_IDLE_DUTY;
|
||||
setIdleRpm(idle, engineConfiguration->targetIdleRpm);
|
||||
idle->timeOfLastIdleChange = 0;
|
||||
IdleValveState::IdleValveState() {
|
||||
value = DEFAULT_IDLE_DUTY;
|
||||
timeOfLastIdleChange = 0;
|
||||
}
|
||||
|
||||
void IdleValveState::init(DECLARE_ENGINE_PARAMETER_F) {
|
||||
setIdleRpm(this, engineConfiguration->targetIdleRpm);
|
||||
}
|
||||
|
||||
void setIdleRpm(IdleValveState *idle, int targetRpm) {
|
||||
|
@ -38,9 +41,9 @@ void setIdleRpm(IdleValveState *idle, int targetRpm) {
|
|||
/**
|
||||
* @brief sets new idle valve duty cycle: checks the bounds and reports new value
|
||||
*/
|
||||
static int setNewValue(IdleValveState *idle, int currentRpm, efitimems_t now, const char * msg, int newValue) {
|
||||
newValue = maxI(newValue, MIN_IDLE);
|
||||
newValue = minI(newValue, MAX_IDLE);
|
||||
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);
|
||||
|
||||
if (idle->value != newValue) {
|
||||
idleDebug(msg, currentRpm);
|
||||
|
@ -51,53 +54,49 @@ static int setNewValue(IdleValveState *idle, int currentRpm, efitimems_t now, co
|
|||
return newValue;
|
||||
}
|
||||
|
||||
static int changeValue(IdleValveState *idle, int currentRpm, int now, const char * msg, int delta DECLARE_ENGINE_PARAMETER_S) {
|
||||
static percent_t changeValue(IdleValveState *idle, int currentRpm, int now, const char * msg, percent_t delta DECLARE_ENGINE_PARAMETER_S) {
|
||||
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;
|
||||
}
|
||||
int newValue = idle->value + delta;
|
||||
percent_t newValue = idle->value + delta;
|
||||
return setNewValue(idle, currentRpm, now, msg, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* now - current time in milliseconds
|
||||
*/
|
||||
int getIdle(IdleValveState *idle, int currentRpm, efitimems_t now DECLARE_ENGINE_PARAMETER_S) {
|
||||
percent_t IdleValveState::getIdle(int currentRpm, efitimems_t now DECLARE_ENGINE_PARAMETER_S) {
|
||||
if (currentRpm == 0 || isCranking()) {
|
||||
return setNewValue(idle, currentRpm, now, "cranking value: ", DEFAULT_IDLE_DUTY);
|
||||
return setNewValue(this, currentRpm, now, "cranking value: ", DEFAULT_IDLE_DUTY);
|
||||
}
|
||||
|
||||
if (currentRpm < 0.7 * idle->targetRpmRangeLeft) {
|
||||
return setNewValue(idle, currentRpm, now, "RPMs are seriously low: ", lastGoodValue);
|
||||
if (currentRpm < 0.7 * targetRpmRangeLeft) {
|
||||
return setNewValue(this, currentRpm, now, "RPMs are seriously low: ", lastGoodValue);
|
||||
}
|
||||
|
||||
if (now - idle->timeOfLastIdleChange < IDLE_PERIOD) {
|
||||
if (now - timeOfLastIdleChange < IDLE_PERIOD) {
|
||||
// too soon to adjust anything - exiting
|
||||
return idle->value;
|
||||
return value;
|
||||
}
|
||||
|
||||
if (currentRpm > idle->targetRpmRangeLeft && currentRpm < idle->targetRpmRangeRight) {
|
||||
if (currentRpm > targetRpmRangeLeft && currentRpm < targetRpmRangeRight) {
|
||||
// current RPM is good enough
|
||||
// todo: need idle signal input
|
||||
//lastGoodValue = idle->value;
|
||||
return idle->value;
|
||||
return value;
|
||||
}
|
||||
|
||||
if (currentRpm >= idle->targetRpmRangeRight + 100)
|
||||
return changeValue(idle, currentRpm, now, "idle control: rpm is too high: ", -IDLE_DECREASE_STEP PASS_ENGINE_PARAMETER);
|
||||
if (currentRpm >= targetRpmRangeRight + 100)
|
||||
return changeValue(this, currentRpm, now, "idle control: rpm is too high: ", -IDLE_DECREASE_STEP PASS_ENGINE_PARAMETER);
|
||||
|
||||
if (currentRpm >= idle->targetRpmRangeRight)
|
||||
return changeValue(idle, currentRpm, now, "idle control: rpm is a bit too high: ", -1 PASS_ENGINE_PARAMETER);
|
||||
if (currentRpm >= targetRpmRangeRight)
|
||||
return changeValue(this, currentRpm, now, "idle control: rpm is a bit too high: ", -IDLE_DECREASE_SMALL_STEP PASS_ENGINE_PARAMETER);
|
||||
|
||||
// we are here if RPM is low, let's see how low
|
||||
// if (currentRpm < 0.7 * idle->targetRpmRangeLeft) {
|
||||
// // todo: act faster in case of really low RPM?
|
||||
// return setNewValue(idle, currentRpm, now, "RPMs are seriously low: ", 15 * IDLE_INCREASE_STEP);
|
||||
// } else
|
||||
if (currentRpm < idle->targetRpmRangeLeft - 100) {
|
||||
return changeValue(idle, currentRpm, now, "idle control: RPMs are low: ", IDLE_INCREASE_STEP PASS_ENGINE_PARAMETER);
|
||||
if (currentRpm < targetRpmRangeLeft - 100) {
|
||||
return changeValue(this, currentRpm, now, "idle control: RPMs are low: ", IDLE_INCREASE_STEP PASS_ENGINE_PARAMETER);
|
||||
}
|
||||
return changeValue(idle, currentRpm, now, "idle control: RPMs are a bit low: ", 1 PASS_ENGINE_PARAMETER);
|
||||
return changeValue(this, currentRpm, now, "idle control: RPMs are a bit low: ", IDLE_INCREASE_SMALL_STEP PASS_ENGINE_PARAMETER);
|
||||
}
|
||||
|
|
|
@ -10,41 +10,35 @@
|
|||
#ifndef IDLE_CONTROLLER_H_
|
||||
#define IDLE_CONTROLLER_H_
|
||||
|
||||
// 600‰ duty cycle by default
|
||||
#define DEFAULT_IDLE_DUTY 600
|
||||
// 60% duty cycle by default
|
||||
#define DEFAULT_IDLE_DUTY 60
|
||||
|
||||
#define IDLE_PERIOD 1000
|
||||
|
||||
// Per mil (1/1000) values
|
||||
#define MIN_IDLE 100
|
||||
#define MAX_IDLE 900
|
||||
#define IDLE_INCREASE_STEP 5
|
||||
#define IDLE_DECREASE_STEP 5
|
||||
// Percent values
|
||||
#define MIN_IDLE 10.0f
|
||||
#define MAX_IDLE 90.0f
|
||||
#define IDLE_INCREASE_STEP 0.5f
|
||||
#define IDLE_DECREASE_STEP 0.5f
|
||||
#define IDLE_INCREASE_SMALL_STEP 0.1F
|
||||
#define IDLE_DECREASE_SMALL_STEP 0.1F
|
||||
|
||||
class IdleValveState {
|
||||
public:
|
||||
IdleValveState();
|
||||
void init(DECLARE_ENGINE_PARAMETER_F);
|
||||
percent_t getIdle(int currentRpm, efitimems_t now DECLARE_ENGINE_PARAMETER_S);
|
||||
|
||||
int time;
|
||||
|
||||
int targetRpmRangeLeft, targetRpmRangeRight;
|
||||
|
||||
int value;
|
||||
percent_t value;
|
||||
efitimems_t timeOfLastIdleChange;
|
||||
};
|
||||
|
||||
void idleInit(IdleValveState *idle DECLARE_ENGINE_PARAMETER_S);
|
||||
int getIdle(IdleValveState *idle, int currentRpm, efitimems_t now DECLARE_ENGINE_PARAMETER_S);
|
||||
void setIdleRpm(IdleValveState *idle, int targetRpm);
|
||||
|
||||
void idleDebug(const char *msg, int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
void idleDebug(const char *msg, percent_t value);
|
||||
|
||||
#endif /* IDLE_CONTROLLER_H_ */
|
||||
|
|
|
@ -56,8 +56,8 @@ int getIdleSwitch() {
|
|||
return idleSwitchState;
|
||||
}
|
||||
|
||||
void idleDebug(const char *msg, int value) {
|
||||
printMsg(&logger, "%s%d", msg, value);
|
||||
void idleDebug(const char *msg, percent_t value) {
|
||||
printMsg(&logger, "%s%f", msg, value);
|
||||
scheduleLogging(&logger);
|
||||
}
|
||||
|
||||
|
@ -72,16 +72,15 @@ static void setIdleControlEnabled(int value) {
|
|||
showIdleInfo();
|
||||
}
|
||||
|
||||
static void setIdleValvePwm(int value) {
|
||||
// todo: change parameter type, maybe change parameter validation?
|
||||
if (value < 1 || value > 999)
|
||||
static void setIdleValvePwm(percent_t value) {
|
||||
if (value < 0.01 || value > 99.9)
|
||||
return;
|
||||
scheduleMsg(&logger, "setting idle valve PWM %d", value);
|
||||
float f = 0.001 * value;
|
||||
scheduleMsg(&logger, "setting idle valve PWM %f", value);
|
||||
float f = 0.01 * value;
|
||||
boardConfiguration->idleSolenoidPwm = f;
|
||||
showIdleInfo();
|
||||
/**
|
||||
* currently idle level is an integer per mil (0-1000 range), and PWM takes a float in the 0..1 range
|
||||
* currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range
|
||||
* todo: unify?
|
||||
*/
|
||||
idleValvePwm.setSimplePwmDutyCycle(f);
|
||||
|
@ -91,7 +90,7 @@ static msg_t ivThread(int param) {
|
|||
(void) param;
|
||||
chRegSetThreadName("IdleValve");
|
||||
|
||||
int currentIdleValve = -1;
|
||||
percent_t currentIdleValve = -1;
|
||||
while (true) {
|
||||
chThdSleepMilliseconds(boardConfiguration->idleThreadPeriod);
|
||||
|
||||
|
@ -104,7 +103,7 @@ static msg_t ivThread(int param) {
|
|||
|
||||
efitimems_t now = currentTimeMillis();
|
||||
|
||||
int newValue = getIdle(&idle, getRpm(), now PASS_ENGINE_PARAMETER);
|
||||
percent_t newValue = idle.getIdle(getRpm(), now PASS_ENGINE_PARAMETER);
|
||||
|
||||
if (currentIdleValve != newValue) {
|
||||
currentIdleValve = newValue;
|
||||
|
@ -140,7 +139,7 @@ void startIdleThread(Engine *engine) {
|
|||
startSimplePwmExt(&idleValvePwm, "Idle Valve", boardConfiguration->idleValvePin, IDLE_VALVE,
|
||||
boardConfiguration->idleSolenoidFrequency, boardConfiguration->idleSolenoidPwm, applyIdleSolenoidPinState);
|
||||
|
||||
idleInit(&idle);
|
||||
idle.init();
|
||||
scheduleMsg(&logger, "initial idle %d", idle.value);
|
||||
|
||||
chThdCreateStatic(ivThreadStack, sizeof(ivThreadStack), NORMALPRIO, (tfunc_t) ivThread, NULL);
|
||||
|
@ -151,7 +150,7 @@ void startIdleThread(Engine *engine) {
|
|||
|
||||
addConsoleAction("idleinfo", showIdleInfo);
|
||||
addConsoleActionI("set_idle_rpm", setIdleRpmAction);
|
||||
addConsoleActionI("set_idle_pwm", setIdleValvePwm);
|
||||
addConsoleActionF("set_idle_pwm", setIdleValvePwm);
|
||||
addConsoleActionI("set_idle_enabled", (VoidInt) setIdleControlEnabled);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
*/
|
||||
typedef uint32_t efitimems_t;
|
||||
|
||||
/**
|
||||
* numeric value from 0 to 100
|
||||
*/
|
||||
typedef float percent_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -265,5 +265,5 @@ int getRusEfiVersion(void) {
|
|||
return 1; // this is here to make the compiler happy about the unused array
|
||||
if (UNUSED_CCM_SIZE == 0)
|
||||
return 1; // this is here to make the compiler happy about the unused array
|
||||
return 20141231;
|
||||
return 20150101;
|
||||
}
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
#include "test_logic_expression.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#include "test_idle_controller.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "map_resize.h"
|
||||
#include "test_idle_controller.h"
|
||||
#include "test_event_registry.h"
|
||||
#include "test_signal_executor.h"
|
||||
#include "test_util.h"
|
||||
|
@ -137,8 +138,10 @@ int main(void) {
|
|||
|
||||
testFLStack();
|
||||
|
||||
testIdleController();
|
||||
|
||||
// resizeMap();
|
||||
printf("Success 20131216\r\n");
|
||||
printf("Success 20150101\r\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,32 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "idle_controller.h"
|
||||
#include "efitime.h"
|
||||
#include "engine_test_helper.h"
|
||||
|
||||
void idleDebug(const char *msg, int value) {
|
||||
void idleDebug(const char *msg, percent_t value) {
|
||||
printf("%s\r\n", msg);
|
||||
}
|
||||
|
||||
static IdleValveState is;
|
||||
|
||||
void testIdleController(void) {
|
||||
EngineTestHelper eth(FORD_INLINE_6_1995);
|
||||
Engine *engine = ð.engine;
|
||||
engine_configuration_s *engineConfiguration = engine->engineConfiguration;
|
||||
|
||||
engineConfiguration->targetIdleRpm = 1200;
|
||||
|
||||
is.init(PASS_ENGINE_PARAMETER_F);
|
||||
|
||||
efitimems_t time = 0;
|
||||
|
||||
assertEquals(60, is.getIdle(900, time PASS_ENGINE_PARAMETER));
|
||||
|
||||
time += 2000;
|
||||
assertEquals(60.5, is.getIdle(900, time PASS_ENGINE_PARAMETER));
|
||||
|
||||
time += 2000;
|
||||
assertEquals(60.6, is.getIdle(1050, time PASS_ENGINE_PARAMETER));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef TEST_IDLE_CONTROLLER_H
|
||||
#define TEST_IDLE_CONTROLLER_H
|
||||
|
||||
void testIdleController(void);
|
||||
void idleDebug(char *msg, int value);
|
||||
//bool_t isCranking(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue