diff --git a/configurations/config_system_hil_attached.json b/configurations/config_system_hil_attached.json index a32921f..b971bca 100644 --- a/configurations/config_system_hil_attached.json +++ b/configurations/config_system_hil_attached.json @@ -15,8 +15,33 @@ {"board":"Dashboard", "harness_connections":[ {"dut":{"connector":"J1","pin":9}, "hil":{"device":"FrontTester", "port":"DAC1"}}, {"dut":{"connector":"J1","pin":10}, "hil":{"device":"FrontTester", "port":"DAC2"}}, - {"dut":{"connector":"J1","pin":11}, "hil":{"device":"FrontTester", "port":"POT1"}}, - {"dut":{"connector":"J1","pin":12}, "hil":{"device":"FrontTester", "port":"POT2"}} + {"dut":{"connector":"J1","pin":11}, "hil":{"device":"FrontTester", "port":"DAC1", "_": "can't do breaks and throttle at once, not enough DACs"}}, + {"dut":{"connector":"J1","pin":12}, "hil":{"device":"FrontTester", "port":"DAC2"}} + ]}, + {"board":"a_box", "harness_connections":[ + {"dut":{"connector":"P9","pin":2}, "hil":{"device":"RearTester", "port":"AI1"}}, + {"dut":{"connector":"P9","pin":4}, "hil":{"device":"RearTester", "port":"AI2"}}, + {"dut":{"connector":"P12","pin":3}, "hil":{"device":"RearTester", "port":"AI2"}}, + {"dut":{"connector":"P12","pin":1}, "hil":{"device":"RearTester", "port":"AI3"}}, + {"dut":{"connector":"P9","pin":6}, "hil":{"device":"RearTester", "port":"AI4"}}, + {"dut":{"connector":"P9","pin":11}, "hil":{"device":"RearTester", "port":"RLY1"}}, + {"dut":{"connector":"P9","pin":5}, "hil":{"device":"RearTester", "port":"RLY2"}}, + {"dut":{"connector":"P7","pin":6}, "hil":{"device":"RearTester", "port":"RLY3"}}, + {"dut":{"connector":"P9","pin":3}, "hil":{"device":"RearTester", "port":"DI3"}}, + {"dut":{"connector":"P9","pin":7}, "hil":{"device":"RearTester", "port":"DI4"}}, + {"dut":{"connector":"P13","pin":3}, "hil":{"device":"RearTester", "port":"DI5"}}, + {"dut":{"connector":"P5","pin":3}, "hil":{"device":"RearTester", "port":"DI6"}}, + {"dut":{"connector":"P12","pin":11}, "hil":{"device":"RearTester", "port":"DAC1"}}, + {"dut":{"connector":"P4","pin":2}, "hil":{"device":"RearTesterArd", "port":"D2"}}, + {"dut":{"connector":"P4","pin":3}, "hil":{"device":"RearTesterArd", "port":"D3"}}, + {"dut":{"connector":"P4","pin":4}, "hil":{"device":"RearTesterArd", "port":"D4"}}, + {"dut":{"connector":"P4","pin":5}, "hil":{"device":"RearTesterArd", "port":"D5"}}, + {"dut":{"connector":"P4","pin":7}, "hil":{"device":"RearTesterArd", "port":"D6"}}, + {"dut":{"connector":"P3","pin":7}, "hil":{"device":"RearTesterArd", "port":"D7"}}, + {"dut":{"connector":"P2","pin":7}, "hil":{"device":"RearTesterArd", "port":"D8"}}, + {"dut":{"connector":"P1","pin":7}, "hil":{"device":"RearTesterArd", "port":"D9"}}, + {"dut":{"connector":"P10","pin":3}, "hil":{"device":"RearTester", "port":"RLY4"}}, + {"dut":{"connector":"P9","pin":8}, "hil":{"device":"RearTester", "port":"DI7"}} ]} ], "hil_devices":[ diff --git a/scripts/node_specific/scripts/test_abox.py b/scripts/node_specific/scripts/test_abox.py index 5fbcfcc..8619b58 100644 --- a/scripts/node_specific/scripts/test_abox.py +++ b/scripts/node_specific/scripts/test_abox.py @@ -31,140 +31,119 @@ def hil(): # ---------------------------------------------------------------------------- # -def test_abox_ams(hil): - # Begin the test - # hil.start_test(test_abox_ams.__name__) +@pytest.mark.parametrize("combo", [0, 1, 2, 3, 4, 5, 6, 7]) +def test_abox_ams(hil, combo): + """Accumulator Management System""" - # Outputs - den = hil.dout("a_box", "Discharge Enable") - csafe = hil.dout("a_box", "Charger Safety") + # HIL outputs (hil writes) + discharge_en = hil.dout("a_box", "Discharge Enable") + charge_safe = hil.dout("a_box", "Charger Safety") bms_override = hil.daq_var("a_box", "bms_daq_override") - bms_stat = hil.daq_var("a_box", "bms_daq_stat") + bms_stat = hil.daq_var("a_box", "bms_daq_stat") - # Inputs - chrg_stat = hil.din("a_box", "BMS Status Charger") - main_stat = hil.din("a_box", "BMS Status PDU") + # HIL inputs (hil reads) + charge_stat = hil.din("a_box", "BMS Status Charger") + main_stat = hil.din("a_box", "BMS Status PDU") # Main power status = discharge + # Force manual overridec bms_override.state = 1 - for i in range(0, 8): - dchg_set = bool(i & 0x1) - chg_set = bool(i & 0x2) - bms_set = bool(i & 0x4) - exp_chrg = not (chg_set or bms_set) - exp_dchg = not (dchg_set or bms_set) - - den.state = dchg_set - csafe.state = chg_set - bms_stat.state = bms_set - print(f"Combo {i}") - time.sleep(0.1) - # hil.check(chrg_stat.state == exp_chrg, f"Chrg stat {exp_chrg}") - # hil.check(main_stat.state == exp_dchg, f"Main stat {exp_dchg}") - check.equal(chrg_stat.state, exp_chrg, f"Chrg stat {exp_chrg}") - check.equal(main_stat.state, exp_dchg, f"Main stat {exp_dchg}") + discharge_set = bool(combo & 0x1) + charge_set = bool(combo & 0x2) + bms_set = bool(combo & 0x4) + + expected_charge = not (charge_set or bms_set) + expected_discharge = not (discharge_set or bms_set) - bms_override.state = 0 + discharge_en.state = discharge_set + charge_safe.state = charge_set + bms_stat.state = bms_set + time.sleep(0.1) + + check.equal(charge_stat.state, expected_charge, f"Charge stat ({combo:b}) {expected_charge}") + check.equal(main_stat.state, expected_discharge, f"Main stat ({combo:b}) {expected_discharge}") - # hil.end_test() + # Reset the override + bms_override.state = 0 # ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- # -def test_isense(hil): - # Begin the test - # hil.start_test(test_isense.__name__) +@pytest.mark.parametrize("voltage", [0.0, DHAB_S124_MIN_OUT_V, DHAB_S124_OFFSET_V, 3.2, DHAB_S124_MAX_OUT_V, 5.0]) +def test_isense(hil, voltage): + """Current sensor voltage divider transfer function""" - # Outputs + # HIL outputs (hil writes) ch1_raw = hil.aout("a_box", "Isense_Ch1_raw") - # Inputs + # HIL inputs (hil reads) ch1_filt = hil.ain("a_box", "ISense Ch1") - # Need to test voltage divider transfer function correct - for v in [0.0, DHAB_S124_MIN_OUT_V, DHAB_S124_OFFSET_V, 3.2, DHAB_S124_MAX_OUT_V, 5.0]: - ch1_raw.state = v - time.sleep(1) - exp_out = ABOX_DHAB_CH1_DIV.div(v) - input(f"enter to meas, set to {v}, expected {exp_out}") - meas = ch1_filt.state - print(f"isense expected: {exp_out}V, measured: {meas}V") - # hil.check_within(meas, exp_out, 0.05, f"Isense v={v:.3}") - check.almost_equal(meas, exp_out, abs=0.05, rel=0.0, msg=f"Isense v={v:.3}") + ch1_raw.state = voltage + time.sleep(1) + expected_out = ABOX_DHAB_CH1_DIV.div(voltage) + # input(f"enter to meas, set to {v}, expected {exp_out}") + check.almost_equal(ch1_filt.state, expected_out, abs=0.05, rel=0.0, msg=f"Isense v={voltage:.3}") + # Test float (hi-Z) is pulled down ch1_raw.hiZ() time.sleep(0.01) - # hil.check_within(ch1_filt.state, 0.0, 0.05, f"Isense float pulled down") - check.almost_equal(ch1_filt.state, 0.0, abs=0.05, rel=0.0, msg="Isense float pulled down") - # hil.end_test() + check.almost_equal(ch1_filt.state, 0.0, abs=0.05, rel=0.0, msg="Isense float (hi-Z) pulled down") # ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- # -RLY_ON = 0 RLY_OFF = 1 -RLY_DLY = 0.01 # Mechanicl relay takes time to transition +RLY_ON = 0 -def test_precharge(hil): - # Begin the test - # hil.start_test(test_precharge.__name__) +@pytest.mark.parametrize("n_pchg_cmplt_set, sdc_set, expected_resistor", [ + (0, RLY_OFF, 0), # Precharge complete, SDC off -> resistor disconnected + (1, RLY_OFF, 0), # Precharge active, SDC off -> resistor disconnected + (1, RLY_ON, 1), # Precharge active, SDC on -> resistor connected + (0, RLY_ON, 0), # Precharge complete, SDC on -> resistor disconnected +]) +def test_not_precharge_complete(hil, n_pchg_cmplt_set, sdc_set, expected_resistor): + """Not precharge complete""" - # Outputs + # HIL outputs (hil writes) n_pchg_cmplt = hil.dout("a_box", "NotPrechargeComplete") sdc = hil.dout("a_box", "SDC") bat_p = hil.dout("a_box", "Batt+") - # Inputs + # HIL inputs (hil reads) resistor = hil.din("a_box", "NetK1_4") # To precharge resistor bat_p.state = RLY_ON - print("Combo 1") - n_pchg_cmplt.state = 0 - sdc.state = RLY_OFF - time.sleep(RLY_DLY) - # hil.check(resistor.state == 0, "Resistor disconnected") - check.equal(resistor.state, 0, "Combo 1, resistor disconnected") + n_pchg_cmplt.state = n_pchg_cmplt_set + sdc.state = sdc_set + time.sleep(0.1) - print("Combo 2") - n_pchg_cmplt.state = 1 - sdc.state = RLY_OFF - time.sleep(RLY_DLY) - # hil.check(resistor.state == 0, "Resistor disconnected") - check.equal(resistor.state, 0, "Combo 2, resistor disconnected") + message = f"not precharge: {n_pchg_cmplt_set}, sdc: {sdc_set} -> resistor: {expected_resistor}" + check.equal(resistor.state, expected_resistor, message) - print("Combo 3") - n_pchg_cmplt.state = 1 - sdc.state = RLY_ON - time.sleep(RLY_DLY) - # hil.check(resistor.state == 1, "Resistor connected") - check.equal(resistor.state, 1, "Combo 3, resistor connected") +def test_precharge_duration(hil): + """Precharge duration""" - print("Combo 4") - n_pchg_cmplt.state = 0 - sdc.state = RLY_ON - time.sleep(RLY_DLY) - # hil.check(resistor.state == 0, "Resistor disconnected") - check.equal(resistor.state, 0, "Combo 4, resistor disconnected") + # HIL outputs (hil writes) + n_pchg_cmplt = hil.dout("a_box", "NotPrechargeComplete") + sdc = hil.dout("a_box", "SDC") + + # HIL inputs (hil reads) + resistor = hil.din("a_box", "NetK1_4") # To precharge resistor - # Duration test time.sleep(1) n_pchg_cmplt.state = 1 - sdc.state = RLY_ON - time.sleep(RLY_DLY) - # hil.check(resistor.state == 1, "Duration init") - check.equal(resistor.state, 1, "Duration init") + sdc.state = RLY_ON + time.sleep(0.1) + check.equal(resistor.state, 1, "Duration start") time.sleep(9) - # hil.check(resistor.state == 1, "Duration mid") - check.equal(resistor.state, 1, "Duration mid") + check.equal(resistor.state, 1, "Duration middle") n_pchg_cmplt.state = 0 - time.sleep(RLY_DLY) - # hil.check(resistor.state == 0, "Duration end") + time.sleep(0.1) check.equal(resistor.state, 0, "Duration end") - - # hil.end_test() # ---------------------------------------------------------------------------- # @@ -173,13 +152,12 @@ def test_precharge(hil): TIFF_DLY = 0.3 def test_tiffomy(hil): - # Begin the test - # hil.start_test(test_tiffomy.__name__) + """Tractive Isolation Fault Detection""" - # Outputs + # HIL outputs (hil writes) bat_p = hil.dout("a_box", "Batt+") - # Inputs + # HIL inputs (hil reads) vbat = hil.ain("a_box", "VBatt") imd_hv = hil.din("a_box", "Batt+_Fused") @@ -188,13 +166,12 @@ def test_tiffomy(hil): utils.log_warning(f"Assuming supply = {SUPPLY_VOLTAGE} V") utils.log_warning(f"Do not reverse polarity Vbat, it will kill Arduino ADC") - input("Click enter to acknowledge or ctrl+c to cancel") + # input("Click enter to acknowledge or ctrl+c to cancel") bat_p.state = RLY_OFF time.sleep(TIFF_DLY) - # hil.check_within(vbat.state, 0.0, 0.1, "TIff off") - # hil.check(imd_hv.state == 0, "IMD HV off") - check.almost_equal(vbat.state, 0.0, abs=0.1, rel=0.0, msg="TIff off") + + check.almost_equal(vbat.state, 0.0, abs=0.1, rel=0.0, msg="Tiff off") check.equal(imd_hv.state, 0, "IMD HV off") bat_p.state = RLY_ON @@ -202,120 +179,73 @@ def test_tiffomy(hil): exp = SUPPLY_VOLTAGE #input("press enter, tiff should be getting volts") meas = tiff_lv_to_hv(vbat.state) - print(f"Tiff HV reading: {meas} V, expect: {SUPPLY_VOLTAGE} V") - # hil.check_within(meas, exp, 2.5, "Tiff on") - # hil.check(imd_hv.state == 1, "IMD HV on") check.almost_equal(meas, exp, abs=2.5, rel=0.0, msg="Tiff on") check.equal(imd_hv.state, 1, "IMD HV on") - - # hil.end_test() # ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- # -def test_tmu(hil): - # Begin the test - # hil.start_test(test_tmu.__name__) +TMU_TOLERANCE = 100 +TMU_HIGH_VALUE = 1970 # 2148 - # Outputs - tmu_a_do = hil.dout("a_box", "TMU_1") - tmu_b_do = hil.dout("a_box", "TMU_2") - tmu_c_do = hil.dout("a_box", "TMU_3") - tmu_d_do = hil.dout("a_box", "TMU_4") +@pytest.mark.parametrize("mux_value", list(range(16))) +def test_tmu_mux(hil, mux_value): + """Thermal Management Unit MUX""" + # HIL outputs (hil writes) daq_override = hil.daq_var("a_box", "tmu_daq_override") daq_therm = hil.daq_var("a_box", "tmu_daq_therm") - # Inputs - mux_a = hil.din("a_box", "MUX_A_NON_ISO") - mux_b = hil.din("a_box", "MUX_B_NON_ISO") - mux_c = hil.din("a_box", "MUX_C_NON_ISO") - mux_d = hil.din("a_box", "MUX_D_NON_ISO") - - tmu_a_ai = hil.daq_var("a_box", "tmu_1") - tmu_b_ai = hil.daq_var("a_box", "tmu_2") - tmu_c_ai = hil.daq_var("a_box", "tmu_3") - tmu_d_ai = hil.daq_var("a_box", "tmu_4") + # HIL inputs (hil reads) + mux_a = hil.din("a_box", "MUX_A_NON_BOOST") + mux_b = hil.din("a_box", "MUX_B_NON_BOOST") + mux_c = hil.din("a_box", "MUX_C_NON_BOOST") + mux_d = hil.din("a_box", "MUX_D_NON_BOOST") daq_therm.state = 0 daq_override.state = 1 - # mux line test - for i in range(0,16): - daq_therm.state = i - time.sleep(0.05) - # hil.check(mux_a.state == bool(i & 0x1), f"Mux A test {i}") - # hil.check(mux_b.state == bool(i & 0x2), f"Mux B test {i}") - # hil.check(mux_c.state == bool(i & 0x4), f"Mux C test {i}") - # hil.check(mux_d.state == bool(i & 0x8), f"Mux D test {i}") - check.equal(mux_a.state, bool(i & 0x1), f"Mux A test {i}") - check.equal(mux_b.state, bool(i & 0x2), f"Mux B test {i}") - check.equal(mux_c.state, bool(i & 0x4), f"Mux C test {i}") - check.equal(mux_d.state, bool(i & 0x8), f"Mux D test {i}") + daq_therm.state = mux_value + time.sleep(0.05) - daq_override.state = 0 + expected_a = bool(mux_value & 0x1) + expected_b = bool(mux_value & 0x2) + expected_c = bool(mux_value & 0x4) + expected_d = bool(mux_value & 0x8) + + check.equal(mux_a.state, expected_a, f"Mux A test ({mux_value})") + check.equal(mux_b.state, expected_b, f"Mux B test ({mux_value})") + check.equal(mux_c.state, expected_c, f"Mux C test ({mux_value})") + check.equal(mux_d.state, expected_d, f"Mux D test ({mux_value})") - TMU_TOLERANCE = 100 - TMU_HIGH_VALUE = 1970 #2148 - - # thermistors - for i in range(0,16): - tmu_a_do.state = bool(i & 0x1) - tmu_b_do.state = bool(i & 0x2) - tmu_c_do.state = bool(i & 0x4) - tmu_d_do.state = bool(i & 0x8) - time.sleep(1.0) - a = int(tmu_a_ai.state) - b = int(tmu_b_ai.state) - c = int(tmu_c_ai.state) - d = int(tmu_d_ai.state) - print(f"Readings at therm={i}: {a}, {b}, {c}, {d}") - # hil.check_within(a, TMU_HIGH_VALUE if (i & 0x1) else 0, TMU_TOLERANCE, f"TMU 1 test {i}") - # hil.check_within(b, TMU_HIGH_VALUE if (i & 0x2) else 0, TMU_TOLERANCE, f"TMU 2 test {i}") - # hil.check_within(c, TMU_HIGH_VALUE if (i & 0x4) else 0, TMU_TOLERANCE, f"TMU 3 test {i}") - # hil.check_within(d, TMU_HIGH_VALUE if (i & 0x8) else 0, TMU_TOLERANCE, f"TMU 4 test {i}") - check.almost_equal(a, TMU_HIGH_VALUE if (i & 0x1) else 0, abs=TMU_TOLERANCE, rel=0.0, msg=f"TMU 1 test {i}") - check.almost_equal(b, TMU_HIGH_VALUE if (i & 0x2) else 0, abs=TMU_TOLERANCE, rel=0.0, msg=f"TMU 2 test {i}") - check.almost_equal(c, TMU_HIGH_VALUE if (i & 0x4) else 0, abs=TMU_TOLERANCE, rel=0.0, msg=f"TMU 3 test {i}") - check.almost_equal(d, TMU_HIGH_VALUE if (i & 0x8) else 0, abs=TMU_TOLERANCE, rel=0.0, msg=f"TMU 4 test {i}") - - # hil.end_test() + daq_override.state = 0 # ---------------------------------------------------------------------------- # # ---------------------------------------------------------------------------- # def test_imd(hil): - # hil.start_test(test_imd.__name__) + """Insulation Monitoring Device""" - # Outputs + # HIL outputs (hil writes) imd_out = hil.dout('a_box', 'IMD_Status') - # Inputs - imd_in = hil.din('a_box', 'IMD_STATUS_LV_COMP') + # HIL inputs (hil reads) + imd_in = hil.din('a_box', 'IMD_STATUS_LV_COMP') imd_mcu = hil.mcu_pin('a_box', 'IMD_STATUS_LV_COMP') - imd_out.state = RLY_OFF - time.sleep(RLY_DLY) + time.sleep(0.1) - # hil.check(imd_in.state == 0, 'IMD LV OFF') - # hil.check(imd_mcu.state == 0, 'IMD MCU OFF') - check.equal(imd_in.state, 0, 'IMD LV OFF') - check.equal(imd_mcu.state, 0, 'IMD MCU OFF') + check.equal(imd_in.state, 0, 'IMD LV off') + check.equal(imd_mcu.state, 0, 'IMD MCU off') imd_out.state = RLY_ON - time.sleep(RLY_DLY) + time.sleep(0.1) - # hil.check(imd_in.state == 1, 'IMD LV ON') - # hil.check(imd_mcu.state == 1, 'IMD MCU ON') - check.equal(imd_in.state, 1, 'IMD LV ON') - check.equal(imd_mcu.state, 1, 'IMD MCU ON') + check.equal(imd_in.state, 1, 'IMD LV on') + check.equal(imd_mcu.state, 1, 'IMD MCU on') imd_out.state = RLY_OFF - time.sleep(RLY_DLY) - - # hil.check(imd_in.state == 0, 'IMD LV BACK OFF') - # hil.check(imd_mcu.state == 0, 'IMD MCU BACK OFF') - check.equal(imd_in.state, 0, 'IMD LV BACK OFF') - check.equal(imd_mcu.state, 0, 'IMD MCU BACK OFF') + time.sleep(0.1) - # hil.end_test() + check.equal(imd_in.state, 0, 'IMD LV BACK off') + check.equal(imd_mcu.state, 0, 'IMD MCU BACK off') # ---------------------------------------------------------------------------- # diff --git a/scripts/node_specific/scripts/test_dash.py b/scripts/node_specific/scripts/test_dash.py index 8b1035f..3ab4b19 100644 --- a/scripts/node_specific/scripts/test_dash.py +++ b/scripts/node_specific/scripts/test_dash.py @@ -5,6 +5,7 @@ from hil.hil import HIL import hil.utils as utils import time +import random from scripts.common.constants.rules_constants import * from scripts.common.constants.vehicle_constants import * @@ -31,50 +32,49 @@ def hil(): # ---------------------------------------------------------------------------- # BRK_SWEEP_DELAY = 0.1 -def test_bspd(hil): - # Begin the test - # hil.start_test(test_bspd.__name__) - # Outputs - brk1 = hil.aout("Dashboard", "BRK1_RAW") - brk2 = hil.aout("Dashboard", "BRK2_RAW") +def test_bspd(hil): + # HIL outputs (hil writes) + brk1 = hil.aout("Dashboard", "BRK1_RAW") + brk2 = hil.aout("Dashboard", "BRK2_RAW") - # Inputs + # HIL inputs (hil reads) brk_fail_tap = hil.mcu_pin("Dashboard", "BRK_FAIL_TAP") brk_stat_tap = hil.mcu_pin("Dashboard", "BRK_STAT_TAP") - # Brake threshold check + # Brakes 1 and 2 are at rest brk1.state = BRK_1_REST_V brk2.state = BRK_2_REST_V - # hil.check(brk_stat_tap.state == 0, "Brake stat starts low") - check.equal(brk_stat_tap.state, 0, "Brake stat starts low") + time.sleep(0.1) + check.equal(brk_stat_tap.state, 0, f"Brakes 1 ({BRK_1_REST_V}) and 2 ({BRK_2_REST_V}) -> rests") + # Brake 1 trips brk1.state = BRK_1_THRESH_V time.sleep(0.1) - # hil.check(brk_stat_tap.state == 1, "Brake stat goes high at brk 1 thresh") - check.equal(brk_stat_tap.state, 1, "Brake stat goes high at brk 1 thresh") + check.equal(brk_stat_tap.state, 1, f"Brake 1 ({BRK_1_THRESH_V}) -> trips") + # Brake 1 resets -> rest brk1.state = BRK_1_REST_V - # hil.check(brk_stat_tap.state == 0, "Brake stat starts low") - check.equal(brk_stat_tap.state, 0, "Brake stat starts low") + time.sleep(0.1) + check.equal(brk_stat_tap.state, 0, f"Brake 1 ({BRK_1_REST_V}) -> rests") + # Brake 2 trips brk2.state = BRK_2_THRESH_V time.sleep(0.1) - # hil.check(brk_stat_tap.state == 1, "Brake stat goes high at brk 2 thresh") - check.equal(brk_stat_tap.state, 1, "Brake stat goes high at brk 2 thresh") + check.equal(brk_stat_tap.state, 1, f"Brake 2 ({BRK_2_THRESH_V}) -> trips") + # Brake 1 high -> still tripped brk1.state = BRK_1_THRESH_V - # hil.check(brk_stat_tap.state == 1, "Brake stat stays high for both brakes") - check.equal(brk_stat_tap.state, 1, "Brake stat stays high for both brakes") - + time.sleep(0.1) + check.equal(brk_stat_tap.state, 1, f"Brakes (1 -> {BRK_1_REST_V}) stay tripped") - # Brake threshold scan + # Reset both brakes brk1.state = BRK_MIN_OUT_V brk2.state = BRK_MIN_OUT_V time.sleep(0.1) - # hil.check(brk_stat_tap.state == 0, "Brake Stat Starts Low Brk 1") - check.equal(brk_stat_tap.state, 0, "Brake Stat Starts Low Brk 1") + check.equal(brk_stat_tap.state, 0, f"Brakes 1 ({BRK_MIN_OUT_V}) and 2 ({BRK_MIN_OUT_V}) -> rests") + # Brake 1 trips at the correct voltage start = BRK_MIN_OUT_V stop = BRK_MAX_OUT_V step = 0.1 @@ -83,98 +83,135 @@ def test_bspd(hil): BRK_SWEEP_DELAY, brk_stat_tap, is_falling=False) print(f"Brake 1 braking threshold: {thresh}") - # hil.check_within(thresh, BRK_1_THRESH_V, 0.2, "Brake 1 trip voltage") - # hil.check(brk_stat_tap.state == 1, "Brake Stat Tripped for Brk 1") check.almost_equal( thresh, BRK_1_THRESH_V, abs=0.2, rel=0.0, - msg="Brake 1 trip voltage" + msg="Brake 1 trips at correct voltage" ) - check.equal(brk_stat_tap.state, 1, "Brake Stat Tripped for Brk 1") + check.equal(brk_stat_tap.state, 1, "Brake 1 tripped") + # Reset both brakes brk1.state = BRK_MIN_OUT_V brk2.state = BRK_MIN_OUT_V - hil.check(brk_stat_tap.state == 0, "Brake Stat Starts Low Brk 2") + time.sleep(0.1) + hil.check(brk_stat_tap.state == 0, f"Brakes 1 ({BRK_MIN_OUT_V}) and 2 ({BRK_MIN_OUT_V}) -> rests") + + # Brake 2 trips at the correct voltage thresh = utils.measure_trip_thresh(brk2, start, stop, step, BRK_SWEEP_DELAY, brk_stat_tap, is_falling=False) print(f"Brake 2 braking threshold: {thresh}") - # hil.check_within(thresh, BRK_2_THRESH_V, 0.2, "Brake 2 trip voltage") - # hil.check(brk_stat_tap.state == 1, "Brake Stat Tripped for Brk 2") check.almost_equal( thresh, BRK_2_THRESH_V, abs=0.2, rel=0.0, - msg="Brake 2 trip voltage" + msg="Brake 2 trips at correct voltage" ) - check.equal(brk_stat_tap.state, 1, "Brake Stat Tripped for Brk 2") + check.equal(brk_stat_tap.state, 1, "Brake 2 tripped") - # Brake Fail scan + + # Brakes at rest brk1.state = BRK_1_REST_V brk2.state = BRK_2_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 1 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 1 Starts 0") + check.equal(brk_fail_tap.state, 0, f"Brakes 1 ({BRK_1_REST_V}) and 2 ({BRK_2_REST_V}) -> no fail") - brk1.state = 0.0 # Force 0 + # Brake 1 forced to 0V (short to GND) + brk1.state = 0.0 time.sleep(0.1) - # hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 1 Short GND") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 1 Short GND") + check.equal(brk_fail_tap.state, 1, "Brake 1 short to GND -> fail") + # Reset brake 1 brk1.state = BRK_1_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 2 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 2 Starts 0") + check.equal(brk_fail_tap.state, 0, "Brake 1 reset -> no fail") - brk2.state = 0.0 # Force 0 + # Brake 2 forced to 0V (short to GND) + brk2.state = 0.0 time.sleep(0.1) - hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 2 Short GND") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 2 Short GND") + check.equal(brk_fail_tap.state, 1, "Brake 2 short to GND -> fail") + # Reset brake 2 brk2.state = BRK_2_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 3 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 3 Starts 0") + check.equal(brk_fail_tap.state, 0, "Brake 2 reset -> no fail") - brk1.state = 5.0 # Short VCC + # Brake 1 forced to 5V (short to VCC) + brk1.state = 5.0 time.sleep(0.1) - # hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 1 Short VCC") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 1 Short VCC") + check.equal(brk_fail_tap.state, 1, "Brake 1 short to VCC -> fail") + # Reset brake 1 brk1.state = BRK_1_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 4 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 4 Starts 0") + check.equal(brk_fail_tap.state, 0, "Brake 1 reset -> no fail") - brk2.state = 5.0 # Short VCC + # Brake 2 forced to 5V (short to VCC) + brk2.state = 5.0 time.sleep(0.1) - # hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 2 Short VCC") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 2 Short VCC") + check.equal(brk_fail_tap.state, 1, "Brake 2 short to VCC -> fail") + # Reset brake 2 brk2.state = BRK_2_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 5 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 5 Starts 0") + check.equal(brk_fail_tap.state, 0, "Brake 2 reset -> no fail") + # Brake 1 Hi-Z brk1.hiZ() time.sleep(0.1) - # hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 1 Hi-Z") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 1 Hi-Z") + check.equal(brk_fail_tap.state, 1, "Brake 1 Hi-Z -> fail") + # Reset brake 1 brk1.state = BRK_1_REST_V time.sleep(0.1) - # hil.check(brk_fail_tap.state == 0, "Brake Fail Check 6 Starts 0") - check.equal(brk_fail_tap.state, 0, "Brake Fail Check 6 Starts 0") + check.equal(brk_fail_tap.state, 0, "Brake 1 reset -> no fail") + # Brake 2 Hi-Z brk2.hiZ() time.sleep(0.1) - # hil.check(brk_fail_tap.state == 1, "Brake Fail Brk 2 Hi-Z") - check.equal(brk_fail_tap.state, 1, "Brake Fail Brk 2 Hi-Z") + check.equal(brk_fail_tap.state, 1, "Brake 2 Hi-Z -> fail") + # Reset brake 2 brk2.state = BRK_2_REST_V - - # End the test - # hil.end_test() # ---------------------------------------------------------------------------- # # TODO: add throttle checks + +# ---------------------------------------------------------------------------- # +THROTTLE_VARIANCE = 0.1 + + +def test_throttle(hil): + # HIL outputs (hil writes) + thrtl1 = hil.aout("Dashboard", "THRTL1_RAW") + thrtl2 = hil.aout("Dashboard", "THRTL2_RAW") + + # HIL inputs (hil reads) + thrtl1_flt = hil.mcu_pin("Dashboard", "THRTL1_FLT") + thrtl2_flt = hil.mcu_pin("Dashboard", "THRTL2_FLT") + + # 0-5V throttle sweep with 0.2 + throttle_values = [x / 10.0 for x in range(0, 52, 2)] + random.shuffle(throttle_values) + + # Sweep throttle 1 + for v in throttle_values: + thrtl1.state = v + time.sleep(0.1) + check.almost_equal( + thrtl1_flt.state, v, + abs=THROTTLE_VARIANCE, rel=0.0, + msg=f"Throttle 1: {v}V" + ) + + # Sweep throttle 2 + for v in throttle_values: + thrtl2.state = v + time.sleep(0.1) + check.almost_equal( + thrtl2_flt.state, v, + abs=THROTTLE_VARIANCE, rel=0.0, + msg=f"Throttle 2: {v}V" + ) +# ---------------------------------------------------------------------------- # +