Example #1
0
class TestHondaNidecAltInterceptorSafety(TestHondaNidecSafety,
                                         common.InterceptorSafetyTest):
    """
    Covers the Honda Nidec safety mode with alt SCM messages and gas interceptor
  """
    def setUp(self):
        self.packer = CANPackerPanda("acura_ilx_2016_can_generated")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC,
                                     Panda.FLAG_HONDA_NIDEC_ALT)
        self.safety.init_tests_honda()

    def _acc_state_msg(self, main_on):
        values = {"MAIN_ON": main_on, "COUNTER": self.cnt_acc_state % 4}
        self.__class__.cnt_acc_state += 1
        return self.packer.make_can_msg_panda("SCM_BUTTONS", self.PT_BUS,
                                              values)

    def _button_msg(self, buttons, main_on=False):
        values = {
            "CRUISE_BUTTONS": buttons,
            "MAIN_ON": main_on,
            "COUNTER": self.cnt_button % 4
        }
        self.__class__.cnt_button += 1
        return self.packer.make_can_msg_panda("SCM_BUTTONS", self.PT_BUS,
                                              values)
Example #2
0
 def setUp(self):
     self.packer = CANPackerPanda("acura_ilx_2016_can_generated")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC,
                                  Panda.FLAG_HONDA_NIDEC_ALT)
     self.safety.init_tests_honda()
     common.InterceptorSafetyTest.setUpClass()
Example #3
0
 def setUp(self):
     self.packer = CANPackerPanda("tesla_powertrain")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(
         Panda.SAFETY_TESLA,
         Panda.FLAG_TESLA_LONG_CONTROL | Panda.FLAG_TESLA_POWERTRAIN)
     self.safety.init_tests()
Example #4
0
class TestSubaruLegacySafety(TestSubaruSafety):

    TX_MSGS = [[0x164, 0], [0x221, 0], [0x322, 0]]
    RELAY_MALFUNCTION_ADDR = 0x164
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [356, 545, 802]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}

    def setUp(self):
        self.packer = CANPackerPanda("subaru_outback_2015_eyesight")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_SUBARU_LEGACY, 0)
        self.safety.init_tests()

    # subaru legacy safety doesn't have brake checks
    def test_prev_brake(self):
        pass

    def test_not_allow_brake_when_moving(self):
        pass

    def test_allow_brake_at_zero_speed(self):
        pass

    # doesn't have speed checks either
    def test_sample_speed(self):
        pass

    def _torque_driver_msg(self, torque):
        # TODO: figure out if this scaling factor from the DBC is right.
        # if it is, remove the scaling from here and put it in the safety code
        values = {"Steer_Torque_Sensor": torque * 8}
        return self.packer.make_can_msg_panda("Steering_Torque", 0, values)

    def _torque_msg(self, torque):
        values = {"LKAS_Command": torque}
        return self.packer.make_can_msg_panda("ES_LKAS", 0, values)

    def _gas_msg(self, gas):
        values = {"Throttle_Pedal": gas}
        return self.packer.make_can_msg_panda("Throttle", 0, values)

    def _pcm_status_msg(self, enable):
        values = {"Cruise_Activated": enable}
        return self.packer.make_can_msg_panda("CruiseControl", 0, values)
Example #5
0
class TestNissanLeafSafety(TestNissanSafety):
    def setUp(self):
        self.packer = CANPackerPanda("nissan_leaf_2018")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0)
        self.safety.init_tests()

    def _user_brake_msg(self, brake):
        values = {"USER_BRAKE_PRESSED": brake}
        return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 0, values)

    def _user_gas_msg(self, gas):
        values = {"GAS_PEDAL": gas}
        return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 0, values)

    # TODO: leaf should use its own safety param
    def test_acc_buttons(self):
        pass
Example #6
0
class TestHyundaiLegacySafetyHEV(TestHyundaiSafety):
  def setUp(self):
    self.packer = CANPackerPanda("hyundai_kia_generic")
    self.safety = libpandasafety_py.libpandasafety
    self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_LEGACY, 2)
    self.safety.init_tests()

  def _gas_msg(self, gas):
    values = {"CR_Vcu_AccPedDep_Pos": gas}
    return self.packer.make_can_msg_panda("E_EMS11", 0, values, fix_checksum=checksum)
Example #7
0
class TestHondaBoschSafetyBase(TestHondaSafetyBase):
    PT_BUS = 1
    STEER_BUS = 0

    TX_MSGS = [[0xE4, 0], [0xE5, 0], [0x296, 1], [0x33D, 0], [0x33DA, 0],
               [0x33DB, 0]]
    FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0xE5, 0x33D, 0x33DA, 0x33DB]}

    @classmethod
    def setUpClass(cls):
        if cls.__name__ == "TestHondaBoschSafetyBase":
            cls.packer = None
            cls.safety = None
            raise unittest.SkipTest

    def setUp(self):
        self.packer = CANPackerPanda("honda_accord_2018_can_generated")
        self.safety = libpandasafety_py.libpandasafety

    def _alt_brake_msg(self, brake):
        values = {"BRAKE_PRESSED": brake, "COUNTER": self.cnt_brake % 4}
        self.__class__.cnt_brake += 1
        return self.packer.make_can_msg_panda("BRAKE_MODULE", self.PT_BUS,
                                              values)

    def _send_brake_msg(self, brake):
        pass

    # TODO: add back in once alternative brake checksum/counter validation is added
    # def test_alt_brake_rx_hook(self):
    #   self.safety.set_honda_alt_brake_msg(1)
    #   self.safety.set_controls_allowed(1)
    #   to_push = self._alt_brake_msg(0)
    #   self.assertTrue(self._rx(to_push))
    #   to_push[0].RDLR = to_push[0].RDLR & 0xFFF0FFFF # invalidate checksum
    #   self.assertFalse(self._rx(to_push))
    #   self.assertFalse(self.safety.get_controls_allowed())
    def test_alt_disengage_on_brake(self):
        self.safety.set_honda_alt_brake_msg(1)
        self.safety.set_controls_allowed(1)
        self._rx(self._alt_brake_msg(1))
        self.assertFalse(self.safety.get_controls_allowed())

        self.safety.set_honda_alt_brake_msg(0)
        self.safety.set_controls_allowed(1)
        self._rx(self._alt_brake_msg(1))
        self.assertTrue(self.safety.get_controls_allowed())
Example #8
0
class TestHondaBoschSafety(TestHondaSafety):
    STANDSTILL_THRESHOLD = 0
    RELAY_MALFUNCTION_ADDR = 0xE4

    @classmethod
    def setUpClass(cls):
        if cls.__name__ == "TestHondaBoschSafety":
            cls.packer = None
            cls.safety = None
            raise unittest.SkipTest

    def setUp(self):
        self.packer = CANPackerPanda("honda_accord_s2t_2018_can_generated")
        self.safety = libpandasafety_py.libpandasafety

    def _alt_brake_msg(self, brake):
        values = {"BRAKE_PRESSED": brake, "COUNTER": self.cnt_brake % 4}
        self.__class__.cnt_brake += 1
        return self.packer.make_can_msg_panda("BRAKE_MODULE", self.PT_BUS,
                                              values)

    def _send_brake_msg(self, brake):
        pass

    # TODO: add back in once alternative brake checksum/counter validation is added
    # def test_alt_brake_rx_hook(self):
    #   self.safety.set_honda_alt_brake_msg(1)
    #   self.safety.set_controls_allowed(1)
    #   to_push = self._alt_brake_msg(0)
    #   self.assertTrue(self._rx(to_push))
    #   to_push[0].RDLR = to_push[0].RDLR & 0xFFF0FFFF # invalidate checksum
    #   self.assertFalse(self._rx(to_push))
    #   self.assertFalse(self.safety.get_controls_allowed())
    def test_alt_disengage_on_brake(self):
        self.safety.set_honda_alt_brake_msg(1)
        self.safety.set_controls_allowed(1)
        self._rx(self._alt_brake_msg(1))
        self.assertFalse(self.safety.get_controls_allowed())

        self.safety.set_honda_alt_brake_msg(0)
        self.safety.set_controls_allowed(1)
        self._rx(self._alt_brake_msg(1))
        self.assertTrue(self.safety.get_controls_allowed())
Example #9
0
 def setUp(self):
     self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, 0)
     self.safety.init_tests()
Example #10
0
 def setUp(self):
     self.packer = CANPackerPanda("honda_accord_s2t_2018_can_generated")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_HARNESS, 0)
     self.safety.init_tests_honda()
Example #11
0
 def setUp(self):
     self.packer = CANPackerPanda("honda_civic_touring_2016_can_generated")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_HONDA_NIDEC, 0)
     self.safety.init_tests_honda()
Example #12
0
 def setUp(self):
     self.packer = CANPackerPanda("toyota_prius_2017_pt_generated")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66)
     self.safety.init_tests()
Example #13
0
 def setUp(self):
     self.packer = CANPackerPanda("nissan_x_trail_2017")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0)
     self.safety.init_tests()
Example #14
0
 def setUp(self):
     self.packer = CANPackerPanda("subaru_outback_2015_eyesight")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_SUBARU_LEGACY, 0)
     self.safety.init_tests_subaru()
