rusefi/firmware/controllers/actuators/electronic_throttle.cpp

661 lines
19 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file electronic_throttle.cpp
2019-04-24 17:47:38 -07:00
* @brief Electronic Throttle driver
2015-07-10 06:01:56 -07:00
*
* todo: make this more universal if/when we get other hardware options
*
2019-09-07 19:16:56 -07:00
* Sep 2019 two-wire TLE9201 official driving around the block! https://www.youtube.com/watch?v=1vCeICQnbzI
2019-09-28 06:59:40 -07:00
* May 2019 two-wire TLE7209 now behaves same as three-wire VNH2SP30 "eBay red board" on BOSCH 0280750009
2019-04-24 17:47:38 -07:00
* Apr 2019 two-wire TLE7209 support added
2019-05-05 15:09:52 -07:00
* Mar 2019 best results so far achieved with three-wire H-bridges like VNH2SP30 on BOSCH 0280750009
2019-02-10 16:13:04 -08:00
* Jan 2019 actually driven around the block but still need some work.
2017-01-27 18:04:23 -08:00
* Jan 2017 status:
2017-05-25 09:09:07 -07:00
* Electronic throttle body with it's spring is definitely not linear - both P and I factors of PID are required to get any results
2017-01-27 18:04:23 -08:00
* PID implementation tested on a bench only
* it is believed that more than just PID would be needed, as is this is probably
* not usable on a real vehicle. Needs to be tested :)
*
2019-11-18 19:25:07 -08:00
* https://raw.githubusercontent.com/wiki/rusefi/rusefi_documentation/oem_docs/VAG/Bosch_0280750009_pinout.jpg
2017-05-25 09:09:07 -07:00
*
2017-05-24 20:53:07 -07:00
* ETB is controlled according to pedal position input (pedal position sensor is a potentiometer)
2019-02-10 16:52:06 -08:00
* pedal 0% means pedal not pressed / idle
2017-05-24 20:53:07 -07:00
* pedal 100% means pedal all the way down
2017-05-25 09:09:07 -07:00
* (not TPS - not the one you can calibrate in TunerStudio)
2017-05-24 20:53:07 -07:00
*
*
2017-05-25 09:09:07 -07:00
* See also pid.cpp
*
2017-05-29 20:36:08 -07:00
* Relevant console commands:
*
2019-02-27 05:55:56 -08:00
* ETB_BENCH_ENGINE
* set engine_type 58
*
2017-05-29 20:36:08 -07:00
* enable verbose_etb
* disable verbose_etb
* ethinfo
2018-01-30 19:04:33 -08:00
* set mock_pedal_position X
2017-05-24 20:53:07 -07:00
*
2018-12-01 13:41:40 -08:00
*
* set debug_mode 17
* for PID outputs
*
2019-03-01 20:09:33 -08:00
* set etb_p X
* set etb_i X
* set etb_d X
2019-04-23 20:18:48 -07:00
* set etb_o X
2019-03-01 20:09:33 -08:00
*
2019-09-21 19:15:34 -07:00
* set_etb_duty X
2019-03-01 20:09:33 -08:00
*
2017-01-27 18:04:23 -08:00
* http://rusefi.com/forum/viewtopic.php?f=5&t=592
*
2015-07-10 06:01:56 -07:00
* @date Dec 7, 2013
2018-01-20 17:55:31 -08:00
* @author Andrey Belomutskiy, (c) 2012-2018
2015-07-10 06:01:56 -07:00
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
2018-09-16 19:26:57 -07:00
#include "global.h"
2019-04-12 19:07:03 -07:00
#if EFI_ELECTRONIC_THROTTLE_BODY
2015-07-10 06:01:56 -07:00
#include "electronic_throttle.h"
#include "tps.h"
#include "io_pins.h"
#include "engine_configuration.h"
#include "pwm_generator_logic.h"
#include "pid.h"
#include "engine_controller.h"
#include "periodic_task.h"
2017-01-02 11:03:17 -08:00
#include "pin_repository.h"
#include "pwm_generator.h"
2019-03-29 06:11:13 -07:00
#include "dc_motor.h"
2017-09-21 20:21:03 -07:00
#include "pid_auto_tune.h"
#if defined(HAS_OS_ACCESS)
#error "Unexpected OS ACCESS HERE"
#endif
#define ETB_MAX_COUNT 2
2017-05-27 20:01:41 -07:00
static bool shouldResetPid = false;
2015-07-10 06:01:56 -07:00
2018-11-22 20:42:30 -08:00
static pid_s tuneWorkingPidSettings;
static Pid tuneWorkingPid(&tuneWorkingPidSettings);
2017-09-21 20:21:03 -07:00
static PID_AutoTune autoTune;
2015-07-10 06:01:56 -07:00
static LoggingWithStorage logger("ETB");
static pedal2tps_t pedal2tpsMap("Pedal2Tps", 1);
2019-02-10 16:52:06 -08:00
EXTERN_ENGINE;
static bool startupPositionError = false;
2019-09-27 20:01:47 -07:00
#define STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD 5
2019-05-04 21:42:50 -07:00
class EtbControl {
private:
OutputPin m_pinEnable;
OutputPin m_pinDir1;
OutputPin m_pinDir2;
2019-04-12 22:03:12 -07:00
2019-05-04 21:42:50 -07:00
SimplePwm m_pwmEnable;
SimplePwm m_pwmDir1;
SimplePwm m_pwmDir2;
2019-04-12 22:03:12 -07:00
SimplePwm etbPwmUp;
2019-05-04 21:42:50 -07:00
public:
DECLARE_ENGINE_PTR;
2019-05-04 21:42:50 -07:00
EtbControl() : etbPwmUp("etbUp"), dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2) {}
TwoPinDcMotor dcMotor;
2019-05-04 21:42:50 -07:00
2019-09-27 20:37:40 -07:00
void setFrequency(int frequency) {
m_pwmEnable.setFrequency(frequency);
m_pwmDir1.setFrequency(frequency);
m_pwmDir2.setFrequency(frequency);
}
2019-05-04 21:42:50 -07:00
void start(bool useTwoWires,
brain_pin_e pinEnable,
2019-09-20 22:21:53 -07:00
// since we have pointer magic here we cannot simply have value parameter
pin_output_mode_e *pinEnableMode,
2019-05-04 21:42:50 -07:00
brain_pin_e pinDir1,
brain_pin_e pinDir2) {
2019-05-04 21:53:24 -07:00
dcMotor.SetType(useTwoWires ? TwoPinDcMotor::ControlType::PwmDirectionPins : TwoPinDcMotor::ControlType::PwmEnablePin);
2019-05-04 21:42:50 -07:00
2019-09-20 22:21:53 -07:00
m_pinEnable.initPin("ETB Enable", pinEnable, pinEnableMode);
2019-05-04 21:42:50 -07:00
m_pinDir1.initPin("ETB Dir 1", pinDir1);
m_pinDir2.initPin("ETB Dir 2", pinDir2);
// Clamp to >100hz
int freq = maxI(100, engineConfiguration->etbFreq);
2019-05-04 21:42:50 -07:00
2019-09-25 05:40:33 -07:00
// no need to complicate event queue with ETB PWM in unit tests
#if ! EFI_UNIT_TEST
2019-05-04 21:42:50 -07:00
startSimplePwm(&m_pwmEnable, "ETB Enable",
&engine->executor,
2019-05-04 21:42:50 -07:00
&m_pinEnable,
freq,
2019-05-04 21:42:50 -07:00
0,
(pwm_gen_callback*)applyPinState);
2019-05-04 21:42:50 -07:00
startSimplePwm(&m_pwmDir1, "ETB Dir 1",
&engine->executor,
&m_pinDir1,
freq,
0,
(pwm_gen_callback*)applyPinState);
2019-05-04 21:42:50 -07:00
startSimplePwm(&m_pwmDir2, "ETB Dir 2",
&engine->executor,
&m_pinDir2,
freq,
0,
(pwm_gen_callback*)applyPinState);
2019-09-25 05:46:26 -07:00
#endif /* EFI_UNIT_TEST */
2019-05-04 21:42:50 -07:00
}
};
static EtbControl etb1;
2019-03-02 12:04:42 -08:00
extern percent_t mockPedalPosition;
2017-05-27 20:01:41 -07:00
Pid etbPid;
2015-07-10 06:01:56 -07:00
2019-07-12 04:48:28 -07:00
static percent_t directPwmValue = NAN;
2017-09-21 20:21:03 -07:00
static percent_t currentEtbDuty;
2015-07-10 06:01:56 -07:00
2019-05-04 21:42:50 -07:00
#define ETB_DUTY_LIMIT 0.9
2019-07-12 04:48:28 -07:00
// this macro clamps both positive and negative percentages from about -100% to 100%
#define ETB_PERCENT_TO_DUTY(X) (maxF(minF((X * 0.01), ETB_DUTY_LIMIT - 0.01), 0.01 - ETB_DUTY_LIMIT))
2019-02-27 14:54:25 -08:00
2019-02-17 15:00:41 -08:00
int EtbController::getPeriodMs() {
return GET_PERIOD_LIMITED(&engineConfiguration->etb);
}
2019-02-10 16:52:06 -08:00
void EtbController::PeriodicTask() {
2018-12-01 13:41:40 -08:00
// set debug_mode 17
2018-10-21 14:45:14 -07:00
if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_PID) {
2019-04-12 19:07:03 -07:00
#if EFI_TUNER_STUDIO
2019-08-15 18:01:04 -07:00
etbPid.postState(&tsOutputChannels);
tsOutputChannels.debugIntField5 = engine->engineState.etbFeedForward;
#endif /* EFI_TUNER_STUDIO */
2018-10-21 14:45:14 -07:00
} else if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_EXTRA) {
2019-04-12 19:07:03 -07:00
#if EFI_TUNER_STUDIO
2018-12-01 13:41:40 -08:00
// set debug_mode 29
2019-04-24 14:00:05 -07:00
tsOutputChannels.debugFloatField1 = directPwmValue;
#endif /* EFI_TUNER_STUDIO */
2018-10-21 14:45:14 -07:00
}
if (startupPositionError) {
etb1.dcMotor.Set(0);
return;
}
2017-05-27 20:01:41 -07:00
if (shouldResetPid) {
2019-08-15 18:01:04 -07:00
etbPid.reset();
2017-05-27 20:01:41 -07:00
shouldResetPid = false;
}
2019-04-24 14:00:05 -07:00
if (!cisnan(directPwmValue)) {
etb1.dcMotor.Set(directPwmValue);
2019-02-10 16:52:06 -08:00
return;
2018-10-21 14:45:14 -07:00
}
if (boardConfiguration->pauseEtbControl) {
etb1.dcMotor.Set(0);
return;
}
percent_t actualThrottlePosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
2018-11-22 20:06:06 -08:00
2017-09-21 20:21:03 -07:00
if (engine->etbAutoTune) {
2018-11-22 20:06:06 -08:00
autoTune.input = actualThrottlePosition;
2018-11-22 20:54:11 -08:00
bool result = autoTune.Runtime(&logger);
2017-09-21 20:21:03 -07:00
2018-11-22 20:42:30 -08:00
tuneWorkingPid.updateFactors(autoTune.output, 0, 0);
2017-09-21 20:21:03 -07:00
float value = tuneWorkingPid.getOutput(50, actualThrottlePosition);
2018-11-25 20:13:03 -08:00
scheduleMsg(&logger, "AT input=%f output=%f PID=%f", autoTune.input,
autoTune.output,
value);
scheduleMsg(&logger, "AT PID=%f", value);
2019-07-12 04:48:28 -07:00
etb1.dcMotor.Set(ETB_PERCENT_TO_DUTY(value));
2018-11-22 20:42:30 -08:00
2018-11-22 20:54:11 -08:00
if (result) {
2018-11-25 20:13:03 -08:00
scheduleMsg(&logger, "GREAT NEWS! %f/%f/%f", autoTune.GetKp(), autoTune.GetKi(), autoTune.GetKd());
2018-11-22 20:54:11 -08:00
}
2019-02-10 16:52:06 -08:00
return;
2017-09-21 20:21:03 -07:00
}
2017-05-27 20:01:41 -07:00
percent_t pedalPosition = getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE);
int rpm = GET_RPM();
engine->engineState.targetFromTable = pedal2tpsMap.getValue(rpm / RPM_1_BYTE_PACKING_MULT, pedalPosition);
percent_t etbIdleAddition = CONFIGB(useETBforIdleControl) ? engine->engineState.idle.etbIdleAddition : 0;
percent_t targetPosition = engine->engineState.targetFromTable + etbIdleAddition;
if (engineConfiguration->debugMode == DBG_ETB_LOGIC) {
#if EFI_TUNER_STUDIO
tsOutputChannels.debugFloatField1 = engine->engineState.targetFromTable;
tsOutputChannels.debugFloatField2 = engine->engineState.idle.etbIdleAddition;
#endif /* EFI_TUNER_STUDIO */
}
2015-07-10 06:01:56 -07:00
engine->engineState.etbFeedForward = interpolate2d("etbb", targetPosition, engineConfiguration->etbBiasBins, engineConfiguration->etbBiasValues);
2017-11-16 11:44:34 -08:00
2019-08-15 18:01:04 -07:00
etbPid.iTermMin = engineConfiguration->etb_iTermMin;
etbPid.iTermMax = engineConfiguration->etb_iTermMax;
2019-03-03 12:27:49 -08:00
currentEtbDuty = engine->engineState.etbFeedForward +
2019-08-15 18:01:04 -07:00
etbPid.getOutput(targetPosition, actualThrottlePosition);
2015-07-10 06:01:56 -07:00
2019-07-12 04:48:28 -07:00
etb1.dcMotor.Set(ETB_PERCENT_TO_DUTY(currentEtbDuty));
2019-05-04 21:42:50 -07:00
2017-05-25 05:57:03 -07:00
if (engineConfiguration->isVerboseETB) {
2019-08-15 18:01:04 -07:00
etbPid.showPidStatus(&logger, "ETB");
2017-05-25 05:57:03 -07:00
}
2019-09-01 10:56:46 -07:00
DISPLAY_STATE(Engine)
DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor))
2019-09-01 08:39:09 -07:00
DISPLAY_TEXT(Electronic_Throttle);
2019-08-15 18:01:04 -07:00
DISPLAY_SENSOR(TPS)
DISPLAY_TEXT(eol);
DISPLAY_TEXT(Pedal);
DISPLAY_SENSOR(PPS);
DISPLAY(DISPLAY_CONFIG(throttlePedalPositionAdcChannel));
2019-08-15 18:01:04 -07:00
DISPLAY_TEXT(eol);
DISPLAY_TEXT(Feed_forward);
DISPLAY(DISPLAY_FIELD(etbFeedForward));
DISPLAY_TEXT(eol);
2019-09-01 10:56:46 -07:00
DISPLAY_STATE(ETB_pid)
2019-09-01 16:37:58 -07:00
DISPLAY_TEXT(input);
DISPLAY(DISPLAY_FIELD(input));
2019-08-15 18:01:04 -07:00
DISPLAY_TEXT(Output);
DISPLAY(DISPLAY_FIELD(output));
DISPLAY_TEXT(iTerm);
DISPLAY(DISPLAY_FIELD(iTerm));
DISPLAY_TEXT(eol);
2019-09-01 16:37:58 -07:00
DISPLAY(DISPLAY_FIELD(errorAmplificationCoef));
DISPLAY(DISPLAY_FIELD(previousError));
DISPLAY_TEXT(eol);
2019-08-15 18:01:04 -07:00
DISPLAY_TEXT(Settings);
DISPLAY(DISPLAY_CONFIG(ETB_PFACTOR));
DISPLAY(DISPLAY_CONFIG(ETB_IFACTOR));
DISPLAY(DISPLAY_CONFIG(ETB_DFACTOR));
DISPLAY_TEXT(eol);
DISPLAY(DISPLAY_CONFIG(ETB_OFFSET));
DISPLAY(DISPLAY_CONFIG(ETB_PERIODMS));
2019-09-01 16:37:58 -07:00
DISPLAY_TEXT(eol);
DISPLAY(DISPLAY_CONFIG(ETB_MINVALUE));
DISPLAY(DISPLAY_CONFIG(ETB_MAXVALUE));
/* DISPLAY_ELSE */
DISPLAY_TEXT(No_Pedal_Sensor);
/* DISPLAY_ENDIF */
#if EFI_TUNER_STUDIO
2019-09-20 17:41:45 -07:00
// 312
tsOutputChannels.etbTarget = targetPosition;
2019-09-20 17:41:45 -07:00
// 316
tsOutputChannels.etb1DutyCycle = currentEtbDuty;
2019-09-20 17:41:45 -07:00
// 320
// Error is positive if the throttle needs to open further
tsOutputChannels.etb1Error = targetPosition - actualThrottlePosition;
#endif /* EFI_TUNER_STUDIO */
2015-07-10 06:01:56 -07:00
}
2019-02-10 16:52:06 -08:00
EtbController etbController;
2015-07-10 06:01:56 -07:00
2018-09-24 20:57:03 -07:00
/**
2019-09-21 19:15:34 -07:00
* set_etb_duty X
2018-10-21 14:45:14 -07:00
* manual duty cycle control without PID. Percent value from 0 to 100
2018-09-24 20:57:03 -07:00
*/
2019-07-12 04:48:28 -07:00
void setThrottleDutyCycle(percent_t level) {
2018-11-26 17:19:42 -08:00
scheduleMsg(&logger, "setting ETB duty=%f%%", level);
2018-11-26 17:40:24 -08:00
if (cisnan(level)) {
2019-04-24 14:00:05 -07:00
directPwmValue = NAN;
2018-11-26 17:40:24 -08:00
return;
}
2015-07-10 06:01:56 -07:00
2019-07-12 04:48:28 -07:00
float dc = ETB_PERCENT_TO_DUTY(level);
2019-04-24 14:00:05 -07:00
directPwmValue = dc;
etb1.dcMotor.Set(dc);
2018-11-26 17:19:42 -08:00
scheduleMsg(&logger, "duty ETB duty=%f", dc);
2015-07-10 06:01:56 -07:00
}
static void showEthInfo(void) {
2019-11-19 23:18:17 -08:00
#if EFI_PROD_CODE
2015-07-10 06:01:56 -07:00
static char pinNameBuffer[16];
2017-09-21 20:21:03 -07:00
scheduleMsg(&logger, "etbAutoTune=%d",
engine->etbAutoTune);
2018-01-23 09:05:14 -08:00
scheduleMsg(&logger, "throttlePedal=%.2f %.2f/%.2f @%s",
getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE),
2017-05-29 20:36:08 -07:00
engineConfiguration->throttlePedalUpVoltage,
engineConfiguration->throttlePedalWOTVoltage,
getPinNameByAdcChannel("tPedal", engineConfiguration->throttlePedalPositionAdcChannel, pinNameBuffer));
2015-07-10 06:01:56 -07:00
scheduleMsg(&logger, "TPS=%.2f", getTPS(PASS_ENGINE_PARAMETER_SIGNATURE));
scheduleMsg(&logger, "dir=%d DC=%f", etb1.dcMotor.isOpenDirection(), etb1.dcMotor.Get());
2015-07-10 06:01:56 -07:00
2018-01-23 09:05:14 -08:00
scheduleMsg(&logger, "etbControlPin1=%s duty=%.2f freq=%d",
hwPortname(CONFIGB(etb1.controlPin1)),
2017-05-29 20:36:08 -07:00
currentEtbDuty,
engineConfiguration->etbFreq);
2019-08-31 14:59:18 -07:00
scheduleMsg(&logger, "dir1=%s", hwPortname(CONFIGB(etb1.directionPin1)));
scheduleMsg(&logger, "dir2=%s", hwPortname(CONFIGB(etb1.directionPin2)));
2019-08-15 18:01:04 -07:00
etbPid.showPidStatus(&logger, "ETB");
2019-11-19 23:18:17 -08:00
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
}
2019-11-19 23:18:17 -08:00
#if EFI_PROD_CODE
2015-07-10 06:01:56 -07:00
2019-09-27 20:37:40 -07:00
static void setEtbFrequency(int frequency) {
engineConfiguration->etbFreq = frequency;
etb1.setFrequency(frequency);
}
2019-03-02 12:04:42 -08:00
static void etbReset() {
scheduleMsg(&logger, "etbReset");
2019-05-04 21:42:50 -07:00
etb1.dcMotor.Set(0);
2019-08-15 18:01:04 -07:00
etbPid.reset();
2019-05-04 21:42:50 -07:00
mockPedalPosition = MOCK_UNDEFINED;
2019-03-02 12:04:42 -08:00
}
2019-11-19 23:18:17 -08:00
#endif /* EFI_PROD_CODE */
2019-11-20 05:46:54 -08:00
#if !EFI_UNIT_TEST
2019-11-19 23:18:17 -08:00
/**
* set etb_p X
*/
void setEtbPFactor(float value) {
engineConfiguration->etb.pFactor = value;
etbPid.reset();
showEthInfo();
}
2019-03-02 12:04:42 -08:00
2019-03-01 20:09:33 -08:00
/**
* set etb_i X
*/
2017-01-06 14:01:28 -08:00
void setEtbIFactor(float value) {
2015-11-11 20:01:18 -08:00
engineConfiguration->etb.iFactor = value;
2019-08-15 18:01:04 -07:00
etbPid.reset();
2018-09-24 20:57:03 -07:00
showEthInfo();
}
2019-03-01 20:09:33 -08:00
/**
* set etb_d X
*/
2018-09-24 20:57:03 -07:00
void setEtbDFactor(float value) {
engineConfiguration->etb.dFactor = value;
2019-08-15 18:01:04 -07:00
etbPid.reset();
2018-11-26 19:17:16 -08:00
showEthInfo();
}
2019-03-03 12:27:49 -08:00
/**
* set etb_o X
*/
2018-11-26 19:17:16 -08:00
void setEtbOffset(int value) {
engineConfiguration->etb.offset = value;
2019-08-15 18:01:04 -07:00
etbPid.reset();
2015-07-10 06:01:56 -07:00
showEthInfo();
}
2019-11-20 05:46:54 -08:00
#endif /* EFI_UNIT_TEST */
void setBoschVNH2SP30Curve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
2019-08-31 17:17:17 -07:00
engineConfiguration->etbBiasBins[0] = 0;
engineConfiguration->etbBiasBins[1] = 1;
engineConfiguration->etbBiasBins[2] = 5;
/**
* This specific throttle has default position of about 7% open
*/
engineConfiguration->etbBiasBins[3] = 7;
engineConfiguration->etbBiasBins[4] = 14;
engineConfiguration->etbBiasBins[5] = 65;
engineConfiguration->etbBiasBins[6] = 66;
engineConfiguration->etbBiasBins[7] = 100;
/**
* Some negative bias for below-default position
*/
engineConfiguration->etbBiasValues[0] = -15;
engineConfiguration->etbBiasValues[1] = -15;
engineConfiguration->etbBiasValues[2] = -10;
/**
* Zero bias for index which corresponds to default throttle position, when no current is applied
* This specific throttle has default position of about 7% open
*/
engineConfiguration->etbBiasValues[3] = 0;
engineConfiguration->etbBiasValues[4] = 19;
engineConfiguration->etbBiasValues[5] = 20;
engineConfiguration->etbBiasValues[6] = 26;
engineConfiguration->etbBiasValues[7] = 28;
}
void setDefaultEtbParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
2019-06-15 10:33:14 -07:00
CONFIG(etbIdleThrottleRange) = 5;
setLinearCurveAny<uint8_t>(config->pedalToTpsPedalBins, PEDAL_TO_TPS_SIZE, /*from*/0, /*to*/100, 1);
2019-06-11 18:44:16 -07:00
setLinearCurveAny<uint8_t>(config->pedalToTpsRpmBins, PEDAL_TO_TPS_SIZE, /*from*/0, /*to*/8000 / RPM_1_BYTE_PACKING_MULT, 1);
2019-06-10 20:38:44 -07:00
2019-06-10 20:57:35 -07:00
for (int pedalIndex = 0;pedalIndex<PEDAL_TO_TPS_SIZE;pedalIndex++) {
for (int rpmIndex = 0;rpmIndex<PEDAL_TO_TPS_SIZE;rpmIndex++) {
config->pedalToTpsTable[pedalIndex][rpmIndex] = config->pedalToTpsPedalBins[pedalIndex];
}
}
engineConfiguration->throttlePedalUpVoltage = 0; // that's voltage, not ADC like with TPS
engineConfiguration->throttlePedalWOTVoltage = 6; // that's voltage, not ADC like with TPS
2015-11-11 20:01:18 -08:00
engineConfiguration->etb.pFactor = 1;
2019-02-27 06:57:03 -08:00
engineConfiguration->etb.iFactor = 0.05;
engineConfiguration->etb.dFactor = 0.0;
2019-04-24 20:46:49 -07:00
engineConfiguration->etb.periodMs = (1000 / DEFAULT_ETB_LOOP_FREQUENCY);
engineConfiguration->etbFreq = DEFAULT_ETB_PWM_FREQUENCY;
2019-03-02 11:00:32 -08:00
engineConfiguration->etb_iTermMin = -300;
engineConfiguration->etb_iTermMax = 300;
2019-09-01 16:37:58 -07:00
// values are above 100% since we have feedforward part of the total summation
engineConfiguration->etb.minValue = -200;
engineConfiguration->etb.maxValue = 200;
2015-07-10 06:01:56 -07:00
}
2019-10-18 15:54:32 -07:00
static bool isEtbPinsChanged(etb_io *current, etb_io *active) {
return current->controlPin1 != active->controlPin1 ||
2019-09-20 19:16:54 -07:00
current->controlPinMode != active->controlPinMode ||
current->directionPin1 != active->directionPin1 ||
current->directionPin2 != active->directionPin2;
}
#if EFI_PROD_CODE
2017-05-30 18:56:56 -07:00
bool isETBRestartNeeded(void) {
/**
* We do not want any interruption in HW pin while adjusting other properties
*/
2019-10-18 15:54:32 -07:00
return isEtbPinsChanged(&engineConfiguration->bc.etb1, &activeConfiguration.bc.etb1);
2017-05-30 18:56:56 -07:00
}
2017-03-19 18:44:52 -07:00
void stopETBPins(void) {
brain_pin_markUnused(activeConfiguration.bc.etb1.controlPin1);
brain_pin_markUnused(activeConfiguration.bc.etb1.directionPin1);
brain_pin_markUnused(activeConfiguration.bc.etb1.directionPin2);
2017-03-19 18:44:52 -07:00
}
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2017-05-27 20:01:41 -07:00
void onConfigurationChangeElectronicThrottleCallback(engine_configuration_s *previousConfiguration) {
2019-08-15 18:01:04 -07:00
shouldResetPid = !etbPid.isSame(&previousConfiguration->etb);
2017-05-27 20:01:41 -07:00
}
void startETBPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2017-05-29 19:08:55 -07:00
2019-09-20 19:16:54 -07:00
// controlPinMode is a strange feature - it's simply because I am short on 5v I/O on Frankenso with Miata NB2 test mule
2019-04-12 22:03:12 -07:00
etb1.start(
CONFIG(etb1_use_two_wires),
CONFIGB(etb1.controlPin1),
2019-09-20 22:21:53 -07:00
&CONFIGB(etb1.controlPinMode),
CONFIGB(etb1.directionPin1),
CONFIGB(etb1.directionPin2)
);
2017-03-19 18:44:52 -07:00
}
#if EFI_PROD_CODE && 0
2017-09-21 20:21:03 -07:00
static void setTempOutput(float value) {
autoTune.output = value;
}
2018-11-25 20:13:03 -08:00
/**
* set_etbat_step X
*/
static void setAutoStep(float value) {
autoTune.reset();
2018-11-22 20:06:06 -08:00
autoTune.SetOutputStep(value);
2017-09-21 20:21:03 -07:00
}
2018-11-25 20:13:03 -08:00
static void setAutoPeriod(int period) {
2019-02-10 19:47:49 -08:00
tuneWorkingPidSettings.periodMs = period;
2018-11-25 20:13:03 -08:00
autoTune.reset();
}
2018-11-26 18:40:41 -08:00
static void setAutoOffset(int offset) {
tuneWorkingPidSettings.offset = offset;
autoTune.reset();
}
2019-11-19 23:18:17 -08:00
#endif /* EFI_PROD_CODE */
2018-11-26 18:40:41 -08:00
void setDefaultEtbBiasCurve(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
2018-12-09 10:50:13 -08:00
engineConfiguration->etbBiasBins[0] = 0;
2019-03-02 11:00:32 -08:00
engineConfiguration->etbBiasBins[1] = 1;
engineConfiguration->etbBiasBins[2] = 2;
2019-04-21 09:24:31 -07:00
/**
* This specific throttle has default position of about 4% open
*/
2019-03-02 11:00:32 -08:00
engineConfiguration->etbBiasBins[3] = 4;
engineConfiguration->etbBiasBins[4] = 7;
2018-12-09 10:50:13 -08:00
engineConfiguration->etbBiasBins[5] = 98;
engineConfiguration->etbBiasBins[6] = 99;
engineConfiguration->etbBiasBins[7] = 100;
2019-04-21 09:24:31 -07:00
/**
* Some negative bias for below-default position
*/
engineConfiguration->etbBiasValues[0] = -20;
engineConfiguration->etbBiasValues[1] = -18;
engineConfiguration->etbBiasValues[2] = -17;
2019-04-21 09:24:31 -07:00
/**
* Zero bias for index which corresponds to default throttle position, when no current is applied
* This specific throttle has default position of about 4% open
*/
engineConfiguration->etbBiasValues[3] = 0;
engineConfiguration->etbBiasValues[4] = 20;
engineConfiguration->etbBiasValues[5] = 21;
engineConfiguration->etbBiasValues[6] = 22;
engineConfiguration->etbBiasValues[7] = 25;
2018-12-09 10:50:13 -08:00
}
void unregisterEtbPins() {
}
void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_PROD_CODE
2017-05-29 19:08:55 -07:00
addConsoleAction("ethinfo", showEthInfo);
2019-03-02 12:04:42 -08:00
addConsoleAction("etbreset", etbReset);
2019-09-27 20:37:40 -07:00
addConsoleActionI("etb_freq", setEtbFrequency);
#endif /* EFI_PROD_CODE */
etbPid.initPidClass(&engineConfiguration->etb);
INJECT_ENGINE_REFERENCE(etb1);
INJECT_ENGINE_REFERENCE(etbController);
pedal2tpsMap.init(config->pedalToTpsTable, config->pedalToTpsPedalBins, config->pedalToTpsRpmBins);
engine->engineState.hasEtbPedalPositionSensor = hasPedalPositionSensor(PASS_ENGINE_PARAMETER_SIGNATURE);
if (!engine->engineState.hasEtbPedalPositionSensor) {
2017-03-19 18:44:52 -07:00
return;
}
2019-09-29 11:00:04 -07:00
#if 0
// not alive code
2018-11-25 20:13:03 -08:00
autoTune.SetOutputStep(0.1);
2019-09-29 11:00:04 -07:00
#endif
2017-03-19 18:44:52 -07:00
2019-09-29 11:00:04 -07:00
#if 0 && ! EFI_UNIT_TEST
percent_t startupThrottlePosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
if (absF(startupThrottlePosition - engineConfiguration->etbNeutralPosition) > STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD) {
/**
* Unexpected electronic throttle start-up position is worth a fatal error
*/
firmwareError(OBD_Throttle_Actuator_Control_Range_Performance_Bank_1, "startup ETB position %.2f not %d",
startupThrottlePosition,
engineConfiguration->etbNeutralPosition);
startupPositionError = true;
}
#endif /* EFI_UNIT_TEST */
startETBPins(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 17:01:36 -07:00
2019-09-29 11:22:51 -07:00
#if EFI_PROD_CODE
2019-09-29 11:00:04 -07:00
if (engineConfiguration->etbCalibrationOnStart) {
etb1.dcMotor.Set(70);
chThdSleep(600);
grabTPSIsWideOpen();
etb1.dcMotor.Set(-70);
chThdSleep(600);
grabTPSIsClosed();
}
// manual duty cycle control without PID. Percent value from 0 to 100
addConsoleActionNANF(CMD_ETB_DUTY, setThrottleDutyCycle);
2019-11-19 23:18:17 -08:00
#endif /* EFI_PROD_CODE */
2019-09-29 11:00:04 -07:00
#if EFI_PROD_CODE && 0
2018-11-22 20:42:30 -08:00
tuneWorkingPidSettings.pFactor = 1;
tuneWorkingPidSettings.iFactor = 0;
tuneWorkingPidSettings.dFactor = 0;
2018-11-25 20:13:03 -08:00
// tuneWorkingPidSettings.offset = 10; // todo: not hard-coded value
2019-02-10 19:47:49 -08:00
//todo tuneWorkingPidSettings.periodMs = 10;
2018-11-22 20:42:30 -08:00
tuneWorkingPidSettings.minValue = 0;
tuneWorkingPidSettings.maxValue = 100;
2019-02-10 19:47:49 -08:00
tuneWorkingPidSettings.periodMs = 100;
2018-11-22 20:42:30 -08:00
2019-03-01 20:09:33 -08:00
// this is useful once you do "enable etb_auto"
2018-11-25 20:13:03 -08:00
addConsoleActionF("set_etbat_output", setTempOutput);
addConsoleActionF("set_etbat_step", setAutoStep);
addConsoleActionI("set_etbat_period", setAutoPeriod);
2018-11-26 18:40:41 -08:00
addConsoleActionI("set_etbat_offset", setAutoOffset);
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2019-09-29 11:00:04 -07:00
2019-08-15 18:01:04 -07:00
etbPid.reset();
2015-07-10 06:01:56 -07:00
2019-02-10 16:52:06 -08:00
etbController.Start();
2015-07-10 06:01:56 -07:00
}
#endif /* EFI_ELECTRONIC_THROTTLE_BODY */