2016-06-26 10:02:23 -07:00
|
|
|
/*
|
|
|
|
* @file aux_pid.cpp
|
|
|
|
*
|
2019-03-31 13:56:13 -07:00
|
|
|
* This class is a copy-paste of alternator_controller.cpp TODO: do something about it? extract more common logic?
|
2016-06-30 20:01:36 -07:00
|
|
|
*
|
2016-06-26 10:02:23 -07:00
|
|
|
* @date Jun 26, 2016
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2016-06-26 10:02:23 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "aux_pid.h"
|
2019-03-31 13:56:13 -07:00
|
|
|
#include "local_version_holder.h"
|
2016-06-30 20:01:36 -07:00
|
|
|
#include "allsensors.h"
|
2016-06-26 10:02:23 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_AUX_PID
|
2016-06-30 19:02:49 -07:00
|
|
|
#include "pwm_generator.h"
|
2016-06-30 20:01:36 -07:00
|
|
|
#include "tunerstudio_configuration.h"
|
2016-07-02 17:01:32 -07:00
|
|
|
#include "fsio_impl.h"
|
|
|
|
#include "engine_math.h"
|
2017-05-02 15:05:29 -07:00
|
|
|
#include "pin_repository.h"
|
2019-07-09 13:24:14 -07:00
|
|
|
#include "periodic_task.h"
|
|
|
|
|
|
|
|
#define NO_PIN_PERIOD 500
|
2016-06-27 19:02:41 -07:00
|
|
|
|
2019-07-05 16:00:44 -07:00
|
|
|
#if defined(HAS_OS_ACCESS)
|
|
|
|
#error "Unexpected OS ACCESS HERE"
|
|
|
|
#endif
|
|
|
|
|
2016-06-27 19:02:41 -07:00
|
|
|
EXTERN_ENGINE
|
|
|
|
;
|
|
|
|
|
2016-07-02 17:01:32 -07:00
|
|
|
extern fsio8_Map3D_f32t fsioTable1;
|
|
|
|
|
2019-03-31 13:56:13 -07:00
|
|
|
// todo: this is to some extent a copy-paste of alternator_controller. maybe same loop
|
2016-06-27 19:02:41 -07:00
|
|
|
// for all PIDs?
|
|
|
|
|
2016-06-30 20:01:36 -07:00
|
|
|
static Logging *logger;
|
2016-06-30 19:02:49 -07:00
|
|
|
|
2016-07-21 21:04:09 -07:00
|
|
|
static bool isEnabled(int index) {
|
|
|
|
// todo: implement bit arrays for configuration
|
|
|
|
switch(index) {
|
|
|
|
case 0:
|
|
|
|
return engineConfiguration->activateAuxPid1;
|
|
|
|
case 1:
|
|
|
|
return engineConfiguration->activateAuxPid2;
|
|
|
|
case 2:
|
|
|
|
return engineConfiguration->activateAuxPid3;
|
|
|
|
default:
|
|
|
|
return engineConfiguration->activateAuxPid4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-09 13:24:14 -07:00
|
|
|
class AuxPidController : public PeriodicTimerController {
|
2019-02-10 20:54:41 -08:00
|
|
|
public:
|
2019-07-09 13:24:14 -07:00
|
|
|
|
2019-07-09 23:27:24 -07:00
|
|
|
SimplePwm auxPidPwm;
|
|
|
|
OutputPin auxOutputPin;
|
|
|
|
|
2019-07-12 05:00:07 -07:00
|
|
|
void init(int index) {
|
|
|
|
this->index = index;
|
|
|
|
pid_s *auxPidS = &persistentState.persistentConfiguration.engineConfiguration.auxPid[index];
|
|
|
|
auxPid.initPidClass(auxPidS);
|
2019-07-12 05:31:38 -07:00
|
|
|
table = getFSIOTable(index);
|
2019-07-12 05:00:07 -07:00
|
|
|
}
|
2019-07-09 23:27:24 -07:00
|
|
|
|
2019-07-09 13:24:14 -07:00
|
|
|
int getPeriodMs() override {
|
|
|
|
return engineConfiguration->auxPidPins[index] == GPIO_UNASSIGNED ? NO_PIN_PERIOD : GET_PERIOD_LIMITED(&engineConfiguration->auxPid[index]);
|
|
|
|
}
|
2016-06-27 19:02:41 -07:00
|
|
|
|
2019-07-09 13:24:14 -07:00
|
|
|
void PeriodicTask() override {
|
2019-04-15 18:09:43 -07:00
|
|
|
if (engine->auxParametersVersion.isOld(engine->getGlobalConfigurationVersion())) {
|
2019-07-12 05:00:07 -07:00
|
|
|
auxPid.reset();
|
|
|
|
|
2017-04-10 12:16:00 -07:00
|
|
|
}
|
2016-06-30 20:01:36 -07:00
|
|
|
|
2019-01-21 17:33:21 -08:00
|
|
|
float rpm = GET_RPM_VALUE;
|
2016-07-02 17:01:32 -07:00
|
|
|
|
|
|
|
// todo: make this configurable?
|
|
|
|
bool enabledAtCurrentRpm = rpm > engineConfiguration->cranking.rpm;
|
|
|
|
|
|
|
|
if (!enabledAtCurrentRpm) {
|
|
|
|
// we need to avoid accumulating iTerm while engine is not running
|
2019-07-12 05:00:07 -07:00
|
|
|
auxPid.reset();
|
2019-02-10 20:54:41 -08:00
|
|
|
return;
|
2016-07-02 17:01:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-30 22:49:10 -08:00
|
|
|
float value = engine->triggerCentral.getVVTPosition();
|
2019-07-12 05:31:38 -07:00
|
|
|
float targetValue = table->getValue(rpm, getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE));
|
2016-06-30 20:01:36 -07:00
|
|
|
|
2019-03-12 15:54:46 -07:00
|
|
|
percent_t pwm = auxPid.getOutput(targetValue, value);
|
2016-07-21 21:04:09 -07:00
|
|
|
if (engineConfiguration->isVerboseAuxPid1) {
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(logger, "aux duty: %.2f/value=%.2f/p=%.2f/i=%.2f/d=%.2f int=%.2f", pwm, value,
|
2016-06-30 20:01:36 -07:00
|
|
|
auxPid.getP(), auxPid.getI(), auxPid.getD(), auxPid.getIntegration());
|
|
|
|
}
|
2016-06-30 19:02:49 -07:00
|
|
|
|
|
|
|
|
2017-11-24 16:16:25 -08:00
|
|
|
if (engineConfiguration->debugMode == DBG_AUX_PID_1) {
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
2016-06-30 20:01:36 -07:00
|
|
|
auxPid.postState(&tsOutputChannels);
|
2016-12-17 06:02:59 -08:00
|
|
|
tsOutputChannels.debugIntField3 = (int)(10 * targetValue);
|
2018-11-16 04:40:06 -08:00
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
2016-06-30 20:01:36 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 05:00:07 -07:00
|
|
|
auxPidPwm.setSimplePwmDutyCycle(PERCENT_TO_DUTY(pwm));
|
2016-06-27 19:02:41 -07:00
|
|
|
}
|
2019-07-12 05:00:07 -07:00
|
|
|
private:
|
|
|
|
Pid auxPid;
|
|
|
|
int index = 0;
|
2019-10-07 22:26:35 -07:00
|
|
|
ValueProvider3D *table = nullptr;
|
2019-02-10 20:54:41 -08:00
|
|
|
};
|
|
|
|
|
2019-07-09 13:24:14 -07:00
|
|
|
static AuxPidController instances[AUX_PID_COUNT];
|
2016-06-27 19:02:41 -07:00
|
|
|
|
2016-07-21 21:04:09 -07:00
|
|
|
static void turnAuxPidOn(int index) {
|
|
|
|
if (!isEnabled(index)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (engineConfiguration->auxPidPins[index] == GPIO_UNASSIGNED) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-09 23:27:24 -07:00
|
|
|
startSimplePwmExt(&instances[index].auxPidPwm, "Aux PID",
|
2019-01-09 05:50:51 -08:00
|
|
|
&engine->executor,
|
|
|
|
engineConfiguration->auxPidPins[index],
|
2019-07-09 23:27:24 -07:00
|
|
|
&instances[index].auxOutputPin,
|
2019-04-12 17:11:27 -07:00
|
|
|
engineConfiguration->auxPidFrequency[index], 0.1, (pwm_gen_callback*)applyPinState);
|
2016-07-21 21:04:09 -07:00
|
|
|
}
|
|
|
|
|
2017-05-02 15:05:29 -07:00
|
|
|
void startAuxPins(void) {
|
|
|
|
for (int i = 0;i <AUX_PID_COUNT;i++) {
|
|
|
|
turnAuxPidOn(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void stopAuxPins(void) {
|
2019-11-25 17:08:01 -08:00
|
|
|
#if EFI_PROD_CODE
|
2017-05-02 15:05:29 -07:00
|
|
|
for (int i = 0;i < AUX_PID_COUNT;i++) {
|
2019-04-09 16:31:10 -07:00
|
|
|
brain_pin_markUnused(activeConfiguration.auxPidPins[i]);
|
2017-05-02 15:05:29 -07:00
|
|
|
}
|
2019-11-25 17:08:01 -08:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2017-05-02 15:05:29 -07:00
|
|
|
}
|
|
|
|
|
2016-06-26 10:02:23 -07:00
|
|
|
void initAuxPid(Logging *sharedLogger) {
|
2016-06-30 20:01:36 -07:00
|
|
|
logger = sharedLogger;
|
|
|
|
|
2019-07-12 05:00:07 -07:00
|
|
|
for (int i = 0;i < AUX_PID_COUNT;i++) {
|
|
|
|
instances[i].init(i);
|
|
|
|
}
|
|
|
|
|
2017-05-02 15:05:29 -07:00
|
|
|
startAuxPins();
|
2019-07-09 13:24:14 -07:00
|
|
|
for (int i = 0;i < AUX_PID_COUNT;i++) {
|
|
|
|
instances[i].Start();
|
|
|
|
}
|
2016-06-26 10:02:23 -07:00
|
|
|
}
|
|
|
|
|
2016-06-27 19:02:41 -07:00
|
|
|
#endif
|