Example #15
0
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest,
                       common.TorqueSteeringSafetyTest):

    TX_MSGS = [
        [0x283, 0],
        [0x2E6, 0],
        [0x2E7, 0],
        [0x33E, 0],
        [0x344, 0],
        [0x365, 0],
        [0x366, 0],
        [0x4CB, 0],  # DSU bus 0
        [0x128, 1],
        [0x141, 1],
        [0x160, 1],
        [0x161, 1],
        [0x470, 1],  # DSU bus 1
        [0x2E4, 0],
        [0x191, 0],
        [0x411, 0],
        [0x412, 0],
        [0x343, 0],
        [0x1D2, 0],  # LKAS + ACC
        [0x200, 0],
        [0x750, 0]
    ]  # interceptor + blindspot monitor
    STANDSTILL_THRESHOLD = 1  # 1kph
    RELAY_MALFUNCTION_ADDR = 0x2E4
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}
    INTERCEPTOR_THRESHOLD = 845

    MAX_RATE_UP = 15
    MAX_RATE_DOWN = 25
    MAX_TORQUE = 1500
    MAX_RT_DELTA = 450
    RT_INTERVAL = 250000
    MAX_TORQUE_ERROR = 350
    TORQUE_MEAS_TOLERANCE = 1  # toyota safety adds one to be conversative for rounding
    EPS_SCALE = 0.73

    def setUp(self):
        self.packer = CANPackerPanda("toyota_nodsu_pt_generated")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 73)
        self.safety.init_tests()

    def _torque_meas_msg(self, torque):
        values = {"STEER_TORQUE_EPS": (torque / self.EPS_SCALE)}
        return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values)

    def _torque_msg(self, torque):
        values = {"STEER_TORQUE_CMD": torque}
        return self.packer.make_can_msg_panda("STEERING_LKA", 0, values)

    def _lta_msg(self, req, req2, angle_cmd):
        values = {
            "STEER_REQUEST": req,
            "STEER_REQUEST_2": req2,
            "STEER_ANGLE_CMD": angle_cmd
        }
        return self.packer.make_can_msg_panda("STEERING_LTA", 0, values)

    def _accel_msg(self, accel):
        values = {"ACCEL_CMD": accel}
        return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values)

    def _speed_msg(self, speed):
        values = {("WHEEL_SPEED_%s" % n): speed
                  for n in ["FR", "FL", "RR", "RL"]}
        return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values)

    def _user_brake_msg(self, brake):
        values = {"BRAKE_PRESSED": brake}
        return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values)

    def _user_gas_msg(self, gas):
        cruise_active = self.safety.get_controls_allowed()
        values = {"GAS_RELEASED": not gas, "CRUISE_ACTIVE": cruise_active}
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    def _pcm_status_msg(self, enable):
        values = {"CRUISE_ACTIVE": enable}
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    def _interceptor_gas_cmd(self, gas):
        return interceptor_msg(gas, 0x200)

    def _interceptor_user_gas(self, gas):
        return interceptor_msg(gas, 0x201)

    def test_block_aeb(self):
        for controls_allowed in (True, False):
            for bad in (True, False):
                for _ in range(10):
                    self.safety.set_controls_allowed(controls_allowed)
                    dat = [random.randint(1, 255) for _ in range(7)]
                    if not bad:
                        dat = [0] * 6 + dat[-1:]
                    msg = common.package_can_msg([0x283, 0, bytes(dat), 0])
                    self.assertEqual(not bad, self._tx(msg))

    def test_accel_actuation_limits(self):
        limits = ((MIN_ACCEL, MAX_ACCEL, ALTERNATIVE_EXPERIENCE.DEFAULT), (
            MIN_ACCEL, MAX_ACCEL,
            ALTERNATIVE_EXPERIENCE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX))

        for min_accel, max_accel, alternative_experience in limits:
            for accel in np.arange(min_accel - 1, max_accel + 1, 0.1):
                for controls_allowed in [True, False]:
                    self.safety.set_controls_allowed(controls_allowed)
                    self.safety.set_alternative_experience(
                        alternative_experience)
                    if controls_allowed:
                        should_tx = int(min_accel * 1000) <= int(
                            accel * 1000) <= int(max_accel * 1000)
                    else:
                        should_tx = np.isclose(accel, 0, atol=0.0001)
                    self.assertEqual(should_tx,
                                     self._tx(self._accel_msg(accel)))

    # Only allow LTA msgs with no actuation
    def test_lta_steer_cmd(self):
        for engaged in [True, False]:
            self.safety.set_controls_allowed(engaged)

            # good msg
            self.assertTrue(self._tx(self._lta_msg(0, 0, 0)))

            # bad msgs
            self.assertFalse(self._tx(self._lta_msg(1, 0, 0)))
            self.assertFalse(self._tx(self._lta_msg(0, 1, 0)))
            self.assertFalse(self._tx(self._lta_msg(0, 0, 1)))

            for _ in range(20):
                req = random.choice([0, 1])
                req2 = random.choice([0, 1])
                angle = random.randint(-50, 50)
                should_tx = not req and not req2 and angle == 0
                self.assertEqual(should_tx,
                                 self._tx(self._lta_msg(req, req2, angle)))

    def test_rx_hook(self):
        # checksum checks
        for msg in ["trq", "pcm"]:
            self.safety.set_controls_allowed(1)
            if msg == "trq":
                to_push = self._torque_meas_msg(0)
            if msg == "pcm":
                to_push = self._pcm_status_msg(True)
            self.assertTrue(self._rx(to_push))
            to_push[0].data[4] = 0
            to_push[0].data[5] = 0
            to_push[0].data[6] = 0
            to_push[0].data[7] = 0
            self.assertFalse(self._rx(to_push))
            self.assertFalse(self.safety.get_controls_allowed())
Example #16
0
 def setUp(self):
   self.packer = CANPackerPanda("vw_mqb_2010")
   self.safety = libpandasafety_py.libpandasafety
   self.safety.set_safety_hooks(Panda.SAFETY_VOLKSWAGEN_MQB, 0)
   self.safety.init_tests_volkswagen()
