Merge branch 'master' of https://github.com/rusefi/rusefi into master
This commit is contained in:
commit
ea533fed1d
|
@ -269,7 +269,7 @@ expected<percent_t> EtbController::getSetpoint() {
|
|||
expected<percent_t> EtbController::getSetpointIdleValve() const {
|
||||
// VW ETB idle mode uses an ETB only for idle (a mini-ETB sets the lower stop, and a normal cable
|
||||
// can pull the throttle up off the stop.), so we directly control the throttle with the idle position.
|
||||
#if EFI_TUNER_STUDIO
|
||||
#if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR)
|
||||
engine->outputChannels.etbTarget = m_idlePosition;
|
||||
#endif // EFI_TUNER_STUDIO
|
||||
return clampF(0, m_idlePosition, 100);
|
||||
|
@ -637,20 +637,41 @@ void EtbController::update() {
|
|||
m_pid.iTermMin = engineConfiguration->etb_iTermMin;
|
||||
m_pid.iTermMax = engineConfiguration->etb_iTermMax;
|
||||
|
||||
ClosedLoopController::update();
|
||||
auto output = ClosedLoopController::update();
|
||||
|
||||
if (!output) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkOutput(output.Value);
|
||||
}
|
||||
|
||||
expected<percent_t> EtbController::getOutput() {
|
||||
// total open + closed loop parts
|
||||
expected<percent_t> output = ClosedLoopController::getOutput();
|
||||
if (!output) {
|
||||
return output;
|
||||
}
|
||||
etbDutyAverage = m_dutyAverage.average(absF(output.Value));
|
||||
void EtbController::checkOutput(percent_t output) {
|
||||
etbDutyAverage = m_dutyAverage.average(absF(output));
|
||||
|
||||
etbDutyRateOfChange = m_dutyRocAverage.average(absF(output.Value - prevOutput));
|
||||
prevOutput = output.Value;
|
||||
return output;
|
||||
etbDutyRateOfChange = m_dutyRocAverage.average(absF(output - prevOutput));
|
||||
prevOutput = output;
|
||||
|
||||
float integrator = absF(m_pid.getIntegration());
|
||||
auto integratorLimit = engineConfiguration->etbJamIntegratorLimit;
|
||||
|
||||
if (integratorLimit != 0) {
|
||||
auto nowNt = getTimeNowNt();
|
||||
|
||||
if (integrator > integratorLimit) {
|
||||
if (m_jamDetectTimer.hasElapsedSec(engineConfiguration->etbJamTimeout)) {
|
||||
// ETB is jammed!
|
||||
jamDetected = true;
|
||||
|
||||
// TODO: do something about it!
|
||||
}
|
||||
} else {
|
||||
m_jamDetectTimer.reset(getTimeNowNt());
|
||||
jamDetected = false;
|
||||
}
|
||||
|
||||
jamTimer = m_jamDetectTimer.getElapsedSeconds(nowNt);
|
||||
}
|
||||
}
|
||||
|
||||
void EtbController::autoCalibrateTps() {
|
||||
|
|
|
@ -53,10 +53,9 @@ public:
|
|||
virtual void setIdlePosition(percent_t pos) = 0;
|
||||
virtual void setWastegatePosition(percent_t pos) = 0;
|
||||
virtual void update() = 0;
|
||||
virtual expected<percent_t> getOutput() = 0;
|
||||
virtual void autoCalibrateTps() = 0;
|
||||
|
||||
virtual const pid_state_s* getPidState() const = 0;
|
||||
virtual const pid_state_s& getPidState() const = 0;
|
||||
|
||||
virtual void setLuaAdjustment(percent_t adjustment) = 0;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,8 @@ float luaAdjustment;"ETB: luaAdjustment"
|
|||
float etbCurrentAdjustedTarget;;"%", 1, 0, -10000, 10000, 3
|
||||
|
||||
bit etbRevLimitActive
|
||||
bit jamDetected
|
||||
|
||||
float etbDutyRateOfChange
|
||||
float etbDutyAverage
|
||||
uint16_t etbTpsErrorCounter;"ETB TPS error counter"
|
||||
|
@ -19,4 +21,6 @@ float luaAdjustment;"ETB: luaAdjustment"
|
|||
|
||||
int8_t etbErrorCode
|
||||
|
||||
uint16_t autoscale jamTimer;ETB jam timer;"sec", 0.01, 0, 0, 100, 2
|
||||
|
||||
end_struct
|
|
@ -34,7 +34,6 @@ public:
|
|||
|
||||
// Update the controller's state: read sensors, send output, etc
|
||||
void update() override;
|
||||
expected<percent_t> getOutput() override;
|
||||
|
||||
// Called when the configuration may have changed. Controller will
|
||||
// reset if necessary.
|
||||
|
@ -57,8 +56,10 @@ public:
|
|||
|
||||
void setOutput(expected<percent_t> outputValue) override;
|
||||
|
||||
void checkOutput(percent_t output);
|
||||
|
||||
// Used to inspect the internal PID controller's state
|
||||
const pid_state_s* getPidState() const override { return &m_pid; };
|
||||
const pid_state_s& getPidState() const override { return m_pid; };
|
||||
|
||||
// Use the throttle to automatically calibrate the relevant throttle position sensor(s).
|
||||
void autoCalibrateTps() override;
|
||||
|
@ -96,6 +97,8 @@ private:
|
|||
ExpAverage m_dutyRocAverage;
|
||||
ExpAverage m_dutyAverage;
|
||||
|
||||
Timer m_jamDetectTimer;
|
||||
|
||||
// Pedal -> target map
|
||||
const ValueProvider3D* m_pedalMap = nullptr;
|
||||
|
||||
|
|
|
@ -2147,6 +2147,12 @@ typedef enum {
|
|||
CUSTOM_CAM_TOO_MANY_TEETH = 9004,
|
||||
CUSTOM_CAM_NOT_ENOUGH_TEETH = 9005,
|
||||
|
||||
// Where we expected one trigger edge, we got two in quick succession
|
||||
CUSTOM_PRIMARY_DOUBLED_EDGE = 9006,
|
||||
|
||||
// A trigger tooth arrived at an unexpected time
|
||||
CUSTOM_PRIMARY_BAD_TOOTH_TIMING = 9007,
|
||||
|
||||
/**
|
||||
* This is not engine miss detection - this is only internal scheduler state validation
|
||||
* Should not happen
|
||||
|
|
|
@ -9,12 +9,15 @@
|
|||
template <typename TInput, typename TOutput>
|
||||
class ClosedLoopController {
|
||||
public:
|
||||
void update() {
|
||||
expected<TOutput> update() {
|
||||
expected<TOutput> outputValue = getOutput();
|
||||
setOutput(outputValue);
|
||||
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
virtual expected<TOutput> getOutput() {
|
||||
private:
|
||||
expected<TOutput> getOutput() {
|
||||
expected<TInput> setpoint = getSetpoint();
|
||||
// If we don't know the setpoint, return failure.
|
||||
if (!setpoint) {
|
||||
|
@ -41,7 +44,6 @@ public:
|
|||
|
||||
return openLoopResult.Value + closedLoopResult.Value;
|
||||
}
|
||||
private:
|
||||
|
||||
// Get the setpoint: where should the controller put the plant?
|
||||
virtual expected<TInput> getSetpoint() = 0;
|
||||
|
|
|
@ -139,10 +139,6 @@ bool warning(obd_code_e code, const char *fmt, ...) {
|
|||
if (hasFirmwareErrorFlag)
|
||||
return true;
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
printf("sim_warning %s\r\n", fmt);
|
||||
#endif /* EFI_SIMULATOR */
|
||||
|
||||
#if EFI_SIMULATOR || EFI_PROD_CODE
|
||||
// we just had this same warning, let's not spam
|
||||
if (engine->engineState.warnings.isWarningNow(code) || !warningEnabled) {
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_63942
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.48way.snap_63942"
|
||||
#define SIGNATURE_HASH snap_22196
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.48way.snap_22196"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_61833
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.all.snap_61833"
|
||||
#define SIGNATURE_HASH snap_24315
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.all.snap_24315"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_27877
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-2chan.snap_27877"
|
||||
#define SIGNATURE_HASH snap_50071
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-2chan.snap_50071"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_57504
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-4chan.snap_57504"
|
||||
#define SIGNATURE_HASH snap_20434
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-4chan.snap_20434"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_28165
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-8chan.snap_28165"
|
||||
#define SIGNATURE_HASH snap_49527
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.alphax-8chan.snap_49527"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_1198
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.atlas.snap_1198"
|
||||
#define SIGNATURE_HASH snap_43996
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.atlas.snap_43996"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_41072
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.core8.snap_41072"
|
||||
#define SIGNATURE_HASH snap_3842
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.core8.snap_3842"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on hellen_cypress_gen_config.bat by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_61833
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.cypress.snap_61833"
|
||||
#define SIGNATURE_HASH snap_24315
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.cypress.snap_24315"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_61833
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.f407-discovery.snap_61833"
|
||||
#define SIGNATURE_HASH snap_24315
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.f407-discovery.snap_24315"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_61833
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.f429-discovery.snap_61833"
|
||||
#define SIGNATURE_HASH snap_24315
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.f429-discovery.snap_24315"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_3405
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.frankenso_na6.snap_3405"
|
||||
#define SIGNATURE_HASH snap_41535
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.frankenso_na6.snap_41535"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_46966
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.harley81.snap_46966"
|
||||
#define SIGNATURE_HASH snap_6148
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.harley81.snap_6148"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_37517
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen-gm-e67.snap_37517"
|
||||
#define SIGNATURE_HASH snap_15871
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen-gm-e67.snap_15871"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_49221
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen-nb1.snap_49221"
|
||||
#define SIGNATURE_HASH snap_28471
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen-nb1.snap_28471"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_3099
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen121nissan.snap_3099"
|
||||
#define SIGNATURE_HASH snap_41833
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen121nissan.snap_41833"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_26260
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen121vag.snap_26260"
|
||||
#define SIGNATURE_HASH snap_51686
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen121vag.snap_51686"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_36018
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen128.snap_36018"
|
||||
#define SIGNATURE_HASH snap_9152
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen128.snap_9152"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_52074
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen154hyundai.snap_52074"
|
||||
#define SIGNATURE_HASH snap_25624
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen154hyundai.snap_25624"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_65282
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen72.snap_65282"
|
||||
#define SIGNATURE_HASH snap_20592
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen72.snap_20592"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_28660
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen81.snap_28660"
|
||||
#define SIGNATURE_HASH snap_49286
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen81.snap_49286"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_57925
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen88bmw.snap_57925"
|
||||
#define SIGNATURE_HASH snap_19767
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellen88bmw.snap_19767"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_16574
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellenNA6.snap_16574"
|
||||
#define SIGNATURE_HASH snap_61388
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellenNA6.snap_61388"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_16481
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellenNA8_96.snap_16481"
|
||||
#define SIGNATURE_HASH snap_61203
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.hellenNA8_96.snap_61203"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on kinetis_gen_config.bat by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_21317
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.kin.snap_21317"
|
||||
#define SIGNATURE_HASH snap_64567
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.kin.snap_64567"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_11442
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.m74_9.snap_11442"
|
||||
#define SIGNATURE_HASH snap_33728
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.m74_9.snap_33728"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_38537
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.mre_f4.snap_38537"
|
||||
#define SIGNATURE_HASH snap_14843
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.mre_f4.snap_14843"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_38537
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.mre_f7.snap_38537"
|
||||
#define SIGNATURE_HASH snap_14843
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.mre_f7.snap_14843"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_10351
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.prometheus_405.snap_10351"
|
||||
#define SIGNATURE_HASH snap_34589
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.prometheus_405.snap_34589"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_10351
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.prometheus_469.snap_10351"
|
||||
#define SIGNATURE_HASH snap_34589
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.prometheus_469.snap_34589"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_14905
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_f4.snap_14905"
|
||||
#define SIGNATURE_HASH snap_38219
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_f4.snap_38219"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_14905
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_f7.snap_14905"
|
||||
#define SIGNATURE_HASH snap_38219
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_f7.snap_38219"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_14905
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_h7.snap_14905"
|
||||
#define SIGNATURE_HASH snap_38219
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.proteus_h7.snap_38219"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_50164
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.s105.snap_50164"
|
||||
#define SIGNATURE_HASH snap_27782
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.s105.snap_27782"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on config/boards/subaru_eg33/config/gen_subaru_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_10323
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.subaru_eg33_f7.snap_10323"
|
||||
#define SIGNATURE_HASH snap_34593
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.subaru_eg33_f7.snap_34593"
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
// was generated automatically by rusEFI tool ConfigDefinition.jar based on gen_config.sh by SignatureConsumer
|
||||
//
|
||||
|
||||
#define SIGNATURE_HASH snap_16349
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.tdg-pdm8.snap_16349"
|
||||
#define SIGNATURE_HASH snap_37039
|
||||
#define TS_SIGNATURE "rusEFI 2023.01.10.tdg-pdm8.snap_37039"
|
||||
|
|
|
@ -85,8 +85,8 @@ float getConfigValueByName(const char *name) {
|
|||
return engineConfiguration->verboseCan;
|
||||
case -1528619572:
|
||||
return engineConfiguration->artificialTestMisfire;
|
||||
case -1571463185:
|
||||
return engineConfiguration->issue_294_31;
|
||||
case -1284359115:
|
||||
return engineConfiguration->useFordRedundantPps;
|
||||
case 513872736:
|
||||
return engineConfiguration->tpsMin;
|
||||
case 513872482:
|
||||
|
@ -1041,6 +1041,10 @@ float getConfigValueByName(const char *name) {
|
|||
return engineConfiguration->ALSSkipRatio;
|
||||
case 612659807:
|
||||
return engineConfiguration->ALSMaxDriverThrottleIntent;
|
||||
case -1744146782:
|
||||
return engineConfiguration->tpsSecondaryMaximum;
|
||||
case -727657058:
|
||||
return engineConfiguration->ppsSecondaryMaximum;
|
||||
}
|
||||
return EFI_ERROR_CODE;
|
||||
}
|
||||
|
@ -1252,9 +1256,9 @@ void setConfigValueByName(const char *name, float value) {
|
|||
engineConfiguration->artificialTestMisfire = (int)value;
|
||||
return;
|
||||
}
|
||||
case -1571463185:
|
||||
case -1284359115:
|
||||
{
|
||||
engineConfiguration->issue_294_31 = (int)value;
|
||||
engineConfiguration->useFordRedundantPps = (int)value;
|
||||
return;
|
||||
}
|
||||
case 513872736:
|
||||
|
@ -3641,6 +3645,16 @@ void setConfigValueByName(const char *name, float value) {
|
|||
{
|
||||
engineConfiguration->ALSMaxDriverThrottleIntent = (int)value;
|
||||
return;
|
||||
}
|
||||
case -1744146782:
|
||||
{
|
||||
engineConfiguration->tpsSecondaryMaximum = (int)value;
|
||||
return;
|
||||
}
|
||||
case -727657058:
|
||||
{
|
||||
engineConfiguration->ppsSecondaryMaximum = (int)value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ This is your injector flow at the fuel pressure used in the vehicle. cc/min, cub
|
|||
Does the vehicle have a turbo or supercharger?
|
||||
|
||||
### useFordRedundantTps
|
||||
On Ford vehicles one of the sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
On some Ford and Toyota vehicles one of the throttle sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
|
||||
### isVerboseAuxPid1
|
||||
|
||||
|
@ -121,8 +121,8 @@ Print incoming and outgoing first bus CAN messages in rusEFI console
|
|||
### artificialTestMisfire
|
||||
Experimental setting that will cause a misfire\nDO NOT ENABLE.
|
||||
|
||||
### issue_294_31
|
||||
|
||||
### useFordRedundantPps
|
||||
On some Ford and Toyota vehicles one of the pedal sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
|
||||
### tpsMin
|
||||
Closed throttle, 1 volt = 200 units.\nSee also tps1_1AdcChannel\nset tps_min X
|
||||
|
@ -1555,3 +1555,9 @@ null
|
|||
### ALSMaxDriverThrottleIntent
|
||||
|
||||
|
||||
### tpsSecondaryMaximum
|
||||
For Ford TPS, use 53%. For Toyota ETCS-i, use 65%
|
||||
|
||||
### ppsSecondaryMaximum
|
||||
For Toyota ETCS-i, use xxx%
|
||||
|
||||
|
|
|
@ -639,6 +639,64 @@ void TriggerCentral::decodeMapCam(efitick_t timestamp, float currentPhase) {
|
|||
}
|
||||
}
|
||||
|
||||
bool TriggerCentral::isToothExpectedNow(efitick_t timestamp) {
|
||||
// Check that the expected next phase (from the last tooth) is close to the actual current phase:
|
||||
// basically, check that the tooth width is correct
|
||||
auto estimatedCurrentPhase = getCurrentEnginePhase(timestamp);
|
||||
auto lastToothPhase = m_lastToothPhaseFromSyncPoint;
|
||||
|
||||
if (expectedNextPhase && estimatedCurrentPhase) {
|
||||
float angleError = expectedNextPhase.Value - estimatedCurrentPhase.Value;
|
||||
|
||||
// Wrap around correctly at the end of the cycle
|
||||
float cycle = getEngineState()->engineCycle;
|
||||
if (angleError < -cycle / 2) {
|
||||
angleError += cycle;
|
||||
}
|
||||
|
||||
triggerToothAngleError = angleError;
|
||||
|
||||
// Only perform checks if engine is spinning quickly
|
||||
// All kinds of garbage happens while cranking
|
||||
if (Sensor::getOrZero(SensorType::Rpm) > 1000) {
|
||||
// Now compute how close we are to the last tooth decoded
|
||||
float angleSinceLastTooth = estimatedCurrentPhase.Value - lastToothPhase;
|
||||
if (angleSinceLastTooth < 0.5f) {
|
||||
// This tooth came impossibly early, ignore it
|
||||
// This rejects things like doubled edges, for example:
|
||||
// |-| |----------------
|
||||
// | | |
|
||||
// ____________| |_|
|
||||
// 1 2
|
||||
// #1 will be decoded
|
||||
// #2 will be ignored
|
||||
// We're not sure which edge was the "real" one, but they were close enough
|
||||
// together that it doesn't really matter.
|
||||
warning(CUSTOM_PRIMARY_DOUBLED_EDGE, "doubled trigger edge after %.2f deg at #%d", angleSinceLastTooth, triggerState.currentCycle.current_index);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Absolute error from last tooth
|
||||
float absError = absF(angleError);
|
||||
float isRpmEnough = Sensor::getOrZero(SensorType::Rpm) > 1000;
|
||||
// TODO: configurable threshold
|
||||
if (isRpmEnough && absError > 10 && absError < 180) {
|
||||
// This tooth came at a very unexpected time, ignore it
|
||||
warning(CUSTOM_PRIMARY_BAD_TOOTH_TIMING, "tooth #%d error of %.1f", triggerState.currentCycle.current_index, angleError);
|
||||
|
||||
// TODO: this causes issues with some real engine logs, should it?
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
triggerToothAngleError = 0;
|
||||
}
|
||||
|
||||
// We aren't ready to reject unexpected teeth, so accept this tooth
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is NOT invoked for VR falls.
|
||||
*/
|
||||
|
@ -661,6 +719,11 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
|||
}
|
||||
}
|
||||
|
||||
if (!isToothExpectedNow(timestamp)) {
|
||||
triggerIgnoredToothCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
isSpinningJustForWatchdog = true;
|
||||
|
||||
m_lastEventTimer.reset(timestamp);
|
||||
|
@ -697,20 +760,6 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
|||
// Adjust so currentPhase is in engine-space angle, not trigger-space angle
|
||||
currentEngineDecodedPhase = wrapAngleMethod(currentPhaseFromSyncPoint - tdcPosition(), "currentEnginePhase", CUSTOM_ERR_6555);
|
||||
|
||||
// Check that the expected next phase (from the last tooth) is close to the actual current phase:
|
||||
// basically, check that the tooth width is correct
|
||||
auto estimatedCurrentPhase = getCurrentEnginePhase(timestamp);
|
||||
if (estimatedCurrentPhase) {
|
||||
float angleError = expectedNextPhase - estimatedCurrentPhase.Value;
|
||||
|
||||
float cycle = getEngineState()->engineCycle;
|
||||
while (angleError < -cycle / 2) {
|
||||
angleError += cycle;
|
||||
}
|
||||
|
||||
triggerToothAngleError = angleError;
|
||||
}
|
||||
|
||||
// Record precise time and phase of the engine. This is used for VVT decode, and to check that the
|
||||
// trigger pattern selected matches reality (ie, we check the next tooth is where we think it should be)
|
||||
{
|
||||
|
@ -752,19 +801,20 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
|||
wrapAngle(nextPhase, "nextEnginePhase", CUSTOM_ERR_6555);
|
||||
} while (nextPhase == currentEngineDecodedPhase);
|
||||
|
||||
expectedNextPhase = nextPhase + tdcPosition();
|
||||
wrapAngle(expectedNextPhase, "nextEnginePhase", CUSTOM_ERR_6555);
|
||||
float expectNextPhase = nextPhase + tdcPosition();
|
||||
wrapAngle(expectNextPhase, "nextEnginePhase", CUSTOM_ERR_6555);
|
||||
expectedNextPhase = expectNextPhase;
|
||||
|
||||
#if EFI_CDM_INTEGRATION
|
||||
if (trgEventIndex == 0 && isBrainPinValid(engineConfiguration->cdmInputPin)) {
|
||||
int cdmKnockValue = getCurrentCdmValue(getTriggerCentral()->triggerState.getCrankSynchronizationCounter());
|
||||
engine->knockLogic(cdmKnockValue);
|
||||
}
|
||||
if (trgEventIndex == 0 && isBrainPinValid(engineConfiguration->cdmInputPin)) {
|
||||
int cdmKnockValue = getCurrentCdmValue(getTriggerCentral()->triggerState.getCrankSynchronizationCounter());
|
||||
engine->knockLogic(cdmKnockValue);
|
||||
}
|
||||
#endif /* EFI_CDM_INTEGRATION */
|
||||
|
||||
if (engine->rpmCalculator.getCachedRpm() > 0 && triggerIndexForListeners == 0) {
|
||||
engine->tpsAccelEnrichment.onEngineCycleTps();
|
||||
}
|
||||
if (engine->rpmCalculator.getCachedRpm() > 0 && triggerIndexForListeners == 0) {
|
||||
engine->tpsAccelEnrichment.onEngineCycleTps();
|
||||
}
|
||||
|
||||
// Handle ignition and injection
|
||||
mainTriggerCallback(triggerIndexForListeners, timestamp, currentEngineDecodedPhase, nextPhase);
|
||||
|
@ -774,6 +824,8 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
|||
} else {
|
||||
// We don't have sync, but report to the wave chart anyway as index 0.
|
||||
reportEventToWaveChart(signal, 0, triggerShape.useOnlyRisingEdges);
|
||||
|
||||
expectedNextPhase = unexpected;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,8 @@ public:
|
|||
private:
|
||||
void decodeMapCam(efitick_t nowNt, float currentPhase);
|
||||
|
||||
bool isToothExpectedNow(efitick_t timestamp);
|
||||
|
||||
// Time since the last tooth
|
||||
Timer m_lastToothTimer;
|
||||
// Phase of the last tooth relative to the sync point
|
||||
|
@ -206,7 +208,7 @@ private:
|
|||
|
||||
// At what engine phase do we expect the next tooth to arrive?
|
||||
// Used for checking whether your trigger pattern is correct.
|
||||
float expectedNextPhase;
|
||||
expected<float> expectedNextPhase = unexpected;
|
||||
};
|
||||
|
||||
void triggerInfo(void);
|
||||
|
|
|
@ -15,5 +15,7 @@ uint32_t vvtCamCounter
|
|||
|
||||
float triggerToothAngleError;;"deg", 1, 0, -30, 30, 2
|
||||
|
||||
uint8_t triggerIgnoredToothCount
|
||||
|
||||
end_struct
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
return m_sens.Register();
|
||||
}
|
||||
|
||||
void unsubscribe() {
|
||||
void deinit() {
|
||||
AdcSubscription::UnsubscribeSensor(m_sens);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void init(bool isFordTps, RedundantFordTps* fordTps, const TpsConfig& primary, const TpsConfig& secondary) {
|
||||
void init(bool isFordTps, RedundantFordTps* fordTps, float secondaryMaximum, const TpsConfig& primary, const TpsConfig& secondary) {
|
||||
bool hasFirst = m_pri.init(primary);
|
||||
if (!hasFirst) {
|
||||
// no input if we have no first channel
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
|
||||
if (isFordTps && fordTps) {
|
||||
// we have a secondary
|
||||
fordTps->configure(5.0f, 52.6f);
|
||||
fordTps->configure(MAX_TPS_PPS_DISCREPANCY, secondaryMaximum);
|
||||
fordTps->Register();
|
||||
} else {
|
||||
// not ford TPS
|
||||
|
@ -137,9 +137,16 @@ printf("init m_redund.Register() %s\n", getSensorType(m_redund.type()));
|
|||
}
|
||||
}
|
||||
|
||||
void unsubscribe() {
|
||||
m_pri.unsubscribe();
|
||||
m_sec.unsubscribe();
|
||||
void deinit(bool isFordTps, RedundantFordTps* fordTps) {
|
||||
m_pri.deinit();
|
||||
m_sec.deinit();
|
||||
|
||||
if (isFordTps && fordTps) {
|
||||
fordTps->unregister();
|
||||
} else {
|
||||
m_redund.unregister();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -161,6 +168,7 @@ static RedundantPair tps2(tps2p, tps2s, SensorType::Tps2);
|
|||
// Used only in case of weird Ford-style ETB TPS
|
||||
static RedundantFordTps fordTps1(SensorType::Tps1, SensorType::Tps1Primary, SensorType::Tps1Secondary);
|
||||
static RedundantFordTps fordTps2(SensorType::Tps2, SensorType::Tps2Primary, SensorType::Tps2Secondary);
|
||||
static RedundantFordTps fordPps(SensorType::AcceleratorPedal, SensorType::AcceleratorPedalPrimary, SensorType::AcceleratorPedalSecondary);
|
||||
|
||||
// Pedal sensors and redundancy
|
||||
static FuncSensPair pedalPrimary(1, SensorType::AcceleratorPedalPrimary);
|
||||
|
@ -181,19 +189,32 @@ void initTps() {
|
|||
|
||||
if (!engineConfiguration->consumeObdSensors) {
|
||||
bool isFordTps = engineConfiguration->useFordRedundantTps;
|
||||
bool isFordPps = engineConfiguration->useFordRedundantPps;
|
||||
|
||||
tps1.init(isFordTps, &fordTps1,
|
||||
float tpsSecondaryMaximum = engineConfiguration->tpsSecondaryMaximum;
|
||||
if (tpsSecondaryMaximum < 20) {
|
||||
// don't allow <20% split point
|
||||
tpsSecondaryMaximum = 20;
|
||||
}
|
||||
|
||||
tps1.init(isFordTps, &fordTps1, tpsSecondaryMaximum,
|
||||
{ engineConfiguration->tps1_1AdcChannel, (float)engineConfiguration->tpsMin, (float)engineConfiguration->tpsMax, min, max },
|
||||
{ engineConfiguration->tps1_2AdcChannel, (float)engineConfiguration->tps1SecondaryMin, (float)engineConfiguration->tps1SecondaryMax, min, max }
|
||||
);
|
||||
|
||||
tps2.init(isFordTps, &fordTps2,
|
||||
tps2.init(isFordTps, &fordTps2, tpsSecondaryMaximum,
|
||||
{ engineConfiguration->tps2_1AdcChannel, (float)engineConfiguration->tps2Min, (float)engineConfiguration->tps2Max, min, max },
|
||||
{ engineConfiguration->tps2_2AdcChannel, (float)engineConfiguration->tps2SecondaryMin, (float)engineConfiguration->tps2SecondaryMax, min, max }
|
||||
);
|
||||
|
||||
float ppsSecondaryMaximum = engineConfiguration->ppsSecondaryMaximum;
|
||||
if (ppsSecondaryMaximum < 20) {
|
||||
// don't allow <20% split point
|
||||
ppsSecondaryMaximum = 20;
|
||||
}
|
||||
|
||||
// Pedal sensors
|
||||
pedal.init(false, nullptr,
|
||||
pedal.init(isFordPps, &fordPps, ppsSecondaryMaximum,
|
||||
{ engineConfiguration->throttlePedalPositionAdcChannel, engineConfiguration->throttlePedalUpVoltage, engineConfiguration->throttlePedalWOTVoltage, min, max },
|
||||
{ engineConfiguration->throttlePedalPositionSecondAdcChannel, engineConfiguration->throttlePedalSecondaryUpVoltage, engineConfiguration->throttlePedalSecondaryWOTVoltage, min, max }
|
||||
);
|
||||
|
@ -214,10 +235,13 @@ void initTps() {
|
|||
}
|
||||
|
||||
void deinitTps() {
|
||||
tps1.unsubscribe();
|
||||
tps2.unsubscribe();
|
||||
pedal.unsubscribe();
|
||||
bool isFordTps = activeConfiguration.useFordRedundantTps;
|
||||
bool isFordPps = activeConfiguration.useFordRedundantPps;
|
||||
|
||||
wastegate.unsubscribe();
|
||||
idlePos.unsubscribe();
|
||||
tps1.deinit(isFordTps, &fordTps1);
|
||||
tps2.deinit(isFordTps, &fordTps2);
|
||||
pedal.deinit(isFordTps, &fordPps);
|
||||
|
||||
wastegate.deinit();
|
||||
idlePos.deinit();
|
||||
}
|
||||
|
|
|
@ -446,7 +446,7 @@ end_struct
|
|||
injector_s injector
|
||||
|
||||
bit isForcedInduction;Does the vehicle have a turbo or supercharger?
|
||||
bit useFordRedundantTps;On Ford vehicles one of the sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
bit useFordRedundantTps;On some Ford and Toyota vehicles one of the throttle sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
bit isVerboseAuxPid1
|
||||
bit overrideTriggerGaps
|
||||
bit enableFan1WithAc;Turn on this fan when AC is on.
|
||||
|
@ -475,7 +475,7 @@ bit enableMapEstimationTableFallback;If enabled, the MAP estimate table will be
|
|||
bit usescriptTableForCanSniffingFiltering
|
||||
bit verboseCan,"Print all","Do not print";Print incoming and outgoing first bus CAN messages in rusEFI console
|
||||
bit artificialTestMisfire,"Danger Mode","No thank you";Experimental setting that will cause a misfire\nDO NOT ENABLE.
|
||||
bit issue_294_31,"si_example","nada_example"
|
||||
bit useFordRedundantPps;On some Ford and Toyota vehicles one of the pedal sensors is not linear on the full range, i.e. in the specific range of the positions we effectively have only one sensor.
|
||||
|
||||
|
||||
!todo: extract these two fields into a structure
|
||||
|
@ -1560,7 +1560,8 @@ uint8_t alsEtbPosition;;"", 1, 0, 0, 20000, 0
|
|||
uint8_t ALSMaxDriverThrottleIntent;;"%", 1, 0, 0, 10, 0
|
||||
pin_input_mode_e ALSActivatePinMode;
|
||||
|
||||
uint8_t[2] unusedHereForYou
|
||||
uint8_t autoscale tpsSecondaryMaximum;For Ford TPS, use 53%. For Toyota ETCS-i, use 65%;"%", 0.5, 0, 0, 100, 1
|
||||
uint8_t autoscale ppsSecondaryMaximum;For Toyota ETCS-i, use xxx%;"%", 0.5, 0, 0, 100, 1
|
||||
pin_input_mode_e[LUA_DIGITAL_INPUT_COUNT iterate] luaDigitalInputPinModes;
|
||||
uint8_t[96] mainUnusedEnd;;"units", 1, 0, 0, 1, 0
|
||||
|
||||
|
|
|
@ -4294,6 +4294,10 @@ dialog = tcuControls, "Transmission Settings"
|
|||
field = "showHumanReadableWarning (affects Burn)", showHumanReadableWarning
|
||||
field = "Warning Message", warning_message
|
||||
field = "Ford redundant TPS mode", useFordRedundantTps
|
||||
field = "Secondary TPS maximum", tpsSecondaryMaximum, {useFordRedundantTps}
|
||||
field = "Ford redundant PPS mode", useFordRedundantPps
|
||||
field = "Secondary PPS maximum", ppsSecondaryMaximum, {useFordRedundantPps}
|
||||
|
||||
field = "consumeObdSensors", consumeObdSensors, { canReadEnabled == 1 && canWriteEnabled == 1}
|
||||
field = "Artificial Misfire", artificialTestMisfire
|
||||
field = "Always use instant RPM", alwaysInstantRpm
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
*.teeth
|
||||
*.csv
|
||||
log_convert
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
g++ -O2 -lstdc++ log_convert.cpp -o log_convert
|
|
@ -0,0 +1,46 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
// the whole order of all packet bytes is reversed, not just the 'endian-swap' integers
|
||||
uint32_t timestamp;
|
||||
// unfortunately all these fields are required by TS...
|
||||
bool priLevel : 1;
|
||||
bool secLevel : 1;
|
||||
bool trigger : 1;
|
||||
bool sync : 1;
|
||||
bool coil : 1;
|
||||
bool injector : 1;
|
||||
} composite_logger_s;
|
||||
|
||||
static_assert(sizeof(composite_logger_s) == 5);
|
||||
|
||||
static inline uint32_t SWAP_UINT32(uint32_t x)
|
||||
{
|
||||
return (((x >> 24) & 0x000000ff) | ((x << 8) & 0x00ff0000) |
|
||||
((x >> 8) & 0x0000ff00) | ((x << 24) & 0xff000000));
|
||||
}
|
||||
|
||||
static constexpr double ticksPerSecond = 1e6;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream src(argv[1], std::ios::binary);
|
||||
std::ofstream dst(argv[2], std::ios::binary);
|
||||
|
||||
dst << std::setprecision(10);
|
||||
|
||||
dst << "timestamp,pri,sec" << std::endl;
|
||||
|
||||
while (!src.eof())
|
||||
{
|
||||
composite_logger_s entry;
|
||||
|
||||
src.read(reinterpret_cast<char*>(&entry), sizeof(composite_logger_s));
|
||||
|
||||
double sec = SWAP_UINT32(entry.timestamp) / ticksPerSecond;
|
||||
|
||||
dst << sec << "," << entry.priLevel << "," << entry.secLevel << std::endl;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# SD Tooth Log Converter
|
||||
|
||||
This program converts SD stored tooth logs to csv for analysis or replay as part of a unit test.
|
||||
|
||||
Create a log by setting "SD logger mode" to "trigger", then restart the ECU with an SD card present (but without USB connected), then crank/run/etc the engine to save a log. Restart again with USB to pull the log off.
|
||||
|
||||
# Usage
|
||||
|
||||
`./build.sh`
|
||||
|
||||
`./log_convert myToothLog.teeth convertedCsv.csv`
|
|
@ -25,12 +25,11 @@ public:
|
|||
MOCK_METHOD(void, setIdlePosition, (percent_t pos), (override));
|
||||
MOCK_METHOD(void, setWastegatePosition, (percent_t pos), (override));
|
||||
MOCK_METHOD(void, autoCalibrateTps, (), (override));
|
||||
MOCK_METHOD(const pid_state_s*, getPidState, (), (const, override));
|
||||
MOCK_METHOD(const pid_state_s&, getPidState, (), (const, override));
|
||||
MOCK_METHOD(void, setLuaAdjustment, (percent_t adjustment), (override));
|
||||
|
||||
|
||||
// ClosedLoopController mocks
|
||||
MOCK_METHOD(expected<percent_t>, getOutput, (), (override));
|
||||
MOCK_METHOD(expected<percent_t>, getSetpoint, (), (override));
|
||||
MOCK_METHOD(expected<percent_t>, observePlant, (), (const, override));
|
||||
MOCK_METHOD(expected<percent_t>, getOpenLoop, (percent_t setpoint), (override));
|
||||
|
|
|
@ -198,7 +198,6 @@ TEST(etb, initializationNoPrimarySensor) {
|
|||
Sensor::resetAllMocks();
|
||||
|
||||
EtbController dut;
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
|
||||
// Needs pedal for init
|
||||
Sensor::setMockValue(SensorType::AcceleratorPedal, 0.0f, true);
|
||||
|
@ -470,7 +469,6 @@ TEST(etb, setpointNoPedalMap) {
|
|||
}
|
||||
|
||||
TEST(etb, setpointIdleValveController) {
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
EtbController etb;
|
||||
|
||||
etb.init(ETB_IdleValve, nullptr, nullptr, nullptr, false);
|
||||
|
@ -490,7 +488,6 @@ TEST(etb, setpointIdleValveController) {
|
|||
}
|
||||
|
||||
TEST(etb, setpointWastegateController) {
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
EtbController etb;
|
||||
|
||||
etb.init(ETB_Wastegate, nullptr, nullptr, nullptr, false);
|
||||
|
@ -561,10 +558,6 @@ TEST(etb, setpointLuaAdder) {
|
|||
}
|
||||
|
||||
TEST(etb, etbTpsSensor) {
|
||||
static engine_configuration_s localConfig;
|
||||
// huh? how is this breaking the test? EngineTestHelper eth(TEST_ENGINE);
|
||||
engineConfiguration = &localConfig;
|
||||
|
||||
// Throw some distinct values on the TPS sensors so we can identify that we're getting the correct one
|
||||
Sensor::setMockValue(SensorType::Tps1, 25.0f, true);
|
||||
Sensor::setMockValue(SensorType::Tps2, 75.0f, true);
|
||||
|
@ -601,7 +594,6 @@ TEST(etb, etbTpsSensor) {
|
|||
etb.init(ETB_IdleValve, nullptr, nullptr, nullptr, true);
|
||||
EXPECT_EQ(etb.observePlant().Value, 66.0f);
|
||||
}
|
||||
engineConfiguration = nullptr;
|
||||
}
|
||||
|
||||
TEST(etb, setOutputInvalid) {
|
||||
|
@ -746,9 +738,6 @@ TEST(etb, setOutputLimpHome) {
|
|||
}
|
||||
|
||||
TEST(etb, closedLoopPid) {
|
||||
static engine_configuration_s localConfig;
|
||||
// huh? how is this breaking the test? EngineTestHelper eth(TEST_ENGINE);
|
||||
engineConfiguration = &localConfig;
|
||||
pid_s pid = {};
|
||||
pid.pFactor = 5;
|
||||
pid.maxValue = 75;
|
||||
|
@ -762,8 +751,6 @@ TEST(etb, closedLoopPid) {
|
|||
EtbController etb;
|
||||
etb.init(ETB_Throttle1, nullptr, &pid, nullptr, true);
|
||||
|
||||
// todo: second part dirty hack :(
|
||||
engineConfiguration = nullptr;
|
||||
// Disable autotune for now
|
||||
Engine e;
|
||||
EngineTestHelperBase base(&e, nullptr, nullptr);
|
||||
|
@ -779,6 +766,59 @@ TEST(etb, closedLoopPid) {
|
|||
EXPECT_FLOAT_EQ(etb.getClosedLoop(50, 30).value_or(-1), 75);
|
||||
}
|
||||
|
||||
extern int timeNowUs;
|
||||
|
||||
TEST(etb, jamDetection) {
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
|
||||
pid_s pid = {};
|
||||
|
||||
// I-only since we're testing out the integrator
|
||||
pid.pFactor = 0;
|
||||
pid.iFactor = 1;
|
||||
pid.dFactor = 0;
|
||||
pid.maxValue = 50;
|
||||
pid.minValue = -50;
|
||||
|
||||
// Must have TPS & PPS initialized for ETB setup
|
||||
Sensor::setMockValue(SensorType::Tps1Primary, 0);
|
||||
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
|
||||
Sensor::setMockValue(SensorType::AcceleratorPedal, 0.0f, true);
|
||||
|
||||
// Limit of 5%, 1 second
|
||||
engineConfiguration->etbJamIntegratorLimit = 5;
|
||||
engineConfiguration->etbJamTimeout = 1;
|
||||
|
||||
EtbController etb;
|
||||
etb.init(ETB_Throttle1, nullptr, &pid, nullptr, true);
|
||||
|
||||
timeNowUs = 0;
|
||||
|
||||
// Reset timer while under integrator limit
|
||||
EXPECT_EQ(etb.getPidState().iTerm, 0);
|
||||
etb.checkOutput(0);
|
||||
EXPECT_EQ(etb.jamTimer, 0);
|
||||
EXPECT_FALSE(etb.jamDetected);
|
||||
|
||||
for (size_t i = 0; i < ETB_LOOP_FREQUENCY; i++) {
|
||||
// Error of 10, should accumulate 10 integrator per second
|
||||
etb.getClosedLoop(50, 40);
|
||||
}
|
||||
|
||||
EXPECT_NEAR(etb.getPidState().iTerm, 10.0f, 1e-3);
|
||||
|
||||
// Just under time limit, no jam yet
|
||||
timeNowUs = 0.9e6;
|
||||
etb.checkOutput(0);
|
||||
EXPECT_NEAR(etb.jamTimer, 0.9f, 1e-3);
|
||||
EXPECT_FALSE(etb.jamDetected);
|
||||
|
||||
// Above the time limit, jam detected!
|
||||
timeNowUs = 1.1e6;
|
||||
etb.checkOutput(0);
|
||||
EXPECT_TRUE(etb.jamDetected);
|
||||
}
|
||||
|
||||
TEST(etb, openLoopThrottle) {
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -40,3 +40,37 @@ TEST(real4b11, running) {
|
|||
|
||||
ASSERT_EQ(0, eth.recentWarnings()->getCount());
|
||||
}
|
||||
|
||||
TEST(real4b11, runningDoubledEdge) {
|
||||
CsvReader reader(1, /* vvtCount */ 0);
|
||||
|
||||
// This log has an extra duplicate edge at 5.393782 seconds (hand added)
|
||||
reader.open("tests/trigger/resources/4b11-running-doubled-edge.csv");
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
engineConfiguration->isFasterEngineSpinUpEnabled = true;
|
||||
engineConfiguration->alwaysInstantRpm = true;
|
||||
|
||||
eth.setTriggerType(TT_36_2_1);
|
||||
|
||||
int eventCount = 0;
|
||||
bool gotRpm = false;
|
||||
|
||||
while (reader.haveMore()) {
|
||||
reader.processLine(ð);
|
||||
eventCount++;
|
||||
engine->rpmCalculator.onSlowCallback();
|
||||
|
||||
auto rpm = Sensor::getOrZero(SensorType::Rpm);
|
||||
if (!gotRpm && rpm) {
|
||||
gotRpm = true;
|
||||
|
||||
// We should get first RPM on exactly the first sync point - this means the instant RPM pre-sync event copy all worked OK
|
||||
EXPECT_EQ(eventCount, 30);
|
||||
EXPECT_NEAR(rpm, 1436.23f, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// Should get a warning for the doubled edge, but NOT one for a trigger error!
|
||||
ASSERT_EQ(1, eth.recentWarnings()->getCount());
|
||||
ASSERT_EQ(CUSTOM_PRIMARY_DOUBLED_EDGE, eth.recentWarnings()->get(0).Code);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue