2020-03-23 20:20:54 -07:00
|
|
|
/*
|
|
|
|
* @file launch_control.cpp
|
|
|
|
*
|
|
|
|
* @date 10. sep. 2019
|
|
|
|
* Author: Ola Ruud
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "engine.h"
|
|
|
|
|
|
|
|
#if EFI_LAUNCH_CONTROL
|
|
|
|
#include "boost_control.h"
|
|
|
|
#include "vehicle_speed.h"
|
|
|
|
#include "launch_control.h"
|
|
|
|
#include "io_pins.h"
|
|
|
|
#include "engine_configuration.h"
|
|
|
|
#include "engine_controller.h"
|
|
|
|
#include "periodic_task.h"
|
|
|
|
#include "pin_repository.h"
|
|
|
|
#include "allsensors.h"
|
2020-04-05 16:33:33 -07:00
|
|
|
#include "sensor.h"
|
2020-03-23 20:20:54 -07:00
|
|
|
#include "engine_math.h"
|
|
|
|
#include "efi_gpio.h"
|
|
|
|
#include "advance_map.h"
|
|
|
|
#include "engine_state.h"
|
|
|
|
#include "advance_map.h"
|
|
|
|
|
2020-12-01 10:03:42 -08:00
|
|
|
static bool isInit = false;
|
2020-03-23 20:20:54 -07:00
|
|
|
static Logging *logger;
|
|
|
|
|
2020-12-01 10:03:42 -08:00
|
|
|
LaunchControlBase launchInstance;
|
|
|
|
|
2020-03-23 20:20:54 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
2020-05-25 10:02:05 -07:00
|
|
|
#include "tunerstudio_outputs.h"
|
2020-03-23 20:20:54 -07:00
|
|
|
extern TunerStudioOutputChannels tsOutputChannels;
|
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
|
|
|
|
2020-03-29 16:06:03 -07:00
|
|
|
EXTERN_ENGINE;
|
2020-03-23 20:20:54 -07:00
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
static int retardThresholdRpm;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We can have active condition from switch or from clutch.
|
|
|
|
* In case we are dependent on VSS we just return true.
|
|
|
|
*/
|
|
|
|
bool LaunchControlBase::isInsideSwitchCondition() const {
|
|
|
|
switch (CONFIG(launchActivationMode)) {
|
2020-03-23 20:20:54 -07:00
|
|
|
case SWITCH_INPUT_LAUNCH:
|
|
|
|
if (CONFIG(launchActivatePin) != GPIO_UNASSIGNED) {
|
2020-11-19 18:14:38 -08:00
|
|
|
//todo: we should take into consideration if this sw is pulled high or low!
|
2020-03-23 20:20:54 -07:00
|
|
|
engine->launchActivatePinState = efiReadPin(CONFIG(launchActivatePin));
|
|
|
|
}
|
|
|
|
return engine->launchActivatePinState;
|
|
|
|
|
|
|
|
case CLUTCH_INPUT_LAUNCH:
|
|
|
|
if (CONFIG(clutchDownPin) != GPIO_UNASSIGNED) {
|
|
|
|
engine->clutchDownState = efiReadPin(CONFIG(clutchDownPin));
|
2020-11-19 18:14:38 -08:00
|
|
|
|
|
|
|
if (CONFIG(clutchDownPinMode) == PI_PULLDOWN)
|
|
|
|
{
|
|
|
|
return !engine->clutchDownState;
|
|
|
|
} else {
|
|
|
|
return engine->clutchDownState;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
2020-11-19 18:14:38 -08:00
|
|
|
|
2020-03-23 20:20:54 -07:00
|
|
|
default:
|
|
|
|
// ALWAYS_ACTIVE_LAUNCH
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
|
|
|
* Returns True in case Vehicle speed is less then trashold.
|
|
|
|
* This condiiion would only return true based on speed if DisablebySpeed is true
|
|
|
|
* The condition logic is written in that way, that if we do not use disable by speed
|
|
|
|
* then we have to return true, and trust that we would disable by other condition!
|
|
|
|
*/
|
2020-11-19 05:15:56 -08:00
|
|
|
bool LaunchControlBase::isInsideSpeedCondition() const {
|
|
|
|
int speed = getVehicleSpeed();
|
2020-12-01 10:03:42 -08:00
|
|
|
|
|
|
|
return (CONFIG(launchSpeedTreshold) > speed) || (!(CONFIG(launchActivationMode) == ALWAYS_ACTIVE_LAUNCH));
|
2020-11-19 05:15:56 -08:00
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
|
|
|
* Returns false if TPS is invalid or TPS > preset trashold
|
|
|
|
*/
|
2020-11-19 05:15:56 -08:00
|
|
|
bool LaunchControlBase::isInsideTpsCondition() const {
|
|
|
|
auto tps = Sensor::get(SensorType::DriverThrottleIntent);
|
|
|
|
|
|
|
|
// Disallow launch without valid TPS
|
|
|
|
if (!tps.Valid) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CONFIG(launchTpsTreshold) < tps.Value;
|
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
|
|
|
* Condition is true as soon as we are above LaunchRpm
|
|
|
|
*/
|
|
|
|
bool LaunchControlBase::isInsideRPMCondition(int rpm) const {
|
|
|
|
int launchRpm = CONFIG(launchRpm);
|
|
|
|
return (launchRpm < rpm);
|
|
|
|
}
|
2020-11-19 05:15:56 -08:00
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
bool LaunchControlBase::isLaunchConditionMet(int rpm) const {
|
2020-11-19 05:15:56 -08:00
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
bool activateSwitchCondition = isInsideSwitchCondition();
|
|
|
|
bool rpmCondition = isInsideRPMCondition(rpm);
|
2020-11-19 05:15:56 -08:00
|
|
|
bool speedCondition = isInsideSpeedCondition();
|
|
|
|
bool tpsCondition = isInsideTpsCondition();
|
2020-03-23 20:20:54 -07:00
|
|
|
|
|
|
|
#if EFI_TUNER_STUDIO
|
2020-11-19 05:15:56 -08:00
|
|
|
if (engineConfiguration->debugMode == DBG_LAUNCH) {
|
|
|
|
tsOutputChannels.debugIntField1 = rpmCondition;
|
|
|
|
tsOutputChannels.debugIntField2 = tpsCondition;
|
|
|
|
tsOutputChannels.debugIntField3 = speedCondition;
|
|
|
|
tsOutputChannels.debugIntField4 = activateSwitchCondition;
|
|
|
|
}
|
2020-03-23 20:20:54 -07:00
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
2020-11-19 05:15:56 -08:00
|
|
|
|
|
|
|
return speedCondition && activateSwitchCondition && rpmCondition && tpsCondition;
|
|
|
|
}
|
|
|
|
|
2020-12-01 10:03:42 -08:00
|
|
|
void updateLaunchConditions(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|
|
|
launchInstance.update();
|
|
|
|
}
|
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
void LaunchControlBase::update() {
|
2020-12-01 10:03:42 -08:00
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
if (!CONFIG(launchControlEnabled)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-01 10:03:42 -08:00
|
|
|
#if ! EFI_UNIT_TEST
|
|
|
|
if(!isInit) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
int rpm = GET_RPM();
|
|
|
|
bool combinedConditions = isLaunchConditionMet(rpm);
|
2020-11-19 18:14:38 -08:00
|
|
|
float timeDelay = CONFIG(launchActivateDelay);
|
|
|
|
|
|
|
|
//recalculate in periodic task, this way we save time in applyLaunchControlLimiting
|
|
|
|
//and still recalculat in case user changed the values
|
2020-12-01 10:03:42 -08:00
|
|
|
retardThresholdRpm = CONFIG(launchRpm) + (CONFIG(enableLaunchRetard) ?
|
|
|
|
CONFIG(launchAdvanceRpmRange) : 0) + CONFIG(hardCutRpmRange);
|
2020-11-19 05:15:56 -08:00
|
|
|
|
|
|
|
if (!combinedConditions) {
|
|
|
|
// conditions not met, reset timer
|
2020-11-30 16:35:06 -08:00
|
|
|
m_launchTimer.reset();
|
2020-11-19 05:15:56 -08:00
|
|
|
engine->isLaunchCondition = false;
|
|
|
|
engine->setLaunchBoostDuty = false;
|
|
|
|
engine->applyLaunchControlRetard = false;
|
|
|
|
engine->applyLaunchExtraFuel = false;
|
|
|
|
} else {
|
|
|
|
// If conditions are met...
|
2020-12-01 10:03:42 -08:00
|
|
|
if (m_launchTimer.hasElapsedMs(timeDelay*1000) && combinedConditions) {
|
2020-11-19 05:15:56 -08:00
|
|
|
engine->isLaunchCondition = true; // ...enable launch!
|
|
|
|
engine->applyLaunchExtraFuel = true;
|
|
|
|
}
|
2020-11-19 18:14:38 -08:00
|
|
|
if (CONFIG(enableLaunchBoost)) {
|
2020-11-19 05:15:56 -08:00
|
|
|
engine->setLaunchBoostDuty = true; // ...enable boost!
|
|
|
|
}
|
2020-11-19 18:14:38 -08:00
|
|
|
if (CONFIG(enableLaunchRetard)) {
|
2020-11-19 05:15:56 -08:00
|
|
|
engine->applyLaunchControlRetard = true; // ...enable retard!
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
#if EFI_TUNER_STUDIO
|
2020-11-19 18:14:38 -08:00
|
|
|
if (CONFIG(debugMode) == DBG_LAUNCH) {
|
2020-11-19 05:15:56 -08:00
|
|
|
tsOutputChannels.debugIntField5 = engine->clutchDownState;
|
|
|
|
tsOutputChannels.debugFloatField1 = engine->launchActivatePinState;
|
|
|
|
tsOutputChannels.debugFloatField2 = engine->isLaunchCondition;
|
|
|
|
tsOutputChannels.debugFloatField3 = combinedConditions;
|
|
|
|
}
|
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
|
|
|
}
|
|
|
|
|
2020-03-23 20:20:54 -07:00
|
|
|
void setDefaultLaunchParameters(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
|
|
|
|
engineConfiguration->launchRpm = 4000; // Rpm to trigger Launch condition
|
|
|
|
engineConfiguration->launchTimingRetard = 10; // retard in absolute degrees ATDC
|
|
|
|
engineConfiguration->launchTimingRpmRange = 500; // Rpm above Launch triggered for full retard
|
|
|
|
engineConfiguration->launchSparkCutEnable = true;
|
|
|
|
engineConfiguration->launchFuelCutEnable = false;
|
|
|
|
engineConfiguration->hardCutRpmRange = 500; //Rpm above Launch triggered +(if retard enabled) launchTimingRpmRange to hard cut
|
|
|
|
engineConfiguration->launchSpeedTreshold = 10; //maximum speed allowed before disable launch
|
|
|
|
engineConfiguration->launchFuelAdded = 10; // Extra fuel in % when launch are triggered
|
|
|
|
engineConfiguration->launchBoostDuty = 70; // boost valve duty cycle at launch
|
|
|
|
engineConfiguration->launchActivateDelay = 3; // Delay in seconds for launch to kick in
|
|
|
|
engineConfiguration->enableLaunchRetard = true;
|
|
|
|
engineConfiguration->enableLaunchBoost = true;
|
|
|
|
engineConfiguration->launchSmoothRetard = true; //interpolates the advance linear from launchrpm to fully retarded at launchtimingrpmrange
|
|
|
|
engineConfiguration->antiLagRpmTreshold = 3000;
|
2020-12-01 10:03:42 -08:00
|
|
|
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void applyLaunchControlLimiting(bool *limitedSpark, bool *limitedFuel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2020-12-01 10:03:42 -08:00
|
|
|
if (( engine->isLaunchCondition ) && ( retardThresholdRpm < GET_RPM() )) {
|
2020-10-03 22:04:15 -07:00
|
|
|
*limitedSpark = engineConfiguration->launchSparkCutEnable;
|
|
|
|
*limitedFuel = engineConfiguration->launchFuelCutEnable;
|
2020-12-01 10:03:42 -08:00
|
|
|
}
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void initLaunchControl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|
|
|
logger = sharedLogger;
|
2020-12-01 10:03:42 -08:00
|
|
|
INJECT_ENGINE_REFERENCE(&launchInstance);
|
|
|
|
|
|
|
|
isInit = true;
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* EFI_LAUNCH_CONTROL */
|