Example #17
0
class TestVolkswagenMqbSafety(common.PandaSafetyTest):
  cnt_eps_01 = 0
  cnt_esp_05 = 0
  cnt_tsk_06 = 0
  cnt_motor_20 = 0
  cnt_hca_01 = 0
  cnt_gra_acc_01 = 0

  # Transmit of GRA_ACC_01 is allowed on bus 0 and 2 to keep
  # compatibility with gateway and camera integration
  TX_MSGS = [[MSG_HCA_01, 0], [MSG_GRA_ACC_01, 0], [MSG_GRA_ACC_01, 2], [MSG_LDW_02, 0]]
  STANDSTILL_THRESHOLD = 1
  RELAY_MALFUNCTION_ADDR = MSG_HCA_01
  RELAY_MALFUNCTION_BUS = 0
  FWD_BLACKLISTED_ADDRS = {2: [MSG_HCA_01, MSG_LDW_02]}
  FWD_BUS_LOOKUP = {0: 2, 2: 0}

  @classmethod
  def setUp(self):
    self.packer = CANPackerPanda("vw_mqb_2010")
    self.safety = libpandasafety_py.libpandasafety
    self.safety.set_safety_hooks(Panda.SAFETY_VOLKSWAGEN_MQB, 0)
    self.safety.init_tests_volkswagen()

  # override these inherited tests from PandaSafetyTest
  def test_cruise_engaged_prev(self): pass

  def _set_prev_torque(self, t):
    self.safety.set_volkswagen_desired_torque_last(t)
    self.safety.set_volkswagen_rt_torque_last(t)

  # Wheel speeds _esp_19_msg
  def _speed_msg(self, speed):
    values = {"ESP_%s_Radgeschw_02"%s: speed for s in ["HL", "HR", "VL", "VR"]}
    return self.packer.make_can_msg_panda("ESP_19", 0, values)

  # Brake light switch _esp_05_msg
  def _brake_msg(self, brake):
    values = {"ESP_Fahrer_bremst": brake, "COUNTER": self.cnt_esp_05 % 16}
    self.__class__.cnt_esp_05 += 1
    return self.packer.make_can_msg_panda("ESP_05", 0, values)

  # Driver throttle input
  def _gas_msg(self, gas):
    values = {"MO_Fahrpedalrohwert_01": gas, "COUNTER": self.cnt_motor_20 % 16}
    self.__class__.cnt_motor_20 += 1
    return self.packer.make_can_msg_panda("Motor_20", 0, values)

  # ACC engagement status
  def _pcm_status_msg(self, enable):
    values = {"TSK_Status": 3 if enable else 1, "COUNTER": self.cnt_tsk_06 % 16}
    self.__class__.cnt_tsk_06 += 1
    return self.packer.make_can_msg_panda("TSK_06", 0, values)

  # Driver steering input torque
  def _eps_01_msg(self, torque):
    values = {"Driver_Strain": abs(torque), "Driver_Strain_VZ": torque < 0,
                "COUNTER": self.cnt_eps_01 % 16}
    self.__class__.cnt_eps_01 += 1
    return self.packer.make_can_msg_panda("EPS_01", 0, values)

  # openpilot steering output torque
  def _hca_01_msg(self, torque):
    values = {"Assist_Torque": abs(torque), "Assist_VZ": torque < 0,
                "COUNTER": self.cnt_hca_01 % 16}
    self.__class__.cnt_hca_01 += 1
    return self.packer.make_can_msg_panda("HCA_01", 0, values)

  # Cruise control buttons
  def _gra_acc_01_msg(self, cancel=0, resume=0, _set=0):
    values = {"GRA_Abbrechen": cancel, "GRA_Tip_Setzen": _set,
                "GRA_Tip_Wiederaufnahme": resume, "COUNTER": self.cnt_gra_acc_01 % 16}
    self.__class__.cnt_gra_acc_01 += 1
    return self.packer.make_can_msg_panda("GRA_ACC_01", 0, values)

  def test_enable_control_allowed_from_cruise(self):
    self.safety.set_controls_allowed(0)
    self._rx(self._pcm_status_msg(True))
    self.assertTrue(self.safety.get_controls_allowed())

  def test_disable_control_allowed_from_cruise(self):
    self.safety.set_controls_allowed(1)
    self._rx(self._pcm_status_msg(False))
    self.assertFalse(self.safety.get_controls_allowed())

  def test_steer_safety_check(self):
    for enabled in [0, 1]:
      for t in range(-500, 500):
        self.safety.set_controls_allowed(enabled)
        self._set_prev_torque(t)
        if abs(t) > MAX_STEER or (not enabled and abs(t) > 0):
          self.assertFalse(self._tx(self._hca_01_msg(t)))
        else:
          self.assertTrue(self._tx(self._hca_01_msg(t)))

  def test_spam_cancel_safety_check(self):
    self.safety.set_controls_allowed(0)
    self.assertTrue(self._tx(self._gra_acc_01_msg(cancel=1)))
    self.assertFalse(self._tx(self._gra_acc_01_msg(resume=1)))
    self.assertFalse(self._tx(self._gra_acc_01_msg(_set=1)))
    # do not block resume if we are engaged already
    self.safety.set_controls_allowed(1)
    self.assertTrue(self._tx(self._gra_acc_01_msg(resume=1)))

  def test_non_realtime_limit_up(self):
    self.safety.set_volkswagen_torque_driver(0, 0)
    self.safety.set_controls_allowed(True)

    self._set_prev_torque(0)
    self.assertTrue(self._tx(self._hca_01_msg(MAX_RATE_UP)))
    self._set_prev_torque(0)
    self.assertTrue(self._tx(self._hca_01_msg(-MAX_RATE_UP)))

    self._set_prev_torque(0)
    self.assertFalse(self._tx(self._hca_01_msg(MAX_RATE_UP + 1)))
    self.safety.set_controls_allowed(True)
    self._set_prev_torque(0)
    self.assertFalse(self._tx(self._hca_01_msg(-MAX_RATE_UP - 1)))

  def test_non_realtime_limit_down(self):
    self.safety.set_volkswagen_torque_driver(0, 0)
    self.safety.set_controls_allowed(True)

  def test_against_torque_driver(self):
    self.safety.set_controls_allowed(True)

    for sign in [-1, 1]:
      for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1):
        t *= -sign
        self.safety.set_volkswagen_torque_driver(t, t)
        self._set_prev_torque(MAX_STEER * sign)
        self.assertTrue(self._tx(self._hca_01_msg(MAX_STEER * sign)))

      self.safety.set_volkswagen_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1)
      self.assertFalse(self._tx(self._hca_01_msg(-MAX_STEER)))

    # spot check some individual cases
    for sign in [-1, 1]:
      driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign
      torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign
      delta = 1 * sign
      self._set_prev_torque(torque_desired)
      self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque)
      self.assertTrue(self._tx(self._hca_01_msg(torque_desired)))
      self._set_prev_torque(torque_desired + delta)
      self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque)
      self.assertFalse(self._tx(self._hca_01_msg(torque_desired + delta)))

      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertTrue(self._tx(self._hca_01_msg((MAX_STEER - MAX_RATE_DOWN) * sign)))
      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertTrue(self._tx(self._hca_01_msg(0)))
      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertFalse(self._tx(self._hca_01_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign)))

  def test_realtime_limits(self):
    self.safety.set_controls_allowed(True)

    for sign in [-1, 1]:
      self.safety.init_tests_volkswagen()
      self._set_prev_torque(0)
      self.safety.set_volkswagen_torque_driver(0, 0)
      for t in np.arange(0, MAX_RT_DELTA, 1):
        t *= sign
        self.assertTrue(self._tx(self._hca_01_msg(t)))
      self.assertFalse(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA + 1))))

      self._set_prev_torque(0)
      for t in np.arange(0, MAX_RT_DELTA, 1):
        t *= sign
        self.assertTrue(self._tx(self._hca_01_msg(t)))

      # Increase timer to update rt_torque_last
      self.safety.set_timer(RT_INTERVAL + 1)
      self.assertTrue(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA - 1))))
      self.assertTrue(self._tx(self._hca_01_msg(sign * (MAX_RT_DELTA + 1))))

  def test_torque_measurements(self):
    self._rx(self._eps_01_msg(50))
    self._rx(self._eps_01_msg(-50))
    self._rx(self._eps_01_msg(0))
    self._rx(self._eps_01_msg(0))
    self._rx(self._eps_01_msg(0))
    self._rx(self._eps_01_msg(0))

    self.assertEqual(-50, self.safety.get_volkswagen_torque_driver_min())
    self.assertEqual(50, self.safety.get_volkswagen_torque_driver_max())

    self._rx(self._eps_01_msg(0))
    self.assertEqual(0, self.safety.get_volkswagen_torque_driver_max())
    self.assertEqual(-50, self.safety.get_volkswagen_torque_driver_min())

    self._rx(self._eps_01_msg(0))
    self.assertEqual(0, self.safety.get_volkswagen_torque_driver_max())
    self.assertEqual(0, self.safety.get_volkswagen_torque_driver_min())

  def test_rx_hook(self):
    # checksum checks
    # TODO: Would be ideal to check ESP_19 as well, but it has no checksum
    # or counter, and I'm not sure if we can easily validate Panda's simple
    # temporal reception-rate check here.
    for msg in [MSG_EPS_01, MSG_ESP_05, MSG_TSK_06, MSG_MOTOR_20]:
      self.safety.set_controls_allowed(1)
      if msg == MSG_EPS_01:
        to_push = self._eps_01_msg(0)
      if msg == MSG_ESP_05:
        to_push = self._brake_msg(False)
      if msg == MSG_TSK_06:
        to_push = self._pcm_status_msg(True)
      if msg == MSG_MOTOR_20:
        to_push = self._gas_msg(0)
      self.assertTrue(self._rx(to_push))
      to_push[0].RDHR ^= 0xFF
      self.assertFalse(self._rx(to_push))
      self.assertFalse(self.safety.get_controls_allowed())

    # counter
    # reset wrong_counters to zero by sending valid messages
    for i in range(MAX_WRONG_COUNTERS + 1):
      self.__class__.cnt_eps_01 += 1
      self.__class__.cnt_esp_05 += 1
      self.__class__.cnt_tsk_06 += 1
      self.__class__.cnt_motor_20 += 1
      if i < MAX_WRONG_COUNTERS:
        self.safety.set_controls_allowed(1)
        self._rx(self._eps_01_msg(0))
        self._rx(self._brake_msg(False))
        self._rx(self._pcm_status_msg(True))
        self._rx(self._gas_msg(0))
      else:
        self.assertFalse(self._rx(self._eps_01_msg(0)))
        self.assertFalse(self._rx(self._brake_msg(False)))
        self.assertFalse(self._rx(self._pcm_status_msg(True)))
        self.assertFalse(self._rx(self._gas_msg(0)))
        self.assertFalse(self.safety.get_controls_allowed())

    # restore counters for future tests with a couple of good messages
    for i in range(2):
      self.safety.set_controls_allowed(1)
      self._rx(self._eps_01_msg(0))
      self._rx(self._brake_msg(False))
      self._rx(self._pcm_status_msg(True))
      self._rx(self._gas_msg(0))
    self.assertTrue(self.safety.get_controls_allowed())
Example #18
0
 def setUp(self):
     self.packer = CANPackerPanda("tesla_can")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_TESLA, 0)
     self.safety.init_tests()
