MCU
Loading...
Searching...
No Matches
state_machine_test.h
Go to the documentation of this file.
1#ifndef STATE_MACHINE_TEST
2#define STATE_MACHINE_TEST
3#include <gtest/gtest.h>
4#include <gmock/gmock.h>
5#include "MCUStateMachine.h"
7
9{
11};
13{
14public:
19
21
22 bool handle_inverter_startup(unsigned long cm) { return drivetrain_inited_; };
23 // check to see if init time limit has passed
24 bool inverter_init_timeout(unsigned long curr_time){};
25
27 void disable(){};
29
32};
33
34SharedCarState_s dummy_state({}, {}, {}, {}, {}, {}, {}, {});
36
37void handle_startup(MCUStateMachine<DrivetrainMock> &state_machine, unsigned long sys_time, DrivetrainMock &drivetrain, PedalsSystem &pedals, DashboardInterface &dash_interface)
38{
39 // ticking without hv over threshold testing and ensuring the tractive system not active still
40 auto sys_time2 = sys_time;
41
42 drivetrain.hv_thresh_ = true;
43
44 state_machine.tick_state_machine(sys_time, dummy_state);
45 // hv going over threshold -> tractive system active
46 drivetrain.hv_thresh_ = true;
47 sys_time2 += 1;
48 state_machine.tick_state_machine(sys_time, dummy_state);
49 sys_time2 += 1;
50 dash_interface.start_button_status_ = true;
51 AnalogConversion_s pedals1_data;
52 pedals1_data.raw = 0;
53 pedals1_data.conversion = 0;
54 pedals1_data.status = AnalogSensorStatus_e::ANALOG_SENSOR_GOOD;
55 auto pedals2_data = pedals1_data;
56
57 AnalogConversion_s pedals3_data;
58 pedals3_data.raw = 3000;
59 pedals3_data.conversion = 1.0;
60 pedals3_data.status = pedals1_data.status;
61 auto pedals4_data = pedals3_data;
62 pedals.tick(SysTick_s{}, pedals1_data, pedals2_data, pedals3_data, pedals4_data);
63 // get to enabling inverters
64 state_machine.tick_state_machine(sys_time, dummy_state);
65}
66
67TEST(MCUStateMachineTesting, test_state_machine_init_tick)
68{
69
70 int mock;
71 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
74 PedalsSystem pedals({}, {});
75 DashboardInterface dash_interface;
76 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
77 SafetySystem ss(&ams, 0);
78 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
79 unsigned long sys_time = 1000;
80 EXPECT_EQ(state_machine.get_state(), CAR_STATE::STARTUP);
81 state_machine.tick_state_machine(sys_time, dummy_state);
82 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
83}
84
85TEST(MCUStateMachineTesting, test_state_machine_tractive_system_activation)
86{
87 int mock;
88 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
91 PedalsSystem pedals({}, {});
92 DashboardInterface dash_interface;
93
94 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
95
96 SafetySystem ss(&ams, 0);
97 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
98 unsigned long sys_time = 1000;
99
100 // ticking without hv over threshold testing and ensuring the tractive system not active still
101 state_machine.tick_state_machine(sys_time, dummy_state);
102 sys_time += 1;
103 drivetrain.hv_thresh_ = false;
104 state_machine.tick_state_machine(sys_time, dummy_state);
105 sys_time += 1;
106 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
107
108 // hv going over threshold -> tractive system
109 drivetrain.hv_thresh_ = true;
110 sys_time += 1;
111 state_machine.tick_state_machine(sys_time, dummy_state);
112 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_ACTIVE);
113
114 // hv going under thresh -> tractive system not active
115 drivetrain.hv_thresh_ = false;
116 sys_time += 1;
117 state_machine.tick_state_machine(sys_time, dummy_state);
118 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
119}
120
121TEST(MCUStateMachineTesting, test_state_machine_tractive_system_enabling)
122{
123 unsigned long sys_time = 1000;
124
125 int mock;
126 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
129 PedalsSystem pedals({}, {});
130 DashboardInterface dash_interface;
131
132 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
133 ;
134 SafetySystem ss(&ams, 0);
135 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
136
137 // ticking without hv over threshold testing and ensuring the tractive system not active still
138 state_machine.tick_state_machine(sys_time, dummy_state);
139 sys_time += 1;
140 drivetrain.hv_thresh_ = false;
141 state_machine.tick_state_machine(sys_time, dummy_state);
142 sys_time += 1;
143 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
144
145 // hv going over threshold -> tractive system
146 drivetrain.hv_thresh_ = true;
147 sys_time += 1;
148 state_machine.tick_state_machine(sys_time, dummy_state);
149 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_ACTIVE);
150
151 sys_time += 1;
152 dash_interface.start_button_status_ = true;
153
154 AnalogConversion_s pedals1_data;
155 pedals1_data.raw = 0;
156 pedals1_data.conversion = 0;
157 pedals1_data.status = AnalogSensorStatus_e::ANALOG_SENSOR_GOOD;
158 auto pedals2_data = pedals1_data;
159
160 AnalogConversion_s pedals3_data;
161 pedals3_data.raw = 3000;
162 pedals3_data.conversion = 1.0;
163 pedals3_data.status = pedals1_data.status;
164 auto pedals4_data = pedals3_data;
165 pedals.tick(SysTick_s{}, pedals1_data, pedals2_data, pedals3_data, pedals4_data);
166 state_machine.tick_state_machine(sys_time, dummy_state);
167 EXPECT_EQ(state_machine.get_state(), CAR_STATE::ENABLING_INVERTERS);
168}
169
170// test getting into and out of the waiting RTD and ensuring it stays within the state when we want it to
171TEST(MCUStateMachineTesting, test_state_machine_ready_to_drive_alert)
172{
173 int mock;
174 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
177 PedalsSystem pedals({}, {});
178 DashboardInterface dash_interface;
179
180 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
181 SafetySystem ss(&ams, 0);
182 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
183
184 unsigned long sys_time = 1000;
185 handle_startup(state_machine, sys_time, drivetrain, pedals, dash_interface);
186 EXPECT_EQ(state_machine.get_state(), CAR_STATE::ENABLING_INVERTERS);
187
188 drivetrain.hv_thresh_ = true;
189 drivetrain.drivetrain_inited_ = true;
190 state_machine.tick_state_machine(sys_time, dummy_state);
191 EXPECT_EQ(state_machine.get_state(), CAR_STATE::WAITING_READY_TO_DRIVE_SOUND);
192 sys_time += 20;
193
194 dash_interface.buzzer = true;
195 state_machine.tick_state_machine(sys_time, dummy_state);
196
197 EXPECT_EQ(state_machine.get_state(), CAR_STATE::WAITING_READY_TO_DRIVE_SOUND);
198 sys_time += 35;
199
200 dash_interface.buzzer = false;
201 state_machine.tick_state_machine(sys_time, dummy_state);
202
203 EXPECT_EQ(state_machine.get_state(), CAR_STATE::READY_TO_DRIVE);
204}
205
206TEST(MCUStateMachineTesting, test_state_machine_ready_to_drive_alert_leaving)
207{
208 int mock;
209 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
212 PedalsSystem pedals({}, {});
213 DashboardInterface dash_interface;
214 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
215 ;
216
217 SafetySystem ss(&ams, 0);
218 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
219
220 unsigned long sys_time = 1000;
221
222 drivetrain.hv_thresh_ = true;
223 handle_startup(state_machine, sys_time, drivetrain, pedals, dash_interface);
224 EXPECT_EQ(state_machine.get_state(), CAR_STATE::ENABLING_INVERTERS);
225
226 drivetrain.drivetrain_inited_ = true;
227 state_machine.tick_state_machine(sys_time, dummy_state);
228
229 buzzer.activate_buzzer(sys_time);
230 EXPECT_EQ(state_machine.get_state(), CAR_STATE::WAITING_READY_TO_DRIVE_SOUND);
231 sys_time += 20;
232
233 drivetrain.hv_thresh_ = false;
234 state_machine.tick_state_machine(sys_time, dummy_state);
235
236 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
237}
238
239// state transitions out of RTD state
240TEST(MCUStateMachineTesting, test_state_machine_rtd_state_transitions_to_ts_active)
241{
242
243 int mock;
244 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
247 drivetrain.drivetrain_error_ = false;
248 PedalsSystem pedals({}, {});
249 DashboardInterface dash_interface;
250 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
251 ;
252
253 SafetySystem ss(&ams, 0);
254 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
255
256 unsigned long sys_time = 1000;
257
258 handle_startup(state_machine, sys_time, drivetrain, pedals, dash_interface);
259 EXPECT_EQ(state_machine.get_state(), CAR_STATE::ENABLING_INVERTERS);
260
261 sys_time += 70;
262 drivetrain.drivetrain_inited_ = true;
263 drivetrain.hv_thresh_ = true;
264 state_machine.tick_state_machine(sys_time, dummy_state);
265 EXPECT_EQ(state_machine.get_state(), CAR_STATE::WAITING_READY_TO_DRIVE_SOUND);
266 sys_time += 70;
267 drivetrain.hv_thresh_ = true;
268
269 dash_interface.buzzer = true;
270 state_machine.tick_state_machine(sys_time, dummy_state);
271 dash_interface.buzzer = false;
272 state_machine.tick_state_machine(sys_time, dummy_state);
273
274 EXPECT_EQ(state_machine.get_state(), CAR_STATE::READY_TO_DRIVE);
275
276 state_machine.tick_state_machine(sys_time, dummy_state);
277
278 EXPECT_EQ(state_machine.get_state(), CAR_STATE::READY_TO_DRIVE);
279
280 drivetrain.drivetrain_error_ = true;
281
282 state_machine.tick_state_machine(sys_time, dummy_state);
283
284 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_ACTIVE);
285}
286
287TEST(MCUStateMachineTesting, test_state_machine_rtd_state_transitions_to_ts_not_active)
288{
289
290 int mock;
291 AMSInterface ams(&mock, 0, 0, 0, 0, 0);
294 drivetrain.drivetrain_error_ = false;
295 PedalsSystem pedals({}, {});
296 DashboardInterface dash_interface;
297
298 TCMuxType tc_mux({static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c), static_cast<Controller *>(&c)}, {true, true, true, true, true});
299 ;
300
301 SafetySystem ss(&ams, 0);
302 MCUStateMachine<DrivetrainMock> state_machine(&buzzer, &drivetrain, &dash_interface, &pedals, &tc_mux, &ss);
303
304 unsigned long sys_time = 1000;
305
306 handle_startup(state_machine, sys_time, drivetrain, pedals, dash_interface);
307 EXPECT_EQ(state_machine.get_state(), CAR_STATE::ENABLING_INVERTERS);
308
309 sys_time += 70;
310 drivetrain.drivetrain_inited_ = true;
311 drivetrain.hv_thresh_ = true;
312 state_machine.tick_state_machine(sys_time, dummy_state);
313 EXPECT_EQ(state_machine.get_state(), CAR_STATE::WAITING_READY_TO_DRIVE_SOUND);
314 sys_time += 70;
315 drivetrain.hv_thresh_ = true;
316
317 dash_interface.buzzer = true;
318 state_machine.tick_state_machine(sys_time, dummy_state);
319 dash_interface.buzzer = false;
320 state_machine.tick_state_machine(sys_time, dummy_state);
321
322 EXPECT_EQ(state_machine.get_state(), CAR_STATE::READY_TO_DRIVE);
323
324 state_machine.tick_state_machine(sys_time, dummy_state);
325
326 EXPECT_EQ(state_machine.get_state(), CAR_STATE::READY_TO_DRIVE);
327
328 // drivetrain.drivetrain_error_ = true;
329
330 drivetrain.hv_thresh_ = false;
331 state_machine.tick_state_machine(sys_time, dummy_state);
332
333 EXPECT_EQ(state_machine.get_state(), CAR_STATE::TRACTIVE_SYSTEM_NOT_ACTIVE);
334}
335
336#endif /* STATE_MACHINE_TEST */
@ WAITING_READY_TO_DRIVE_SOUND
@ TRACTIVE_SYSTEM_NOT_ACTIVE
@ TRACTIVE_SYSTEM_ACTIVE
@ ENABLING_INVERTERS
this class is for interfacing with the AMS (accumulator management system)
Definition: AMSInterface.h:27
void activate_buzzer(unsigned long act_time)
Definition: Buzzer.cpp:8
Base class for all controllers, which define drivetrain command containing different variations of
bool hv_over_threshold_on_drivetrain()
void command_drivetrain_no_torque()
void command_drivetrain(const DrivetrainCommand_s &data)
bool handle_inverter_startup(unsigned long cm)
bool drivetrain_error_occured()
bool inverter_init_timeout(unsigned long curr_time)
TorqueControllerOutput_s evaluate(const SharedCarState_s &state)
This mehod must be implemented by every controller in the Tc Muxer. This is called in the Muxer whene...
void tick_state_machine(unsigned long cm, const SharedCarState_s &current_car_state)
function to tick the state machine.
CAR_STATE get_state()
void tick(const SysTick_s &tick, const AnalogConversion_s &accel1, const AnalogConversion_s &accel2, const AnalogConversion_s &brake)
overloaded tick function that runs the evaluation of the pedals system. evaluates brake using only mi...
DriveSys_t drivetrain
Definition: main.cpp:223
BuzzerController buzzer(BUZZER_ON_INTERVAL)
Definition: main.cpp:325
TEST(MCUStateMachineTesting, test_state_machine_init_tick)
void handle_startup(MCUStateMachine< DrivetrainMock > &state_machine, unsigned long sys_time, DrivetrainMock &drivetrain, PedalsSystem &pedals, DashboardInterface &dash_interface)
DumbController c
SharedCarState_s dummy_state({}, {}, {}, {}, {}, {}, {}, {})
Stores setpoints for a command to the Drivetrain, containing speed and torque setpoints for each moto...
car state struct that contains state of everything about the car including
Packages drivetrain command with ready boolean to give feedback on controller successfully evaluating...