rusefi/firmware/controllers/algo/engine.h

513 lines
11 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file engine.h
*
* @date May 21, 2014
2017-01-03 03:05:22 -08:00
* @author Andrey Belomutskiy, (c) 2012-2017
2015-07-10 06:01:56 -07:00
*/
2016-08-01 19:04:24 -07:00
#ifndef H_ENGINE_H_
#define H_ENGINE_H_
2015-07-10 06:01:56 -07:00
2016-02-06 09:02:24 -08:00
#include "global.h"
2015-07-10 06:01:56 -07:00
#include "main.h"
2016-02-06 09:02:24 -08:00
#include "pid.h"
2015-07-10 06:01:56 -07:00
#include "engine_configuration.h"
#include "rpm_calculator.h"
#include "engine_configuration.h"
#include "event_registry.h"
#include "trigger_structure.h"
#include "table_helper.h"
#include "listener_array.h"
#include "accel_enrichment.h"
2015-09-13 14:02:44 -07:00
#include "trigger_central.h"
2015-07-10 06:01:56 -07:00
2016-01-23 15:01:40 -08:00
#define MOCK_ADC_SIZE 16
class MockAdcState {
public:
MockAdcState();
bool hasMockAdc[MOCK_ADC_SIZE];
int fakeAdcValues[MOCK_ADC_SIZE];
void setMockVoltage(int hwChannel, float voltage);
int getMockAdcValue(int hwChannel);
};
2016-11-30 19:06:43 -08:00
#define MAX_INJECTION_OUTPUT_COUNT INJECTION_PIN_COUNT
2015-07-10 06:01:56 -07:00
/**
* This class knows about when to inject fuel
*/
class FuelSchedule {
public:
FuelSchedule();
/**
* this method schedules all fuel events for an engine cycle
*/
2017-05-15 20:33:22 -07:00
void addFuelEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE);
bool addFuelEventsForCylinder(int i DECLARE_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
2016-11-30 19:06:43 -08:00
InjectionEvent elements[MAX_INJECTION_OUTPUT_COUNT];
bool isReady;
2016-01-24 23:03:01 -08:00
2015-07-10 06:01:56 -07:00
private:
void clear();
};
class ThermistorMath {
public:
ThermistorMath();
2016-12-21 15:01:56 -08:00
void setConfig(thermistor_conf_s *config);
2016-12-22 11:02:38 -08:00
void prepareThermistorCurve(thermistor_conf_s *tc);
2016-12-23 11:01:45 -08:00
bool isLinearSensor();
2016-12-27 08:01:26 -08:00
float getKelvinTemperatureByResistance(float resistance);
2016-12-22 11:02:38 -08:00
float s_h_a;
float s_h_b;
float s_h_c;
2015-07-10 06:01:56 -07:00
private:
thermistor_conf_s currentConfig;
};
2017-08-17 06:10:22 -07:00
class Accelerometer {
public:
Accelerometer();
float x; // G value
float y;
float z;
};
class SensorsState {
2015-07-10 06:01:56 -07:00
public:
SensorsState();
2015-07-10 06:01:56 -07:00
/**
2016-02-06 09:02:24 -08:00
* Performance optimization:
* log() function needed for thermistor logic is relatively heavy, to avoid it we have these
* pre-calculated values
2015-07-10 06:01:56 -07:00
* Access to these two fields is not synchronized in any way - that should work since float read/write are atomic.
2016-02-06 09:02:24 -08:00
*
* values are in Celsius
2015-07-10 06:01:56 -07:00
*/
float iat;
float clt;
/**
* Oil pressure in kPa
*/
float oilPressure;
2017-08-17 06:10:22 -07:00
Accelerometer accelerometer;
2017-03-06 23:01:17 -08:00
float vBatt;
float currentAfr;
/**
* that's fuel in tank - just a gauge
*/
percent_t fuelTankGauge;
void reset();
};
2017-05-24 04:35:44 -07:00
class FuelConsumptionState {
public:
FuelConsumptionState();
void addData(float durationMs);
2017-12-31 17:13:04 -08:00
void update(efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
2017-05-24 04:35:44 -07:00
float perSecondConsumption;
float perMinuteConsumption;
float perSecondAccumulator;
float perMinuteAccumulator;
2017-12-31 16:25:59 -08:00
efitick_t accumulatedSecondPrevNt;
efitick_t accumulatedMinutePrevNt;
2017-05-24 04:35:44 -07:00
};
2017-08-03 19:30:47 -07:00
class TransmissionState {
public:
TransmissionState();
gear_e gearSelectorPosition;
};
2017-05-24 04:35:44 -07:00
class EngineState {
public:
EngineState();
2017-05-15 20:33:22 -07:00
void periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2017-05-24 04:35:44 -07:00
FuelConsumptionState fuelConsumption;
2017-03-06 23:01:17 -08:00
2016-12-06 20:03:39 -08:00
efitick_t crankingTime;
efitick_t timeSinceCranking;
2016-07-13 16:03:06 -07:00
int warningCounter;
2016-07-13 19:02:35 -07:00
int lastErrorCode;
2016-07-14 20:02:55 -07:00
efitimesec_t timeOfPreviousWarning;
2016-07-13 16:03:06 -07:00
2017-01-05 18:12:06 -08:00
/**
* speed-density logic, calculated air mass in gramms
*/
2015-12-02 17:10:06 -08:00
float airMass;
2016-01-01 14:02:49 -08:00
float engineNoiseHipLevel;
2017-11-26 19:30:37 -08:00
float auxValveStart;
float auxValveEnd;
2015-07-10 06:01:56 -07:00
ThermistorMath iatCurve;
ThermistorMath cltCurve;
2015-09-06 18:02:46 -07:00
/**
* MAP averaging angle start, in relation to 'mapAveragingSchedulingAtIndex' trigger index index
*/
angle_t mapAveragingStart[INJECTION_PIN_COUNT];
2015-07-10 06:01:56 -07:00
angle_t mapAveragingDuration;
// spark-related
floatms_t sparkDwell;
angle_t timingAdvance;
/**
* ignition dwell duration as crankshaft angle
*/
angle_t dwellAngle;
2017-01-05 18:12:06 -08:00
angle_t cltTimingCorrection;
2015-07-10 06:01:56 -07:00
// fuel-related;
float iatFuelCorrection;
float cltFuelCorrection;
2016-12-06 20:03:39 -08:00
float postCrankingFuelCorrection;
2016-02-06 09:02:24 -08:00
/**
2018-01-17 16:18:48 -08:00
* injectorLag(VBatt)
2016-02-06 09:02:24 -08:00
*
* this value depends on a slow-changing VBatt value, so
* we update it once in a while
*/
floatms_t injectorLag;
2016-02-06 13:02:41 -08:00
/**
* See useWarmupPidAfr
*/
2016-02-06 09:02:24 -08:00
Pid warmupAfrPid;
2016-02-10 14:01:44 -08:00
float warmupTargetAfr;
2015-07-10 06:01:56 -07:00
float baroCorrection;
// speed density
float tChargeK;
float currentVE;
2016-06-09 08:02:31 -07:00
float targetAFR;
2015-07-10 06:01:56 -07:00
2017-05-21 20:17:08 -07:00
int vssEventCounter;
2017-02-09 19:02:07 -08:00
int totalLoggedBytes;
2017-02-09 09:03:46 -08:00
2015-12-02 17:10:06 -08:00
/**
* pre-calculated value from simple fuel lookup
*/
2016-01-02 22:01:37 -08:00
floatms_t baseTableFuel;
2015-12-02 17:10:06 -08:00
/**
2017-01-19 12:03:17 -08:00
* Raw fuel injection duration produced by current fuel algorithm, without any correction
2015-12-02 17:10:06 -08:00
*/
2016-01-02 22:01:37 -08:00
floatms_t baseFuel;
2015-07-10 06:01:56 -07:00
2017-01-22 14:03:31 -08:00
/**
* closed-loop fuel correction
*/
floatms_t fuelPidCorrection;
2015-12-26 09:03:13 -08:00
/**
2016-05-23 18:01:32 -07:00
* Total fuel with CLT, IAT and TPS acceleration corrections per cycle,
* as squirt duration.
* Without injector lag.
2016-09-09 21:02:11 -07:00
* @see baseFuel
2016-05-23 18:01:32 -07:00
* @see actualLastInjection
2015-12-26 09:03:13 -08:00
*/
2016-01-02 22:01:37 -08:00
floatms_t runningFuel;
2015-12-26 09:03:13 -08:00
2016-01-30 19:03:36 -08:00
/**
* TPS acceleration: extra fuel amount
*/
2016-01-02 22:01:37 -08:00
floatms_t tpsAccelEnrich;
2015-12-26 09:03:13 -08:00
2015-07-10 06:01:56 -07:00
angle_t injectionOffset;
2016-01-23 15:01:40 -08:00
2016-01-26 17:02:45 -08:00
#if EFI_ENABLE_MOCK_ADC || defined(__DOXYGEN__)
2016-01-23 15:01:40 -08:00
MockAdcState mockAdcState;
2016-01-26 17:02:45 -08:00
#endif /* EFI_ENABLE_MOCK_ADC */
2015-07-10 06:01:56 -07:00
};
class RpmCalculator;
#define MAF_DECODING_CACHE_SIZE 256
#define MAF_DECODING_CACHE_MULT (MAF_DECODING_CACHE_SIZE / 5.0)
typedef struct {
uint32_t beforeMainTrigger;
uint32_t mainTriggerCallbackTime;
uint32_t beforeIgnitionSch;
uint32_t ignitionSchTime;
uint32_t beforeInjectonSch;
uint32_t injectonSchTime;
uint32_t beforeZeroTest;
uint32_t zeroTestTime;
uint32_t beforeAdvance;
uint32_t advanceLookupTime;
uint32_t beforeFuelCalc;
uint32_t fuelCalcTime;
uint32_t beforeMapAveragingCb;
uint32_t mapAveragingCbTime;
uint32_t beforeHipCb;
uint32_t hipCbTime;
uint32_t beforeRpmCb;
uint32_t rpmCbTime;
} monitoring_timestamps_s;
class Engine;
2016-02-06 07:01:34 -08:00
class WallFuel;
2015-07-10 06:01:56 -07:00
typedef void (*configuration_callback_t)(Engine*);
class Engine {
public:
Engine(persistent_config_s *config);
2016-12-18 07:02:38 -08:00
Engine();
void setConfig(persistent_config_s *config);
void reset();
2017-05-15 20:33:22 -07:00
injection_mode_e getCurrentInjectionMode(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2016-12-18 07:02:38 -08:00
2017-05-24 04:57:58 -07:00
InjectionSignalPair fuelActuators[INJECTION_PIN_COUNT];
2016-12-18 07:02:38 -08:00
IgnitionEventList ignitionEvents;
2016-01-25 09:01:30 -08:00
2016-12-18 09:03:48 -08:00
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
FuelSchedule injectionEvents;
#endif /* EFI_ENGINE_CONTROL */
2016-02-06 07:01:34 -08:00
2017-06-25 23:14:31 -07:00
float fsioLastValue[FSIO_COMMAND_COUNT];
2016-12-18 09:03:48 -08:00
WallFuel wallFuel;
2016-08-05 22:04:28 -07:00
2017-09-17 19:05:03 -07:00
bool etbAutoTune;
2016-01-26 20:01:44 -08:00
/**
* That's the list of pending spark firing events
*/
IgnitionEvent *iHead;
2016-01-30 19:03:36 -08:00
/**
* this is based on isEngineChartEnabled and engineSnifferRpmThreshold settings
*/
bool isEngineChartEnabled;
/**
* this is based on sensorChartMode and sensorSnifferRpmThreshold settings
*/
sensor_chart_e sensorChartMode;
2016-01-31 16:01:34 -08:00
/**
* based on current RPM and isAlternatorControlEnabled setting
*/
bool isAlternatorControlEnabled;
2016-01-26 20:01:44 -08:00
2017-05-11 05:32:08 -07:00
bool isCltBroken;
2017-05-01 19:33:20 -07:00
// floatms_t callToPitEndTime;
/**
2017-05-04 14:03:23 -07:00
* remote telemetry: if not zero, time to stop flashing 'CALL FROM PIT STOP' light
2017-05-01 19:33:20 -07:00
*/
2017-07-26 17:27:08 -07:00
efitime_t callFromPitStopEndTime;
// timestamp of most recent time RPM hard limit was triggered
efitime_t rpmHardLimitTimestamp;
2017-05-01 19:33:20 -07:00
2017-02-24 16:20:33 -08:00
/**
* This flag indicated a big enough problem that engine control would be
* prohibited if this flag is set to true.
*/
bool withError;
2015-07-10 06:01:56 -07:00
RpmCalculator rpmCalculator;
persistent_config_s *config;
engine_configuration_s *engineConfiguration;
/**
* this is about 'stopengine' command
*/
efitick_t stopEngineRequestTimeNt;
2016-01-30 19:03:36 -08:00
/**
* always 360 or 720, never zero
*/
2016-01-14 21:01:42 -08:00
angle_t engineCycle;
2015-12-31 10:02:19 -08:00
AccelEnrichmemnt engineLoadAccelEnrichment;
2015-07-10 06:01:56 -07:00
AccelEnrichmemnt tpsAccelEnrichment;
2015-09-13 14:02:44 -07:00
TriggerCentral triggerCentral;
2015-07-10 06:01:56 -07:00
/**
2016-10-12 22:02:02 -07:00
* Each individual fuel injection duration for current engine cycle, without wall wetting
* including everything including injector lag, both cranking and running
2017-11-06 19:29:39 -08:00
* @see getInjectionDuration()
2015-07-10 06:01:56 -07:00
*/
2017-11-06 19:29:39 -08:00
floatms_t injectionDuration;
2016-01-02 22:01:37 -08:00
/**
* fuel injection time correction to account for wall wetting effect, for current cycle
*/
2015-09-02 18:03:43 -07:00
floatms_t wallFuelCorrection;
2015-07-10 06:01:56 -07:00
2015-08-23 20:02:37 -07:00
/**
* This one with wall wetting accounted for, used for logging.
*/
floatms_t actualLastInjection;
2017-05-15 20:33:22 -07:00
void periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
2016-01-11 14:01:33 -08:00
bool clutchUpState;
bool clutchDownState;
2017-05-15 02:08:17 -07:00
bool brakePedalState;
2015-07-10 06:01:56 -07:00
2016-01-11 14:01:33 -08:00
bool isRunningPwmTest;
2015-07-10 06:01:56 -07:00
2017-07-25 17:37:46 -07:00
float fsioTimingAdjustment;
2015-07-10 06:01:56 -07:00
/**
* Are we experiencing knock right now?
*/
2016-01-11 14:01:33 -08:00
bool knockNow;
2015-07-10 06:01:56 -07:00
/**
* Have we experienced knock since engine was started?
*/
2016-01-11 14:01:33 -08:00
bool knockEver;
2015-07-10 06:01:56 -07:00
/**
* KnockCount is directly proportional to the degrees of ignition
* advance removed
*/
int knockCount;
2015-07-11 13:01:31 -07:00
float knockVolts;
2016-01-11 14:01:33 -08:00
bool knockDebug;
2015-07-10 06:01:56 -07:00
efitimeus_t timeOfLastKnockEvent;
/**
* are we running any kind of functional test? this affect
* some areas
*/
2016-01-11 14:01:33 -08:00
bool isTestMode;
2015-07-10 06:01:56 -07:00
/**
* pre-calculated offset for given sequence index within engine cycle
* (not cylinder ID)
* todo: better name?
*/
angle_t angleExtra[IGNITION_PIN_COUNT];
/**
* pre-calculated reference to which output pin should be used for
* given sequence index within engine cycle
2016-01-16 14:02:38 -08:00
* todo: update documentation
2015-07-10 06:01:56 -07:00
*/
2016-01-16 14:02:38 -08:00
int ignitionPin[IGNITION_PIN_COUNT];
2015-07-10 06:01:56 -07:00
2017-11-20 12:01:48 -08:00
/**
* this is invoked each time we register a trigger tooth signal
*/
void onTriggerSignalEvent(efitick_t nowNt);
2015-07-10 06:01:56 -07:00
EngineState engineState;
SensorsState sensors;
2017-11-20 12:01:48 -08:00
efitick_t lastTriggerToothEventTimeNt;
2015-07-10 06:01:56 -07:00
/**
* This coefficient translates ADC value directly into voltage adjusted according to
* voltage divider configuration. This is a future (?) performance optimization.
*/
float adcToVoltageInputDividerCoefficient;
/**
* This field is true if we are in 'cylinder cleanup' state right now
* see isCylinderCleanupEnabled
*/
2016-01-11 14:01:33 -08:00
bool isCylinderCleanupMode;
2015-07-10 06:01:56 -07:00
/**
* value of 'triggerShape.getLength()'
* pre-calculating this value is a performance optimization
*/
2017-05-15 19:02:36 -07:00
uint32_t engineCycleEventCount;
2015-07-10 06:01:56 -07:00
/**
* fast spark dwell time interpolation helper
* todo: finish the implementation and
*/
Table2D<DWELL_CURVE_SIZE> sparkTable;
/**
* fast kg/hour MAF decoding lookup table with ~0.2 volt step
* This table is build based on MAF decoding curve
*/
float mafDecodingLookup[MAF_DECODING_CACHE_SIZE];
void preCalculate();
void watchdog();
/**
* Needed by EFI_MAIN_RELAY_CONTROL to shut down the engine correctly.
*/
void checkShutdown();
/**
* Allows to finish some long-term shutdown procedures (stepper motor parking etc.)
Returns true if some operations are in progress on background.
*/
bool isInShutdownMode();
2015-07-10 06:01:56 -07:00
monitoring_timestamps_s m;
void knockLogic(float knockVolts);
void printKnockState(void);
private:
/**
* By the way:
* 'cranking' means engine is not stopped and the rpm are below crankingRpm
* 'running' means RPM are above crankingRpm
* 'spinning' means the engine is not stopped
*/
2016-01-11 14:01:33 -08:00
bool isSpinning;
2015-07-10 06:01:56 -07:00
};
/**
* 6 crossing over 50% TPS means pressing and releasing three times
*/
#define PUMPS_TO_PRIME 6
class StartupFuelPumping {
public:
StartupFuelPumping();
2017-05-15 20:33:22 -07:00
void update(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
bool isTpsAbove50;
int pumpsCounter;
private:
2017-05-15 18:25:32 -07:00
void setPumpsCounter(int newValue);
2015-07-10 06:01:56 -07:00
};
2017-05-15 20:33:22 -07:00
void prepareShapes(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void resetConfigurationExt(Logging * logger, engine_type_e engineType DECLARE_ENGINE_PARAMETER_SUFFIX);
void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_SUFFIX);
void prepareOutputSignals(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void assertEngineReference(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2017-08-31 04:53:41 -07:00
void validateConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
2016-08-01 19:04:24 -07:00
#endif /* H_ENGINE_H_ */