#include // #ifdef ARDUINO #include // #endif #include "p_controller.h" #include "pi_controller.h" static const double KP = 2.0; static const double TI = 1.0; static const double T = 0.1; static const double TOL = 1e-4; // double er 32-bita float a AVR // void setUp(void) {} // void tearDown(void) {} // Normal flow: engin villa -> ekkert úttak void test_zero_error_gives_zero_output(void) { PI_controller c(KP, TI, T); TEST_ASSERT_FLOAT_WITHIN(TOL, 0.0, c.update(10.0, 10.0)); } // Normal flow: fyrsta skref u = Kp * (e + e*T/Ti) void test_first_step(void) { PI_controller c(KP, TI, T); double e = 5.0; TEST_ASSERT_FLOAT_WITHIN(TOL, KP * (e + e * T / TI), c.update(e, 0.0)); } // Normal flow: stöðug villa safnast upp, u_n = Kp * (e + n*e*T/Ti) void test_integral_accumulates(void) { PI_controller c(KP, TI, T); double e = 5.0; double u = 0.0; for (int n = 1; n <= 5; n++) { u = c.update(e, 0.0); TEST_ASSERT_FLOAT_WITHIN(TOL, KP * (e + n * e * T / TI), u); } } // Normal flow: þegar villan er orðin 0 heldur integralið úttakinu uppi void test_output_held_when_error_zero(void) { PI_controller c(KP, TI, T); double e = 5.0; for (int n = 0; n < 5; n++) { c.update(e, 0.0); } double E = 5 * e * T; TEST_ASSERT_FLOAT_WITHIN(TOL, KP * E / TI, c.update(0.0, 0.0)); } // Alt flow: villa langt utan getu -> mettun í +100 % void test_saturates_high(void) { PI_controller c(KP, TI, T); TEST_ASSERT_FLOAT_WITHIN(TOL, 100.0, c.update(10000.0, 0.0)); } // Alt flow: mettun í -100 % void test_saturates_low(void) { PI_controller c(KP, TI, T); TEST_ASSERT_FLOAT_WITHIN(TOL, -100.0, c.update(-10000.0, 0.0)); } // Alt flow: anti-windup. Eftir langa mettun á lítil neikvæð villa // strax að gefa úttak undir mettun (integralið óx ekki) void test_no_integral_windup(void) { PI_controller c(KP, TI, T); for (int n = 0; n < 1000; n++) { c.update(10000.0, 0.0); } double u = c.update(0.0, 1.0); // e = -1 TEST_ASSERT_TRUE(u < 0.0); } // Alt flow: reset (stopped -> operational) hreinsar integralið void test_reset_clears_integral(void) { PI_controller c(KP, TI, T); for (int n = 0; n < 5; n++) { c.update(5.0, 0.0); } c.reset(); TEST_ASSERT_FLOAT_WITHIN(TOL, 0.0, c.update(0.0, 0.0)); } // Polymorphism: kall í gegnum P_controller& gefur PI hegðun void test_polymorphic_update(void) { PI_controller pi(KP, TI, T); P_controller& c = pi; double e = 5.0; TEST_ASSERT_FLOAT_WITHIN(TOL, KP * (e + e * T / TI), c.update(e, 0.0)); } // P_controller hegðar sér óbreytt void test_p_controller_unchanged(void) { P_controller c(KP); TEST_ASSERT_FLOAT_WITHIN(TOL, KP * 5.0, c.update(5.0, 0.0)); } void setup() { // init(); delay(2000); UNITY_BEGIN(); RUN_TEST(test_zero_error_gives_zero_output); RUN_TEST(test_first_step); RUN_TEST(test_integral_accumulates); RUN_TEST(test_output_held_when_error_zero); RUN_TEST(test_saturates_high); RUN_TEST(test_saturates_low); RUN_TEST(test_no_integral_windup); RUN_TEST(test_reset_clears_integral); RUN_TEST(test_polymorphic_update); RUN_TEST(test_p_controller_unchanged); // return UNITY_END(); UNITY_END(); } void loop() {} // #ifdef ARDUINO // void setup() // { // delay(2000); // bida eftir serial tengingu eftir reset // run_tests(); // } // void loop() // { // } // #else // int main(int argc, char** argv) // { // return run_tests(); // } // #endif