resolve VVT phase using every tooth, not just sync point (#4434)
* resolve VVT phase using every tooth, not just sync point * fix tests * comment * changelog
This commit is contained in:
parent
0907c009bd
commit
fcb9897443
|
@ -35,6 +35,7 @@ Release template (copy/paste this for new release):
|
|||
- Additional CAN messages #4401
|
||||
- Option to invert VVT control (exhaust cams, etc) #4424
|
||||
- Raw Battery gauge
|
||||
- More accurate/stable VVT angle calculation #4433
|
||||
|
||||
### Fixed
|
||||
- Lua CAN reception fixed for 11-bit IDs where the frame would be received, but a corrupt ID was passed to the handler function. #4321
|
||||
|
|
|
@ -79,7 +79,18 @@ expected<float> TriggerCentral::getCurrentEnginePhase(efitick_t nowNt) const {
|
|||
return unexpected;
|
||||
}
|
||||
|
||||
return m_syncPointTimer.getElapsedUs(nowNt) / oneDegreeUs;
|
||||
float elapsed;
|
||||
float toothPhase;
|
||||
|
||||
{
|
||||
// under lock to avoid mismatched tooth phase and time
|
||||
chibios_rt::CriticalSectionLocker csl;
|
||||
|
||||
elapsed = m_lastToothTimer.getElapsedUs(nowNt);
|
||||
toothPhase = m_lastToothPhaseFromSyncPoint;
|
||||
}
|
||||
|
||||
return toothPhase + elapsed / oneDegreeUs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -685,19 +696,28 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal, efitick_t timesta
|
|||
int crankDivider = getCrankDivider(triggerShape.getOperationMode());
|
||||
int crankInternalIndex = triggerState.getTotalRevolutionCounter() % crankDivider;
|
||||
int triggerIndexForListeners = decodeResult.Value.CurrentIndex + (crankInternalIndex * triggerShape.getSize());
|
||||
if (triggerIndexForListeners == 0) {
|
||||
m_syncPointTimer.reset(timestamp);
|
||||
}
|
||||
|
||||
reportEventToWaveChart(signal, triggerIndexForListeners);
|
||||
|
||||
// Compute the current engine absolute phase, 0 means currently at #1 TDC
|
||||
auto currentPhase = engine->triggerCentral.triggerFormDetails.eventAngles[triggerIndexForListeners] - tdcPosition();
|
||||
// Look up this tooth's angle from the sync point. If this tooth is the sync point, we'll get 0 here.
|
||||
auto currentPhaseFromSyncPoint = engine->triggerCentral.triggerFormDetails.eventAngles[triggerIndexForListeners];
|
||||
|
||||
// Adjust so currentPhase is in engine-space angle, not trigger-space angle
|
||||
auto currentPhase = currentPhaseFromSyncPoint - tdcPosition();
|
||||
wrapAngle(currentPhase, "currentEnginePhase", CUSTOM_ERR_6555);
|
||||
#if EFI_TUNER_STUDIO
|
||||
engine->outputChannels.currentEnginePhase = currentPhase;
|
||||
#endif // EFI_TUNER_STUDIO
|
||||
|
||||
// Record precise time and phase of the engine. This is used for VVT decode.
|
||||
{
|
||||
// under lock to avoid mismatched tooth phase and time
|
||||
chibios_rt::CriticalSectionLocker csl;
|
||||
|
||||
m_lastToothTimer.reset(timestamp);
|
||||
m_lastToothPhaseFromSyncPoint = currentPhaseFromSyncPoint;
|
||||
}
|
||||
|
||||
#if TRIGGER_EXTREME_LOGGING
|
||||
efiPrintf("trigger %d %d %d", triggerIndexForListeners, getRevolutionCounter(), (int)getTimeNowUs());
|
||||
#endif /* TRIGGER_EXTREME_LOGGING */
|
||||
|
|
|
@ -140,9 +140,10 @@ public:
|
|||
private:
|
||||
void decodeMapCam(efitick_t nowNt, float currentPhase);
|
||||
|
||||
// Keep track of the last time we saw the sync tooth go by (trigger index 0)
|
||||
// not TDC point
|
||||
Timer m_syncPointTimer;
|
||||
// Time since the last tooth
|
||||
Timer m_lastToothTimer;
|
||||
// Phase of the last tooth relative to the sync point
|
||||
float m_lastToothPhaseFromSyncPoint;
|
||||
};
|
||||
|
||||
void triggerInfo(void);
|
||||
|
|
|
@ -173,7 +173,7 @@ TEST(trigger, testNB2CamInput) {
|
|||
eth.moveTimeForwardUs(MS2US( 30));
|
||||
hwHandleVvtCamSignal(TV_RISE, getTimeNowNt(), 0);
|
||||
|
||||
EXPECT_NEAR(288.0f, engine->triggerCentral.getVVTPosition(0, 0), EPS2D);
|
||||
EXPECT_NEAR(290.5f, engine->triggerCentral.getVVTPosition(0, 0), EPS2D);
|
||||
// actually position based on VVT!
|
||||
ASSERT_EQ(totalRevolutionCountBeforeVvtSync + 3, engine->triggerCentral.triggerState.getTotalRevolutionCounter());
|
||||
|
||||
|
|
|
@ -23,13 +23,13 @@ TEST(realCrankingVQ40, normalCranking) {
|
|||
float vvt1 = engine->triggerCentral.getVVTPosition(/*bankIndex*/0, /*camIndex*/0);
|
||||
|
||||
if (vvt1 != 0 && !hasSeenFirstVvt) {
|
||||
EXPECT_NEAR(vvt1, -33.204, 1);
|
||||
EXPECT_NEAR(vvt1, -45.56, 1);
|
||||
hasSeenFirstVvt = true;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_NEAR(engine->triggerCentral.getVVTPosition(/*bankIndex*/0, /*camIndex*/0), -46.817, 1e-2);
|
||||
EXPECT_NEAR(engine->triggerCentral.getVVTPosition(/*bankIndex*/1, /*camIndex*/0), -47.411, 1e-2);
|
||||
EXPECT_NEAR(engine->triggerCentral.getVVTPosition(/*bankIndex*/0, /*camIndex*/0), -45.67, 1e-2);
|
||||
EXPECT_NEAR(engine->triggerCentral.getVVTPosition(/*bankIndex*/1, /*camIndex*/0), -45.47, 1e-2);
|
||||
ASSERT_EQ(241, round(Sensor::getOrZero(SensorType::Rpm)))<< reader.lineIndex();
|
||||
|
||||
// TODO: why warnings?
|
||||
|
|
Loading…
Reference in New Issue