ETB duty cycle jitter #4833

need whole output not just closed loop part
This commit is contained in:
Andrey 2022-11-30 15:25:50 -05:00
parent 8833543546
commit 47aac2b46e
7 changed files with 25 additions and 15 deletions

View File

@ -522,13 +522,7 @@ expected<percent_t> EtbController::getClosedLoop(percent_t target, percent_t obs
} }
// Normal case - use PID to compute closed loop part // Normal case - use PID to compute closed loop part
float output = m_pid.getOutput(target, observation, etbPeriodSeconds); return m_pid.getOutput(target, observation, etbPeriodSeconds);
etbDutyAverage = m_dutyAverage.average(output);
etbDutyRateOfChange = m_dutyRocAverage.average(output - prevOutput);
prevOutput = output;
return output;
} }
} }
@ -623,6 +617,19 @@ void EtbController::update() {
ClosedLoopController::update(); ClosedLoopController::update();
} }
expected<percent_t> EtbController::getOutput() {
// total open + closed loop parts
expected<percent_t> output = ClosedLoopController::getOutput();
if (!output) {
return output;
}
etbDutyAverage = m_dutyAverage.average(output.Value);
etbDutyRateOfChange = m_dutyRocAverage.average(output.Value - prevOutput);
prevOutput = output.Value;
return output;
}
void EtbController::autoCalibrateTps() { void EtbController::autoCalibrateTps() {
// Only auto calibrate throttles // Only auto calibrate throttles
if (m_function == ETB_Throttle1 || m_function == ETB_Throttle2) { if (m_function == ETB_Throttle1 || m_function == ETB_Throttle2) {

View File

@ -53,6 +53,7 @@ public:
virtual void setIdlePosition(percent_t pos) = 0; virtual void setIdlePosition(percent_t pos) = 0;
virtual void setWastegatePosition(percent_t pos) = 0; virtual void setWastegatePosition(percent_t pos) = 0;
virtual void update() = 0; virtual void update() = 0;
virtual expected<percent_t> getOutput() = 0;
virtual void autoCalibrateTps() = 0; virtual void autoCalibrateTps() = 0;
virtual const pid_state_s* getPidState() const = 0; virtual const pid_state_s* getPidState() const = 0;

View File

@ -34,6 +34,7 @@ public:
// Update the controller's state: read sensors, send output, etc // Update the controller's state: read sensors, send output, etc
void update() override; void update() override;
expected<percent_t> getOutput() override;
// Called when the configuration may have changed. Controller will // Called when the configuration may have changed. Controller will
// reset if necessary. // reset if necessary.

View File

@ -14,8 +14,7 @@ public:
setOutput(outputValue); setOutput(outputValue);
} }
private: virtual expected<TOutput> getOutput() {
expected<TOutput> getOutput() {
expected<TInput> setpoint = getSetpoint(); expected<TInput> setpoint = getSetpoint();
// If we don't know the setpoint, return failure. // If we don't know the setpoint, return failure.
if (!setpoint) { if (!setpoint) {
@ -42,6 +41,7 @@ private:
return openLoopResult.Value + closedLoopResult.Value; return openLoopResult.Value + closedLoopResult.Value;
} }
private:
// Get the setpoint: where should the controller put the plant? // Get the setpoint: where should the controller put the plant?
virtual expected<TInput> getSetpoint() = 0; virtual expected<TInput> getSetpoint() = 0;

View File

@ -20,7 +20,7 @@ GTEST_API_ int main(int argc, char **argv) {
* See TEST_FROM_TRIGGER_ID to limit test just for last trigger * See TEST_FROM_TRIGGER_ID to limit test just for last trigger
*/ */
// setVerboseTrigger(true); // setVerboseTrigger(true);
//::testing::GTEST_FLAG(filter) = "*AllTriggersFixture*"; // ::testing::GTEST_FLAG(filter) = "*integrated*";
int result = RUN_ALL_TESTS(); int result = RUN_ALL_TESTS();
// windows ERRORLEVEL in Jenkins batch file seems to want negative value to detect failure // windows ERRORLEVEL in Jenkins batch file seems to want negative value to detect failure
return result == 0 ? 0 : -1; return result == 0 ? 0 : -1;

View File

@ -30,6 +30,7 @@ public:
// ClosedLoopController mocks // ClosedLoopController mocks
MOCK_METHOD(expected<percent_t>, getOutput, (), (override));
MOCK_METHOD(expected<percent_t>, getSetpoint, (), (override)); MOCK_METHOD(expected<percent_t>, getSetpoint, (), (override));
MOCK_METHOD(expected<percent_t>, observePlant, (), (const, override)); MOCK_METHOD(expected<percent_t>, observePlant, (), (const, override));
MOCK_METHOD(expected<percent_t>, getOpenLoop, (percent_t setpoint), (override)); MOCK_METHOD(expected<percent_t>, getOpenLoop, (percent_t setpoint), (override));

View File

@ -30,18 +30,18 @@ TEST(etb, integrated) {
etb->update(); etb->update();
ASSERT_EQ(engine->outputChannels.etbTarget, 40); ASSERT_EQ(engine->outputChannels.etbTarget, 40);
ASSERT_EQ(etb->prevOutput, 100); ASSERT_NEAR(etb->prevOutput, 120.363, EPS3D);
ASSERT_EQ(etb->etbDutyAverage, 50); ASSERT_NEAR(etb->etbDutyAverage, 60.1813, EPS3D);
Sensor::setMockValue(SensorType::AcceleratorPedal, 10, true); Sensor::setMockValue(SensorType::AcceleratorPedal, 10, true);
etb->update(); etb->update();
ASSERT_EQ(etb->etbDutyAverage, -25); ASSERT_NEAR(etb->etbDutyAverage, -9.89286, EPS3D);
ASSERT_EQ(etb->etbDutyRateOfChange, -75); ASSERT_NEAR(etb->etbDutyRateOfChange, -70.074, EPS3D);
float destination; float destination;
int offset = ELECTRONIC_THROTTLE_BASE_ADDRESS + offsetof(electronic_throttle_s, etbDutyRateOfChange); int offset = ELECTRONIC_THROTTLE_BASE_ADDRESS + offsetof(electronic_throttle_s, etbDutyRateOfChange);
copyRange((uint8_t*)&destination, getLiveDataFragments(), offset, sizeof(destination)); copyRange((uint8_t*)&destination, getLiveDataFragments(), offset, sizeof(destination));
ASSERT_EQ(destination, -75); ASSERT_NEAR(destination, -70.074, EPS3D);
} }