Example #19
0
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest):

    TX_MSGS = [
        [0x283, 0],
        [0x2E6, 0],
        [0x2E7, 0],
        [0x33E, 0],
        [0x344, 0],
        [0x365, 0],
        [0x366, 0],
        [0x4CB, 0],  # DSU bus 0
        [0x128, 1],
        [0x141, 1],
        [0x160, 1],
        [0x161, 1],
        [0x470, 1],  # DSU bus 1
        [0x2E4, 0],
        [0x411, 0],
        [0x412, 0],
        [0x343, 0],
        [0x1D2, 0],  # LKAS + ACC
        [0x200, 0],
        [0x750, 0]
    ]  # interceptor + blindspot monitor
    STANDSTILL_THRESHOLD = 1  # 1kph
    RELAY_MALFUNCTION_ADDR = 0x2E4
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}
    INTERCEPTOR_THRESHOLD = 845

    @classmethod
    def setUp(self):
        self.packer = CANPackerPanda("toyota_prius_2017_pt_generated")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66)
        self.safety.init_tests_toyota()

    def _set_prev_torque(self, t):
        self.safety.set_toyota_desired_torque_last(t)
        self.safety.set_toyota_rt_torque_last(t)
        self.safety.set_toyota_torque_meas(t, t)

    def _torque_meas_msg(self, torque):
        values = {"STEER_TORQUE_EPS": torque}
        return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values)

    def _torque_msg(self, torque):
        values = {"STEER_TORQUE_CMD": torque}
        return self.packer.make_can_msg_panda("STEERING_LKA", 0, values)

    def _accel_msg(self, accel):
        values = {"ACCEL_CMD": accel}
        return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values)

    def _speed_msg(self, s):
        values = {("WHEEL_SPEED_%s" % n): s for n in ["FR", "FL", "RR", "RL"]}
        return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values)

    def _brake_msg(self, pressed):
        values = {"BRAKE_PRESSED": pressed}
        return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values)

    def _gas_msg(self, pressed):
        cruise_active = self.safety.get_controls_allowed()
        values = {"GAS_RELEASED": not pressed, "CRUISE_ACTIVE": cruise_active}
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    def _pcm_status_msg(self, cruise_on):
        values = {"CRUISE_ACTIVE": cruise_on}
        values["CHECKSUM"] = 1
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    # Toyota gas gains are the same
    def _interceptor_msg(self, gas, addr):
        to_send = make_msg(0, addr, 6)
        to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
                          ((gas & 0xff) << 24) | ((gas & 0xff00) << 8)
        return to_send

    def test_accel_actuation_limits(self):
        limits = ((MIN_ACCEL, MAX_ACCEL, UNSAFE_MODE.DEFAULT),
                  (ISO_MIN_ACCEL, ISO_MAX_ACCEL,
                   UNSAFE_MODE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX))

        for min_accel, max_accel, unsafe_mode in limits:
            for accel in np.arange(min_accel - 1, max_accel + 1, 0.1):
                for controls_allowed in [True, False]:
                    self.safety.set_controls_allowed(controls_allowed)
                    self.safety.set_unsafe_mode(unsafe_mode)
                    if controls_allowed:
                        should_tx = int(min_accel * 1000) <= int(
                            accel * 1000) <= int(max_accel * 1000)
                    else:
                        should_tx = np.isclose(accel, 0, atol=0.0001)
                    self.assertEqual(should_tx,
                                     self._tx(self._accel_msg(accel)))

    def test_torque_absolute_limits(self):
        for controls_allowed in [True, False]:
            for torque in np.arange(-MAX_TORQUE - 1000, MAX_TORQUE + 1000,
                                    MAX_RATE_UP):
                self.safety.set_controls_allowed(controls_allowed)
                self.safety.set_toyota_rt_torque_last(torque)
                self.safety.set_toyota_torque_meas(torque, torque)
                self.safety.set_toyota_desired_torque_last(torque -
                                                           MAX_RATE_UP)

                if controls_allowed:
                    send = (-MAX_TORQUE <= torque <= MAX_TORQUE)
                else:
                    send = torque == 0

                self.assertEqual(send, self._tx(self._torque_msg(torque)))

    def test_non_realtime_limit_up(self):
        self.safety.set_controls_allowed(True)

        self._set_prev_torque(0)
        self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP)))

        self._set_prev_torque(0)
        self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1)))

    def test_non_realtime_limit_down(self):
        self.safety.set_controls_allowed(True)

        self.safety.set_toyota_rt_torque_last(1000)
        self.safety.set_toyota_torque_meas(500, 500)
        self.safety.set_toyota_desired_torque_last(1000)
        self.assertTrue(self._tx(self._torque_msg(1000 - MAX_RATE_DOWN)))

        self.safety.set_toyota_rt_torque_last(1000)
        self.safety.set_toyota_torque_meas(500, 500)
        self.safety.set_toyota_desired_torque_last(1000)
        self.assertFalse(self._tx(self._torque_msg(1000 - MAX_RATE_DOWN + 1)))

    def test_exceed_torque_sensor(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            self._set_prev_torque(0)
            for t in np.arange(0, MAX_TORQUE_ERROR + 10, 10):
                t *= sign
                self.assertTrue(self._tx(self._torque_msg(t)))

            self.assertFalse(
                self._tx(self._torque_msg(sign * (MAX_TORQUE_ERROR + 10))))

    def test_realtime_limit_up(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            self.safety.init_tests_toyota()
            self._set_prev_torque(0)
            for t in np.arange(0, 380, 10):
                t *= sign
                self.safety.set_toyota_torque_meas(t, t)
                self.assertTrue(self._tx(self._torque_msg(t)))
            self.assertFalse(self._tx(self._torque_msg(sign * 380)))

            self._set_prev_torque(0)
            for t in np.arange(0, 370, 10):
                t *= sign
                self.safety.set_toyota_torque_meas(t, t)
                self.assertTrue(self._tx(self._torque_msg(t)))

            # Increase timer to update rt_torque_last
            self.safety.set_timer(RT_INTERVAL + 1)
            self.assertTrue(self._tx(self._torque_msg(sign * 370)))
            self.assertTrue(self._tx(self._torque_msg(sign * 380)))

    def test_torque_measurements(self):
        for trq in [50, -50, 0, 0, 0, 0]:
            self._rx(self._torque_meas_msg(trq))

        # toyota safety adds one to be conservative on rounding
        self.assertEqual(-51, self.safety.get_toyota_torque_meas_min())
        self.assertEqual(51, self.safety.get_toyota_torque_meas_max())

        self._rx(self._torque_meas_msg(0))
        self.assertEqual(1, self.safety.get_toyota_torque_meas_max())
        self.assertEqual(-51, self.safety.get_toyota_torque_meas_min())

        self._rx(self._torque_meas_msg(0))
        self.assertEqual(1, self.safety.get_toyota_torque_meas_max())
        self.assertEqual(-1, self.safety.get_toyota_torque_meas_min())

    def test_rx_hook(self):
        # checksum checks
        for msg in ["trq", "pcm"]:
            self.safety.set_controls_allowed(1)
            if msg == "trq":
                to_push = self._torque_meas_msg(0)
            if msg == "pcm":
                to_push = self._pcm_status_msg(True)
            self.assertTrue(self._rx(to_push))
            to_push[0].RDHR = 0
            self.assertFalse(self._rx(to_push))
            self.assertFalse(self.safety.get_controls_allowed())
Example #20
0
class TestChryslerSafety(common.PandaSafetyTest,
                         common.TorqueSteeringSafetyTest):
    TX_MSGS = [[571, 0], [658, 0], [678, 0]]
    STANDSTILL_THRESHOLD = 0
    RELAY_MALFUNCTION_ADDR = 0x292
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [658, 678]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}

    MAX_RATE_UP = 3
    MAX_RATE_DOWN = 3
    MAX_TORQUE = 261
    MAX_RT_DELTA = 112
    RT_INTERVAL = 250000
    MAX_TORQUE_ERROR = 80

    cnt_torque_meas = 0
    cnt_gas = 0
    cnt_cruise = 0
    cnt_brake = 0

    def setUp(self):
        self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, 0)
        self.safety.init_tests()

    def _button_msg(self, cancel):
        values = {"ACC_CANCEL": cancel}
        return self.packer.make_can_msg_panda("WHEEL_BUTTONS", 0, values)

    def _pcm_status_msg(self, enable):
        values = {
            "ACC_STATUS_2": 0x7 if enable else 0,
            "COUNTER": self.cnt_cruise % 16
        }
        self.__class__.cnt_cruise += 1
        return self.packer.make_can_msg_panda("ACC_2", 0, values)

    def _speed_msg(self, speed):
        values = {"SPEED_LEFT": speed, "SPEED_RIGHT": speed}
        return self.packer.make_can_msg_panda("SPEED_1", 0, values)

    def _gas_msg(self, gas):
        values = {"ACCEL_134": gas, "COUNTER": self.cnt_gas % 16}
        self.__class__.cnt_gas += 1
        return self.packer.make_can_msg_panda("ACCEL_GAS_134", 0, values)

    def _brake_msg(self, brake):
        values = {
            "BRAKE_PRESSED_2": 5 if brake else 0,
            "COUNTER": self.cnt_brake % 16
        }
        self.__class__.cnt_brake += 1
        return self.packer.make_can_msg_panda("BRAKE_2", 0, values)

    def _torque_meas_msg(self, torque):
        values = {"TORQUE_MOTOR": torque, "COUNTER": self.cnt_torque_meas % 16}
        self.__class__.cnt_torque_meas += 1
        return self.packer.make_can_msg_panda("EPS_STATUS", 0, values)

    def _torque_msg(self, torque):
        values = {"LKAS_STEERING_TORQUE": torque}
        return self.packer.make_can_msg_panda("LKAS_COMMAND", 0, values)

    def test_disengage_on_gas(self):
        self.safety.set_controls_allowed(1)
        self._rx(self._speed_msg(2.1))
        self._rx(self._gas_msg(1))
        self.assertTrue(self.safety.get_controls_allowed())
        self._rx(self._gas_msg(0))
        self._rx(self._speed_msg(2.2))
        self._rx(self._gas_msg(1))
        self.assertFalse(self.safety.get_controls_allowed())

    def test_cancel_button(self):
        for cancel in [True, False]:
            self.assertEqual(cancel, self._tx(self._button_msg(cancel)))
