42#if EFI_ELECTRONIC_THROTTLE_BODY
51#if defined(HAS_OS_ACCESS)
52#error "Unexpected OS ACCESS HERE"
60#define ETB_MAX_COUNT 2
63#ifndef ETB_INTERMITTENT_LIMIT
64#define ETB_INTERMITTENT_LIMIT 50
162#define ETB_DUTY_LIMIT 0.9
164#define ETB_PERCENT_TO_DUTY(x) (clampF(-ETB_DUTY_LIMIT, 0.01f * (x), ETB_DUTY_LIMIT))
172 if (function == DC_None) {
224 efiPrintf(
"ETB reset %s", reason);
237 efiPrintf(
" ETB m_shouldResetPid");
279#if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR)
288 return clampPercentValue(targetPosition);
296 return clampPercentValue(pedalPosition.value_or(0));
300 return currentEtbTarget;
340#if EFI_ANTILAG_SYSTEM
356 targetPosition = clampPercentValue(targetPosition);
360 if (etbRpmLimit != 0) {
363 float targetPositionBefore = targetPosition;
365 targetPosition =
interpolateClamped(etbRpmLimit, targetPosition, fullyLimitedRpm, 0, rpm);
376 maxPosition = std::min(maxPosition, 100.0f);
378 targetPosition = clampF(minPosition, targetPosition, maxPosition);
381 return targetPosition;
433 bool isPositive = actualThrottlePosition > target;
435 float autotuneAmplitude = 20;
446 constexpr float alpha = 0.05;
447 m_a = alpha * a + (1 - alpha) *
m_a;
448 m_tu = alpha * tu + (1 - alpha) *
m_tu;
458 float b = 2 * autotuneAmplitude;
461 float ku = 4 * b / (CONST_PI *
m_a);
466 float kp = 0.35f * ku;
467 float ki = 0.25f * ku /
m_tu;
468 float kd = 0.08f * ku *
m_tu;
522 return autotuneAmplitude * (isPositive ? -1 : 1);
575 }
else if (!outputValue) {
586 m_motor->
set(ETB_PERCENT_TO_DUTY(outputValue.Value));
644#if EFI_SHAFT_POSITION_INPUT
691 float absError = std::abs(setpoint - observation);
696 if (jamDetectThreshold != 0 && jamTimeout != 0) {
701 efiPrintf(
" ************* ETB is jammed! ***************");
734 for (
int i = 0;i<ETB_COUNT;i++) {
750 for (
int i = 0 ; i < ETB_COUNT; i++) {
752 assertNotNullVoid(controller);
764 for (
int i = 0 ; i < ETB_COUNT; i++) {
766 assertNotNullVoid(controller);
767 controller->reset(
"unit_test");
775 for (
size_t i = 0 ; i < ETB_COUNT; i++) {
779 assertNotNullVoid(controller);
780 if (controller->getFunction() == function) {
782 controller->autoCalibrateTps(reportToTs);
791 if (throttleIndex >= ETB_COUNT) {
802 0, 1, 5, 7, 14, 65, 66, 100
805 -15, -15, -10, 0, 19, 20, 26, 28
832 for (
int pedalIndex = 0;pedalIndex<PEDAL_TO_TPS_SIZE;pedalIndex++) {
833 for (
int rpmIndex = 0;rpmIndex<PEDAL_TO_TPS_RPM_SIZE;rpmIndex++) {
864 for (
int i = 0; i < ETB_COUNT; i++) {
870 0, 1, 2, 4, 7, 98, 99, 100
873 -20, -18, -17, 0, 20, 21, 22, 25
899 bool anyEtbConfigured =
false;
904 for (
int i = 0 ; i < ETB_COUNT; i++) {
906 if (func == DC_None) {
914 criticalAssertVoid(controller !=
nullptr,
"null ETB");
919 if (isStartupInit && dcConfigured) {
920 controller->reset(
"init");
922 anyEtbConfigured |= dcConfigured && controller->isEtbMode();
927 criticalError(
"A pedal position sensor was configured, but no electronic throttles are configured.");
930#if 0 && ! EFI_UNIT_TEST
931 percent_t startupThrottlePosition = getTPS();
937 startupThrottlePosition,
939 startupPositionError =
true;
944 static bool started =
false;
945 if (started ==
false) {
953 if (hasFirmwareError()) {
957 for (
int i = 0; i < ETB_COUNT; i++) {
963 efiPrintf(
"etbAutocal invoked");
971 efiPrintf(
"ETB1 duty=%.2f",
974 efiPrintf(
"ETB freq=%d",
977 for (
int i = 0; i < ETB_COUNT; i++) {
978 efiPrintf(
"ETB%d", i);
997 for (
int i = 0; i < ETB_COUNT; i++) {
999 assertNotNullVoid(etb);
1000 etb->setIdlePosition(pos);
1006 for (
int i = 0; i < ETB_COUNT; i++) {
1008 assertNotNullVoid(etb);
1009 etb->setWastegatePosition(pos);
1015 for (
int i = 0; i < ETB_COUNT; i++) {
1019 assertNotNullVoid(etb);
1021 if (etb->getFunction() == DC_Throttle1 || etb->getFunction() == DC_Throttle2) {
1022 etb->setLuaAdjustment(pos);
1029 for (
int i = 0; i < ETB_COUNT; i++) {
1033 assertNotNullVoid(etb);
1035 if (etb->getFunction() == DC_Wastegate) {
1036 etb->setLuaAdjustment(pos);
1076 setPPSInputs(PROTEUS_IN_ANALOG_VOLT_6, PROTEUS_IN_PPS2);
1085#if EFI_ELECTRONIC_THROTTLE_BODY
Brushed or brushless DC motor interface.
virtual bool set(float duty)=0
Sets the motor duty cycle.
virtual void disable(const char *msg)=0
TriggerCentral triggerCentral
AntilagSystemBase antilagController
IEtbController * etbControllers[ETB_COUNT]
TunerStudioOutputChannels outputChannels
constexpr auto & module()
float accumulate(float error)
void init(float ignoreError, float dt)
const ValueProvider3D & m_throttle2Trim
percent_t getThrottleTrim(float rpm, percent_t) const override
void setWastegatePosition(percent_t pos) override
float getLuaAdjustment() const
bool isEtbMode() const override
uint8_t m_autotuneCounter
uint8_t m_autotuneCurrentParam
expected< percent_t > getSetpointIdleValve() const
expected< percent_t > getSetpointEtb()
void setIdlePosition(percent_t pos) override
void checkJam(percent_t setpoint, percent_t observation)
expected< percent_t > getSetpoint() override
ErrorAccumulator m_targetErrorAccumulator
virtual percent_t getThrottleTrim(float, percent_t) const
expected< percent_t > getClosedLoopAutotune(percent_t setpoint, percent_t actualThrottlePosition)
Timer m_luaAdjustmentTimer
bool init(dc_function_e function, DcMotor *motor, pid_s *pidParameters, const ValueProvider3D *pedalMap) override
SensorType m_positionSensor
void setLuaAdjustment(percent_t adjustment) override
expected< percent_t > getClosedLoop(percent_t setpoint, percent_t observation) override
expected< percent_t > getOpenLoop(percent_t target) override
void reset(const char *reason) override
void onConfigurationChange(pid_s *previousConfiguration)
const ValueProvider3D * m_pedalProvider
expected< percent_t > observePlant() override
expected< percent_t > getSetpointWastegate() const
void setOutput(expected< percent_t > outputValue) override
virtual bool getIgnState() const
bool allowElectronicThrottle() const
void initTable(TValueInit(&table)[TRowNum][TColNum], const TXColumnInit(&columnBins)[TColNum], const TRowInit(&rowBins)[TRowNum])
Base class for a controller that needs to run periodically to perform work.
virtual void PeriodicTask(efitick_t nowNt)=0
Called periodically. Override this method to do work for your controller.
bool isSame(const pid_s *parameters) const
void postState(pid_status_s &pidStatus) const
void showPidStatus(const char *msg) const
void initPidClass(pid_s *parameters)
float getOutput(float target, float input)
virtual bool hasSensor() const
virtual SensorResult get() const =0
virtual bool isRedundant() const
static float getOrZero(SensorType type)
bool engineMovedRecently(efitick_t nowNt) const
virtual float getValue(float xColumn, float yRow) const =0
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
DcMotor * initDcMotor(const char *disPinMsg, const dc_io &io, size_t index, bool useTwoWires)
void showDcMotorInfo(int i)
void setPPSInputs(adc_channel_e pps1, adc_channel_e pps2)
void setPPSCalibration(float primaryUp, float primaryDown, float secondaryUp, float secondaryDown)
float interpolateClamped(float x1, float y1, float x2, float y2, float x)
void setDefaultEtbParameters()
void setToyota89281_33010_pedal_position_sensor()
static TsCalMode functionToCalModePriMin(dc_function_e func)
void setHitachiEtbBiasBins()
static const float boschBiasValues[]
void setEtbLuaAdjustment(percent_t pos)
void initElectronicThrottle()
void setHitachiEtbCalibration()
EtbImpl< EtbController2 > etb2(throttle2TrimTable)
constexpr float etbPeriodSeconds
void setEtbIdlePosition(percent_t pos)
static const float boschBiasBins[]
void etbAutocal(dc_function_e function, bool reportToTs)
void setEtbWastegatePosition(percent_t pos)
static Map3D< TRACTION_CONTROL_ETB_DROP_SLIP_SIZE, TRACTION_CONTROL_ETB_DROP_SPEED_SIZE, int8_t, uint16_t, uint8_t > tcEtbDropTable
const electronic_throttle_s * getLiveData(size_t idx)
void onConfigurationChangeElectronicThrottleCallback(engine_configuration_s *previousConfiguration)
static Map3D< ETB2_TRIM_SIZE, ETB2_TRIM_SIZE, int8_t, uint8_t, uint8_t > throttle2TrimTable
void blinkEtbErrorCodes(bool blinkPhase)
static const float defaultBiasValues[]
static SensorType functionToPositionSensor(dc_function_e func)
static pid_s * getPidForDcFunction(dc_function_e function)
EtbStatus etbGetState(size_t throttleIndex)
static TsCalMode functionToCalModeSecMin(dc_function_e func)
PUBLIC_API_WEAK bool isBoardAllowingLackOfPps()
static SensorType functionToTpsSensorPrimary(dc_function_e func)
static EtbController * etbControllers[]
PUBLIC_API_WEAK ValueProvider3D * pedal2TpsProvider()
static const float hardCodedetbHitachiBiasValues[8]
static DcThread dcThread CCM_OPTIONAL
static const float defaultBiasBins[]
static pedal2tps_t pedal2tpsMap
PUBLIC_API_WEAK float boardAdjustEtbTarget(float currentEtbTarget)
void setProteusHitachiEtbDefaults()
float getSanitizedPedal()
static SensorType functionToTpsSensor(dc_function_e func)
static TsCalMode functionToCalModePriMax(dc_function_e func)
static const float hardCodedetbHitachiBiasBins[8]
void setEwgLuaAdjustment(percent_t pos)
EtbImpl< EtbController1 > etb1
static SensorType functionToTpsSensorSecondary(dc_function_e func)
static TsCalMode functionToCalModeSecMax(dc_function_e func)
void doInitElectronicThrottle(bool isStartupInit)
void setBoschVNH2SP30Curve()
void setDefaultEtbBiasCurve()
LimpManager * getLimpManager()
static EngineAccessor engine
static constexpr persistent_config_s * config
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
@ OBD_Throttle_Actuator_Control_Range_Performance_Bank_1
const char * hwPortname(brain_pin_e brainPin)
@ AcceleratorPedalPrimary
etbErrorCode("etbErrorCode", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1864, 1.0, -1.0, -1.0, "")
scaled_channel< uint16_t, 100, 1 > jamTimer
uint16_t etbTpsErrorCounter
float targetWithIdlePosition
float m_wastegatePosition
scaled_channel< int16_t, 100, 1 > m_adjustedTarget
uint16_t etbPpsErrorCounter
int8_t etbErrorCodeBlinker
adc_channel_e tps2_2AdcChannel
uint8_t etbJamDetectThreshold
uint8_t tractionControlSpeedBins[TRACTION_CONTROL_ETB_DROP_SPEED_SIZE]
dc_function_e etbFunctions[ETB_COUNT]
uint16_t etbRevLimitRange
uint8_t etbNeutralPosition
tps_limit_t tps1SecondaryMax
bool disableEtbWhenEngineStopped
uint8_t etbMaximumPosition
uint16_t tps2SecondaryMax
adc_channel_e tps1_2AdcChannel
scaled_channel< uint16_t, 100, 1 > tractionControlSlipBins[TRACTION_CONTROL_ETB_DROP_SLIP_SIZE]
int8_t tractionControlEtbDrop[TRACTION_CONTROL_ETB_DROP_SLIP_SIZE][TRACTION_CONTROL_ETB_DROP_SPEED_SIZE]
float etbIdleThrottleRange
scaled_channel< uint8_t, 50, 1 > etbJamTimeout
tps_limit_t tps1SecondaryMin
scaled_channel< uint8_t, 10, 1 > etbMinimumPosition
uint16_t etbRevLimitStart
adc_channel_e tps2_1AdcChannel
uint16_t tps2SecondaryMin
pid_status_s wastegateDcStatus
scaled_channel< int16_t, 100, 1 > etb1DutyCycle
scaled_channel< int16_t, 100, 1 > dcWastegateBiasValues[ETB_BIAS_CURVE_LENGTH]
uint8_t pedalToTpsPedalBins[PEDAL_TO_TPS_SIZE]
uint8_t pedalToTpsTable[PEDAL_TO_TPS_SIZE][PEDAL_TO_TPS_RPM_SIZE]
scaled_channel< uint8_t, 1, 100 > throttle2TrimRpmBins[ETB2_TRIM_SIZE]
float etbBiasValues[ETB_BIAS_CURVE_LENGTH]
uint8_t throttle2TrimTpsBins[ETB2_TRIM_SIZE]
scaled_channel< uint8_t, 1, 100 > pedalToTpsRpmBins[PEDAL_TO_TPS_RPM_SIZE]
float etbBiasBins[ETB_BIAS_CURVE_LENGTH]
int8_t dcWastegateBiasBins[ETB_BIAS_CURVE_LENGTH]
scaled_channel< int8_t, 10, 1 > throttle2TrimTable[ETB2_TRIM_SIZE][ETB2_TRIM_SIZE]
void setRpmTableBin(TValue(&array)[TSize])
void setLinearCurve(TValue(&array)[TSize], float from, float to, float precision=0.01f)
void onTransitionEvent(TransitionEvent event)
void tsCalibrationSetData(TsCalMode mode, float value, float value2, float timeoutMs)
maintainConstantValue implementation header