LCOV - code coverage report
Current view: top level - tests/unit - test_actuator_driver.c (source / functions) Hit Total Coverage
Test: coverage.clean.info Lines: 116 116 100.0 %
Date: 2026-05-12 07:34:16 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @file test_actuator_driver.c
       3             :  * @brief Unit-Tests fuer den Actuator-Driver.
       4             :  *
       5             :  * @reqs SWE-006 SWE-013 SWE-014 SWE-015
       6             :  * @arch SWA-003
       7             :  */
       8             : #include "../unit_test_framework.h"
       9             : #include "../../src/actuator_driver.h"
      10             : 
      11             : TestStats g_test_stats = {0, 0};
      12             : 
      13           2 : static void test_init(void)
      14             : {
      15           2 :     TEST_BEGIN("init -> beide Aktoren STOP, 0 mA");
      16           2 :     ASSERT_EQ(actuator_init(), EPB_OK);
      17           2 :     ActuatorStatus l = actuator_get_status(ACTUATOR_LEFT);
      18           2 :     ActuatorStatus r = actuator_get_status(ACTUATOR_RIGHT);
      19           2 :     ASSERT_EQ(l.direction, ACT_DIR_STOP);
      20           2 :     ASSERT_EQ(r.direction, ACT_DIR_STOP);
      21           2 :     ASSERT_EQ(l.current_ma, 0);
      22           2 :     TEST_END();
      23           2 : }
      24             : 
      25           2 : static void test_apply_invalid_id(void)
      26             : {
      27           2 :     TEST_BEGIN("apply: invalid ID -> EINVAL");
      28           2 :     (void)actuator_init();
      29           2 :     ASSERT_EQ(actuator_apply((ActuatorId)42, 50), EPB_EINVAL);
      30           2 :     TEST_END();
      31           2 : }
      32             : 
      33           2 : static void test_apply_pwm_out_of_range(void)
      34             : {
      35           2 :     TEST_BEGIN("apply: PWM > 100% -> EINVAL");
      36           2 :     (void)actuator_init();
      37           2 :     ASSERT_EQ(actuator_apply(ACTUATOR_LEFT, 101), EPB_EINVAL);
      38           2 :     TEST_END();
      39           2 : }
      40             : 
      41           2 : static void test_apply_normal(void)
      42             : {
      43           2 :     TEST_BEGIN("apply normal -> direction=APPLY, pwm=80");
      44           2 :     (void)actuator_init();
      45           2 :     ASSERT_EQ(actuator_apply(ACTUATOR_LEFT, 80), EPB_OK);
      46           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
      47           2 :     ASSERT_EQ(s.direction, ACT_DIR_APPLY);
      48           2 :     ASSERT_EQ(s.pwm_percent, 80);
      49           2 :     TEST_END();
      50           2 : }
      51             : 
      52           2 : static void test_release_normal(void)
      53             : {
      54           2 :     TEST_BEGIN("release normal -> direction=RELEASE");
      55           2 :     (void)actuator_init();
      56           2 :     ASSERT_EQ(actuator_release(ACTUATOR_LEFT, 70), EPB_OK);
      57           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
      58           2 :     ASSERT_EQ(s.direction, ACT_DIR_RELEASE);
      59           2 :     TEST_END();
      60           2 : }
      61             : 
      62           2 : static void test_isr_samples_current(void)
      63             : {
      64           2 :     TEST_BEGIN("ISR-Sample setzt current_ma und peak");
      65           2 :     (void)actuator_init();
      66           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
      67           2 :     actuator_isr_1khz(ACTUATOR_LEFT, 3000);
      68           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
      69           2 :     ASSERT_EQ(s.current_ma, 3000);
      70           2 :     ASSERT_EQ(s.peak_current_ma, 3000);
      71           2 :     TEST_END();
      72           2 : }
      73             : 
      74           2 : static void test_overcurrent_cutoff_after_100ms(void)
      75             : {
      76           2 :     TEST_BEGIN("Overcurrent > 8 A fuer 100 ms -> STOP + overcurrent flag");
      77           2 :     (void)actuator_init();
      78           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
      79             :     /* 100 Samples (= 100 ms bei 1 kHz) ueber 8 A */
      80         202 :     for (int i = 0; i < 100; ++i) {
      81         200 :         actuator_isr_1khz(ACTUATOR_LEFT, 8500);
      82             :     }
      83           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
      84           2 :     ASSERT_EQ(s.direction, ACT_DIR_STOP);
      85           2 :     ASSERT_TRUE(s.overcurrent);
      86           2 :     ASSERT_EQ(s.last_error, EPB_EOVERCURRENT);
      87           2 :     TEST_END();
      88           2 : }
      89             : 
      90           2 : static void test_overcurrent_below_window_no_cutoff(void)
      91             : {
      92           2 :     TEST_BEGIN("Overcurrent < 100 ms loest noch nicht aus");
      93           2 :     (void)actuator_init();
      94           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
      95         102 :     for (int i = 0; i < 50; ++i) {
      96         100 :         actuator_isr_1khz(ACTUATOR_LEFT, 8500);
      97             :     }
      98           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
      99           2 :     ASSERT_EQ(s.direction, ACT_DIR_APPLY);
     100           2 :     ASSERT_TRUE(!s.overcurrent);
     101           2 :     TEST_END();
     102           2 : }
     103             : 
     104           2 : static void test_overcurrent_blocks_subsequent_apply(void)
     105             : {
     106           2 :     TEST_BEGIN("nach Overcurrent: weiterer apply -> EOVERCURRENT");
     107           2 :     (void)actuator_init();
     108           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
     109         242 :     for (int i = 0; i < 120; ++i) {
     110         240 :         actuator_isr_1khz(ACTUATOR_LEFT, 9000);
     111             :     }
     112           2 :     EpbStatus rc = actuator_apply(ACTUATOR_LEFT, 80);
     113           2 :     ASSERT_EQ(rc, EPB_EOVERCURRENT);
     114           2 :     TEST_END();
     115           2 : }
     116             : 
     117           2 : static void test_clamping_force_estimate(void)
     118             : {
     119           2 :     TEST_BEGIN("Klemmkraft-Schaetzung aus Peak-Strom (SWE-015)");
     120           2 :     (void)actuator_init();
     121           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
     122           2 :     actuator_isr_1khz(ACTUATOR_LEFT, 4000);  /* 4 A Peak */
     123           2 :     actuator_isr_1khz(ACTUATOR_LEFT, 3500);  /* danach niedriger */
     124           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
     125             :     /* F = (4000 * 2500) / 1000 = 10000 N */
     126           2 :     ASSERT_EQ(s.clamping_force_n, 10000);
     127           2 :     TEST_END();
     128           2 : }
     129             : 
     130           2 : static void test_stop_clears_pwm(void)
     131             : {
     132           2 :     TEST_BEGIN("stop -> direction=STOP, pwm=0");
     133           2 :     (void)actuator_init();
     134           2 :     (void)actuator_apply(ACTUATOR_LEFT, 80);
     135           2 :     (void)actuator_stop(ACTUATOR_LEFT);
     136           2 :     ActuatorStatus s = actuator_get_status(ACTUATOR_LEFT);
     137           2 :     ASSERT_EQ(s.direction, ACT_DIR_STOP);
     138           2 :     ASSERT_EQ(s.pwm_percent, 0);
     139           2 :     TEST_END();
     140           2 : }
     141             : 
     142           2 : int main(void)
     143             : {
     144           2 :     printf("== test_actuator_driver ==\n");
     145           2 :     test_init();
     146           2 :     test_apply_invalid_id();
     147           2 :     test_apply_pwm_out_of_range();
     148           2 :     test_apply_normal();
     149           2 :     test_release_normal();
     150           2 :     test_isr_samples_current();
     151           2 :     test_overcurrent_cutoff_after_100ms();
     152           2 :     test_overcurrent_below_window_no_cutoff();
     153           2 :     test_overcurrent_blocks_subsequent_apply();
     154           2 :     test_clamping_force_estimate();
     155           2 :     test_stop_clears_pwm();
     156           2 :     TEST_SUMMARY();
     157             : }

Generated by: LCOV version 1.14