Example #21
0
class TestNissanSafety(common.PandaSafetyTest):

    TX_MSGS = [[0x169, 0], [0x2b1, 0], [0x4cc, 0], [0x20b, 2], [0x280, 2]]
    STANDSTILL_THRESHOLD = 0
    GAS_PRESSED_THRESHOLD = 3
    RELAY_MALFUNCTION_ADDR = 0x169
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {0: [0x280], 2: [0x169, 0x2b1, 0x4cc]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}

    def setUp(self):
        self.packer = CANPackerPanda("nissan_x_trail_2017")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0)
        self.safety.init_tests()

    def _angle_meas_msg(self, angle):
        values = {"STEER_ANGLE": angle}
        return self.packer.make_can_msg_panda("STEER_ANGLE_SENSOR", 0, values)

    def _set_prev_angle(self, t):
        t = int(t * -100)
        self.safety.set_desired_angle_last(t)

    def _angle_meas_msg_array(self, angle):
        for _ in range(6):
            self._rx(self._angle_meas_msg(angle))

    def _pcm_status_msg(self, enable):
        values = {"CRUISE_ENABLED": enable}
        return self.packer.make_can_msg_panda("CRUISE_STATE", 2, values)

    def _lkas_control_msg(self, angle, state):
        values = {"DESIRED_ANGLE": angle, "LKA_ACTIVE": state}
        return self.packer.make_can_msg_panda("LKAS", 0, values)

    def _speed_msg(self, speed):
        # TODO: why the 3.6? m/s to kph? not in dbc
        values = {"WHEEL_SPEED_%s" % s: speed * 3.6 for s in ["RR", "RL"]}
        return self.packer.make_can_msg_panda("WHEEL_SPEEDS_REAR", 0, values)

    def _brake_msg(self, brake):
        values = {"USER_BRAKE_PRESSED": brake}
        return self.packer.make_can_msg_panda("DOORS_LIGHTS", 1, values)

    def _gas_msg(self, gas):
        values = {"GAS_PEDAL": gas}
        return self.packer.make_can_msg_panda("GAS_PEDAL", 0, values)

    def _acc_button_cmd(self, cancel=0, propilot=0, flw_dist=0, _set=0, res=0):
        no_button = not any([cancel, propilot, flw_dist, _set, res])
        values = {
            "CANCEL_BUTTON": cancel,
            "PROPILOT_BUTTON": propilot,
            "FOLLOW_DISTANCE_BUTTON": flw_dist,
            "SET_BUTTON": _set,
            "RES_BUTTON": res,
            "NO_BUTTON_PRESSED": no_button
        }
        return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 2, values)

    def test_angle_cmd_when_enabled(self):
        # when controls are allowed, angle cmd rate limit is enforced
        speeds = [0., 1., 5., 10., 15., 50.]
        angles = [-300, -100, -10, 0, 10, 100, 300]
        for a in angles:
            for s in speeds:
                max_delta_up = np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V)
                max_delta_down = np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU)

                # first test against false positives
                self._angle_meas_msg_array(a)
                self._rx(self._speed_msg(s))

                self._set_prev_angle(a)
                self.safety.set_controls_allowed(1)

                # Stay within limits
                # Up
                self.assertEqual(
                    True,
                    self._tx(
                        self._lkas_control_msg(a + sign(a) * max_delta_up, 1)))
                self.assertTrue(self.safety.get_controls_allowed())

                # Don't change
                self.assertEqual(True, self._tx(self._lkas_control_msg(a, 1)))
                self.assertTrue(self.safety.get_controls_allowed())

                # Down
                self.assertEqual(
                    True,
                    self._tx(
                        self._lkas_control_msg(a - sign(a) * max_delta_down,
                                               1)))
                self.assertTrue(self.safety.get_controls_allowed())

                # Inject too high rates
                # Up
                self.assertEqual(
                    False,
                    self._tx(
                        self._lkas_control_msg(
                            a + sign(a) * (max_delta_up + 1), 1)))
                self.assertFalse(self.safety.get_controls_allowed())

                # Don't change
                self.safety.set_controls_allowed(1)
                self._set_prev_angle(a)
                self.assertTrue(self.safety.get_controls_allowed())
                self.assertEqual(True, self._tx(self._lkas_control_msg(a, 1)))
                self.assertTrue(self.safety.get_controls_allowed())

                # Down
                self.assertEqual(
                    False,
                    self._tx(
                        self._lkas_control_msg(
                            a - sign(a) * (max_delta_down + 1), 1)))
                self.assertFalse(self.safety.get_controls_allowed())

                # Check desired steer should be the same as steer angle when controls are off
                self.safety.set_controls_allowed(0)
                self.assertEqual(True, self._tx(self._lkas_control_msg(a, 0)))

    def test_angle_cmd_when_disabled(self):
        self.safety.set_controls_allowed(0)

        self._set_prev_angle(0)
        self.assertFalse(self._tx(self._lkas_control_msg(0, 1)))
        self.assertFalse(self.safety.get_controls_allowed())

    def test_acc_buttons(self):
        self.safety.set_controls_allowed(1)
        self._tx(self._acc_button_cmd(cancel=1))
        self.assertTrue(self.safety.get_controls_allowed())
        self._tx(self._acc_button_cmd(propilot=1))
        self.assertFalse(self.safety.get_controls_allowed())
        self.safety.set_controls_allowed(1)
        self._tx(self._acc_button_cmd(flw_dist=1))
        self.assertFalse(self.safety.get_controls_allowed())
        self.safety.set_controls_allowed(1)
        self._tx(self._acc_button_cmd(_set=1))
        self.assertFalse(self.safety.get_controls_allowed())
        self.safety.set_controls_allowed(1)
        self._tx(self._acc_button_cmd(res=1))
        self.assertFalse(self.safety.get_controls_allowed())
        self.safety.set_controls_allowed(1)
        self._tx(self._acc_button_cmd())
        self.assertFalse(self.safety.get_controls_allowed())
Example #22
0
class TestHyundaiSafety(common.PandaSafetyTest):
  TX_MSGS = [[832, 0], [1265, 0], [1157, 0]]
  STANDSTILL_THRESHOLD = 30  # ~1kph
  RELAY_MALFUNCTION_ADDR = 832
  RELAY_MALFUNCTION_BUS = 0
  FWD_BLACKLISTED_ADDRS = {2: [832, 1157]}
  FWD_BUS_LOOKUP = {0: 2, 2: 0}

  cnt_gas = 0
  cnt_speed = 0
  cnt_brake = 0
  cnt_cruise = 0

  def setUp(self):
    self.packer = CANPackerPanda("hyundai_kia_generic")
    self.safety = libpandasafety_py.libpandasafety
    self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI, 0)
    self.safety.init_tests()

  def _button_msg(self, buttons):
    values = {"CF_Clu_CruiseSwState": buttons}
    return self.packer.make_can_msg_panda("CLU11", 0, values)

  def _gas_msg(self, gas):
    values = {"CF_Ems_AclAct": gas, "AliveCounter": self.cnt_gas % 4}
    self.__class__.cnt_gas += 1
    return self.packer.make_can_msg_panda("EMS16", 0, values, fix_checksum=checksum)

  def _brake_msg(self, brake):
    values = {"DriverBraking": brake, "AliveCounterTCS": self.cnt_brake % 8}
    self.__class__.cnt_brake += 1
    return self.packer.make_can_msg_panda("TCS13", 0, values, fix_checksum=checksum)

  def _speed_msg(self, speed):
    # panda safety doesn't scale, so undo the scaling
    values = {"WHL_SPD_%s" % s: speed * 0.03125 for s in ["FL", "FR", "RL", "RR"]}
    values["WHL_SPD_AliveCounter_LSB"] = (self.cnt_speed % 16) & 0x3
    values["WHL_SPD_AliveCounter_MSB"] = (self.cnt_speed % 16) >> 2
    self.__class__.cnt_speed += 1
    return self.packer.make_can_msg_panda("WHL_SPD11", 0, values)

  def _pcm_status_msg(self, enable):
    values = {"ACCMode": enable, "CR_VSM_Alive": self.cnt_cruise % 16}
    self.__class__.cnt_cruise += 1
    return self.packer.make_can_msg_panda("SCC12", 0, values, fix_checksum=checksum)

  def _set_prev_torque(self, t):
    self.safety.set_desired_torque_last(t)
    self.safety.set_rt_torque_last(t)

  # TODO: this is unused
  def _torque_driver_msg(self, torque):
    values = {"CR_Mdps_StrColTq": torque}
    return self.packer.make_can_msg_panda("MDPS12", 0, values)

  def _torque_msg(self, torque):
    values = {"CR_Lkas_StrToqReq": torque}
    return self.packer.make_can_msg_panda("LKAS11", 0, values)

  def test_steer_safety_check(self):
    for enabled in [0, 1]:
      for t in range(-0x200, 0x200):
        self.safety.set_controls_allowed(enabled)
        self._set_prev_torque(t)
        if abs(t) > MAX_STEER or (not enabled and abs(t) > 0):
          self.assertFalse(self._tx(self._torque_msg(t)))
        else:
          self.assertTrue(self._tx(self._torque_msg(t)))

  def test_non_realtime_limit_up(self):
    self.safety.set_torque_driver(0, 0)
    self.safety.set_controls_allowed(True)

    self._set_prev_torque(0)
    self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP)))
    self._set_prev_torque(0)
    self.assertTrue(self._tx(self._torque_msg(-MAX_RATE_UP)))

    self._set_prev_torque(0)
    self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1)))
    self.safety.set_controls_allowed(True)
    self._set_prev_torque(0)
    self.assertFalse(self._tx(self._torque_msg(-MAX_RATE_UP - 1)))

  def test_non_realtime_limit_down(self):
    self.safety.set_torque_driver(0, 0)
    self.safety.set_controls_allowed(True)

  def test_against_torque_driver(self):
    self.safety.set_controls_allowed(True)

    for sign in [-1, 1]:
      for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1):
        t *= -sign
        self.safety.set_torque_driver(t, t)
        self._set_prev_torque(MAX_STEER * sign)
        self.assertTrue(self._tx(self._torque_msg(MAX_STEER * sign)))

      self.safety.set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1)
      self.assertFalse(self._tx(self._torque_msg(-MAX_STEER)))

    # spot check some individual cases
    for sign in [-1, 1]:
      driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign
      torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign
      delta = 1 * sign
      self._set_prev_torque(torque_desired)
      self.safety.set_torque_driver(-driver_torque, -driver_torque)
      self.assertTrue(self._tx(self._torque_msg(torque_desired)))
      self._set_prev_torque(torque_desired + delta)
      self.safety.set_torque_driver(-driver_torque, -driver_torque)
      self.assertFalse(self._tx(self._torque_msg(torque_desired + delta)))

      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertTrue(self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign)))
      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertTrue(self._tx(self._torque_msg(0)))
      self._set_prev_torque(MAX_STEER * sign)
      self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
      self.assertFalse(self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign)))

  def test_realtime_limits(self):
    self.safety.set_controls_allowed(True)

    for sign in [-1, 1]:
      self.safety.init_tests()
      self._set_prev_torque(0)
      self.safety.set_torque_driver(0, 0)
      for t in np.arange(0, MAX_RT_DELTA, 1):
        t *= sign
        self.assertTrue(self._tx(self._torque_msg(t)))
      self.assertFalse(self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1))))

      self._set_prev_torque(0)
      for t in np.arange(0, MAX_RT_DELTA, 1):
        t *= sign
        self.assertTrue(self._tx(self._torque_msg(t)))

      # Increase timer to update rt_torque_last
      self.safety.set_timer(RT_INTERVAL + 1)
      self.assertTrue(self._tx(self._torque_msg(sign * (MAX_RT_DELTA - 1))))
      self.assertTrue(self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1))))

  def test_spam_cancel_safety_check(self):
    RESUME_BTN = 1
    SET_BTN = 2
    CANCEL_BTN = 4
    self.safety.set_controls_allowed(0)
    self.assertTrue(self._tx(self._button_msg(CANCEL_BTN)))
    self.assertFalse(self._tx(self._button_msg(RESUME_BTN)))
    self.assertFalse(self._tx(self._button_msg(SET_BTN)))
    # do not block resume if we are engaged already
    self.safety.set_controls_allowed(1)
    self.assertTrue(self._tx(self._button_msg(RESUME_BTN)))
