MCU
Loading...
Searching...
No Matches
tc_mux_v2_testing.h
Go to the documentation of this file.
1#ifndef __TC_MUX_V2_TESTING_H__
2#define __TC_MUX_V2_TESTING_H__
3
5#include "TorqueControllers.h"
7#include "gtest/gtest.h"
8
9
10
11// TODO
12// - [x] test to ensure that the size checking for desired modes works and failes properly
13template <typename quad_array_type>
14void set_four_outputs(quad_array_type &out, float val)
15{
16 out[0] = val;
17 out[1] = val;
18 out[2] = val;
19 out[3] = val;
20}
21
22template <typename controller_type>
23void set_outputs(controller_type &controller, float mps, float torque)
24{
25 controller.output.command.speeds_rpm[0] = METERS_PER_SECOND_TO_RPM * mps;
26 controller.output.command.speeds_rpm[1] = METERS_PER_SECOND_TO_RPM * mps;
27 controller.output.command.speeds_rpm[2] = METERS_PER_SECOND_TO_RPM * mps;
28 controller.output.command.speeds_rpm[3] = METERS_PER_SECOND_TO_RPM * mps;
29 controller.output.command.inverter_torque_limit[0] = torque;
30 controller.output.command.inverter_torque_limit[1] = torque;
31 controller.output.command.inverter_torque_limit[2] = torque;
32 controller.output.command.inverter_torque_limit[3] = torque;
33}
34template <typename controller_type>
35void set_output_rpm(controller_type &controller, float rpm, float torque)
36{
37 controller.output.command.speeds_rpm[0] = rpm;
38 controller.output.command.speeds_rpm[1] = rpm;
39 controller.output.command.speeds_rpm[2] = rpm;
40 controller.output.command.speeds_rpm[3] = rpm;
41 controller.output.command.inverter_torque_limit[0] = torque;
42 controller.output.command.inverter_torque_limit[1] = torque;
43 controller.output.command.inverter_torque_limit[2] = torque;
44 controller.output.command.inverter_torque_limit[3] = torque;
45}
46TEST(TorqueControllerMuxTesting, test_construction)
47{
48 TestControllerType inst1, inst2;
49 TorqueControllerMux<2> test({static_cast<Controller *>(&inst1), static_cast<Controller *>(&inst2)}, {false, false});
50}
51
52TEST(TorqueControllerMuxTesting, test_invalid_controller_request_error)
53{
54 TestControllerType inst1, inst2;
55 TorqueControllerMux<2> test({static_cast<Controller *>(&inst1), static_cast<Controller *>(&inst2)}, {false, false});
56 SharedCarState_s state({}, {}, {}, {}, {}, {}, {}, {});
57 auto res = test.getDrivetrainCommand(ControllerMode_e::MODE_2, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
58
59 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::ERROR_CONTROLLER_INDEX_OUT_OF_BOUNDS);
60 for (int i =0; i< 4; i++)
61 {
62
63 ASSERT_EQ(res.speeds_rpm[i], 0.0);
64 ASSERT_EQ(res.inverter_torque_limit[i], 0.0);
65 }
66}
67
68
69// ensure that swapping to a controller that has a higher desired output speed than previously
70// commanded that we dont switch
71TEST(TorqueControllerMuxTesting, test_controller_output_swap_logic)
72{
73 TestControllerType inst1, inst2;
74 set_outputs(inst1, 0, 1);
75 set_outputs(inst2, 6, 1);
76 TorqueControllerMux<2> test({static_cast<Controller *>(&inst1), static_cast<Controller *>(&inst2)}, {false, false});
77 SharedCarState_s state({}, {}, {}, {}, {}, {}, {}, {});
78 set_four_outputs(state.drivetrain_data.measuredSpeeds, 10000.0);
79
80 state.pedals_data = {};
81 state.vn_data = {};
82
83 auto out1 = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
84
85 // auto out1 = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
86 out1 = test.getDrivetrainCommand(ControllerMode_e::MODE_1, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
87
88 ASSERT_EQ(test.get_tc_mux_status().active_controller_mode, ControllerMode_e::MODE_0);
89 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::ERROR_SPEED_DIFF_TOO_HIGH);
90
91 set_outputs(inst1, 0, 1);
92 set_outputs(inst2, 0, 1);
93 set_four_outputs(state.drivetrain_data.measuredSpeeds, 0);
94
95 out1 = test.getDrivetrainCommand(ControllerMode_e::MODE_1, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
96
97 ASSERT_EQ(test.get_tc_mux_status().active_controller_mode, ControllerMode_e::MODE_1);
98 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::NO_ERROR);
99}
100
101TEST(TorqueControllerMuxTesting, test_torque_diff_swap_limit)
102{
103 TestControllerType inst1, inst2;
104 set_outputs(inst1, 0.1, 1);
105 set_outputs(inst2, 3, 10);
106 TorqueControllerMux<2> test({static_cast<Controller *>(&inst1), static_cast<Controller *>(&inst2)}, {false, false});
107 SharedCarState_s state({}, {}, {}, {}, {}, {}, {}, {});
108
109 auto out1 = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_FULL_TORQUE, state);
111 ASSERT_EQ(test.get_tc_mux_status().active_controller_mode, ControllerMode_e::MODE_0);
112 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::ERROR_TORQUE_DIFF_TOO_HIGH);
113
114 // tick it a bunch of times
121
122 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::ERROR_TORQUE_DIFF_TOO_HIGH);
123
124 ASSERT_EQ(test.get_tc_mux_status().active_controller_mode, ControllerMode_e::MODE_0);
125
126 ASSERT_EQ(out1.inverter_torque_limit[0], 1);
127 ASSERT_EQ(out1.inverter_torque_limit[1], 1);
128 ASSERT_EQ(out1.inverter_torque_limit[2], 1);
129 ASSERT_EQ(out1.inverter_torque_limit[3], 1);
130}
131
132TEST(TorqueControllerMuxTesting, test_construction_with_new_controller_orgs)
133{
134 // mode 0
136 // mode 1
138 // mode 2
139 DummyQueue_s q;
140 CASESystem<DummyQueue_s> case_sys(&q, 100, 70, 550, {});
141 TorqueControllerCASEWrapper<DummyQueue_s> case_wrapper(&case_sys);
142
143 // mode 3
145 // mode 4
146 TorqueControllerSlipLaunch slip_launch;
147
150 static_cast<Controller *>(&tc_vec),
151 static_cast<Controller *>(&case_wrapper),
152 static_cast<Controller *>(&simple_launch),
153 static_cast<Controller *>(&slip_launch)},
154 {false, false, true, false, false});
155}
156
157TEST(TorqueControllerMuxTesting, test_mode0_evaluation)
158{
159
160 float max_torque = 21.42;
161 // mode 0
163 // mode 1
165 // mode 2
166 DummyQueue_s q;
167 CASESystem<DummyQueue_s> case_sys(&q, 100, 70, 550, {});
168 TorqueControllerCASEWrapper<DummyQueue_s> case_wrapper(&case_sys);
169
170 // mode 3
172 // mode 4
173 TorqueControllerSlipLaunch slip_launch;
175 static_cast<Controller *>(&tc_vec),
176 static_cast<Controller *>(&case_wrapper),
177 static_cast<Controller *>(&simple_launch),
178 static_cast<Controller *>(&slip_launch)},
179 {false, true, false, false, false});
180 SharedCarState_s mode_0_input_state({}, {}, {}, {}, {.accelPercent = 0.5f, .brakePercent = 0.0f, .regenPercent = 0.0}, {}, {}, {});
181
183 ASSERT_NEAR(out.inverter_torque_limit[0], (max_torque / 2), 0.01);
184 ASSERT_NEAR(out.inverter_torque_limit[1], (max_torque / 2), 0.01);
185 ASSERT_NEAR(out.inverter_torque_limit[2], (max_torque / 2), 0.01);
186 ASSERT_NEAR(out.inverter_torque_limit[3], (max_torque / 2), 0.01);
187
188 mode_0_input_state = {{}, {}, {}, {}, {.accelPercent = 0.0f, .brakePercent = 0.0f, .regenPercent = 0.0}, {}, {}, {}};
190 ASSERT_EQ(out.inverter_torque_limit[0], 0);
191 ASSERT_EQ(out.inverter_torque_limit[1], 0);
192 ASSERT_EQ(out.inverter_torque_limit[2], 0);
193 ASSERT_EQ(out.inverter_torque_limit[3], 0);
194
195 // out = torque_controller_mux.getDrivetrainCommand(ControllerMode_e::MODE_1, TorqueLimit_e::TCMUX_FULL_TORQUE, mode_1_input_state);
196}
197
198TEST(TorqueControllerMuxTesting, test_power_limit)
199{
200 TestControllerType inst1;
201 set_output_rpm(inst1, 20000, 10.0);
202 TorqueControllerMux<1> test({static_cast<Controller *>(&inst1)}, {false});
203
204 DrivetrainDynamicReport_s drivetrain_data = {};
205 for (int i = 0; i < 4; i++)
206 {
207 drivetrain_data.measuredSpeeds[i] = 500.0f;
208 }
209 SharedCarState_s mode_0_input_state({}, {}, drivetrain_data, {}, {.accelPercent = 0.5f, .brakePercent = 0.0f, .regenPercent = 0.0}, {}, {} , {});
210
211 DrivetrainCommand_s res = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_FULL_TORQUE, mode_0_input_state);
212
213 for (int i = 0; i < 4; i++)
214 {
215 ASSERT_EQ(res.inverter_torque_limit[i], 10.0f);
216 }
217 for (int i = 0; i < 4; i++)
218 {
219 drivetrain_data.measuredSpeeds[i] = 20000.0f;
220 }
221 set_output_rpm(inst1, 20000, 21.0);
222
223 SharedCarState_s mode_0_input_state_high_power({}, {}, drivetrain_data, {}, {.accelPercent = 1.0f, .brakePercent = 0.0f, .regenPercent = 0.0}, {}, {}, {});
224 res = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_FULL_TORQUE, mode_0_input_state_high_power);
225
226 for (int i = 0; i < 4; i++)
227 {
228 ASSERT_LT(res.inverter_torque_limit[i], 7.6); // hardcoded value based on online calculator
229 }
230}
231
232TEST(TorqueControllerMuxTesting, test_torque_limit)
233{
234
235 TestControllerType inst1;
236
237 set_output_rpm(inst1, 500, 10.0);
239 TorqueControllerMux<1> test({static_cast<Controller *>(&inst1)}, {false});
240
241 DrivetrainDynamicReport_s drivetrain_data = {};
242 for (int i = 0; i < 4; i++)
243 {
244 drivetrain_data.measuredSpeeds[i] = 500.0f;
245 }
246
247 SharedCarState_s mode_0_input_state({}, {}, drivetrain_data, {}, {.accelPercent = 0.5f, .brakePercent = 0.0f, .regenPercent = 0.0}, {}, {}, {});
248
249 auto drive_command = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_LOW_TORQUE, mode_0_input_state);
250
251 ASSERT_EQ(drive_command.inverter_torque_limit[0], 5.0f);
252 ASSERT_EQ(drive_command.inverter_torque_limit[1], 10.0f);
253 ASSERT_EQ(drive_command.inverter_torque_limit[2], 10.0f);
254 ASSERT_EQ(drive_command.inverter_torque_limit[3], 10.0f);
255
256 set_output_rpm(inst1, 500, 20.0);
258
259 drive_command = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_LOW_TORQUE, mode_0_input_state);
260
261 ASSERT_LT(drive_command.inverter_torque_limit[0], 3.5f);
262 ASSERT_LT(drive_command.inverter_torque_limit[1], 12.5f);
263 ASSERT_LT(drive_command.inverter_torque_limit[2], 12.5f);
264 ASSERT_LT(drive_command.inverter_torque_limit[3], 12.5f);
265
266 printf("torque 1: %.2f\n", drive_command.inverter_torque_limit[0]);
267 printf("torque 2: %.2f\n", drive_command.inverter_torque_limit[1]);
268 printf("torque 3: %.2f\n", drive_command.inverter_torque_limit[2]);
269 printf("torque 4: %.2f\n", drive_command.inverter_torque_limit[3]);
270}
271
272TEST(TorqueControllerMuxTesting, test_null_pointer_error_state)
273{
274 TorqueControllerMux<1> test({nullptr}, {true});
275 SharedCarState_s state({}, {}, {}, {}, {}, {}, {}, {});
276 auto res = test.getDrivetrainCommand(ControllerMode_e::MODE_0, TorqueLimit_e::TCMUX_LOW_TORQUE, state);
277 for (int i = 0; i < 4; i++)
278 {
279 ASSERT_EQ(res.inverter_torque_limit[i], 0.0f);
280 ASSERT_EQ(res.speeds_rpm[i], 0.0f);
281 }
282 ASSERT_EQ(test.get_tc_mux_status().active_error, TorqueControllerMuxError::ERROR_CONTROLLER_NULL_POINTER);
283}
284#endif // __TC_MUX_V2_TESTING_H__
constexpr const float METERS_PER_SECOND_TO_RPM
this class with both take in sensor inputs as well as handle calculations for various derived states ...
Definition: CASESystem.h:97
Base class for all controllers, which define drivetrain command containing different variations of
TorqueControllerOutput_s output
makes CASE system a part of Controller hierarchy for use in TC Mux
DrivetrainCommand_s getDrivetrainCommand(ControllerMode_e requested_controller_type, TorqueLimit_e controller_command_torque_limit, const SharedCarState_s &input_state)
function that evaluates the mux, controllers and gets the active command
TorqueControllerSimple tc_simple(1.0f, 1.0f)
TCMuxType torque_controller_mux({static_cast< Controller * >(&tc_simple), static_cast< Controller * >(&tc_vec), static_cast< Controller * >(&case_wrapper), static_cast< Controller * >(&simple_launch), static_cast< Controller * >(&db_controller)}, {false, false, true, false, true})
TorqueControllerLoadCellVectoring tc_vec
Definition: main.cpp:308
TorqueControllerSimpleLaunch simple_launch
Definition: main.cpp:313
Stores setpoints for a command to the Drivetrain, containing speed and torque setpoints for each moto...
float inverter_torque_limit[NUM_MOTORS]
car state struct that contains state of everything about the car including
DrivetrainCommand_s command
void set_outputs(controller_type &controller, float mps, float torque)
void set_output_rpm(controller_type &controller, float rpm, float torque)
void set_four_outputs(quad_array_type &out, float val)
TEST(TorqueControllerMuxTesting, test_construction)