Skip to content

Commit fefe358

Browse files
committed
added tests for the encoder
1 parent 621c376 commit fefe358

2 files changed

Lines changed: 159 additions & 0 deletions

File tree

Tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ message(STATUS "Generating test executable for ST-LIB")
1919
add_executable(${STLIB_TEST_EXECUTABLE}
2020
${CMAKE_CURRENT_LIST_DIR}/../Src/HALAL/Models/SPI/SPI2.cpp
2121
${CMAKE_CURRENT_LIST_DIR}/../Src/HALAL/Models/DMA/DMA2.cpp
22+
${CMAKE_CURRENT_LIST_DIR}/Time/encoder_test.cpp
2223
${CMAKE_CURRENT_LIST_DIR}/Time/scheduler_test.cpp
2324
${CMAKE_CURRENT_LIST_DIR}/Time/timer_wrapper_test.cpp
2425
${CMAKE_CURRENT_LIST_DIR}/adc_test.cpp

Tests/Time/encoder_test.cpp

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#include <gtest/gtest.h>
2+
3+
#include "HALAL/Services/Time/TimerWrapper.hpp"
4+
#include "ST-LIB_LOW/Sensors/EncoderSensor/NewEncoderSensor.hpp"
5+
6+
namespace ST_LIB::TestErrorHandler {
7+
void reset();
8+
void set_fail_on_error(bool enabled);
9+
extern int call_count;
10+
} // namespace ST_LIB::TestErrorHandler
11+
12+
namespace {
13+
14+
constexpr ST_LIB::TimerDomain::Timer encoder_timer_decl{
15+
ST_LIB::TimerRequest::GeneralPurpose32bit_2,
16+
ST_LIB::TimerDomain::EMPTY_TIMER_NAME,
17+
ST_LIB::TimerPin{
18+
.af = ST_LIB::TimerAF::Encoder,
19+
.pin = ST_LIB::PA0,
20+
.channel = ST_LIB::TimerChannel::CHANNEL_1,
21+
},
22+
ST_LIB::TimerPin{
23+
.af = ST_LIB::TimerAF::Encoder,
24+
.pin = ST_LIB::PA1,
25+
.channel = ST_LIB::TimerChannel::CHANNEL_2,
26+
},
27+
};
28+
29+
struct MockEncoder {
30+
uint32_t counter = 1234;
31+
uint32_t initial_counter = 1234;
32+
bool direction = true;
33+
int turn_on_calls = 0;
34+
int turn_off_calls = 0;
35+
int reset_calls = 0;
36+
37+
void turn_on() { ++turn_on_calls; }
38+
void turn_off() { ++turn_off_calls; }
39+
void reset() {
40+
++reset_calls;
41+
counter = initial_counter;
42+
}
43+
uint32_t get_counter() { return counter; }
44+
bool get_direction() { return direction; }
45+
uint32_t get_initial_counter_value() { return initial_counter; }
46+
};
47+
48+
using MockSensor = ST_LIB::EncoderSensor<MockEncoder, 4>;
49+
50+
} // namespace
51+
52+
class EncoderTest : public ::testing::Test {
53+
protected:
54+
TIM_HandleTypeDef hal_tim{};
55+
ST_LIB::TimerDomain::Instance instance{};
56+
ST_LIB::TimerWrapper<encoder_timer_decl> wrapper{};
57+
58+
void SetUp() override {
59+
ST_LIB::TestErrorHandler::reset();
60+
61+
TIM2_BASE->CNT = 0U;
62+
TIM2_BASE->ARR = 0U;
63+
TIM2_BASE->PSC = 0U;
64+
TIM2_BASE->CR1 = 0U;
65+
66+
hal_tim = {};
67+
hal_tim.Instance = TIM2_BASE;
68+
hal_tim.State = HAL_TIM_STATE_READY;
69+
70+
instance.tim = TIM2_BASE;
71+
instance.hal_tim = &hal_tim;
72+
instance.timer_idx = 0U;
73+
74+
wrapper = ST_LIB::TimerWrapper<encoder_timer_decl>(&instance);
75+
ST_LIB::Encoder<encoder_timer_decl>::init(&wrapper);
76+
ST_LIB::Encoder<encoder_timer_decl>::turn_off();
77+
}
78+
};
79+
80+
TEST_F(EncoderTest, ResetUsesConfiguredInitialCounterValue) {
81+
TIM2_BASE->CNT = 17U;
82+
83+
ST_LIB::Encoder<encoder_timer_decl>::reset();
84+
85+
EXPECT_EQ(TIM2_BASE->ARR, 55000U);
86+
EXPECT_EQ(
87+
TIM2_BASE->CNT,
88+
ST_LIB::Encoder<encoder_timer_decl>::get_initial_counter_value()
89+
);
90+
}
91+
92+
TEST_F(EncoderTest, TurnOffKeepsTryingIfHALStopFails) {
93+
ST_LIB::TestErrorHandler::set_fail_on_error(false);
94+
ST_LIB::Encoder<encoder_timer_decl>::turn_on();
95+
96+
instance.hal_tim = nullptr;
97+
98+
ST_LIB::Encoder<encoder_timer_decl>::turn_off();
99+
ST_LIB::Encoder<encoder_timer_decl>::turn_off();
100+
101+
EXPECT_EQ(ST_LIB::TestErrorHandler::call_count, 2);
102+
}
103+
104+
TEST(EncoderSensorTest, ReadTreatsEncoderInitialCounterAsZeroPosition) {
105+
MockEncoder encoder{};
106+
double position = -1.0;
107+
double speed = -1.0;
108+
double acceleration = -1.0;
109+
MockSensor::Direction direction = MockSensor::BACKWARDS;
110+
111+
MockSensor sensor(
112+
encoder,
113+
0.5,
114+
0.1,
115+
&direction,
116+
&position,
117+
&speed,
118+
&acceleration
119+
);
120+
121+
sensor.read();
122+
123+
EXPECT_DOUBLE_EQ(position, 0.0);
124+
EXPECT_DOUBLE_EQ(speed, 0.0);
125+
EXPECT_DOUBLE_EQ(acceleration, 0.0);
126+
EXPECT_EQ(direction, MockSensor::FORWARD);
127+
}
128+
129+
TEST(EncoderSensorTest, ResetForwardsToEncoderAndClearsHistory) {
130+
MockEncoder encoder{};
131+
encoder.counter = 1240U;
132+
133+
double position = 0.0;
134+
double speed = 0.0;
135+
double acceleration = 0.0;
136+
MockSensor::Direction direction = MockSensor::BACKWARDS;
137+
138+
MockSensor sensor(
139+
encoder,
140+
1.0,
141+
1.0,
142+
&direction,
143+
&position,
144+
&speed,
145+
&acceleration
146+
);
147+
148+
sensor.read();
149+
ASSERT_NE(position, 0.0);
150+
151+
sensor.reset();
152+
sensor.read();
153+
154+
EXPECT_EQ(encoder.reset_calls, 1);
155+
EXPECT_DOUBLE_EQ(position, 0.0);
156+
EXPECT_DOUBLE_EQ(speed, 0.0);
157+
EXPECT_DOUBLE_EQ(acceleration, 0.0);
158+
}

0 commit comments

Comments
 (0)