Example #23
0
class TestSubaruSafety(common.PandaSafetyTest):
    cnt_gas = 0
    cnt_torque_driver = 0
    cnt_cruise = 0
    cnt_speed = 0
    cnt_brake = 0

    TX_MSGS = [[0x122, 0], [0x221, 0], [0x322, 0]]
    STANDSTILL_THRESHOLD = 20  # 1kph (see dbc file)
    RELAY_MALFUNCTION_ADDR = 0x122
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [290, 545, 802]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}

    def setUp(self):
        self.packer = CANPackerPanda("subaru_global_2017")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_SUBARU, 0)
        self.safety.init_tests_subaru()

    def _set_prev_torque(self, t):
        self.safety.set_subaru_desired_torque_last(t)
        self.safety.set_subaru_rt_torque_last(t)

    def _torque_driver_msg(self, torque):
        values = {
            "Steer_Torque_Sensor": -torque,
            "counter": self.cnt_torque_driver % 4
        }
        self.__class__.cnt_torque_driver += 1
        return self.packer.make_can_msg_panda("Steering_Torque", 0, values)

    def _speed_msg(self, speed):
        # subaru safety doesn't use the scaled value, so undo the scaling
        values = {s: speed * 0.057 for s in ["FR", "FL", "RR", "RL"]}
        values["Counter"] = self.cnt_speed % 4
        self.__class__.cnt_speed += 1
        return self.packer.make_can_msg_panda("Wheel_Speeds", 0, values)

    def _brake_msg(self, brake):
        values = {"Brake_Pedal": brake, "Counter": self.cnt_brake % 4}
        self.__class__.cnt_brake += 1
        return self.packer.make_can_msg_panda("Brake_Pedal", 0, values)

    def _torque_msg(self, torque):
        values = {"LKAS_Output": -torque}
        return self.packer.make_can_msg_panda("ES_LKAS", 0, values)

    def _gas_msg(self, gas):
        values = {"Throttle_Pedal": gas, "Counter": self.cnt_gas % 4}
        self.__class__.cnt_gas += 1
        return self.packer.make_can_msg_panda("Throttle", 0, values)

    def _pcm_status_msg(self, cruise):
        values = {"Cruise_Activated": cruise, "Counter": self.cnt_cruise % 4}
        self.__class__.cnt_cruise += 1
        return self.packer.make_can_msg_panda("CruiseControl", 0, values)

    def _set_torque_driver(self, min_t, max_t):
        for i in range(0, 5):
            self.safety.safety_rx_hook(self._torque_driver_msg(min_t))
        self.safety.safety_rx_hook(self._torque_driver_msg(max_t))

    def test_steer_safety_check(self):
        for enabled in [0, 1]:
            for t in range(-3000, 3000):
                self.safety.set_controls_allowed(enabled)
                self._set_prev_torque(t)
                block = abs(t) > MAX_STEER or (not enabled and abs(t) > 0)
                self.assertEqual(
                    not block, self.safety.safety_tx_hook(self._torque_msg(t)))

    def test_non_realtime_limit_up(self):
        self._set_torque_driver(0, 0)
        self.safety.set_controls_allowed(True)

        self._set_prev_torque(0)
        self.assertTrue(
            self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP)))
        self._set_prev_torque(0)
        self.assertTrue(
            self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP)))

        self._set_prev_torque(0)
        self.assertFalse(
            self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1)))
        self.safety.set_controls_allowed(True)
        self._set_prev_torque(0)
        self.assertFalse(
            self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1)))

    def test_non_realtime_limit_down(self):
        self._set_torque_driver(0, 0)
        self.safety.set_controls_allowed(True)

    def test_against_torque_driver(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1):
                t *= -sign
                self._set_torque_driver(t, t)
                self._set_prev_torque(MAX_STEER * sign)
                self.assertTrue(
                    self.safety.safety_tx_hook(
                        self._torque_msg(MAX_STEER * sign)))

            self._set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1,
                                    DRIVER_TORQUE_ALLOWANCE + 1)
            self.assertFalse(
                self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER)))

        # arbitrary high driver torque to ensure max steer torque is allowed
        max_driver_torque = int(MAX_STEER / DRIVER_TORQUE_FACTOR +
                                DRIVER_TORQUE_ALLOWANCE + 1)

        # spot check some individual cases
        for sign in [-1, 1]:
            driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign
            torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign
            delta = 1 * sign
            self._set_prev_torque(torque_desired)
            self._set_torque_driver(-driver_torque, -driver_torque)
            self.assertTrue(
                self.safety.safety_tx_hook(self._torque_msg(torque_desired)))
            self._set_prev_torque(torque_desired + delta)
            self._set_torque_driver(-driver_torque, -driver_torque)
            self.assertFalse(
                self.safety.safety_tx_hook(
                    self._torque_msg(torque_desired + delta)))

            self._set_prev_torque(MAX_STEER * sign)
            self._set_torque_driver(-max_driver_torque * sign,
                                    -max_driver_torque * sign)
            self.assertTrue(
                self.safety.safety_tx_hook(
                    self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign)))
            self._set_prev_torque(MAX_STEER * sign)
            self._set_torque_driver(-max_driver_torque * sign,
                                    -max_driver_torque * sign)
            self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0)))
            self._set_prev_torque(MAX_STEER * sign)
            self._set_torque_driver(-max_driver_torque * sign,
                                    -max_driver_torque * sign)
            self.assertFalse(
                self.safety.safety_tx_hook(
                    self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign)))

    def test_realtime_limits(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            self.safety.init_tests_subaru()
            self._set_prev_torque(0)
            self._set_torque_driver(0, 0)
            for t in np.arange(0, MAX_RT_DELTA, 1):
                t *= sign
                self.assertTrue(self.safety.safety_tx_hook(
                    self._torque_msg(t)))
            self.assertFalse(
                self.safety.safety_tx_hook(
                    self._torque_msg(sign * (MAX_RT_DELTA + 1))))

            self._set_prev_torque(0)
            for t in np.arange(0, MAX_RT_DELTA, 1):
                t *= sign
                self.assertTrue(self.safety.safety_tx_hook(
                    self._torque_msg(t)))

            # Increase timer to update rt_torque_last
            self.safety.set_timer(RT_INTERVAL + 1)
            self.assertTrue(
                self.safety.safety_tx_hook(
                    self._torque_msg(sign * (MAX_RT_DELTA - 1))))
            self.assertTrue(
                self.safety.safety_tx_hook(
                    self._torque_msg(sign * (MAX_RT_DELTA + 1))))
Example #24
0
class TestGmSafety(common.PandaSafetyTest):
    TX_MSGS = [
        [384, 0],
        [1033, 0],
        [1034, 0],
        [715, 0],
        [880, 0],  # pt bus
        [161, 1],
        [774, 1],
        [776, 1],
        [784, 1],  # obs bus
        [789, 2],  # ch bus
        [0x104c006c, 3],
        [0x10400060, 3]
    ]  # gmlan
    STANDSTILL_THRESHOLD = 0
    RELAY_MALFUNCTION_ADDR = 384
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {}
    FWD_BUS_LOOKUP: Dict[int, int] = {}

    def setUp(self):
        self.packer = CANPackerPanda("gm_global_a_powertrain")
        self.packer_chassis = CANPackerPanda("gm_global_a_chassis")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_GM, 0)
        self.safety.init_tests()

    # override these tests from PandaSafetyTest, GM uses button enable
    def test_disable_control_allowed_from_cruise(self):
        pass

    def test_enable_control_allowed_from_cruise(self):
        pass

    def test_cruise_engaged_prev(self):
        pass

    def _pcm_status_msg(self, enable):
        raise NotImplementedError

    def _speed_msg(self, speed):
        values = {"%sWheelSpd" % s: speed for s in ["RL", "RR"]}
        return self.packer.make_can_msg_panda("EBCMWheelSpdRear", 0, values)

    def _button_msg(self, buttons):
        values = {"ACCButtons": buttons}
        return self.packer.make_can_msg_panda("ASCMSteeringButton", 0, values)

    def _brake_msg(self, brake):
        # GM safety has a brake threshold of 10
        values = {"BrakePedalPosition": 10 if brake else 0}
        return self.packer.make_can_msg_panda("EBCMBrakePedalPosition", 0,
                                              values)

    def _gas_msg(self, gas):
        values = {"AcceleratorPedal": 1 if gas else 0}
        return self.packer.make_can_msg_panda("AcceleratorPedal", 0, values)

    def _send_brake_msg(self, brake):
        values = {"FrictionBrakeCmd": -brake}
        return self.packer_chassis.make_can_msg_panda("EBCMFrictionBrakeCmd",
                                                      2, values)

    def _send_gas_msg(self, gas):
        values = {"GasRegenCmd": gas}
        return self.packer.make_can_msg_panda("ASCMGasRegenCmd", 0, values)

    def _set_prev_torque(self, t):
        self.safety.set_desired_torque_last(t)
        self.safety.set_rt_torque_last(t)

    def _torque_driver_msg(self, torque):
        values = {"LKADriverAppldTrq": torque}
        return self.packer.make_can_msg_panda("PSCMStatus", 0, values)

    def _torque_msg(self, torque):
        values = {"LKASteeringCmd": torque}
        return self.packer.make_can_msg_panda("ASCMLKASteeringCmd", 0, values)

    def test_resume_button(self):
        RESUME_BTN = 2
        self.safety.set_controls_allowed(0)
        self._rx(self._button_msg(RESUME_BTN))
        self.assertTrue(self.safety.get_controls_allowed())

    def test_set_button(self):
        SET_BTN = 3
        self.safety.set_controls_allowed(0)
        self._rx(self._button_msg(SET_BTN))
        self.assertTrue(self.safety.get_controls_allowed())

    def test_cancel_button(self):
        CANCEL_BTN = 6
        self.safety.set_controls_allowed(1)
        self._rx(self._button_msg(CANCEL_BTN))
        self.assertFalse(self.safety.get_controls_allowed())

    def test_brake_safety_check(self):
        for enabled in [0, 1]:
            for b in range(0, 500):
                self.safety.set_controls_allowed(enabled)
                if abs(b) > MAX_BRAKE or (not enabled and b != 0):
                    self.assertFalse(self._tx(self._send_brake_msg(b)))
                else:
                    self.assertTrue(self._tx(self._send_brake_msg(b)))

    def test_gas_safety_check(self):
        for enabled in [0, 1]:
            for g in range(0, 2**12 - 1):
                self.safety.set_controls_allowed(enabled)
                if abs(g) > MAX_GAS or (not enabled and g != MAX_REGEN):
                    self.assertFalse(self._tx(self._send_gas_msg(g)))
                else:
                    self.assertTrue(self._tx(self._send_gas_msg(g)))

    def test_steer_safety_check(self):
        for enabled in [0, 1]:
            for t in range(-0x200, 0x200):
                self.safety.set_controls_allowed(enabled)
                self._set_prev_torque(t)
                if abs(t) > MAX_STEER or (not enabled and abs(t) > 0):
                    self.assertFalse(self._tx(self._torque_msg(t)))
                else:
                    self.assertTrue(self._tx(self._torque_msg(t)))

    def test_non_realtime_limit_up(self):
        self.safety.set_torque_driver(0, 0)
        self.safety.set_controls_allowed(True)

        self._set_prev_torque(0)
        self.assertTrue(self._tx(self._torque_msg(MAX_RATE_UP)))
        self._set_prev_torque(0)
        self.assertTrue(self._tx(self._torque_msg(-MAX_RATE_UP)))

        self._set_prev_torque(0)
        self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP + 1)))
        self.safety.set_controls_allowed(True)
        self._set_prev_torque(0)
        self.assertFalse(self._tx(self._torque_msg(-MAX_RATE_UP - 1)))

    def test_non_realtime_limit_down(self):
        self.safety.set_torque_driver(0, 0)
        self.safety.set_controls_allowed(True)

    def test_against_torque_driver(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1):
                t *= -sign
                self.safety.set_torque_driver(t, t)
                self._set_prev_torque(MAX_STEER * sign)
                self.assertTrue(self._tx(self._torque_msg(MAX_STEER * sign)))

            self.safety.set_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1,
                                          DRIVER_TORQUE_ALLOWANCE + 1)
            self.assertFalse(self._tx(self._torque_msg(-MAX_STEER)))

        # spot check some individual cases
        for sign in [-1, 1]:
            driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign
            torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign
            delta = 1 * sign
            self._set_prev_torque(torque_desired)
            self.safety.set_torque_driver(-driver_torque, -driver_torque)
            self.assertTrue(self._tx(self._torque_msg(torque_desired)))
            self._set_prev_torque(torque_desired + delta)
            self.safety.set_torque_driver(-driver_torque, -driver_torque)
            self.assertFalse(self._tx(self._torque_msg(torque_desired +
                                                       delta)))

            self._set_prev_torque(MAX_STEER * sign)
            self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
            self.assertTrue(
                self._tx(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign)))
            self._set_prev_torque(MAX_STEER * sign)
            self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
            self.assertTrue(self._tx(self._torque_msg(0)))
            self._set_prev_torque(MAX_STEER * sign)
            self.safety.set_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
            self.assertFalse(
                self._tx(
                    self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign)))

    def test_realtime_limits(self):
        self.safety.set_controls_allowed(True)

        for sign in [-1, 1]:
            self.safety.init_tests()
            self._set_prev_torque(0)
            self.safety.set_torque_driver(0, 0)
            for t in np.arange(0, MAX_RT_DELTA, 1):
                t *= sign
                self.assertTrue(self._tx(self._torque_msg(t)))
            self.assertFalse(
                self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1))))

            self._set_prev_torque(0)
            for t in np.arange(0, MAX_RT_DELTA, 1):
                t *= sign
                self.assertTrue(self._tx(self._torque_msg(t)))

            # Increase timer to update rt_torque_last
            self.safety.set_timer(RT_INTERVAL + 1)
            self.assertTrue(
                self._tx(self._torque_msg(sign * (MAX_RT_DELTA - 1))))
            self.assertTrue(
                self._tx(self._torque_msg(sign * (MAX_RT_DELTA + 1))))

    def test_tx_hook_on_pedal_pressed(self):
        for pedal in ['brake', 'gas']:
            if pedal == 'brake':
                # brake_pressed_prev and vehicle_moving
                self._rx(self._speed_msg(100))
                self._rx(self._brake_msg(MAX_BRAKE))
            elif pedal == 'gas':
                # gas_pressed_prev
                self._rx(self._gas_msg(MAX_GAS))

            self.safety.set_controls_allowed(1)
            self.assertFalse(self._tx(self._send_brake_msg(MAX_BRAKE)))
            self.assertFalse(self._tx(self._torque_msg(MAX_RATE_UP)))
            self.assertFalse(self._tx(self._send_gas_msg(MAX_GAS)))

            # reset status
            self.safety.set_controls_allowed(0)
            self._tx(self._send_brake_msg(0))
            self._tx(self._torque_msg(0))
            if pedal == 'brake':
                self._rx(self._speed_msg(0))
                self._rx(self._brake_msg(0))
            elif pedal == 'gas':
                self._rx(self._gas_msg(0))

    def test_tx_hook_on_pedal_pressed_on_unsafe_gas_mode(self):
        for pedal in ['brake', 'gas']:
            self.safety.set_unsafe_mode(UNSAFE_MODE.DISABLE_DISENGAGE_ON_GAS)
            if pedal == 'brake':
                # brake_pressed_prev and vehicle_moving
                self._rx(self._speed_msg(100))
                self._rx(self._brake_msg(MAX_BRAKE))
                allow_ctrl = False
            elif pedal == 'gas':
                # gas_pressed_prev
                self._rx(self._gas_msg(MAX_GAS))
                allow_ctrl = True

            self.safety.set_controls_allowed(1)
            self.assertEqual(allow_ctrl,
                             self._tx(self._send_brake_msg(MAX_BRAKE)))
            self.assertEqual(allow_ctrl,
                             self._tx(self._torque_msg(MAX_RATE_UP)))
            self.assertEqual(allow_ctrl, self._tx(self._send_gas_msg(MAX_GAS)))

            # reset status
            self.safety.set_controls_allowed(0)
            self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
            self._tx(self._send_brake_msg(0))
            self._tx(self._torque_msg(0))
            if pedal == 'brake':
                self._rx(self._speed_msg(0))
                self._rx(self._brake_msg(0))
            elif pedal == 'gas':
                self._rx(self._gas_msg(0))
