tests.dashboard.main2

  1from typing import Optional
  2
  3import hil2.hil2 as hil2
  4import hil2.component as hil2_comp
  5import hil2.can_helper as can_helper
  6import mk_assert.mk_assert as mka
  7
  8import time
  9import logging
 10
 11# Consts ------------------------------------------------------------------------------#
 12PEDAL_LOW_V = 0.5 # volts read when pedal is not pressed (in normal orientation)
 13PEDAL_HIGH_V = 4.5 # volts read when pedal is fully pressed (in normal orientation)
 14PEDAL_PERCENT_V = (PEDAL_HIGH_V - PEDAL_LOW_V) / 100.0
 15
 16SLEEP_TIME = 0.01 # seconds, how long to wait before checking a CAN message
 17
 18PEDAL_MSG = "raw_throttle_brake" # note: motor "off" => throttle = 0
 19SHOCK_MSG = "shock_front"
 20
 21
 22# Helpers -----------------------------------------------------------------------------#
 23def power_cycle(h: hil2.Hil2, delay_s: float = 0.5):
 24    """
 25    Power cycle the system by turning the power off for delay_s seconds, then back on.
 26    
 27    :param pow: Power DO component (e.g. relay)
 28    :param delay_s: Time in seconds to wait with power off
 29    """
 30    pow = h.do("HIL2", "RLY1")
 31    pow.set(False)
 32    time.sleep(delay_s)
 33    pow.set(True)
 34    time.sleep(delay_s)
 35
 36def pedal_percent_to_volts_1(percent: float) -> float:
 37    """
 38    Normal linear mapping from 0-100% to volts
 39    
 40    :param percent: Percent value from 0 to 100
 41    :return: Corresponding voltage value
 42    """
 43    return PEDAL_LOW_V + percent * PEDAL_PERCENT_V
 44
 45def pedal_percent_to_volts_2(percent: float) -> float:
 46    """
 47    Inverted linear mapping from 0-100% to volts
 48    
 49    :param percent: Percent value from 0 to 100
 50    :return: Corresponding voltage value
 51    """
 52    return PEDAL_HIGH_V - percent * PEDAL_PERCENT_V
 53
 54def set_both(pedal1: hil2_comp.AO, pedal2: hil2_comp.AO, percent: float) -> None:
 55    """
 56    Set a set of two pedals to the same percent value.
 57
 58    :param pedal1: First pedal AO component (in normal orientation)
 59    :param pedal2: Second pedal AO component (in inverted orientation)
 60    :param percent: Percent value from 0 to 100
 61    """
 62    pedal1.set(pedal_percent_to_volts_1(percent))
 63    pedal2.set(pedal_percent_to_volts_2(percent))
 64
 65def check_msg(can_bus: hil2_comp.CAN, msg_name: str | int, test_prefix: str) -> Optional[can_helper.CanMessage]:
 66    msg = can_bus.get_last(msg_name)
 67    mka.assert_true(msg is not None, f"{test_prefix}: VCAN message received")
 68    return msg
 69
 70def check_brakes(msg: Optional[can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
 71    mka.assert_eqf(msg is not None and msg.data["brake"],       exp_percent, tol_v, f"{test_prefix}: brake left {exp_percent}%")
 72    mka.assert_eqf(msg is not None and msg.data["brake_right"], exp_percent, tol_v, f"{test_prefix}: brake right {exp_percent}%")
 73
 74def check_throttles_diff(msg: Optional[can_helper.CanMessage], exp_percent1: float, exp_percent2: float, tol_v: float, test_prefix: str):
 75    mka.assert_eqf(msg is not None and msg.data["throttle"],       exp_percent1, tol_v, f"{test_prefix}: throttle left {exp_percent1}%")
 76    mka.assert_eqf(msg is not None and msg.data["throttle_right"], exp_percent2, tol_v, f"{test_prefix}: throttle right {exp_percent2}%")
 77
 78def check_throttles(msg: Optional[can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
 79    check_throttles_diff(msg, exp_percent, exp_percent, tol_v, test_prefix)
 80
 81def check_uart(uart: hil2_comp.DI, test_prefix: str):
 82    for _ in range(10):
 83        if uart.get():
 84            mka.assert_true(True, f"{test_prefix}: UART activity detected")
 85            return
 86        time.sleep(0.01)
 87    mka.assert_true(False, f"{test_prefix}: UART activity detected")
 88
 89def float_range(start, stop, step):
 90    while start <= stop:
 91        yield start
 92        start += step
 93
 94def shockpots_from_voltage(v_left: float, v_right: float) -> tuple[int, int]:
 95    POT_VOLT_MAX = 3.0
 96    POT_VOLT_MIN_L = 4082.0
 97    POT_VOLT_MIN_R = 4090.0
 98    POT_MAX_DIST = 75
 99    POT_DIST_DROOP_L = 56
100    POT_DIST_DROOP_R = 56
101
102    adc_left = (v_left / POT_VOLT_MAX) * POT_VOLT_MIN_L
103    adc_right = (v_right / POT_VOLT_MAX) * POT_VOLT_MIN_R
104
105    shock_l = -1 * ((POT_MAX_DIST - int((adc_left / (POT_VOLT_MIN_L - POT_VOLT_MAX)) * POT_MAX_DIST)) - POT_DIST_DROOP_L)
106    shock_r = -1 * ((POT_MAX_DIST - int((adc_right / (POT_VOLT_MIN_R - POT_VOLT_MAX)) * POT_MAX_DIST)) - POT_DIST_DROOP_R)
107
108    return shock_l, shock_r
109
110
111# EV.4.7.2 ----------------------------------------------------------------------------#
112def ev_4_7_2_test(h: hil2.Hil2):
113    """
114    If brake is activated (5% pressed) and throttle is activated more than 25%, motor
115    must shutdown and stay shutdown until throttle is under 5%
116    
117    - brake low, throttle low, check motor on
118    - brake high, throttle low, check motor on
119    - brake high, throttle high, check motor off
120    - brake low, throttle mid, check motor off (sweep down to 5% on throttle)
121    - brake low, throttle low, check motor back on
122    """
123
124    brk1 = h.ao("Dashboard", "BRK1_RAW")
125    brk2 = h.ao("Dashboard", "BRK2_RAW")
126    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
127    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
128    vcan = h.can("HIL2", "VCAN")
129
130    # Setup: set brake and throttle to 0%
131    vcan.clear()
132    set_both(brk1, brk2, 0)
133    set_both(thrtl1, thrtl2, 0)
134    time.sleep(SLEEP_TIME)
135    msg = check_msg(vcan, PEDAL_MSG, "Setup")
136    check_brakes(msg, 0, 0.1, "Setup")
137    check_throttles(msg, 0, 0.1, "Setup")
138    time.sleep(0.1)
139    
140    # Test 1: brake low, throttle low, check motor on
141    vcan.clear()
142    set_both(brk1, brk2, 5)
143    set_both(thrtl1, thrtl2, 5)
144    time.sleep(SLEEP_TIME)
145    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle low")
146    check_brakes(vcan, 5, 0.1, "Brakes low, throttle low")
147    check_throttles(vcan, 5, 0.1, "Brakes low, throttle low")
148    time.sleep(0.1)
149
150    # Test 2: brake high, throttle low, check motor on
151    vcan.clear()
152    set_both(brk1, brk2, 50)
153    set_both(thrtl1, thrtl2, 5)
154    time.sleep(SLEEP_TIME)
155    msg = check_msg(vcan, PEDAL_MSG, "Brakes high, throttle low")
156    check_brakes(msg, 50, 0.1, "Brakes high, throttle low")
157    check_throttles(msg, 5, 0.1, "Brakes high, throttle low")
158    time.sleep(0.1)
159
160    # Test 3: brake high, throttle high, check motor off
161    vcan.clear()
162    set_both(brk1, brk2, 50)
163    set_both(thrtl1, thrtl2, 50)
164    time.sleep(SLEEP_TIME)
165    msg = check_msg(vcan, PEDAL_MSG, "Brakes high, throttle high")
166    check_brakes(msg, 50, 0.1, "Brakes high, throttle high")
167    check_throttles(msg, 0, 0.1, "Brakes high, throttle high")
168    time.sleep(0.1)
169
170    # Test 4: brake low, throttle mid, check motor off (sweep down to 5% on throttle)
171    vcan.clear()
172    set_both(brk1, brk2, 4)
173    time.sleep(SLEEP_TIME)
174    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle mid")
175    check_brakes(msg, 4, 0.1, "Brakes low, throttle mid")
176
177    for p in range(50, 4, -1):
178        vcan.clear()
179        set_both(thrtl1, thrtl2, p)
180        time.sleep(SLEEP_TIME)
181        msg = check_msg(vcan, PEDAL_MSG, f"Brakes low, throttle {p}")
182        expected_throttle = 0 if p > 5 else p
183        check_throttles(msg, expected_throttle, 0.1, f"Brakes low, throttle {p} (expected {expected_throttle}%)")
184    
185    time.sleep(0.1)
186
187    # Test 5: brake low, throttle mid, check motor back on
188    vcan.clear()
189    set_both(brk1, brk2, 5)
190    set_both(thrtl1, thrtl2, 25)
191    time.sleep(SLEEP_TIME)
192    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle mid")
193    check_brakes(msg, 5, 0.1, "Brakes low, throttle mid")
194    check_throttles(msg, 25, 0.1, "Brakes low, throttle mid")
195
196
197# T.4.2.5 -----------------------------------------------------------------------------#
198def t_4_2_5_test(h: hil2.Hil2):
199    """
200    - sens1 and sens2 similar, check motor on, sdc not triggered
201    - sens1 and sens2 slightly different, check motor on, sdc not triggered
202    - sens1 and sens2 10% different, check motor on, sdc not triggered
203    - sens1 and sens2 slightly different, check motor on, sdc not triggered
204    - sens1 and sens2 10% different, check motor on, sdc not triggered
205    - sens1 and sens2 still 10% different (~100 msec later), check motor off, sdc not triggered
206    - power cycle, confirm everything resets
207    - sens1 and sens2 similar, check motor on, sdc not triggered
208    """
209    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
210    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
211    vcan = h.can("HIL2", "VCAN")
212    sdc = h.di("Dashboard", "SDC")
213
214    # Set 1: sens1 = left, sens2 = right ----------------------------------------------#
215
216    # Similar, check motor on, sdc not triggered
217    vcan.clear()
218    set_both(thrtl1, thrtl2, 25)
219    time.sleep(SLEEP_TIME)
220    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Similar")
221    check_throttles(msg, 25, 0.1, "Set 1 - Similar")
222    mka.assert_false(sdc.get(), "Set 1 - Similar: SDC not triggered")
223    time.sleep(0.1)
224
225    # Slightly different, check motor on, sdc not triggered
226    vcan.clear()
227    thrtl1.set(pedal_percent_to_volts_1(20))
228    thrtl2.set(pedal_percent_to_volts_2(25))
229    time.sleep(SLEEP_TIME)
230    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Slightly different")
231    check_throttles_diff(msg, 20, 25, 0.1, "Set 1 - Slightly different")
232    mka.assert_false(sdc.get(), "Set 1 - Slightly different: SDC not triggered")
233    time.sleep(0.1)
234
235    # 10% different, check motor on, sdc not triggered
236    vcan.clear()
237    thrtl1.set(pedal_percent_to_volts_1(20))
238    thrtl2.set(pedal_percent_to_volts_2(30))
239    time.sleep(SLEEP_TIME)
240    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - 10% different")
241    check_throttles_diff(msg, 20, 30, 0.1, "Set 1 - 10% different")
242    mka.assert_false(sdc.get(), "Set 1 - 10% different: SDC not triggered")
243    time.sleep(0.03)
244
245    # Slightly different, check motor on, sdc not triggered
246    vcan.clear()
247    thrtl1.set(pedal_percent_to_volts_1(25))
248    thrtl2.set(pedal_percent_to_volts_2(30))
249    time.sleep(SLEEP_TIME)
250    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Slightly different")
251    check_throttles_diff(msg, 25, 30, 0.1, "Set 1 - Slightly different")
252    mka.assert_false(sdc.get(), "Set 1 - Slightly different: SDC not triggered")
253    time.sleep(0.1)
254
255    # 10% different, check motor on, sdc not triggered
256    vcan.clear()
257    thrtl1.set(pedal_percent_to_volts_1(20))
258    thrtl2.set(pedal_percent_to_volts_2(30))
259    time.sleep(SLEEP_TIME)
260    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - 10% different")
261    check_throttles_diff(msg, 20, 30, 0.1, "Set 1 - 10% different")
262    mka.assert_false(sdc.get(), "Set 1 - 10% different: SDC not triggered")
263    time.sleep(0.03)
264
265    # Still 10% different (~100 msec later), check motor off, sdc not triggered
266    vcan.clear()
267    time.sleep(0.07)
268    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Still 10% different (~100 msec later)")
269    check_throttles(msg, 0, 0.1, "Set 1 - Still 10% different (~100 msec later)")
270    mka.assert_false(sdc.get(), "Set 1 - Still 10% different (~100 msec later): SDC not triggered")
271    time.sleep(0.1)
272
273    # Power cycle and confirm everything resets
274    power_cycle(h)
275
276    # Similar, check motor on, sdc not triggered
277    vcan.clear()
278    set_both(thrtl1, thrtl2, 20)
279    time.sleep(SLEEP_TIME)
280    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Similar")
281    check_throttles(msg, 20, 0.1, "Set 1 - Similar")
282    mka.assert_false(sdc.get(), "Set 1 - Similar: SDC not triggered")
283    time.sleep(0.1)
284
285    # Set 2: sens1 = right, sens2 = left ----------------------------------------------#
286    
287    # Similar, check motor on, sdc not triggered
288    vcan.clear()
289    set_both(thrtl1, thrtl2, 25)
290    time.sleep(SLEEP_TIME)
291    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Similar")
292    check_throttles(msg, 25, 0.1, "Set 2 - Similar")
293    mka.assert_false(sdc.get(), "Set 2 - Similar: SDC not triggered")
294    time.sleep(0.1)
295
296    # Slightly different, check motor on, sdc not triggered
297    vcan.clear()
298    thrtl1.set(pedal_percent_to_volts_1(25))
299    thrtl2.set(pedal_percent_to_volts_2(20))
300    time.sleep(SLEEP_TIME)
301    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Slightly different")
302    check_throttles_diff(msg, 25, 20, 0.1, "Set 2 - Slightly different")
303    mka.assert_false(sdc.get(), "Set 2 - Slightly different: SDC not triggered")
304    time.sleep(0.1)
305
306    # 10% different, check motor on, sdc not triggered
307    vcan.clear()
308    thrtl1.set(pedal_percent_to_volts_1(30))
309    thrtl2.set(pedal_percent_to_volts_2(20))
310    time.sleep(SLEEP_TIME)
311    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - 10% different")
312    check_throttles_diff(msg, 30, 20, 0.1, "Set 2 - 10% different")
313    mka.assert_false(sdc.get(), "Set 2 - 10% different: SDC not triggered")
314    time.sleep(0.03)
315
316    # Slightly different, check motor on, sdc not triggered
317    vcan.clear()
318    thrtl1.set(pedal_percent_to_volts_1(30))
319    thrtl2.set(pedal_percent_to_volts_2(25))
320    time.sleep(SLEEP_TIME)
321    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Slightly different")
322    check_throttles_diff(msg, 30, 25, 0.1, "Set 2 - Slightly different")
323    mka.assert_false(sdc.get(), "Set 2 - Slightly different: SDC not triggered")
324    time.sleep(0.1)
325
326    # 10% different, check motor on, sdc not triggered
327    vcan.clear()
328    thrtl1.set(pedal_percent_to_volts_1(30))
329    thrtl2.set(pedal_percent_to_volts_2(20))
330    time.sleep(SLEEP_TIME)
331    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - 10% different")
332    check_throttles_diff(msg, 30, 20, 0.1, "Set 2 - 10% different")
333    mka.assert_false(sdc.get(), "Set 2 - 10% different: SDC not triggered")
334    time.sleep(0.03)
335
336    # Still 10% different (~100 msec later), check motor off, sdc not triggered
337    vcan.clear()
338    time.sleep(0.07)
339    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Still 10% different (~100 msec later)")
340    check_throttles(msg, 0, 0.1, "Set 2 - Still 10% different (~100 msec later)")
341    mka.assert_false(sdc.get(), "Set 2 - Still 10% different (~100 msec later): SDC not triggered")
342    time.sleep(0.1)
343
344    # Power cycle and confirm everything resets
345    power_cycle(h)
346
347    # Similar, check motor on, sdc not triggered
348    vcan.clear()
349    set_both(thrtl1, thrtl2, 20)
350    time.sleep(SLEEP_TIME)
351    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Similar")
352    check_throttles(msg, 20, 0.1, "Set 2 - Similar")
353    mka.assert_false(sdc.get(), "Set 2 - Similar: SDC not triggered")
354    time.sleep(0.1)
355
356# T.4.2.10 ----------------------------------------------------------------------------#
357def t_4_2_10_test(h: hil2.Hil2):
358    """
359    - sens1 and sens2 ok, check motor on, sdc not triggered
360    - both are out of range high, check motor off, sdc triggered
361    """
362
363    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
364    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
365    vcan = h.can("HIL2", "VCAN")
366    sdc = h.di("Dashboard", "SDC")
367
368    # Set 1: out of range high --------------------------------------------------------#
369
370    # Both ok, check motor on, sdc not triggered
371    vcan.clear()
372    set_both(thrtl1, thrtl2, 25)
373    time.sleep(SLEEP_TIME)
374    msg = check_msg(vcan, PEDAL_MSG, "Both ok")
375    check_throttles(msg, 25, 0.1, "Both ok")
376    mka.assert_false(sdc.get(), "Both ok: SDC not triggered")
377    time.sleep(0.1)
378
379    # Both out of range high, check motor off, sdc triggered
380    vcan.clear()
381    thrtl1.set(5.5) # volts
382    thrtl2.set(5.5) # volts
383    time.sleep(SLEEP_TIME)
384    msg = check_msg(vcan, PEDAL_MSG, "Both out of range high")
385    check_throttles(msg, 0, 0.1, "Both out of range high")
386    mka.assert_true(sdc.get(), "Both out of range high: SDC triggered")
387    time.sleep(0.1)
388
389    # Power cycle and confirm everything resets
390    power_cycle(h)
391
392    # Both ok, check motor on, sdc not triggered
393    vcan.clear()
394    set_both(thrtl1, thrtl2, 20)
395    time.sleep(SLEEP_TIME)
396    msg = check_msg(vcan, PEDAL_MSG, "Both ok")
397    check_throttles(msg, 20, 0.1, "Both ok")
398    mka.assert_false(sdc.get(), "Both ok: SDC not triggered")
399    time.sleep(0.1)
400
401
402    # Set 2: throttle 1 disconnects ---------------------------------------------------#
403
404    # Sens1 disconnected, check motor off, sdc triggered
405    vcan.clear()
406    thrtl2.set(pedal_percent_to_volts_2(25))
407    thrtl1.hiZ()
408    time.sleep(SLEEP_TIME)
409    msg = check_msg(vcan, PEDAL_MSG, "Sens1 disconnected")
410    check_throttles(msg, 0, 0.1, "Sens1 disconnected")
411    mka.assert_true(sdc.get(), "Sens1 disconnected: SDC triggered")
412    time.sleep(0.1)
413
414    # Power cycle and confirm everything resets
415    power_cycle(h)
416
417    # Sens1 and sens2 ok, check motor on, sdc not triggered
418    vcan.clear()
419    set_both(thrtl1, thrtl2, 20)
420    time.sleep(SLEEP_TIME)
421    msg = check_msg(vcan, PEDAL_MSG, "Sens1 and sens2 ok")
422    check_throttles(msg, 20, 0.1, "Sens1 and sens2 ok")
423    mka.assert_false(sdc.get(), "Sens1 and sens2 ok: SDC not triggered")
424    time.sleep(0.1)
425
426    # Set 3: throttle 2 disconnects ---------------------------------------------------#
427
428    # Sens2 disconnected, check motor off, sdc triggered
429    vcan.clear()
430    thrtl1.set(pedal_percent_to_volts_1(25))
431    thrtl2.hiZ()
432    time.sleep(SLEEP_TIME)
433    msg = check_msg(vcan, PEDAL_MSG, "Sens2 disconnected")
434    check_throttles(msg, 0, 0.1, "Sens2 disconnected")
435    mka.assert_true(sdc.get(), "Sens2 disconnected: SDC triggered")
436    time.sleep(0.1)
437
438    # Power cycle and confirm everything resets
439    power_cycle(h)
440
441    # Sens1 and sens2 ok, check motor on, sdc not triggered
442    vcan.clear()
443    set_both(thrtl1, thrtl2, 20)
444    time.sleep(SLEEP_TIME)
445    msg = check_msg(vcan, PEDAL_MSG, "Sens1 and sens2 ok")
446    check_throttles(msg, 20, 0.1, "Sens1 and sens2 ok")
447    mka.assert_false(sdc.get(), "Sens1 and sens2 ok: SDC not triggered")
448    time.sleep(0.1)
449
450
451# Buttons test ------------------------------------------------------------------------#
452def buttons_test(h: hil2.Hil2):
453    """
454    4 buttons, gpio on the UART line
455    - Try different combinations of the buttons and check that there is activity on the UART
456    """
457
458    up = h.do("Dashboard", "UP")
459    down = h.do("Dashboard", "DOWN")
460    select = h.do("Dashboard", "SELECT")
461    start = h.do("Dashboard", "START")
462    uart = h.di("Dashboard", "USART_LCD_TX")
463
464    # Setup: set all buttons to not pressed
465    up.set(False)
466    down.set(False)
467    select.set(False)
468    start.set(False)
469
470    # Test 1: press UP, check UART activity
471    up.set(True)
472    check_uart(uart, "Press UP")
473    up.set(False)
474    time.sleep(0.1)
475
476    # Test 2: press DOWN, check UART activity
477    down.set(True)
478    check_uart(uart, "Press DOWN")
479    down.set(False)
480    time.sleep(0.1)
481
482    # Test 3: press SELECT, check UART activity
483    select.set(True)
484    check_uart(uart, "Press SELECT")
485    select.set(False)
486    time.sleep(0.1)
487
488    # Test 4: press START, check UART activity
489    start.set(True)
490    check_uart(uart, "Press START")
491    start.set(False)
492    time.sleep(0.1)
493
494
495# Shockpot test -----------------------------------------------------------------------#
496def shockpot_test(h: hil2.Hil2):
497    """
498    DAC -> sweep 0 to 3v and check CAN values
499    Read can messages to check the values
500    """
501
502    left = h.ao("Dashboard", "LeftPot")
503    right = h.ao("Dashboard", "RightPot")
504    vcan = h.can("HIL2", "VCAN")
505
506    for lv in float_range(0, 3, 0.2):
507        left.set(lv)
508        for rv in float_range(0, 3, 0.2):
509            vcan.clear()
510            right.set(rv)
511            time.sleep(SLEEP_TIME)
512
513            msg = check_msg(vcan, SHOCK_MSG, f"Left {lv:.1f}V, Right {rv:.1f}V")
514            exp_l, exp_r = shockpots_from_voltage(lv, rv)
515            mka.assert_true(msg is not None, f"Left {lv:.1f}V, Right {rv:.1f}V: CAN message received")
516            mka.assert_true(msg is not None and msg["left_shock"] == exp_l, f"Left {lv:.1f}V, Right {rv:.1f}V: left shock {exp_l}")
517            mka.assert_true(msg is not None and msg["right_shock"] == exp_r, f"Left {lv:.1f}V, Right {rv:.1f}V: right shock {exp_r}")
518
519
520
521
522
523# Main --------------------------------------------------------------------------------#
524def main():
525    logging.basicConfig(level=logging.DEBUG)
526
527    with hil2.Hil2(
528        "./tests/dashboard/config.json",
529        "./device_configs",
530        "./netmap/per24.csv",
531        "TODO"
532    ) as h:
533        mka.set_setup_fn(lambda: power_cycle(h))
534        mka.set_teardown_fn(h.close)
535
536        mka.add_test(ev_4_7_2_test, h)
537        mka.add_test(t_4_2_5_test, h)
538        mka.add_test(t_4_2_10_test, h)
539        mka.add_test(buttons_test, h)
540        mka.add_test(shockpot_test, h)
541        
542        mka.run_tests()
543
544
545if __name__ == "__main__":
546    main()
PEDAL_LOW_V = 0.5
PEDAL_HIGH_V = 4.5
PEDAL_PERCENT_V = 0.04
SLEEP_TIME = 0.01
PEDAL_MSG = 'raw_throttle_brake'
SHOCK_MSG = 'shock_front'
def power_cycle(h: hil2.hil2.Hil2, delay_s: float = 0.5):
24def power_cycle(h: hil2.Hil2, delay_s: float = 0.5):
25    """
26    Power cycle the system by turning the power off for delay_s seconds, then back on.
27    
28    :param pow: Power DO component (e.g. relay)
29    :param delay_s: Time in seconds to wait with power off
30    """
31    pow = h.do("HIL2", "RLY1")
32    pow.set(False)
33    time.sleep(delay_s)
34    pow.set(True)
35    time.sleep(delay_s)

Power cycle the system by turning the power off for delay_s seconds, then back on.

Parameters
  • pow: Power DO component (e.g. relay)
  • delay_s: Time in seconds to wait with power off
def pedal_percent_to_volts_1(percent: float) -> float:
37def pedal_percent_to_volts_1(percent: float) -> float:
38    """
39    Normal linear mapping from 0-100% to volts
40    
41    :param percent: Percent value from 0 to 100
42    :return: Corresponding voltage value
43    """
44    return PEDAL_LOW_V + percent * PEDAL_PERCENT_V

Normal linear mapping from 0-100% to volts

Parameters
  • percent: Percent value from 0 to 100
Returns

Corresponding voltage value

def pedal_percent_to_volts_2(percent: float) -> float:
46def pedal_percent_to_volts_2(percent: float) -> float:
47    """
48    Inverted linear mapping from 0-100% to volts
49    
50    :param percent: Percent value from 0 to 100
51    :return: Corresponding voltage value
52    """
53    return PEDAL_HIGH_V - percent * PEDAL_PERCENT_V

Inverted linear mapping from 0-100% to volts

Parameters
  • percent: Percent value from 0 to 100
Returns

Corresponding voltage value

def set_both( pedal1: hil2.component.AO, pedal2: hil2.component.AO, percent: float) -> None:
55def set_both(pedal1: hil2_comp.AO, pedal2: hil2_comp.AO, percent: float) -> None:
56    """
57    Set a set of two pedals to the same percent value.
58
59    :param pedal1: First pedal AO component (in normal orientation)
60    :param pedal2: Second pedal AO component (in inverted orientation)
61    :param percent: Percent value from 0 to 100
62    """
63    pedal1.set(pedal_percent_to_volts_1(percent))
64    pedal2.set(pedal_percent_to_volts_2(percent))

Set a set of two pedals to the same percent value.

Parameters
  • pedal1: First pedal AO component (in normal orientation)
  • pedal2: Second pedal AO component (in inverted orientation)
  • percent: Percent value from 0 to 100
def check_msg( can_bus: hil2.component.CAN, msg_name: str | int, test_prefix: str) -> Optional[hil2.can_helper.CanMessage]:
66def check_msg(can_bus: hil2_comp.CAN, msg_name: str | int, test_prefix: str) -> Optional[can_helper.CanMessage]:
67    msg = can_bus.get_last(msg_name)
68    mka.assert_true(msg is not None, f"{test_prefix}: VCAN message received")
69    return msg
def check_brakes( msg: Optional[hil2.can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
71def check_brakes(msg: Optional[can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
72    mka.assert_eqf(msg is not None and msg.data["brake"],       exp_percent, tol_v, f"{test_prefix}: brake left {exp_percent}%")
73    mka.assert_eqf(msg is not None and msg.data["brake_right"], exp_percent, tol_v, f"{test_prefix}: brake right {exp_percent}%")
def check_throttles_diff( msg: Optional[hil2.can_helper.CanMessage], exp_percent1: float, exp_percent2: float, tol_v: float, test_prefix: str):
75def check_throttles_diff(msg: Optional[can_helper.CanMessage], exp_percent1: float, exp_percent2: float, tol_v: float, test_prefix: str):
76    mka.assert_eqf(msg is not None and msg.data["throttle"],       exp_percent1, tol_v, f"{test_prefix}: throttle left {exp_percent1}%")
77    mka.assert_eqf(msg is not None and msg.data["throttle_right"], exp_percent2, tol_v, f"{test_prefix}: throttle right {exp_percent2}%")
def check_throttles( msg: Optional[hil2.can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
79def check_throttles(msg: Optional[can_helper.CanMessage], exp_percent: float, tol_v: float, test_prefix: str):
80    check_throttles_diff(msg, exp_percent, exp_percent, tol_v, test_prefix)
def check_uart(uart: hil2.component.DI, test_prefix: str):
82def check_uart(uart: hil2_comp.DI, test_prefix: str):
83    for _ in range(10):
84        if uart.get():
85            mka.assert_true(True, f"{test_prefix}: UART activity detected")
86            return
87        time.sleep(0.01)
88    mka.assert_true(False, f"{test_prefix}: UART activity detected")
def float_range(start, stop, step):
90def float_range(start, stop, step):
91    while start <= stop:
92        yield start
93        start += step
def shockpots_from_voltage(v_left: float, v_right: float) -> tuple[int, int]:
 95def shockpots_from_voltage(v_left: float, v_right: float) -> tuple[int, int]:
 96    POT_VOLT_MAX = 3.0
 97    POT_VOLT_MIN_L = 4082.0
 98    POT_VOLT_MIN_R = 4090.0
 99    POT_MAX_DIST = 75
100    POT_DIST_DROOP_L = 56
101    POT_DIST_DROOP_R = 56
102
103    adc_left = (v_left / POT_VOLT_MAX) * POT_VOLT_MIN_L
104    adc_right = (v_right / POT_VOLT_MAX) * POT_VOLT_MIN_R
105
106    shock_l = -1 * ((POT_MAX_DIST - int((adc_left / (POT_VOLT_MIN_L - POT_VOLT_MAX)) * POT_MAX_DIST)) - POT_DIST_DROOP_L)
107    shock_r = -1 * ((POT_MAX_DIST - int((adc_right / (POT_VOLT_MIN_R - POT_VOLT_MAX)) * POT_MAX_DIST)) - POT_DIST_DROOP_R)
108
109    return shock_l, shock_r
def ev_4_7_2_test(h: hil2.hil2.Hil2):
113def ev_4_7_2_test(h: hil2.Hil2):
114    """
115    If brake is activated (5% pressed) and throttle is activated more than 25%, motor
116    must shutdown and stay shutdown until throttle is under 5%
117    
118    - brake low, throttle low, check motor on
119    - brake high, throttle low, check motor on
120    - brake high, throttle high, check motor off
121    - brake low, throttle mid, check motor off (sweep down to 5% on throttle)
122    - brake low, throttle low, check motor back on
123    """
124
125    brk1 = h.ao("Dashboard", "BRK1_RAW")
126    brk2 = h.ao("Dashboard", "BRK2_RAW")
127    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
128    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
129    vcan = h.can("HIL2", "VCAN")
130
131    # Setup: set brake and throttle to 0%
132    vcan.clear()
133    set_both(brk1, brk2, 0)
134    set_both(thrtl1, thrtl2, 0)
135    time.sleep(SLEEP_TIME)
136    msg = check_msg(vcan, PEDAL_MSG, "Setup")
137    check_brakes(msg, 0, 0.1, "Setup")
138    check_throttles(msg, 0, 0.1, "Setup")
139    time.sleep(0.1)
140    
141    # Test 1: brake low, throttle low, check motor on
142    vcan.clear()
143    set_both(brk1, brk2, 5)
144    set_both(thrtl1, thrtl2, 5)
145    time.sleep(SLEEP_TIME)
146    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle low")
147    check_brakes(vcan, 5, 0.1, "Brakes low, throttle low")
148    check_throttles(vcan, 5, 0.1, "Brakes low, throttle low")
149    time.sleep(0.1)
150
151    # Test 2: brake high, throttle low, check motor on
152    vcan.clear()
153    set_both(brk1, brk2, 50)
154    set_both(thrtl1, thrtl2, 5)
155    time.sleep(SLEEP_TIME)
156    msg = check_msg(vcan, PEDAL_MSG, "Brakes high, throttle low")
157    check_brakes(msg, 50, 0.1, "Brakes high, throttle low")
158    check_throttles(msg, 5, 0.1, "Brakes high, throttle low")
159    time.sleep(0.1)
160
161    # Test 3: brake high, throttle high, check motor off
162    vcan.clear()
163    set_both(brk1, brk2, 50)
164    set_both(thrtl1, thrtl2, 50)
165    time.sleep(SLEEP_TIME)
166    msg = check_msg(vcan, PEDAL_MSG, "Brakes high, throttle high")
167    check_brakes(msg, 50, 0.1, "Brakes high, throttle high")
168    check_throttles(msg, 0, 0.1, "Brakes high, throttle high")
169    time.sleep(0.1)
170
171    # Test 4: brake low, throttle mid, check motor off (sweep down to 5% on throttle)
172    vcan.clear()
173    set_both(brk1, brk2, 4)
174    time.sleep(SLEEP_TIME)
175    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle mid")
176    check_brakes(msg, 4, 0.1, "Brakes low, throttle mid")
177
178    for p in range(50, 4, -1):
179        vcan.clear()
180        set_both(thrtl1, thrtl2, p)
181        time.sleep(SLEEP_TIME)
182        msg = check_msg(vcan, PEDAL_MSG, f"Brakes low, throttle {p}")
183        expected_throttle = 0 if p > 5 else p
184        check_throttles(msg, expected_throttle, 0.1, f"Brakes low, throttle {p} (expected {expected_throttle}%)")
185    
186    time.sleep(0.1)
187
188    # Test 5: brake low, throttle mid, check motor back on
189    vcan.clear()
190    set_both(brk1, brk2, 5)
191    set_both(thrtl1, thrtl2, 25)
192    time.sleep(SLEEP_TIME)
193    msg = check_msg(vcan, PEDAL_MSG, "Brakes low, throttle mid")
194    check_brakes(msg, 5, 0.1, "Brakes low, throttle mid")
195    check_throttles(msg, 25, 0.1, "Brakes low, throttle mid")

If brake is activated (5% pressed) and throttle is activated more than 25%, motor must shutdown and stay shutdown until throttle is under 5%

  • brake low, throttle low, check motor on
  • brake high, throttle low, check motor on
  • brake high, throttle high, check motor off
  • brake low, throttle mid, check motor off (sweep down to 5% on throttle)
  • brake low, throttle low, check motor back on
def t_4_2_5_test(h: hil2.hil2.Hil2):
199def t_4_2_5_test(h: hil2.Hil2):
200    """
201    - sens1 and sens2 similar, check motor on, sdc not triggered
202    - sens1 and sens2 slightly different, check motor on, sdc not triggered
203    - sens1 and sens2 10% different, check motor on, sdc not triggered
204    - sens1 and sens2 slightly different, check motor on, sdc not triggered
205    - sens1 and sens2 10% different, check motor on, sdc not triggered
206    - sens1 and sens2 still 10% different (~100 msec later), check motor off, sdc not triggered
207    - power cycle, confirm everything resets
208    - sens1 and sens2 similar, check motor on, sdc not triggered
209    """
210    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
211    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
212    vcan = h.can("HIL2", "VCAN")
213    sdc = h.di("Dashboard", "SDC")
214
215    # Set 1: sens1 = left, sens2 = right ----------------------------------------------#
216
217    # Similar, check motor on, sdc not triggered
218    vcan.clear()
219    set_both(thrtl1, thrtl2, 25)
220    time.sleep(SLEEP_TIME)
221    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Similar")
222    check_throttles(msg, 25, 0.1, "Set 1 - Similar")
223    mka.assert_false(sdc.get(), "Set 1 - Similar: SDC not triggered")
224    time.sleep(0.1)
225
226    # Slightly different, check motor on, sdc not triggered
227    vcan.clear()
228    thrtl1.set(pedal_percent_to_volts_1(20))
229    thrtl2.set(pedal_percent_to_volts_2(25))
230    time.sleep(SLEEP_TIME)
231    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Slightly different")
232    check_throttles_diff(msg, 20, 25, 0.1, "Set 1 - Slightly different")
233    mka.assert_false(sdc.get(), "Set 1 - Slightly different: SDC not triggered")
234    time.sleep(0.1)
235
236    # 10% different, check motor on, sdc not triggered
237    vcan.clear()
238    thrtl1.set(pedal_percent_to_volts_1(20))
239    thrtl2.set(pedal_percent_to_volts_2(30))
240    time.sleep(SLEEP_TIME)
241    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - 10% different")
242    check_throttles_diff(msg, 20, 30, 0.1, "Set 1 - 10% different")
243    mka.assert_false(sdc.get(), "Set 1 - 10% different: SDC not triggered")
244    time.sleep(0.03)
245
246    # Slightly different, check motor on, sdc not triggered
247    vcan.clear()
248    thrtl1.set(pedal_percent_to_volts_1(25))
249    thrtl2.set(pedal_percent_to_volts_2(30))
250    time.sleep(SLEEP_TIME)
251    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Slightly different")
252    check_throttles_diff(msg, 25, 30, 0.1, "Set 1 - Slightly different")
253    mka.assert_false(sdc.get(), "Set 1 - Slightly different: SDC not triggered")
254    time.sleep(0.1)
255
256    # 10% different, check motor on, sdc not triggered
257    vcan.clear()
258    thrtl1.set(pedal_percent_to_volts_1(20))
259    thrtl2.set(pedal_percent_to_volts_2(30))
260    time.sleep(SLEEP_TIME)
261    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - 10% different")
262    check_throttles_diff(msg, 20, 30, 0.1, "Set 1 - 10% different")
263    mka.assert_false(sdc.get(), "Set 1 - 10% different: SDC not triggered")
264    time.sleep(0.03)
265
266    # Still 10% different (~100 msec later), check motor off, sdc not triggered
267    vcan.clear()
268    time.sleep(0.07)
269    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Still 10% different (~100 msec later)")
270    check_throttles(msg, 0, 0.1, "Set 1 - Still 10% different (~100 msec later)")
271    mka.assert_false(sdc.get(), "Set 1 - Still 10% different (~100 msec later): SDC not triggered")
272    time.sleep(0.1)
273
274    # Power cycle and confirm everything resets
275    power_cycle(h)
276
277    # Similar, check motor on, sdc not triggered
278    vcan.clear()
279    set_both(thrtl1, thrtl2, 20)
280    time.sleep(SLEEP_TIME)
281    msg = check_msg(vcan, PEDAL_MSG, "Set 1 - Similar")
282    check_throttles(msg, 20, 0.1, "Set 1 - Similar")
283    mka.assert_false(sdc.get(), "Set 1 - Similar: SDC not triggered")
284    time.sleep(0.1)
285
286    # Set 2: sens1 = right, sens2 = left ----------------------------------------------#
287    
288    # Similar, check motor on, sdc not triggered
289    vcan.clear()
290    set_both(thrtl1, thrtl2, 25)
291    time.sleep(SLEEP_TIME)
292    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Similar")
293    check_throttles(msg, 25, 0.1, "Set 2 - Similar")
294    mka.assert_false(sdc.get(), "Set 2 - Similar: SDC not triggered")
295    time.sleep(0.1)
296
297    # Slightly different, check motor on, sdc not triggered
298    vcan.clear()
299    thrtl1.set(pedal_percent_to_volts_1(25))
300    thrtl2.set(pedal_percent_to_volts_2(20))
301    time.sleep(SLEEP_TIME)
302    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Slightly different")
303    check_throttles_diff(msg, 25, 20, 0.1, "Set 2 - Slightly different")
304    mka.assert_false(sdc.get(), "Set 2 - Slightly different: SDC not triggered")
305    time.sleep(0.1)
306
307    # 10% different, check motor on, sdc not triggered
308    vcan.clear()
309    thrtl1.set(pedal_percent_to_volts_1(30))
310    thrtl2.set(pedal_percent_to_volts_2(20))
311    time.sleep(SLEEP_TIME)
312    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - 10% different")
313    check_throttles_diff(msg, 30, 20, 0.1, "Set 2 - 10% different")
314    mka.assert_false(sdc.get(), "Set 2 - 10% different: SDC not triggered")
315    time.sleep(0.03)
316
317    # Slightly different, check motor on, sdc not triggered
318    vcan.clear()
319    thrtl1.set(pedal_percent_to_volts_1(30))
320    thrtl2.set(pedal_percent_to_volts_2(25))
321    time.sleep(SLEEP_TIME)
322    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Slightly different")
323    check_throttles_diff(msg, 30, 25, 0.1, "Set 2 - Slightly different")
324    mka.assert_false(sdc.get(), "Set 2 - Slightly different: SDC not triggered")
325    time.sleep(0.1)
326
327    # 10% different, check motor on, sdc not triggered
328    vcan.clear()
329    thrtl1.set(pedal_percent_to_volts_1(30))
330    thrtl2.set(pedal_percent_to_volts_2(20))
331    time.sleep(SLEEP_TIME)
332    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - 10% different")
333    check_throttles_diff(msg, 30, 20, 0.1, "Set 2 - 10% different")
334    mka.assert_false(sdc.get(), "Set 2 - 10% different: SDC not triggered")
335    time.sleep(0.03)
336
337    # Still 10% different (~100 msec later), check motor off, sdc not triggered
338    vcan.clear()
339    time.sleep(0.07)
340    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Still 10% different (~100 msec later)")
341    check_throttles(msg, 0, 0.1, "Set 2 - Still 10% different (~100 msec later)")
342    mka.assert_false(sdc.get(), "Set 2 - Still 10% different (~100 msec later): SDC not triggered")
343    time.sleep(0.1)
344
345    # Power cycle and confirm everything resets
346    power_cycle(h)
347
348    # Similar, check motor on, sdc not triggered
349    vcan.clear()
350    set_both(thrtl1, thrtl2, 20)
351    time.sleep(SLEEP_TIME)
352    msg = check_msg(vcan, PEDAL_MSG, "Set 2 - Similar")
353    check_throttles(msg, 20, 0.1, "Set 2 - Similar")
354    mka.assert_false(sdc.get(), "Set 2 - Similar: SDC not triggered")
355    time.sleep(0.1)
  • sens1 and sens2 similar, check motor on, sdc not triggered
  • sens1 and sens2 slightly different, check motor on, sdc not triggered
  • sens1 and sens2 10% different, check motor on, sdc not triggered
  • sens1 and sens2 slightly different, check motor on, sdc not triggered
  • sens1 and sens2 10% different, check motor on, sdc not triggered
  • sens1 and sens2 still 10% different (~100 msec later), check motor off, sdc not triggered
  • power cycle, confirm everything resets
  • sens1 and sens2 similar, check motor on, sdc not triggered
def t_4_2_10_test(h: hil2.hil2.Hil2):
358def t_4_2_10_test(h: hil2.Hil2):
359    """
360    - sens1 and sens2 ok, check motor on, sdc not triggered
361    - both are out of range high, check motor off, sdc triggered
362    """
363
364    thrtl1 = h.ao("Dashboard", "THRTL1_RAW")
365    thrtl2 = h.ao("Dashboard", "THRTL2_RAW")
366    vcan = h.can("HIL2", "VCAN")
367    sdc = h.di("Dashboard", "SDC")
368
369    # Set 1: out of range high --------------------------------------------------------#
370
371    # Both ok, check motor on, sdc not triggered
372    vcan.clear()
373    set_both(thrtl1, thrtl2, 25)
374    time.sleep(SLEEP_TIME)
375    msg = check_msg(vcan, PEDAL_MSG, "Both ok")
376    check_throttles(msg, 25, 0.1, "Both ok")
377    mka.assert_false(sdc.get(), "Both ok: SDC not triggered")
378    time.sleep(0.1)
379
380    # Both out of range high, check motor off, sdc triggered
381    vcan.clear()
382    thrtl1.set(5.5) # volts
383    thrtl2.set(5.5) # volts
384    time.sleep(SLEEP_TIME)
385    msg = check_msg(vcan, PEDAL_MSG, "Both out of range high")
386    check_throttles(msg, 0, 0.1, "Both out of range high")
387    mka.assert_true(sdc.get(), "Both out of range high: SDC triggered")
388    time.sleep(0.1)
389
390    # Power cycle and confirm everything resets
391    power_cycle(h)
392
393    # Both ok, check motor on, sdc not triggered
394    vcan.clear()
395    set_both(thrtl1, thrtl2, 20)
396    time.sleep(SLEEP_TIME)
397    msg = check_msg(vcan, PEDAL_MSG, "Both ok")
398    check_throttles(msg, 20, 0.1, "Both ok")
399    mka.assert_false(sdc.get(), "Both ok: SDC not triggered")
400    time.sleep(0.1)
401
402
403    # Set 2: throttle 1 disconnects ---------------------------------------------------#
404
405    # Sens1 disconnected, check motor off, sdc triggered
406    vcan.clear()
407    thrtl2.set(pedal_percent_to_volts_2(25))
408    thrtl1.hiZ()
409    time.sleep(SLEEP_TIME)
410    msg = check_msg(vcan, PEDAL_MSG, "Sens1 disconnected")
411    check_throttles(msg, 0, 0.1, "Sens1 disconnected")
412    mka.assert_true(sdc.get(), "Sens1 disconnected: SDC triggered")
413    time.sleep(0.1)
414
415    # Power cycle and confirm everything resets
416    power_cycle(h)
417
418    # Sens1 and sens2 ok, check motor on, sdc not triggered
419    vcan.clear()
420    set_both(thrtl1, thrtl2, 20)
421    time.sleep(SLEEP_TIME)
422    msg = check_msg(vcan, PEDAL_MSG, "Sens1 and sens2 ok")
423    check_throttles(msg, 20, 0.1, "Sens1 and sens2 ok")
424    mka.assert_false(sdc.get(), "Sens1 and sens2 ok: SDC not triggered")
425    time.sleep(0.1)
426
427    # Set 3: throttle 2 disconnects ---------------------------------------------------#
428
429    # Sens2 disconnected, check motor off, sdc triggered
430    vcan.clear()
431    thrtl1.set(pedal_percent_to_volts_1(25))
432    thrtl2.hiZ()
433    time.sleep(SLEEP_TIME)
434    msg = check_msg(vcan, PEDAL_MSG, "Sens2 disconnected")
435    check_throttles(msg, 0, 0.1, "Sens2 disconnected")
436    mka.assert_true(sdc.get(), "Sens2 disconnected: SDC triggered")
437    time.sleep(0.1)
438
439    # Power cycle and confirm everything resets
440    power_cycle(h)
441
442    # Sens1 and sens2 ok, check motor on, sdc not triggered
443    vcan.clear()
444    set_both(thrtl1, thrtl2, 20)
445    time.sleep(SLEEP_TIME)
446    msg = check_msg(vcan, PEDAL_MSG, "Sens1 and sens2 ok")
447    check_throttles(msg, 20, 0.1, "Sens1 and sens2 ok")
448    mka.assert_false(sdc.get(), "Sens1 and sens2 ok: SDC not triggered")
449    time.sleep(0.1)
  • sens1 and sens2 ok, check motor on, sdc not triggered
  • both are out of range high, check motor off, sdc triggered
def buttons_test(h: hil2.hil2.Hil2):
453def buttons_test(h: hil2.Hil2):
454    """
455    4 buttons, gpio on the UART line
456    - Try different combinations of the buttons and check that there is activity on the UART
457    """
458
459    up = h.do("Dashboard", "UP")
460    down = h.do("Dashboard", "DOWN")
461    select = h.do("Dashboard", "SELECT")
462    start = h.do("Dashboard", "START")
463    uart = h.di("Dashboard", "USART_LCD_TX")
464
465    # Setup: set all buttons to not pressed
466    up.set(False)
467    down.set(False)
468    select.set(False)
469    start.set(False)
470
471    # Test 1: press UP, check UART activity
472    up.set(True)
473    check_uart(uart, "Press UP")
474    up.set(False)
475    time.sleep(0.1)
476
477    # Test 2: press DOWN, check UART activity
478    down.set(True)
479    check_uart(uart, "Press DOWN")
480    down.set(False)
481    time.sleep(0.1)
482
483    # Test 3: press SELECT, check UART activity
484    select.set(True)
485    check_uart(uart, "Press SELECT")
486    select.set(False)
487    time.sleep(0.1)
488
489    # Test 4: press START, check UART activity
490    start.set(True)
491    check_uart(uart, "Press START")
492    start.set(False)
493    time.sleep(0.1)

4 buttons, gpio on the UART line

  • Try different combinations of the buttons and check that there is activity on the UART
def shockpot_test(h: hil2.hil2.Hil2):
497def shockpot_test(h: hil2.Hil2):
498    """
499    DAC -> sweep 0 to 3v and check CAN values
500    Read can messages to check the values
501    """
502
503    left = h.ao("Dashboard", "LeftPot")
504    right = h.ao("Dashboard", "RightPot")
505    vcan = h.can("HIL2", "VCAN")
506
507    for lv in float_range(0, 3, 0.2):
508        left.set(lv)
509        for rv in float_range(0, 3, 0.2):
510            vcan.clear()
511            right.set(rv)
512            time.sleep(SLEEP_TIME)
513
514            msg = check_msg(vcan, SHOCK_MSG, f"Left {lv:.1f}V, Right {rv:.1f}V")
515            exp_l, exp_r = shockpots_from_voltage(lv, rv)
516            mka.assert_true(msg is not None, f"Left {lv:.1f}V, Right {rv:.1f}V: CAN message received")
517            mka.assert_true(msg is not None and msg["left_shock"] == exp_l, f"Left {lv:.1f}V, Right {rv:.1f}V: left shock {exp_l}")
518            mka.assert_true(msg is not None and msg["right_shock"] == exp_r, f"Left {lv:.1f}V, Right {rv:.1f}V: right shock {exp_r}")

DAC -> sweep 0 to 3v and check CAN values Read can messages to check the values

def main():
525def main():
526    logging.basicConfig(level=logging.DEBUG)
527
528    with hil2.Hil2(
529        "./tests/dashboard/config.json",
530        "./device_configs",
531        "./netmap/per24.csv",
532        "TODO"
533    ) as h:
534        mka.set_setup_fn(lambda: power_cycle(h))
535        mka.set_teardown_fn(h.close)
536
537        mka.add_test(ev_4_7_2_test, h)
538        mka.add_test(t_4_2_5_test, h)
539        mka.add_test(t_4_2_10_test, h)
540        mka.add_test(buttons_test, h)
541        mka.add_test(shockpot_test, h)
542        
543        mka.run_tests()