From 7154da1f5fdf22af1e2aec262e3db6883977a0ec Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Sun, 6 Jan 2019 17:45:51 -0800 Subject: [PATCH] Improve wall wetting AE to use time constant (#650) * impruv * c++17 * add tests, docs --- firmware/Makefile | 2 +- firmware/config/engines/dodge_neon.cpp | 8 +- .../controllers/algo/accel_enrichment.cpp | 94 +++++++++++++++---- ...ngine_configuration_generated_structures.h | 10 +- firmware/controllers/algo/rusefi_generated.h | 8 +- firmware/controllers/settings.cpp | 8 +- firmware/integration/rusefi_config.txt | 6 +- firmware/tunerstudio/rusefi.input | 4 +- firmware/util/efilib.cpp | 35 +++++++ firmware/util/efilib.h | 4 + .../autotest/src/com/rusefi/AutoTest.java | 4 +- .../models/src/com/rusefi/config/Fields.java | 14 +-- .../ui/src/com/rusefi/ui/SettingsTab.java | 4 +- unit_tests/Makefile | 2 +- unit_tests/test.mk | 1 + unit_tests/test_basic_math/test_efilib.cpp | 23 +++++ 16 files changed, 175 insertions(+), 52 deletions(-) create mode 100644 unit_tests/test_basic_math/test_efilib.cpp diff --git a/firmware/Makefile b/firmware/Makefile index d353b7fadb..86add23e05 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -30,7 +30,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -std=c++11 -fno-rtti -fno-exceptions -fno-use-cxa-atexit -Werror=write-strings -Werror=type-limits + USE_CPPOPT = -std=c++17 -Wno-register -fno-rtti -fno-exceptions -fno-use-cxa-atexit -Werror=write-strings -Werror=type-limits endif # Enable this if you want the linker to remove unused code and data diff --git a/firmware/config/engines/dodge_neon.cpp b/firmware/config/engines/dodge_neon.cpp index 4d83c2c7d4..8d7cdcdca2 100644 --- a/firmware/config/engines/dodge_neon.cpp +++ b/firmware/config/engines/dodge_neon.cpp @@ -502,11 +502,11 @@ void setDodgeNeonNGCEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { engineConfiguration->tpsAccelLength = 12; engineConfiguration->tpsAccelEnrichmentThreshold = 10; - engineConfiguration->suckedOffCoef = 0.05; - engineConfiguration->addedToWallCoef = 0.40; + engineConfiguration->wwaeTau = 1.0f; + engineConfiguration->wwaeBeta = 0.40f; - engineConfiguration->suckedOffCoef = 0; - engineConfiguration->addedToWallCoef = 0; + engineConfiguration->wwaeTau = 0; + engineConfiguration->wwaeBeta = 0; boardConfiguration->isSdCardEnabled = false; boardConfiguration->manIdlePosition = 36; // set_idle_pwm 40 diff --git a/firmware/controllers/algo/accel_enrichment.cpp b/firmware/controllers/algo/accel_enrichment.cpp index 336aec71f9..0a594117f6 100644 --- a/firmware/controllers/algo/accel_enrichment.cpp +++ b/firmware/controllers/algo/accel_enrichment.cpp @@ -18,6 +18,7 @@ * @date Apr 21, 2014 * @author Dmitry Sidin * @author Andrey Belomutskiy, (c) 2012-2018 + * @author Matthew Kennedy */ #include "global.h" @@ -47,34 +48,93 @@ void WallFuel::reset() { memset(wallFuel, 0, sizeof(wallFuel)); } -floatms_t WallFuel::adjust(int injectorIndex, floatms_t target DECLARE_ENGINE_PARAMETER_SUFFIX) { - if (cisnan(target)) { - return target; +floatms_t WallFuel::adjust(int injectorIndex, floatms_t M_des DECLARE_ENGINE_PARAMETER_SUFFIX) { + if (cisnan(M_des)) { + return M_des; } // disable this correction for cranking if (ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE)) { - return target; + return M_des; } - float addedToWallCoef = CONFIG(addedToWallCoef); - /** - * What amount of fuel is sucked of the walls, based on current amount of fuel on the wall. - */ - floatms_t suckedOffWallsAmount = wallFuel[injectorIndex] * CONFIG(suckedOffCoef); + /* + this math is based on + SAE 810494 by C. F. Aquino + SAE 1999-01-0553 by Peter J Maloney - floatms_t adjustedFuelPulse = (target - suckedOffWallsAmount) / (1 - addedToWallCoef); + M_cmd = commanded fuel mass (output of this function) + M_des = desired fuel mass (input to this function) + M_f = fuel film mass (how much is currently on the wall) + First we compute how much fuel to command, by accounting for + a) how much fuel will evaporate from the walls, entering the air + b) how much fuel from the injector will hit the walls, being deposited + + Next, we compute how much fuel will be deposited on the walls. The net + effect of these two steps is computed (some leaves walls, some is deposited) + and stored back in M_f. + + alpha describes the amount of fuel that REMAINS on the wall per cycle. + It is computed as a function of the evaporation time constant (tau) and + the time the fuel spent on the wall this cycle, (recriprocal RPM). + + beta describes the amount of fuel that hits the wall. + + TODO: these parameters, tau and beta vary with various engine parameters, + most notably manifold pressure (as a proxy for air speed), and coolant + temperature (as a proxy for the intake valve and runner temperature). + + TAU: decreases with increasing temperature. + decreases with decreasing manifold pressure. + + BETA: decreases with increasing temperature. + decreases with decreasing manifold pressure. + */ + + // if tau is really small, we get div/0. + // you probably meant to disable wwae. + float tau = CONFIG(wwaeTau); + if(tau < 0.01f) + { + return M_des; + } + + // Ignore really slow RPM + int rpm = getRpmE(engine); + if(rpm < 100) + { + return M_des; + } + + float alpha = expf_taylor(-120 / (rpm * tau)); + float beta = CONFIG(wwaeBeta); + + // If beta is larger than alpha, the system is underdamped. + // For reasonable values {tau, beta}, this should only be possible + // at extremely low engine speeds (<300rpm ish) + // Clamp beta to less than alpha. + if(beta > alpha) + { + beta = alpha; + } + + float M_f = wallFuel[injectorIndex]; + float M_cmd = (M_des - (1 - alpha) * M_f) / (1 - beta); + // We can't inject a negative amount of fuel // If this goes below zero we will be over-fueling slightly, // but that's ok. - if(adjustedFuelPulse < 0) { - adjustedFuelPulse = 0; + if(M_cmd <= 0) + { + M_cmd = 0; } - float addedToWallsAmount = adjustedFuelPulse * addedToWallCoef; - wallFuel[injectorIndex] += addedToWallsAmount - suckedOffWallsAmount; - engine->wallFuelCorrection = adjustedFuelPulse - target; - return adjustedFuelPulse; + // remainder on walls from last time + new from this time + float M_f_next = alpha * M_f + beta * M_cmd; + + wallFuel[injectorIndex] = M_f_next; + engine->wallFuelCorrection = M_cmd - M_des; + return M_cmd; } floatms_t WallFuel::getWallFuel(int injectorIndex) { @@ -211,7 +271,7 @@ static void accelInfo() { // scheduleMsg(logger, "TPS accel length=%d", tpsInstance.cb.getSize()); scheduleMsg(logger, "TPS accel th=%.2f/mult=%.2f", engineConfiguration->tpsAccelEnrichmentThreshold, -1); - scheduleMsg(logger, "added to wall=%.2f/sucked=%.2f", engineConfiguration->addedToWallCoef, engineConfiguration->suckedOffCoef); + scheduleMsg(logger, "beta=%.2f/tau=%.2f", engineConfiguration->wwaeBeta, engineConfiguration->wwaeTau); } void setEngineLoadAccelThr(float value) { diff --git a/firmware/controllers/algo/engine_configuration_generated_structures.h b/firmware/controllers/algo/engine_configuration_generated_structures.h index b166f18f30..f85729907e 100644 --- a/firmware/controllers/algo/engine_configuration_generated_structures.h +++ b/firmware/controllers/algo/engine_configuration_generated_structures.h @@ -1,4 +1,4 @@ -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sat Jan 05 23:35:34 EST 2019 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 06 03:15:03 PST 2019 // begin #ifndef ENGINE_CONFIGURATION_GENERATED_H_ #define ENGINE_CONFIGURATION_GENERATED_H_ @@ -1602,7 +1602,7 @@ typedef struct { /** * offset 1808 */ - float suckedOffCoef; + float wwaeTau; /** * offset 1812 */ @@ -1639,7 +1639,7 @@ typedef struct { * Wall wetting/evaporation factor/Tau factor/fuel film * offset 1904 */ - float addedToWallCoef; + float wwaeBeta; /** * blue LED on discovery by default * offset 1908 @@ -2321,7 +2321,7 @@ typedef struct { float cltIdleCorr[CLT_CURVE_SIZE]; /** * kg/hour value. - * By the way 2.081989116 kg/h = 1 ft³/m + * By the way 2.081989116 kg/h = 1 ft�/m * offset 10784 */ float mafDecoding[MAF_DECODING_COUNT]; @@ -2472,4 +2472,4 @@ typedef struct { #endif // end -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sat Jan 05 23:35:34 EST 2019 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 06 03:15:03 PST 2019 diff --git a/firmware/controllers/algo/rusefi_generated.h b/firmware/controllers/algo/rusefi_generated.h index 02e3420d6a..13540a76e4 100644 --- a/firmware/controllers/algo/rusefi_generated.h +++ b/firmware/controllers/algo/rusefi_generated.h @@ -1071,8 +1071,8 @@ #define tachPulseDuractionMs_offset_hex 708 #define tachPulseTriggerIndex_offset 1804 #define tachPulseTriggerIndex_offset_hex 70c -#define suckedOffCoef_offset 1808 -#define suckedOffCoef_offset_hex 710 +#define wwaeTau_offset 1808 +#define wwaeTau_offset_hex 710 #define alternatorControl_offset 1812 #define alternatorControl_offset_hex 714 #define alternatorControl_pFactor_offset 1812 @@ -1143,8 +1143,8 @@ #define idleRpmPid_minValue_offset_hex 76c #define idleRpmPid_maxValue_offset 1902 #define idleRpmPid_maxValue_offset_hex 76e -#define addedToWallCoef_offset 1904 -#define addedToWallCoef_offset_hex 770 +#define wwaeBeta_offset 1904 +#define wwaeBeta_offset_hex 770 #define communicationLedPin_offset 1908 #define communicationLedPin_offset_hex 774 #define runningLedPin_offset 1912 diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index e7e05afba1..5db44646b7 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -1302,10 +1302,10 @@ static void setValue(const char *paramStr, const char *valueStr) { engineConfiguration->step1timing = valueI; } else if (strEqualCaseInsensitive(paramStr, "operation_mode")) { engineConfiguration->operationMode = (operation_mode_e)valueI; - } else if (strEqualCaseInsensitive(paramStr, "suckedOffCoef")) { - engineConfiguration->suckedOffCoef = valueF; - } else if (strEqualCaseInsensitive(paramStr, "addedToWallCoef")) { - engineConfiguration->addedToWallCoef = valueF; + } else if (strEqualCaseInsensitive(paramStr, "wwaeTau")) { + engineConfiguration->wwaeTau = valueF; + } else if (strEqualCaseInsensitive(paramStr, "wwaeBeta")) { + engineConfiguration->wwaeBeta = valueF; } else if (strEqualCaseInsensitive(paramStr, "cranking_dwell")) { engineConfiguration->ignitionDwellForCrankingMs = valueF; } else if (strEqualCaseInsensitive(paramStr, "targetvbatt")) { diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index c37d6788ad..13b360af83 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -756,7 +756,7 @@ custom pin_mode_e 4 bits, U32, @OFFSET@, [0:5], @@pin_mode_e_enum@@ float tachPulseDuractionMs;;"ms", 1, 0, 0.0, 100.0, 2 int tachPulseTriggerIndex;+Trigger cycle index at which we start tach pulse (performance consideration);"index", 1, 0, 0.0, 360.0, 0 - float suckedOffCoef;;"%", 1, 0, 0.0, 300.0, 2 + float wwaeTau;;"%", 1, 0, 0.0, 3.0, 2 pid_s alternatorControl; pid_s etb; pid_s warmupAfrPid; @@ -766,7 +766,7 @@ custom pin_mode_e 4 bits, U32, @OFFSET@, [0:5], @@pin_mode_e_enum@@ float mapErrorDetectionTooHigh;kPa value which is too high to be true;"kPa", 1, 0, -100.0, 800.0, 2 int step1RpmWindow;RPMs prior to step1rpm point where ignition advance is retarded;"rpm", 1, 0, 0, 3000.0, 2 pid_s idleRpmPid;See cltIdleRpmBins - float addedToWallCoef;Wall wetting/evaporation factor/Tau factor/fuel film;"%", 1, 0, 0.0, 300.0, 2 + float wwaeBeta;Wall wetting/evaporation factor/Tau factor/fuel film;"%", 1, 0, 0.0, 1.0, 2 brain_pin_e communicationLedPin;blue LED on discovery by default brain_pin_e runningLedPin;green LED on discovery by default brain_pin_e binarySerialTxPin; @@ -968,7 +968,7 @@ float[IAT_CURVE_SIZE] iatFuelCorr;;"%", 1, 0, 0.0, 500.0, 2 float[CLT_CURVE_SIZE] cltIdleCorrBins;CLT-based idle position multiplier for simple manual idle controller;"C", 1, 0, -100.0, 250.0, 2 float[CLT_CURVE_SIZE] cltIdleCorr; CLT-based idle position multiplier for simple manual idle controller;"%", 1, 0, 0.0, 1000.0, 2 -float[MAF_DECODING_COUNT] mafDecoding;kg/hour value.\nBy the way 2.081989116 kg/h = 1 ft³/m;"kg/hour", 1, 0, -500.0, 4000.0, 2 +float[MAF_DECODING_COUNT] mafDecoding;kg/hour value.\nBy the way 2.081989116 kg/h = 1 ft�/m;"kg/hour", 1, 0, -500.0, 4000.0, 2 float[MAF_DECODING_COUNT] mafDecodingBins;; "V", 1, 0, -5.0, 150.0, 2 angle_table_t ignitionIatCorrTable; diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 70e7980fb2..80edd3fdfc 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -2044,8 +2044,8 @@ cmd_stop_engine = "w\x00\x99\x00\x00" ; field = "Decel Multiplier", tpsDecelEnleanmentMultiplier dialog = WallWettingAccelPanel, "Wall Wetting (alpha version)" - field = "sucked off wall coefficient", suckedOffCoef - field = "added to wall coef", addedToWallCoef + field = "evaporation time constant", wwaeTau + field = "added to wall coef", wwaeBeta ; Tuning->AccelEnrichment diff --git a/firmware/util/efilib.cpp b/firmware/util/efilib.cpp index f42ec023d9..0aa13fcd13 100644 --- a/firmware/util/efilib.cpp +++ b/firmware/util/efilib.cpp @@ -315,3 +315,38 @@ float limitRateOfChange(float newValue, float oldValue, float incrLimitPerSec, f return (incrLimitPerSec <= 0.0f) ? newValue : oldValue + minF(newValue - oldValue, incrLimitPerSec * secsPassed); return (decrLimitPerSec <= 0.0f) ? newValue : oldValue - minF(oldValue - newValue, decrLimitPerSec * secsPassed); } + +constexpr float constant_e = 2.71828f; + +constexpr float expf_taylor_impl(float x, uint8_t n) +{ + if (x < -2) + { + return 0.818f; + } + else if (x > 0) + { + return 1; + } + + x = x + 1; + + float x_power = x; + int fac = 1; + float sum = 1; + + for (int i = 1; i <= n; i++) + { + fac *= i; + sum += x_power / fac; + + x_power *= x; + } + + return sum / constant_e; +} + +float expf_taylor(float x) +{ + return expf_taylor_impl(x, 4); +} diff --git a/firmware/util/efilib.h b/firmware/util/efilib.h index 3abf0c472f..9706e396ea 100644 --- a/firmware/util/efilib.h +++ b/firmware/util/efilib.h @@ -68,6 +68,10 @@ bool strEqual(const char *str1, const char *str2); // Currently used by air-interp. tCharge mode (see EngineState::updateTChargeK()). float limitRateOfChange(float newValue, float oldValue, float incrLimitPerSec, float decrLimitPerSec, float secsPassed); +// @brief Compute e^x using a 4th order taylor expansion centered at x=-1. Provides +// bogus results outside the range -2 < x < 0. +float expf_taylor(float x); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/java_console/autotest/src/com/rusefi/AutoTest.java b/java_console/autotest/src/com/rusefi/AutoTest.java index bcf38a9c8a..3d63f3b3ce 100644 --- a/java_console/autotest/src/com/rusefi/AutoTest.java +++ b/java_console/autotest/src/com/rusefi/AutoTest.java @@ -144,8 +144,8 @@ public class AutoTest { private static void test2003DodgeNeon() { setEngineType(23); - sendCommand("set suckedOffCoef 0"); - sendCommand("set addedToWallCoef 0"); + sendCommand("set wwaeTau 0"); + sendCommand("set wwaeBeta 0"); sendCommand("set mock_map_voltage 1"); sendCommand("set mock_vbatt_voltage 1.20"); sendCommand("disable cylinder_cleanup"); diff --git a/java_console/models/src/com/rusefi/config/Fields.java b/java_console/models/src/com/rusefi/config/Fields.java index 256d33ce9f..138ef951c3 100644 --- a/java_console/models/src/com/rusefi/config/Fields.java +++ b/java_console/models/src/com/rusefi/config/Fields.java @@ -1,6 +1,6 @@ package com.rusefi.config; -// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sat Jan 05 16:40:23 EST 2019 +// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Sun Jan 06 03:15:03 PST 2019 public class Fields { public static final int LE_COMMAND_LENGTH = 200; public static final int BLOCKING_FACTOR = 400; @@ -723,8 +723,8 @@ public class Fields { public static final int tachPulseDuractionMs_offset = 1800; public static final int tachPulseDuractionMs_offset_hex = 708; public static final int tachPulseTriggerIndex_offset = 1804; - public static final int suckedOffCoef_offset = 1808; - public static final int suckedOffCoef_offset_hex = 710; + public static final int wwaeTau_offset = 1808; + public static final int wwaeTau_offset_hex = 710; public static final int alternatorControl_offset = 1812; public static final int alternatorControl_offset_hex = 714; public static final int alternatorControl_pFactor_offset = 1812; @@ -782,8 +782,8 @@ public class Fields { public static final int idleRpmPid_period_offset = 1898; public static final int idleRpmPid_minValue_offset = 1900; public static final int idleRpmPid_maxValue_offset = 1902; - public static final int addedToWallCoef_offset = 1904; - public static final int addedToWallCoef_offset_hex = 770; + public static final int wwaeBeta_offset = 1904; + public static final int wwaeBeta_offset_hex = 770; public static final int communicationLedPin_offset = 1908; public static final int communicationLedPin_offset_hex = 774; public static final int runningLedPin_offset = 1912; @@ -1676,7 +1676,7 @@ public class Fields { public static final Field SPI2MISOMODE = Field.create("SPI2MISOMODE", 1732, FieldType.INT, pin_mode_e); public static final Field TACHPULSEDURACTIONMS = Field.create("TACHPULSEDURACTIONMS", 1800, FieldType.FLOAT); public static final Field TACHPULSETRIGGERINDEX = Field.create("TACHPULSETRIGGERINDEX", 1804, FieldType.INT); - public static final Field SUCKEDOFFCOEF = Field.create("SUCKEDOFFCOEF", 1808, FieldType.FLOAT); + public static final Field WWAETAU = Field.create("WWAETAU", 1808, FieldType.FLOAT); public static final Field ALTERNATORCONTROL_PFACTOR = Field.create("ALTERNATORCONTROL_PFACTOR", 1812, FieldType.FLOAT); public static final Field ALTERNATORCONTROL_IFACTOR = Field.create("ALTERNATORCONTROL_IFACTOR", 1816, FieldType.FLOAT); public static final Field ALTERNATORCONTROL_DFACTOR = Field.create("ALTERNATORCONTROL_DFACTOR", 1820, FieldType.FLOAT); @@ -1708,7 +1708,7 @@ public class Fields { public static final Field IDLERPMPID_PERIOD = Field.create("IDLERPMPID_PERIOD", 1898, FieldType.INT); public static final Field IDLERPMPID_MINVALUE = Field.create("IDLERPMPID_MINVALUE", 1900, FieldType.INT); public static final Field IDLERPMPID_MAXVALUE = Field.create("IDLERPMPID_MAXVALUE", 1902, FieldType.INT); - public static final Field ADDEDTOWALLCOEF = Field.create("ADDEDTOWALLCOEF", 1904, FieldType.FLOAT); + public static final Field WWAEBETA = Field.create("WWAEBETA", 1904, FieldType.FLOAT); public static final Field COMMUNICATIONLEDPIN = Field.create("COMMUNICATIONLEDPIN", 1908, FieldType.INT, brain_pin_e); public static final Field RUNNINGLEDPIN = Field.create("RUNNINGLEDPIN", 1912, FieldType.INT, brain_pin_e); public static final Field BINARYSERIALTXPIN = Field.create("BINARYSERIALTXPIN", 1916, FieldType.INT, brain_pin_e); diff --git a/java_console/ui/src/com/rusefi/ui/SettingsTab.java b/java_console/ui/src/com/rusefi/ui/SettingsTab.java index bb26badbfb..ed55aa64ef 100644 --- a/java_console/ui/src/com/rusefi/ui/SettingsTab.java +++ b/java_console/ui/src/com/rusefi/ui/SettingsTab.java @@ -104,8 +104,8 @@ public class SettingsTab { // panel.add(UiUtils.wrap(new ConfigField(Fields.IGNITIONOFFSET, "Ignition offset").getContent())); // panel.add(UiUtils.wrap(new ConfigField(Fields.CRANKINGTIMINGANGLE, "Cranking timing").getContent())); // -// panel.add(UiUtils.wrap(new ConfigField(Fields.ADDEDTOWALLCOEF, "Added to wall").getContent())); -// panel.add(UiUtils.wrap(new ConfigField(Fields.SUCKEDOFFCOEF, "Sucked off wall").getContent())); +// panel.add(UiUtils.wrap(new ConfigField(Fields.WWAEBETA, "Added to wall").getContent())); +// panel.add(UiUtils.wrap(new ConfigField(Fields.WWAETAU, "Sucked off wall").getContent())); //// panel.add(UiUtils.wrap(new ConfigField(Fields.TPSACCELENRICHMENTTHRESHOLD, "TPS accel threshold").getContent())); // panel.add(UiUtils.wrap(new ConfigField(Fields.TPSACCELENRICHMENTMULTIPLIER, "TPS accel coef").getContent())); diff --git a/unit_tests/Makefile b/unit_tests/Makefile index 84277ccd55..82584f358d 100644 --- a/unit_tests/Makefile +++ b/unit_tests/Makefile @@ -34,7 +34,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -std=c++11 -fno-rtti -fpermissive -fno-exceptions -fno-use-cxa-atexit + USE_CPPOPT = -std=c++17 -fno-rtti -fpermissive -fno-exceptions -fno-use-cxa-atexit endif # Enable this if you want the linker to remove unused code and data diff --git a/unit_tests/test.mk b/unit_tests/test.mk index 161bf396e6..8c58ff38d7 100644 --- a/unit_tests/test.mk +++ b/unit_tests/test.mk @@ -4,6 +4,7 @@ TEST_SRC_CPP = unit_test_framework.cpp \ global_execution_queue.cpp \ test_basic_math/test_find_index.cpp \ test_basic_math/test_interpolation_3d.cpp \ + test_basic_math/test_efilib.cpp \ tests/test_util.cpp \ tests/test_ion.cpp \ tests/test_hip9011.cpp \ diff --git a/unit_tests/test_basic_math/test_efilib.cpp b/unit_tests/test_basic_math/test_efilib.cpp new file mode 100644 index 0000000000..713083f6b3 --- /dev/null +++ b/unit_tests/test_basic_math/test_efilib.cpp @@ -0,0 +1,23 @@ +/* + * test_efilib.cpp + * + * Created on: Jan 6, 2019 + * @author Matthew Kennedy, (c) 2019 + */ + +#include "gtest/gtest.h" + +#include "efilib.h" +#include + +TEST(EfiLibTest, ExpTaylor) +{ + float x = -2; + + // test from -2 < x < 0 + for(float x = -2; x < 0; x += 0.05) + { + // Compare taylor to libc implementation + EXPECT_NEAR(expf_taylor(x), expf(x), 0.01f); + } +}