Example #25
0
 def setUp(self):
     self.packer = CANPackerPanda("subaru_global_2017")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_SUBARU, 0)
     self.safety.init_tests_subaru()
Example #26
0
class TestMazdaSafety(common.PandaSafetyTest):

  TX_MSGS = [[0x243, 0], [0x09d, 0]]
  STANDSTILL_THRESHOLD = .1
  RELAY_MALFUNCTION_ADDR = 0x243
  RELAY_MALFUNCTION_BUS = 0
  FWD_BLACKLISTED_ADDRS = {2: [0x243]}
  FWD_BUS_LOOKUP = {0: 2, 2: 0}
  LKAS_ENABLE_SPEED  = 52
  LKAS_DISABLE_SPEED = 45

  def setUp(self):
    self.packer = CANPackerPanda("mazda_cx5_gt_2017")
    self.safety = libpandasafety_py.libpandasafety
    self.safety.set_safety_hooks(Panda.SAFETY_MAZDA, 0)
    self.safety.init_tests()

  def _torque_meas_msg(self, torque):
    values = {"STEER_TORQUE_MOTOR": torque}
    return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values)

#  def _torque_driver_msg(self, torque):
#    values = {"STEER_TORQUE_DRIVER": torque}
#    return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values)

  def _torque_msg(self, torque):
    values = {"LKAS_REQUEST": torque}
    return self.packer.make_can_msg_panda("CAM_LKAS", 0, values)

  def _speed_msg(self, s):
    values = {"SPEED": s}
    return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values)

  def _brake_msg(self, pressed):
    values = {"BRAKE_ON": pressed}
    return self.packer.make_can_msg_panda("PEDALS", 0, values)

  def _gas_msg(self, pressed):
    values = {"PEDAL_GAS": pressed}
    return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values)

  def _pcm_status_msg(self, cruise_on):
    values = {"CRZ_ACTIVE": cruise_on}
    return self.packer.make_can_msg_panda("CRZ_CTRL", 0, values)

  def test_enable_control_allowed_from_cruise(self):
    self._rx(self._pcm_status_msg(False))
    self.assertFalse(self.safety.get_controls_allowed())

    self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1))
    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
    self._rx(self._pcm_status_msg(True))
    self.assertFalse(self.safety.get_controls_allowed())

    self._rx(self._pcm_status_msg(False))

    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))
    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
    self._rx(self._pcm_status_msg(True))
    self.assertTrue(self.safety.get_controls_allowed())

    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))
    self._rx(self._pcm_status_msg(True))
    self.assertTrue(self.safety.get_controls_allowed())

    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
    self.assertTrue(self.safety.get_controls_allowed())

    # Enabled going down
    self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1))
    self.assertTrue(self.safety.get_controls_allowed())

    self._rx(self._pcm_status_msg(False))

    # Disabled going up
    self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED + 1))
    self._rx(self._pcm_status_msg(True))
    self.assertFalse(self.safety.get_controls_allowed())

  def test_cruise_engaged_prev(self):
    self._rx(self._pcm_status_msg(False))
    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
    self._rx(self._pcm_status_msg(True))
    self.assertFalse(self.safety.get_cruise_engaged_prev())

    self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))

    for engaged in [True, False]:
      self._rx(self._pcm_status_msg(engaged))
      self.assertEqual(engaged, self.safety.get_cruise_engaged_prev())
      self._rx(self._pcm_status_msg(not engaged))
      self.assertEqual(not engaged, self.safety.get_cruise_engaged_prev())
