2020-03-23 20:20:54 -07:00
|
|
|
/*
|
|
|
|
* @file launch_control.cpp
|
|
|
|
*
|
|
|
|
* @date 10. sep. 2019
|
|
|
|
* Author: Ola Ruud
|
|
|
|
*/
|
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
2020-03-23 20:20:54 -07:00
|
|
|
|
|
|
|
#if EFI_LAUNCH_CONTROL
|
|
|
|
#include "boost_control.h"
|
|
|
|
#include "launch_control.h"
|
|
|
|
#include "periodic_task.h"
|
|
|
|
#include "advance_map.h"
|
|
|
|
#include "engine_state.h"
|
|
|
|
#include "advance_map.h"
|
2021-11-25 19:40:19 -08:00
|
|
|
#include "tinymt32.h"
|
2020-03-23 20:20:54 -07:00
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
|
|
|
* We can have active condition from switch or from clutch.
|
|
|
|
* In case we are dependent on VSS we just return true.
|
|
|
|
*/
|
2021-11-15 17:09:03 -08:00
|
|
|
bool LaunchControlBase::isInsideSwitchCondition() {
|
2022-01-24 17:58:21 -08:00
|
|
|
isSwitchActivated = engineConfiguration->launchActivationMode == SWITCH_INPUT_LAUNCH;
|
|
|
|
isClutchActivated = engineConfiguration->launchActivationMode == CLUTCH_INPUT_LAUNCH;
|
|
|
|
|
|
|
|
|
|
|
|
if (isSwitchActivated) {
|
2021-11-16 13:45:14 -08:00
|
|
|
#if !EFI_SIMULATOR
|
2021-11-17 00:54:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->launchActivatePin)) {
|
2022-04-19 17:43:41 -07:00
|
|
|
launchActivatePinState = engineConfiguration->launchActivateInverted ^ efiReadPin(engineConfiguration->launchActivatePin);
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
2021-11-16 13:31:35 -08:00
|
|
|
#endif // EFI_PROD_CODE
|
2021-11-15 17:09:03 -08:00
|
|
|
return launchActivatePinState;
|
2022-01-24 17:58:21 -08:00
|
|
|
} else if (isClutchActivated) {
|
2021-11-17 00:54:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->clutchDownPin)) {
|
2022-06-28 23:37:24 -07:00
|
|
|
return engine->engineState.clutchDownState;
|
2020-11-19 18:14:38 -08:00
|
|
|
} else {
|
|
|
|
return false;
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
2022-01-24 17:58:21 -08:00
|
|
|
} else {
|
2020-03-23 20:20:54 -07:00
|
|
|
// ALWAYS_ACTIVE_LAUNCH
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
2021-11-16 13:46:54 -08:00
|
|
|
* Returns True in case Vehicle speed is less then threshold.
|
|
|
|
* This condition would only return true based on speed if DisablebySpeed is true
|
2020-11-19 18:14:38 -08:00
|
|
|
* 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 {
|
2021-10-05 16:59:07 -07:00
|
|
|
int speed = Sensor::getOrZero(SensorType::VehicleSpeed);
|
2020-12-01 10:03:42 -08:00
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
return (engineConfiguration->launchSpeedThreshold > speed) || (!(engineConfiguration->launchActivationMode == ALWAYS_ACTIVE_LAUNCH));
|
2020-11-19 05:15:56 -08:00
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
2021-11-16 13:46:54 -08:00
|
|
|
* Returns false if TPS is invalid or TPS > preset threshold
|
2020-11-19 18:14:38 -08:00
|
|
|
*/
|
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;
|
|
|
|
}
|
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
return engineConfiguration->launchTpsTreshold < tps.Value;
|
2020-11-19 05:15:56 -08:00
|
|
|
}
|
|
|
|
|
2020-11-19 18:14:38 -08:00
|
|
|
/**
|
|
|
|
* Condition is true as soon as we are above LaunchRpm
|
|
|
|
*/
|
|
|
|
bool LaunchControlBase::isInsideRPMCondition(int rpm) const {
|
2021-11-17 00:54:21 -08:00
|
|
|
int launchRpm = engineConfiguration->launchRpm;
|
2020-11-19 18:14:38 -08:00
|
|
|
return (launchRpm < rpm);
|
|
|
|
}
|
2020-11-19 05:15:56 -08:00
|
|
|
|
2021-11-15 17:09:03 -08:00
|
|
|
bool LaunchControlBase::isLaunchConditionMet(int rpm) {
|
2020-11-19 05:15:56 -08:00
|
|
|
|
2021-12-16 13:19:33 -08:00
|
|
|
activateSwitchCondition = isInsideSwitchCondition();
|
|
|
|
rpmCondition = isInsideRPMCondition(rpm);
|
|
|
|
speedCondition = isInsideSpeedCondition();
|
|
|
|
tpsCondition = isInsideTpsCondition();
|
2020-03-23 20:20:54 -07:00
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
return speedCondition && activateSwitchCondition && rpmCondition && tpsCondition;
|
|
|
|
}
|
|
|
|
|
2021-12-16 11:47:00 -08:00
|
|
|
LaunchControlBase::LaunchControlBase() {
|
|
|
|
launchActivatePinState = false;
|
|
|
|
isLaunchCondition = false;
|
|
|
|
}
|
|
|
|
|
2020-11-19 05:15:56 -08:00
|
|
|
void LaunchControlBase::update() {
|
2021-11-17 00:54:21 -08:00
|
|
|
if (!engineConfiguration->launchControlEnabled) {
|
2020-11-19 05:15:56 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-20 20:43:18 -08:00
|
|
|
int rpm = Sensor::getOrZero(SensorType::Rpm);
|
2021-12-16 11:47:00 -08:00
|
|
|
combinedConditions = isLaunchConditionMet(rpm);
|
2020-11-19 18:14:38 -08:00
|
|
|
|
2021-12-16 11:47:00 -08:00
|
|
|
//and still recalculate in case user changed the values
|
2022-07-20 15:16:54 -07:00
|
|
|
retardThresholdRpm = engineConfiguration->launchRpm
|
|
|
|
+ (engineConfiguration->enableLaunchRetard ? engineConfiguration->launchAdvanceRpmRange : 0)
|
|
|
|
+ engineConfiguration->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();
|
2021-11-15 17:09:03 -08:00
|
|
|
isLaunchCondition = false;
|
2020-11-19 05:15:56 -08:00
|
|
|
} else {
|
|
|
|
// If conditions are met...
|
2021-11-17 00:54:21 -08:00
|
|
|
isLaunchCondition = m_launchTimer.hasElapsedSec(engineConfiguration->launchActivateDelay);
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
2020-11-19 05:15:56 -08:00
|
|
|
}
|
|
|
|
|
2021-11-15 16:48:55 -08:00
|
|
|
bool LaunchControlBase::isLaunchRpmRetardCondition() const {
|
2022-01-20 20:43:18 -08:00
|
|
|
return isLaunchCondition && (retardThresholdRpm < Sensor::getOrZero(SensorType::Rpm));
|
2021-11-15 16:48:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool LaunchControlBase::isLaunchSparkRpmRetardCondition() const {
|
|
|
|
return isLaunchRpmRetardCondition() && engineConfiguration->launchSparkCutEnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LaunchControlBase::isLaunchFuelRpmRetardCondition() const {
|
|
|
|
return isLaunchRpmRetardCondition() && engineConfiguration->launchFuelCutEnable;
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
|
2021-11-16 10:15:12 -08:00
|
|
|
void SoftSparkLimiter::setTargetSkipRatio(float targetSkipRatio) {
|
|
|
|
this->targetSkipRatio = targetSkipRatio;
|
|
|
|
}
|
|
|
|
|
2021-11-25 19:40:19 -08:00
|
|
|
static tinymt32_t tinymt;
|
|
|
|
|
2021-11-16 10:15:12 -08:00
|
|
|
bool SoftSparkLimiter::shouldSkip() {
|
|
|
|
if (targetSkipRatio == 0 || wasJustSkipped) {
|
|
|
|
wasJustSkipped = false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-11-25 19:40:19 -08:00
|
|
|
float r = tinymt32_generate_float(&tinymt);
|
2021-11-16 10:15:12 -08:00
|
|
|
wasJustSkipped = r < 2 * targetSkipRatio;
|
|
|
|
return wasJustSkipped;
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void initLaunchControl() {
|
2021-11-25 19:40:19 -08:00
|
|
|
tinymt32_init(&tinymt, 1345135);
|
2020-03-23 20:20:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* EFI_LAUNCH_CONTROL */
|