/** * @file test_actuator_driver.c * @brief Unit-Tests fuer den Actuator-Driver. * * @reqs SWE-006 SWE-013 SWE-014 SWE-015 * @arch SWA-003 */ #include "../unit_test_framework.h" #include "../../src/actuator_driver.h" TestStats g_test_stats = {0, 0}; static void test_init(void) { TEST_BEGIN("init -> beide Aktoren STOP, 0 mA"); ASSERT_EQ(actuator_init(), EPB_OK); ActuatorStatus l = actuator_get_status(ACTUATOR_LEFT); ActuatorStatus r = actuator_get_status(ACTUATOR_RIGHT); ASSERT_EQ(l.direction, ACT_DIR_STOP); ASSERT_EQ(r.direction, ACT_DIR_STOP); ASSERT_EQ(l.current_ma, 0); TEST_END(); } static void test_apply_invalid_id(void) { TEST_BEGIN("apply: invalid ID -> EINVAL"); (void)actuator_init(); ASSERT_EQ(actuator_apply((ActuatorId)42, 50), EPB_EINVAL); TEST_END(); } static void test_apply_pwm_out_of_range(void) { TEST_BEGIN("apply: PWM > 100% -> EINVAL"); (void)actuator_init(); ASSERT_EQ(actuator_apply(ACTUATOR_LEFT, 101), EPB_EINVAL); TEST_END(); } static void test_apply_normal(void) { TEST_BEGIN("apply normal -> direction=APPLY, pwm=80"); (void)actuator_init(); ASSERT_EQ(actuator_apply(ACTUATOR_LEFT, 80), EPB_OK); ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.direction, ACT_DIR_APPLY); ASSERT_EQ(s.pwm_percent, 80); TEST_END(); } static void test_release_normal(void) { TEST_BEGIN("release normal -> direction=RELEASE"); (void)actuator_init(); ASSERT_EQ(actuator_release(ACTUATOR_LEFT, 70), EPB_OK); ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.direction, ACT_DIR_RELEASE); TEST_END(); } static void test_isr_samples_current(void) { TEST_BEGIN("ISR-Sample setzt current_ma und peak"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); actuator_isr_1khz(ACTUATOR_LEFT, 3000); ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.current_ma, 3000); ASSERT_EQ(s.peak_current_ma, 3000); TEST_END(); } static void test_overcurrent_cutoff_after_100ms(void) { TEST_BEGIN("Overcurrent > 8 A fuer 100 ms -> STOP + overcurrent flag"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); /* 100 Samples (= 100 ms bei 1 kHz) ueber 8 A */ for (int i = 0; i < 100; ++i) { actuator_isr_1khz(ACTUATOR_LEFT, 8500); } ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.direction, ACT_DIR_STOP); ASSERT_TRUE(s.overcurrent); ASSERT_EQ(s.last_error, EPB_EOVERCURRENT); TEST_END(); } static void test_overcurrent_below_window_no_cutoff(void) { TEST_BEGIN("Overcurrent < 100 ms loest noch nicht aus"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); for (int i = 0; i < 50; ++i) { actuator_isr_1khz(ACTUATOR_LEFT, 8500); } ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.direction, ACT_DIR_APPLY); ASSERT_TRUE(!s.overcurrent); TEST_END(); } static void test_overcurrent_blocks_subsequent_apply(void) { TEST_BEGIN("nach Overcurrent: weiterer apply -> EOVERCURRENT"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); for (int i = 0; i < 120; ++i) { actuator_isr_1khz(ACTUATOR_LEFT, 9000); } EpbStatus rc = actuator_apply(ACTUATOR_LEFT, 80); ASSERT_EQ(rc, EPB_EOVERCURRENT); TEST_END(); } static void test_clamping_force_estimate(void) { TEST_BEGIN("Klemmkraft-Schaetzung aus Peak-Strom (SWE-015)"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); actuator_isr_1khz(ACTUATOR_LEFT, 4000); /* 4 A Peak */ actuator_isr_1khz(ACTUATOR_LEFT, 3500); /* danach niedriger */ ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); /* F = (4000 * 2500) / 1000 = 10000 N */ ASSERT_EQ(s.clamping_force_n, 10000); TEST_END(); } static void test_stop_clears_pwm(void) { TEST_BEGIN("stop -> direction=STOP, pwm=0"); (void)actuator_init(); (void)actuator_apply(ACTUATOR_LEFT, 80); (void)actuator_stop(ACTUATOR_LEFT); ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT); ASSERT_EQ(s.direction, ACT_DIR_STOP); ASSERT_EQ(s.pwm_percent, 0); TEST_END(); } int main(void) { printf("== test_actuator_driver ==\n"); test_init(); test_apply_invalid_id(); test_apply_pwm_out_of_range(); test_apply_normal(); test_release_normal(); test_isr_samples_current(); test_overcurrent_cutoff_after_100ms(); test_overcurrent_below_window_no_cutoff(); test_overcurrent_blocks_subsequent_apply(); test_clamping_force_estimate(); test_stop_clears_pwm(); TEST_SUMMARY(); }