Example #27
0
 def setUp(self):
   self.packer = CANPackerPanda("hyundai_kia_generic")
   self.safety = libpandasafety_py.libpandasafety
   self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI, 0)
   self.safety.init_tests()
Example #28
0
 def setUp(self):
   self.packer = CANPackerPanda("mazda_cx5_gt_2017")
   self.safety = libpandasafety_py.libpandasafety
   self.safety.set_safety_hooks(Panda.SAFETY_MAZDA, 0)
   self.safety.init_tests()
Example #29
0
 def setUp(self):
     self.packer = CANPackerPanda("gm_global_a_powertrain")
     self.packer_chassis = CANPackerPanda("gm_global_a_chassis")
     self.safety = libpandasafety_py.libpandasafety
     self.safety.set_safety_hooks(Panda.SAFETY_GM, 0)
     self.safety.init_tests()
Example #30
0
class TestToyotaSafety(common.PandaSafetyTest, common.InterceptorSafetyTest, \
                       common.TorqueSteeringSafetyTest):

    TX_MSGS = [
        [0x283, 0],
        [0x2E6, 0],
        [0x2E7, 0],
        [0x33E, 0],
        [0x344, 0],
        [0x365, 0],
        [0x366, 0],
        [0x4CB, 0],  # DSU bus 0
        [0x128, 1],
        [0x141, 1],
        [0x160, 1],
        [0x161, 1],
        [0x470, 1],  # DSU bus 1
        [0x2E4, 0],
        [0x411, 0],
        [0x412, 0],
        [0x343, 0],
        [0x1D2, 0],  # LKAS + ACC
        [0x200, 0],
        [0x750, 0]
    ]  # interceptor + blindspot monitor
    STANDSTILL_THRESHOLD = 1  # 1kph
    RELAY_MALFUNCTION_ADDR = 0x2E4
    RELAY_MALFUNCTION_BUS = 0
    FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x343]}
    FWD_BUS_LOOKUP = {0: 2, 2: 0}
    INTERCEPTOR_THRESHOLD = 845

    MAX_RATE_UP = 10
    MAX_RATE_DOWN = 25
    MAX_TORQUE = 1500
    MAX_RT_DELTA = 375
    RT_INTERVAL = 250000
    MAX_TORQUE_ERROR = 350
    TORQUE_MEAS_TOLERANCE = 1  # toyota safety adds one to be conversative for rounding

    def setUp(self):
        self.packer = CANPackerPanda("toyota_prius_2017_pt_generated")
        self.safety = libpandasafety_py.libpandasafety
        self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, 66)
        self.safety.init_tests()

    def _torque_meas_msg(self, torque):
        values = {"STEER_TORQUE_EPS": torque}
        return self.packer.make_can_msg_panda("STEER_TORQUE_SENSOR", 0, values)

    def _torque_msg(self, torque):
        values = {"STEER_TORQUE_CMD": torque}
        return self.packer.make_can_msg_panda("STEERING_LKA", 0, values)

    def _accel_msg(self, accel):
        values = {"ACCEL_CMD": accel}
        return self.packer.make_can_msg_panda("ACC_CONTROL", 0, values)

    def _speed_msg(self, s):
        values = {("WHEEL_SPEED_%s" % n): s for n in ["FR", "FL", "RR", "RL"]}
        return self.packer.make_can_msg_panda("WHEEL_SPEEDS", 0, values)

    def _brake_msg(self, pressed):
        values = {"BRAKE_PRESSED": pressed}
        return self.packer.make_can_msg_panda("BRAKE_MODULE", 0, values)

    def _gas_msg(self, pressed):
        cruise_active = self.safety.get_controls_allowed()
        values = {"GAS_RELEASED": not pressed, "CRUISE_ACTIVE": cruise_active}
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    def _pcm_status_msg(self, cruise_on):
        values = {"CRUISE_ACTIVE": cruise_on}
        return self.packer.make_can_msg_panda("PCM_CRUISE", 0, values)

    # Toyota gas gains are the same
    def _interceptor_msg(self, gas, addr):
        to_send = make_msg(0, addr, 6)
        to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \
                          ((gas & 0xff) << 24) | ((gas & 0xff00) << 8)
        return to_send

    def test_accel_actuation_limits(self):
        limits = ((MIN_ACCEL, MAX_ACCEL, UNSAFE_MODE.DEFAULT),
                  (ISO_MIN_ACCEL, ISO_MAX_ACCEL,
                   UNSAFE_MODE.RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX))

        for min_accel, max_accel, unsafe_mode in limits:
            for accel in np.arange(min_accel - 1, max_accel + 1, 0.1):
                for controls_allowed in [True, False]:
                    self.safety.set_controls_allowed(controls_allowed)
                    self.safety.set_unsafe_mode(unsafe_mode)
                    if controls_allowed:
                        should_tx = int(min_accel * 1000) <= int(
                            accel * 1000) <= int(max_accel * 1000)
                    else:
                        should_tx = np.isclose(accel, 0, atol=0.0001)
                    self.assertEqual(should_tx,
                                     self._tx(self._accel_msg(accel)))

    def test_rx_hook(self):
        # checksum checks
        for msg in ["trq", "pcm"]:
            self.safety.set_controls_allowed(1)
            if msg == "trq":
                to_push = self._torque_meas_msg(0)
            if msg == "pcm":
                to_push = self._pcm_status_msg(True)
            self.assertTrue(self._rx(to_push))
            to_push[0].RDHR = 0
            self.assertFalse(self._rx(to_push))
            self.assertFalse(self.safety.get_controls_allowed())