diff --git a/RELEASES.md b/RELEASES.md index 106010ec52..943bf9a1ff 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,6 @@ Version 0.7.11 (2020-XX-XX) ======================== + * Grey panda is no longer supported, upgrade to comma two or black panda * Lexus NX 2018 support thanks to matt12eagles! * Kia Niro EV 2020 support thanks to nickn17! diff --git a/apk/ai.comma.plus.offroad.apk b/apk/ai.comma.plus.offroad.apk index 472f894bcc..d3d2acc1f1 100644 --- a/apk/ai.comma.plus.offroad.apk +++ b/apk/ai.comma.plus.offroad.apk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3290c11ee8ededb1dc268aa24000c0831565c64d32ac9ce6521bfef2161b6e6 -size 13702753 +oid sha256:f9f629c0894ada01bdb7018899cec970ffa058948b25760ca840ebc3f4851767 +size 13710345 diff --git a/cereal b/cereal index d87b4bbef9..eb0ede91af 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit d87b4bbef90404ef4d2629db11499d163d0d15aa +Subproject commit eb0ede91af24aba72adcefa545233107e4a970fe diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index 75ebacb3f5..b926cf4e9f 100755 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -69,6 +69,7 @@ keys = { b"Offroad_IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START], b"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START], b"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START], + b"Offroad_HardwareUnsupported": [TxType.CLEAR_ON_MANAGER_START], } def ensure_bytes(v): diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 3df7c4c5c8..14dbbb889d 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -9,12 +9,11 @@ from selfdrive.swaglog import cloudlog import cereal.messaging as messaging from selfdrive.car import gen_empty_fingerprint -from cereal import car, log +from cereal import car EventName = car.CarEvent.EventName -HwType = log.HealthData.HwType -def get_startup_event(car_recognized, controller_available, hw_type): +def get_startup_event(car_recognized, controller_available): if comma_remote and tested_branch: event = EventName.startup else: @@ -24,8 +23,6 @@ def get_startup_event(car_recognized, controller_available, hw_type): event = EventName.startupNoCar elif car_recognized and not controller_available: event = EventName.startupNoControl - elif hw_type == HwType.greyPanda: - event = EventName.startupGreyPanda return event @@ -84,11 +81,11 @@ def only_toyota_left(candidate_cars): # **** for use live only **** -def fingerprint(logcan, sendcan, has_relay): +def fingerprint(logcan, sendcan): fixed_fingerprint = os.environ.get('FINGERPRINT', "") skip_fw_query = os.environ.get('SKIP_FW_QUERY', False) - if has_relay and not fixed_fingerprint and not skip_fw_query: + if not fixed_fingerprint and not skip_fw_query: # Vin query only reliably works thorugh OBDII bus = 1 @@ -171,15 +168,15 @@ def fingerprint(logcan, sendcan, has_relay): return car_fingerprint, finger, vin, car_fw, source -def get_car(logcan, sendcan, has_relay=False): - candidate, fingerprints, vin, car_fw, source = fingerprint(logcan, sendcan, has_relay) +def get_car(logcan, sendcan): + candidate, fingerprints, vin, car_fw, source = fingerprint(logcan, sendcan) if candidate is None: cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints) candidate = "mock" CarInterface, CarController, CarState = interfaces[candidate] - car_params = CarInterface.get_params(candidate, fingerprints, has_relay, car_fw) + car_params = CarInterface.get_params(candidate, fingerprints, car_fw) car_params.carVin = vin car_params.carFw = car_fw car_params.fingerprintSource = source diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index fbc469ebeb..e433665d99 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from cereal import car -from selfdrive.car.chrysler.values import Ecu, ECU_FINGERPRINT, CAR, FINGERPRINTS -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.chrysler.values import CAR +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.car.interfaces import CarInterfaceBase @@ -11,11 +11,11 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @staticmethod - def get_params(candidate, fingerprint=None, has_relay=False, car_fw=None): + def get_params(candidate, fingerprint=None, car_fw=None): if fingerprint is None: fingerprint = gen_empty_fingerprint() - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "chrysler" ret.safetyModel = car.CarParams.SafetyModel.chrysler @@ -52,8 +52,7 @@ class CarInterface(CarInterfaceBase): # mass and CG position, so all cars will have approximately similar dyn behaviors ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront) - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay - print("ECU Camera Simulated: {0}".format(ret.enableCamera)) + ret.enableCamera = True return ret diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index b7fb53f530..88110f0530 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -91,8 +91,3 @@ DBC = { } STEER_THRESHOLD = 120 - - -ECU_FINGERPRINT = { - Ecu.fwdCamera: [0x292], # lkas cmd -} diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index 6d6c82f0b8..9def1ca86b 100755 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -2,8 +2,8 @@ from cereal import car from selfdrive.swaglog import cloudlog from selfdrive.config import Conversions as CV -from selfdrive.car.ford.values import MAX_ANGLE, Ecu, ECU_FINGERPRINT, FINGERPRINTS -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.ford.values import MAX_ANGLE +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.car.interfaces import CarInterfaceBase @@ -14,8 +14,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "ford" ret.safetyModel = car.CarParams.SafetyModel.ford ret.dashcamOnly = True @@ -43,7 +43,7 @@ class CarInterface(CarInterfaceBase): ret.steerControlType = car.CarParams.SteerControlType.angle - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera) return ret diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 7c4d0aed98..315c398ab6 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -15,10 +15,6 @@ FINGERPRINTS = { }], } -ECU_FINGERPRINT = { - Ecu.fwdCamera: [970, 973, 984] -} - DBC = { CAR.FUSION: dbc_dict('ford_fusion_2018_pt', 'ford_fusion_2018_adas'), } diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 0fc3d278ce..2f7d8f473b 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV -from selfdrive.car.gm.values import CAR, Ecu, ECU_FINGERPRINT, CruiseButtons, \ - AccState, FINGERPRINTS -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.gm.values import CAR, CruiseButtons, \ + AccState +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -16,8 +16,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "gm" ret.safetyModel = car.CarParams.SafetyModel.gm ret.enableCruise = False # stock cruise control is kept off @@ -29,7 +29,7 @@ class CarInterface(CarInterfaceBase): # Presence of a camera on the object bus is ok. # Have to go to read_only if ASCM is online (ACC-enabled cars), # or camera is on powertrain bus (LKA cars without ACC). - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True ret.openpilotLongitudinalControl = ret.enableCamera tire_stiffness_factor = 0.444 # not optimized yet diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index efe696f8a6..5e50e6166e 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -70,10 +70,6 @@ FINGERPRINTS = { STEER_THRESHOLD = 1.0 -ECU_FINGERPRINT = { - Ecu.fwdCamera: [384, 715] # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" -} - DBC = { CAR.HOLDEN_ASTRA: dbc_dict('gm_global_a_powertrain', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'), CAR.VOLT: dbc_dict('gm_global_a_powertrain', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'), diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 60f3a94e48..b73af39a66 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -145,22 +145,22 @@ class CarController(): # Send steering command. idx = frame % 4 can_sends.append(hondacan.create_steering_control(self.packer, apply_steer, - lkas_active, CS.CP.carFingerprint, idx, CS.CP.isPandaBlack, CS.CP.openpilotLongitudinalControl)) + lkas_active, CS.CP.carFingerprint, idx, CS.CP.openpilotLongitudinalControl)) # Send dashboard UI commands. if (frame % 10) == 0: idx = (frame//10) % 4 - can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx, CS.CP.isPandaBlack, CS.CP.openpilotLongitudinalControl, CS.stock_hud)) + can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx, CS.CP.openpilotLongitudinalControl, CS.stock_hud)) if not CS.CP.openpilotLongitudinalControl: if (frame % 2) == 0: idx = frame // 2 - can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, CS.CP.carFingerprint, idx, CS.CP.isPandaBlack)) + can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, CS.CP.carFingerprint, idx)) # If using stock ACC, spam cancel command to kill gas when OP disengages. if pcm_cancel_cmd: - can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack)) + can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, CS.CP.carFingerprint)) elif CS.out.cruiseState.standstill: - can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack)) + can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint)) else: # Send gas and brake commands. @@ -174,7 +174,7 @@ class CarController(): apply_brake = int(clip(self.brake_last * P.BRAKE_MAX, 0, P.BRAKE_MAX - 1)) pump_on, self.last_pump_ts = brake_pump_hysteresis(apply_brake, self.apply_brake_last, self.last_pump_ts, ts) can_sends.append(hondacan.create_brake_command(self.packer, apply_brake, pump_on, - pcm_override, pcm_cancel_cmd, hud.fcw, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack, CS.stock_brake)) + pcm_override, pcm_cancel_cmd, hud.fcw, idx, CS.CP.carFingerprint, CS.stock_brake)) self.apply_brake_last = apply_brake if CS.CP.enableGasInterceptor: diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 56e16e6d5c..16d85892a6 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -336,7 +336,7 @@ class CarState(CarStateBase): @staticmethod def get_can_parser(CP): signals, checks = get_can_signals(CP) - bus_pt = 1 if CP.isPandaBlack and CP.carFingerprint in HONDA_BOSCH else 0 + bus_pt = 1 if CP.carFingerprint in HONDA_BOSCH else 0 return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_pt) @staticmethod @@ -361,8 +361,7 @@ class CarState(CarStateBase): if CP.carFingerprint in [CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]: checks = [(0x194, 100)] - bus_cam = 1 if CP.carFingerprint in HONDA_BOSCH and not CP.isPandaBlack else 2 - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_cam) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) @staticmethod def get_body_can_parser(CP): diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 45aea3fc1c..ef25647022 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -7,24 +7,19 @@ from selfdrive.car.honda.values import HONDA_BOSCH # 2 = ACC-CAN - camera side # 3 = F-CAN A - OBDII port -# CAN bus layout with giraffe -# 0 = F-CAN B - powertrain -# 1 = ACC-CAN - camera side -# 2 = ACC-CAN - radar side +def get_pt_bus(car_fingerprint): + return 1 if car_fingerprint in HONDA_BOSCH else 0 -def get_pt_bus(car_fingerprint, has_relay): - return 1 if car_fingerprint in HONDA_BOSCH and has_relay else 0 - -def get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled=False): +def get_lkas_cmd_bus(car_fingerprint, radar_disabled=False): if radar_disabled: # when radar is disabled, steering commands are sent directly to powertrain bus - return get_pt_bus(car_fingerprint, has_relay) + return get_pt_bus(car_fingerprint) # normally steering commands are sent to radar, which forwards them to powertrain bus - return 2 if car_fingerprint in HONDA_BOSCH and not has_relay else 0 + return 0 -def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, idx, car_fingerprint, has_relay, stock_brake): +def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, idx, car_fingerprint, stock_brake): # TODO: do we loose pressure if we keep pump off for long? brakelights = apply_brake > 0 brake_rq = apply_brake > 0 @@ -45,13 +40,13 @@ def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_ "AEB_REQ_2": 0, "AEB_STATUS": 0, } - bus = get_pt_bus(car_fingerprint, has_relay) + bus = get_pt_bus(car_fingerprint) return packer.make_can_msg("BRAKE_COMMAND", bus, values, idx) -def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, car_fingerprint, has_relay): +def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, car_fingerprint): commands = [] - bus = get_pt_bus(car_fingerprint, has_relay) + bus = get_pt_bus(car_fingerprint) control_on = 5 if enabled else 0 # no gas = -30000 @@ -84,31 +79,31 @@ def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, ca return commands -def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx, has_relay, radar_disabled): +def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx, radar_disabled): values = { "STEER_TORQUE": apply_steer if lkas_active else 0, "STEER_TORQUE_REQUEST": lkas_active, } - bus = get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled) + bus = get_lkas_cmd_bus(car_fingerprint, radar_disabled) return packer.make_can_msg("STEERING_CONTROL", bus, values, idx) -def create_bosch_supplemental_1(packer, car_fingerprint, idx, has_relay): +def create_bosch_supplemental_1(packer, car_fingerprint, idx): # non-active params values = { "SET_ME_X04": 0x04, "SET_ME_X80": 0x80, "SET_ME_X10": 0x10, } - bus = get_lkas_cmd_bus(car_fingerprint, has_relay) + bus = get_lkas_cmd_bus(car_fingerprint) return packer.make_can_msg("BOSCH_SUPPLEMENTAL_1", bus, values, idx) -def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, has_relay, openpilot_longitudinal_control, stock_hud): +def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, openpilot_longitudinal_control, stock_hud): commands = [] - bus_pt = get_pt_bus(car_fingerprint, has_relay) + bus_pt = get_pt_bus(car_fingerprint) radar_disabled = car_fingerprint in HONDA_BOSCH and openpilot_longitudinal_control - bus_lkas = get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled) + bus_lkas = get_lkas_cmd_bus(car_fingerprint, radar_disabled) if openpilot_longitudinal_control: if car_fingerprint in HONDA_BOSCH: @@ -158,10 +153,10 @@ def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, return commands -def spam_buttons_command(packer, button_val, idx, car_fingerprint, has_relay): +def spam_buttons_command(packer, button_val, idx, car_fingerprint): values = { 'CRUISE_BUTTONS': button_val, 'CRUISE_SETTING': 0, } - bus = get_pt_bus(car_fingerprint, has_relay) + bus = get_pt_bus(car_fingerprint) return packer.make_can_msg("SCM_BUTTONS", bus, values, idx) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 7331c673c7..22bf25ade9 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -6,8 +6,8 @@ from common.realtime import DT_CTRL from selfdrive.swaglog import cloudlog from selfdrive.config import Conversions as CV from selfdrive.controls.lib.events import ET -from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH, Ecu, ECU_FINGERPRINT, FINGERPRINTS -from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH +from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.controls.lib.planner import _A_CRUISE_MAX_V_FOLLOWING from selfdrive.car.interfaces import CarInterfaceBase @@ -119,19 +119,18 @@ class CarInterface(CarInterfaceBase): return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter) @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "honda" if candidate in HONDA_BOSCH: - ret.safetyModel = car.CarParams.SafetyModel.hondaBoschHarness if has_relay else car.CarParams.SafetyModel.hondaBoschGiraffe - rdr_bus = 0 if has_relay else 2 - ret.enableCamera = is_ecu_disconnected(fingerprint[rdr_bus], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.safetyModel = car.CarParams.SafetyModel.hondaBoschHarness + ret.enableCamera = True ret.radarOffCan = True ret.openpilotLongitudinalControl = False else: ret.safetyModel = car.CarParams.SafetyModel.hondaNidec - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True ret.enableGasInterceptor = 0x201 in fingerprint[0] ret.openpilotLongitudinalControl = ret.enableCamera diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 949ddaf9f3..5eca73c2d7 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1036,10 +1036,4 @@ SPEED_FACTOR = { CAR.INSIGHT: 1., } -# msgs sent for steering controller by camera module on can 0. -# those messages are mutually exclusive on CRV and non-CRV cars -ECU_FINGERPRINT = { - Ecu.fwdCamera: [0xE4, 0x194], # steer torque cmd -} - HONDA_BOSCH = set([CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_5G, CAR.CRV_HYBRID, CAR.INSIGHT, CAR.ACURA_RDX_3G]) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 0b86a1f21b..eff7c6d207 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV -from selfdrive.car.hyundai.values import Ecu, ECU_FINGERPRINT, CAR, FINGERPRINTS -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.hyundai.values import CAR +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.car.interfaces import CarInterfaceBase class CarInterface(CarInterfaceBase): @@ -12,8 +12,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "hyundai" ret.safetyModel = car.CarParams.SafetyModel.hyundai @@ -168,10 +168,10 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 13.75 * 1.15 tire_stiffness_factor = 0.5 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] # these cars require a special panda safety mode due to missing counters and checksums in the messages - if candidate in [CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_2019, + if candidate in [CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_2019, CAR.KIA_NIRO_EV, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70]: ret.safetyModel = car.CarParams.SafetyModel.hyundaiLegacy @@ -186,7 +186,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, tire_stiffness_factor=tire_stiffness_factor) - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True return ret diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 97040fcd10..dd76f7bbbd 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -150,10 +150,6 @@ FINGERPRINTS = { }] } -ECU_FINGERPRINT = { - Ecu.fwdCamera: [832, 1156, 1191, 1342] -} - # Don't use these fingerprints for fingerprinting, they are still used for ECU detection IGNORED_FINGERPRINTS = [CAR.VELOSTER, CAR.GENESIS_G70, CAR.KONA] diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index a4dcb905c5..f7078ed238 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -42,15 +42,15 @@ class CarInterfaceBase(): raise NotImplementedError @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): raise NotImplementedError # returns a set of default params to avoid repetition in car specific params @staticmethod - def get_std_params(candidate, fingerprint, has_relay): + def get_std_params(candidate, fingerprint): ret = car.CarParams.new_message() ret.carFingerprint = candidate - ret.isPandaBlack = has_relay + ret.isPandaBlack = True # TODO: deprecate this field # standard ALC params ret.steerControlType = car.CarParams.SteerControlType.torque diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 81dff12b9c..fc1219453b 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV -from selfdrive.car.mazda.values import CAR, LKAS_LIMITS, FINGERPRINTS, ECU_FINGERPRINT, Ecu -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, is_ecu_disconnected +from selfdrive.car.mazda.values import CAR, LKAS_LIMITS +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -15,8 +15,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "mazda" ret.safetyModel = car.CarParams.SafetyModel.mazda @@ -67,7 +67,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, tire_stiffness_factor=tire_stiffness_factor) - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True return ret diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 4e194d61d1..81c2b2b4a4 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -71,10 +71,6 @@ FINGERPRINTS = { ], } -ECU_FINGERPRINT = { - Ecu.fwdCamera: [579], # steer torque cmd -} - DBC = { CAR.CX5: dbc_dict('mazda_2017', None), diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 4b703d5e90..f75d1c58ff 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -33,8 +33,8 @@ class CarInterface(CarInterfaceBase): return accel @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "mock" ret.safetyModel = car.CarParams.SafetyModel.noOutput ret.mass = 1700. diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 9c419c5a8f..9f2ac20e0a 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -14,9 +14,9 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "nissan" ret.safetyModel = car.CarParams.SafetyModel.nissan diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 6d65f64f3d..8012624a3c 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -11,8 +11,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "subaru" ret.radarOffCan = True @@ -24,11 +24,8 @@ class CarInterface(CarInterfaceBase): # Subaru port is a community feature, since we don't own one to test ret.communityFeature = True - ret.dashcamOnly = candidate in PREGLOBAL_CARS - # force openpilot to fake the stock camera, since car harness is not supported yet and old style giraffe (with switches) - # was never released ret.enableCamera = True ret.steerRateCost = 0.7 diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 8cbb6fe72d..937728d885 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -78,10 +78,6 @@ STEER_THRESHOLD = { CAR.OUTBACK_PREGLOBAL_2018: 75, } -ECU_FINGERPRINT = { - Ecu.fwdCamera: [290, 356], # steer torque cmd -} - DBC = { CAR.ASCENT: dbc_dict('subaru_global_2017_generated', None), CAR.IMPREZA: dbc_dict('subaru_global_2017_generated', None), diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 069d5af00b..be05c9d065 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -25,36 +25,35 @@ class TestCarInterfaces(unittest.TestCase): car_fw = [] - for has_relay in [True, False]: - car_params = CarInterface.get_params(car_name, fingerprints, has_relay, car_fw) - car_interface = CarInterface(car_params, CarController, CarState) - assert car_params - assert car_interface + car_params = CarInterface.get_params(car_name, fingerprints, car_fw) + car_interface = CarInterface(car_params, CarController, CarState) + assert car_params + assert car_interface - self.assertGreater(car_params.mass, 1) - self.assertGreater(car_params.steerRateCost, 1e-3) + self.assertGreater(car_params.mass, 1) + self.assertGreater(car_params.steerRateCost, 1e-3) - tuning = car_params.lateralTuning.which() - if tuning == 'pid': - self.assertTrue(len(car_params.lateralTuning.pid.kpV)) - elif tuning == 'lqr': - self.assertTrue(len(car_params.lateralTuning.lqr.a)) - elif tuning == 'indi': - self.assertGreater(car_params.lateralTuning.indi.outerLoopGain, 1e-3) + tuning = car_params.lateralTuning.which() + if tuning == 'pid': + self.assertTrue(len(car_params.lateralTuning.pid.kpV)) + elif tuning == 'lqr': + self.assertTrue(len(car_params.lateralTuning.lqr.a)) + elif tuning == 'indi': + self.assertGreater(car_params.lateralTuning.indi.outerLoopGain, 1e-3) - # Run car interface - CC = car.CarControl.new_message() - for _ in range(10): - car_interface.update(CC, []) - car_interface.apply(CC) - car_interface.apply(CC) + # Run car interface + CC = car.CarControl.new_message() + for _ in range(10): + car_interface.update(CC, []) + car_interface.apply(CC) + car_interface.apply(CC) - CC = car.CarControl.new_message() - CC.enabled = True - for _ in range(10): - car_interface.update(CC, []) - car_interface.apply(CC) - car_interface.apply(CC) + CC = car.CarControl.new_message() + CC.enabled = True + for _ in range(10): + car_interface.update(CC, []) + car_interface.apply(CC) + car_interface.apply(CC) # Test radar interface RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % car_params.carName).RadarInterface diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index e40ad2f00e..711c65a58f 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -14,8 +14,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "toyota" ret.safetyModel = car.CarParams.SafetyModel.toyota @@ -275,7 +275,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, tire_stiffness_factor=tire_stiffness_factor) - ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay + ret.enableCamera = True # Detect smartDSU, which intercepts ACC_CMD from the DSU allowing openpilot to send it smartDsu = 0x2FF in fingerprint[0] # In TSS2 cars the camera does long control @@ -327,8 +327,6 @@ class CarInterface(CarInterfaceBase): # events events = self.create_common_events(ret) - if self.cp_cam.can_invalid_cnt >= 200 and self.CP.enableCamera and not self.CP.isPandaBlack: - events.add(EventName.invalidGiraffeToyota) if self.CS.low_speed_lockout and self.CP.openpilotLongitudinalControl: events.add(EventName.lowSpeedLockout) if ret.vEgo < self.CP.minEnableSpeed and self.CP.openpilotLongitudinalControl: diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index c041c6c44c..252306322b 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -18,8 +18,8 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @staticmethod - def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None): - ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) + def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None): + ret = CarInterfaceBase.get_std_params(candidate, fingerprint) # VW port is a community feature, since we don't own one to test ret.communityFeature = True diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index d58eb26775..e8cd95f34a 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -61,12 +61,10 @@ class Controls: self.can_sock = messaging.sub_sock('can', timeout=can_timeout) # wait for one health and one CAN packet - hw_type = messaging.recv_one(self.sm.sock['health']).health.hwType - has_relay = hw_type in [HwType.blackPanda, HwType.uno, HwType.dos] print("Waiting for CAN messages...") get_one_can(self.can_sock) - self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], has_relay) + self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan']) # read params params = Params() @@ -131,7 +129,7 @@ class Controls: self.sm['dMonitoringState'].awarenessStatus = 1. self.sm['dMonitoringState'].faceDetected = False - self.startup_event = get_startup_event(car_recognized, controller_available, hw_type) + self.startup_event = get_startup_event(car_recognized, controller_available) if not sounds_available: self.events.add(EventName.soundsUnavailable, static=True) @@ -141,8 +139,6 @@ class Controls: self.events.add(EventName.communityFeatureDisallowed, static=True) if not car_recognized: self.events.add(EventName.carUnrecognized, static=True) - if hw_type == HwType.whitePanda: - self.events.add(EventName.whitePandaUnsupported, static=True) # controlsd is driven by can recv, expected at 100Hz self.rk = Ratekeeper(100, print_delay_threshold=None) diff --git a/selfdrive/controls/lib/alerts_offroad.json b/selfdrive/controls/lib/alerts_offroad.json index f343f4cd5e..a47eb8c0a2 100644 --- a/selfdrive/controls/lib/alerts_offroad.json +++ b/selfdrive/controls/lib/alerts_offroad.json @@ -36,5 +36,9 @@ "Offroad_NeosUpdate": { "text": "An update to your device's operating system is downloading in the background. You will be prompted to update when it's ready to install.", "severity": 0 + }, + "Offroad_HardwareUnsupported": { + "text": "White and grey panda are unsupported. Upgrade to comma two or black panda.", + "severity": 0 } } diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index ce5ef47952..d0b10ec84e 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -252,31 +252,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), }, - EventName.startupGreyPanda: { - ET.PERMANENT: Alert( - "WARNING: Grey panda is deprecated", - "Upgrade to comma two or black panda", - AlertStatus.userPrompt, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), - }, - - EventName.invalidGiraffeToyota: { - ET.PERMANENT: Alert( - "Unsupported Giraffe Configuration", - "Visit comma.ai/tg", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - }, - - EventName.whitePandaUnsupported: { - ET.PERMANENT: Alert( - "White Panda No Longer Supported", - "Upgrade to comma two or black panda", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - ET.NO_ENTRY: NoEntryAlert("Unsupported Hardware"), - }, - EventName.invalidLkasSetting: { ET.PERMANENT: Alert( "Stock LKAS is turned on", diff --git a/selfdrive/debug/get_fingerprint.py b/selfdrive/debug/get_fingerprint.py index 2695d457d1..6c38957be3 100755 --- a/selfdrive/debug/get_fingerprint.py +++ b/selfdrive/debug/get_fingerprint.py @@ -6,7 +6,6 @@ # - connect to a Panda # - run selfdrive/boardd/boardd # - launching this script -# - turn on the car in STOCK MODE (set giraffe switches properly). # Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint # - since some messages are published at low frequency, keep this script running for at least 30s, # until all messages are received at least once diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py index 6c57f5fc3f..7890a9ec4b 100755 --- a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -325,6 +325,7 @@ def setup_output(): class LongitudinalControl(unittest.TestCase): @classmethod def setUpClass(cls): + os.environ['SKIP_FW_QUERY'] = "1" os.environ['NO_CAN_TIMEOUT'] = "1" setup_output() diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 3b81cc8896..a88c59e7ba 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -75,10 +75,6 @@ class DumbSocket: # lists dat = messaging.new_message(s, 0) - # TODO: remove this after deprecated all hw without a relay - if s == "health": - dat.health.hwType = log.HealthData.HwType.uno - self.data = dat.to_bytes() def receive(self, non_blocking=False): diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 9f8f6c05ea..0866904338 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -f863303a303348b27d624a1e301857ec0b432e17 \ No newline at end of file +f863303a303348b27d624a1e301857ec0b432e17 diff --git a/selfdrive/test/test_models.py b/selfdrive/test/test_models.py index 3a95136b52..b0c4723051 100755 --- a/selfdrive/test/test_models.py +++ b/selfdrive/test/test_models.py @@ -30,6 +30,12 @@ ignore_can_valid = [ "TOYOTA AVALON 2016", "HONDA PILOT 2019 ELITE", "HYUNDAI SANTA FE LIMITED 2019", + + # TODO: get new routes for these cars, current routes are from giraffe with different buses + "HONDA CR-V 2019 HYBRID", + "HONDA ACCORD 2018 SPORT 2T", + "HONDA INSIGHT 2019 TOURING", + "HONDA ACCORD 2018 HYBRID TOURING", ] @parameterized_class(('car_model'), [(car,) for car in all_known_cars()]) @@ -53,7 +59,6 @@ class TestCarModel(unittest.TestCase): if seg == 0: raise - has_relay = False can_msgs = [] fingerprint = {i: dict() for i in range(3)} for msg in lr: @@ -62,41 +67,38 @@ class TestCarModel(unittest.TestCase): if m.src < 128: fingerprint[m.src][m.address] = len(m.dat) can_msgs.append(msg) - elif msg.which() == "health": - has_relay = msg.health.hwType in [HwType.blackPanda, HwType.uno, HwType.dos] cls.can_msgs = sorted(can_msgs, key=lambda msg: msg.logMonoTime) CarInterface, CarController, CarState = interfaces[cls.car_model] - # TODO: test with relay and without - cls.car_params = CarInterface.get_params(cls.car_model, fingerprint, has_relay, []) - assert cls.car_params + cls.CP = CarInterface.get_params(cls.car_model, fingerprint, []) + assert cls.CP - cls.CI = CarInterface(cls.car_params, CarController, CarState) + cls.CI = CarInterface(cls.CP, CarController, CarState) assert cls.CI def test_car_params(self): - if self.car_params.dashcamOnly: + if self.CP.dashcamOnly: self.skipTest("no need to check carParams for dashcamOnly") # make sure car params are within a valid range - self.assertGreater(self.car_params.mass, 1) - self.assertGreater(self.car_params.steerRateCost, 1e-3) + self.assertGreater(self.CP.mass, 1) + self.assertGreater(self.CP.steerRateCost, 1e-3) - tuning = self.car_params.lateralTuning.which() + tuning = self.CP.lateralTuning.which() if tuning == 'pid': - self.assertTrue(len(self.car_params.lateralTuning.pid.kpV)) + self.assertTrue(len(self.CP.lateralTuning.pid.kpV)) elif tuning == 'lqr': - self.assertTrue(len(self.car_params.lateralTuning.lqr.a)) + self.assertTrue(len(self.CP.lateralTuning.lqr.a)) elif tuning == 'indi': - self.assertGreater(self.car_params.lateralTuning.indi.outerLoopGain, 1e-3) + self.assertGreater(self.CP.lateralTuning.indi.outerLoopGain, 1e-3) - self.assertTrue(self.car_params.enableCamera) + self.assertTrue(self.CP.enableCamera) # TODO: check safetyModel is in release panda build safety = libpandasafety_py.libpandasafety - set_status = safety.set_safety_hooks(self.car_params.safetyModel.raw, self.car_params.safetyParam) - self.assertEqual(0, set_status, f"failed to set safetyModel {self.car_params.safetyModel}") + set_status = safety.set_safety_hooks(self.CP.safetyModel.raw, self.CP.safetyParam) + self.assertEqual(0, set_status, f"failed to set safetyModel {self.CP.safetyModel}") def test_car_interface(self): # TODO: also check for checkusm and counter violations from can parser @@ -115,8 +117,8 @@ class TestCarModel(unittest.TestCase): def test_radar_interface(self): os.environ['NO_RADAR_SLEEP'] = "1" - RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % self.car_params.carName).RadarInterface - RI = RadarInterface(self.car_params) + RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % self.CP.carName).RadarInterface + RI = RadarInterface(self.CP) assert RI error_cnt = 0 @@ -127,11 +129,11 @@ class TestCarModel(unittest.TestCase): self.assertLess(error_cnt, 20) def test_panda_safety_rx(self): - if self.car_params.dashcamOnly: + if self.CP.dashcamOnly: self.skipTest("no need to check panda safety for dashcamOnly") safety = libpandasafety_py.libpandasafety - set_status = safety.set_safety_hooks(self.car_params.safetyModel.raw, self.car_params.safetyParam) + set_status = safety.set_safety_hooks(self.CP.safetyModel.raw, self.CP.safetyParam) self.assertEqual(0, set_status) failed_addrs = Counter() diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index 76b9ad3b26..a6f2d4c4e9 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -9,7 +9,6 @@ from common.params import Params, put_nonblocking from common.hardware import TICI from selfdrive.swaglog import cloudlog -PANDA_OUTPUT_VOLTAGE = 5.28 CAR_VOLTAGE_LOW_PASS_K = 0.091 # LPF gain for 5s tau (dt/tau / (dt/tau + 1)) # A C2 uses about 1W while idling, and 30h seens like a good shutoff for most cars @@ -62,11 +61,6 @@ def _read_param(path, parser, default=0): return default -def panda_current_to_actual_current(panda_current): - # From white/grey panda schematic - return (3.3 - (panda_current * 3.3 / 4096)) / 8.25 - - class PowerMonitoring: def __init__(self): self.params = Params() @@ -135,11 +129,6 @@ class PowerMonitoring: # If the battery is discharging, we can use this measurement # On C2: this is low by about 10-15%, probably mostly due to UNO draw not being factored in current_power = ((get_battery_voltage() / 1000000) * (get_battery_current() / 1000000)) - elif (health.health.hwType in [log.HealthData.HwType.whitePanda, log.HealthData.HwType.greyPanda]) and (health.health.current > 1): - # If white/grey panda, use the integrated current measurements if the measurement is not 0 - # If the measurement is 0, the current is 400mA or greater, and out of the measurement range of the panda - # This seems to be accurate to about 5% - current_power = (PANDA_OUTPUT_VOLTAGE * panda_current_to_actual_current(health.health.current)) elif (self.next_pulsed_measurement_time is not None) and (self.next_pulsed_measurement_time <= now): # TODO: Figure out why this is off by a factor of 3/4??? FUDGE_FACTOR = 1.33 diff --git a/selfdrive/thermald/tests/test_power_monitoring.py b/selfdrive/thermald/tests/test_power_monitoring.py index af46e447e5..fe91dce8e3 100755 --- a/selfdrive/thermald/tests/test_power_monitoring.py +++ b/selfdrive/thermald/tests/test_power_monitoring.py @@ -18,8 +18,7 @@ def mock_sec_since_boot(): with patch("common.realtime.sec_since_boot", new=mock_sec_since_boot): with patch("common.params.put_nonblocking", new=params.put): from selfdrive.thermald.power_monitoring import PowerMonitoring, CAR_BATTERY_CAPACITY_uWh, \ - PANDA_OUTPUT_VOLTAGE, CAR_CHARGING_RATE_W, \ - VBATT_PAUSE_CHARGING + CAR_CHARGING_RATE_W, VBATT_PAUSE_CHARGING def actual_current_to_panda_current(actual_current): return max(int(((3.3 - (actual_current * 8.25)) * 4096) / 3.3), 0) @@ -66,16 +65,6 @@ class TestPowerMonitoring(unittest.TestCase): pm.calculate(self.mock_health(True, hw_type)) self.assertEqual(pm.get_power_used(), 0) - # Test to see that it integrates with white/grey panda while charging - @parameterized.expand([(log.HealthData.HwType.whitePanda,), (log.HealthData.HwType.greyPanda,)]) - def test_offroad_integration_white(self, hw_type): - with pm_patch("get_battery_voltage", 4e6), pm_patch("get_battery_current", 1e5), pm_patch("get_battery_status", "Charging"): - pm = PowerMonitoring() - for _ in range(TEST_DURATION_S + 1): - pm.calculate(self.mock_health(False, hw_type, current=0.1)) - expected_power_usage = ((TEST_DURATION_S/3600) * (0.1 * PANDA_OUTPUT_VOLTAGE) * 1e6) - self.assertLess(abs(pm.get_power_used() - expected_power_usage), 10) - # Test to see that it integrates with discharging battery @parameterized.expand(ALL_PANDA_TYPES) def test_offroad_integration_discharging(self, hw_type): diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 39e07c0dd7..47782c0de1 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -198,7 +198,6 @@ def thermald_thread(): should_start_prev = False handle_fan = None is_uno = False - has_relay = False params = Params() pm = PowerMonitoring() @@ -229,7 +228,6 @@ def thermald_thread(): # Setup fan handler on first connect to panda if handle_fan is None and health.health.hwType != log.HealthData.HwType.unknown: is_uno = health.health.hwType == log.HealthData.HwType.uno - has_relay = health.health.hwType in [log.HealthData.HwType.blackPanda, log.HealthData.HwType.uno, log.HealthData.HwType.dos] if (not EON) or is_uno: cloudlog.info("Setting up UNO fan handler") @@ -286,7 +284,7 @@ def thermald_thread(): # since going onroad increases load and can make temps go over 107 # We only do this if there is a relay that prevents the car from faulting is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (sec_since_boot() - off_ts > 60 * 5)) - if max_cpu_temp > 107. or bat_temp >= 63. or (has_relay and is_offroad_for_5_min and max_cpu_temp > 70.0): + if max_cpu_temp > 107. or bat_temp >= 63. or (is_offroad_for_5_min and max_cpu_temp > 70.0): # onroad not allowed thermal_status = ThermalStatus.danger elif max_comp_temp > 96.0 or bat_temp > 60.: @@ -350,7 +348,6 @@ def thermald_thread(): startup_conditions["not_uninstalling"] = not params.get("DoUninstall") == b"1" startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version - completed_training = params.get("CompletedTrainingVersion") == training_version panda_signature = params.get("PandaFirmware") startup_conditions["fw_version_match"] = (panda_signature is None) or (panda_signature == FW_SIGNATURE) # don't show alert is no panda is connected (None) @@ -358,7 +355,8 @@ def thermald_thread(): # with 2% left, we killall, otherwise the phone will take a long time to boot startup_conditions["free_space"] = msg.thermal.freeSpace > 0.02 - startup_conditions["completed_training"] = completed_training or (current_branch in ['dashcam', 'dashcam-staging']) + startup_conditions["completed_training"] = params.get("CompletedTrainingVersion") == training_version or \ + (current_branch in ['dashcam', 'dashcam-staging']) startup_conditions["not_driver_view"] = not params.get("IsDriverViewEnabled") == b"1" startup_conditions["not_taking_snapshot"] = not params.get("IsTakingSnapshot") == b"1" # if any CPU gets above 107 or the battery gets above 63, kill all processes @@ -367,6 +365,9 @@ def thermald_thread(): set_offroad_alert_if_changed("Offroad_TemperatureTooHigh", (not startup_conditions["device_temp_good"])) should_start = all(startup_conditions.values()) + startup_conditions["hardware_supported"] = health is not None and health.health.hwType not in [log.HealthData.HwType.whitePanda, log.HealthData.HwType.greyPanda] + set_offroad_alert_if_changed("Offroad_HardwareUnsupported", not startup_conditions["hardware_supported"]) + if should_start: if not should_start_prev: params.delete("IsOffroad") diff --git a/tools/carcontrols/debug_controls.py b/tools/carcontrols/debug_controls.py index cdb5e3af87..2334e2576b 100755 --- a/tools/carcontrols/debug_controls.py +++ b/tools/carcontrols/debug_controls.py @@ -14,7 +14,6 @@ def steer_thread(): poller = messaging.Poller() logcan = messaging.sub_sock('can') - health = messaging.sub_sock('health') joystick_sock = messaging.sub_sock('testJoystick', conflate=True, poller=poller) carstate = messaging.pub_sock('carState') @@ -24,13 +23,11 @@ def steer_thread(): button_1_last = 0 enabled = False - # wait for health and CAN packets - hw_type = messaging.recv_one(health).health.hwType - has_relay = hw_type in [HwType.blackPanda, HwType.uno, HwType.dos] + # wait for CAN packets print("Waiting for CAN messages...") get_one_can(logcan) - CI, CP = get_car(logcan, sendcan, has_relay) + CI, CP = get_car(logcan, sendcan) Params().put("CarParams", CP.to_bytes()) CC = car.CarControl.new_message() diff --git a/tools/webcam/README.md b/tools/webcam/README.md index c8def05d53..472b95177a 100644 --- a/tools/webcam/README.md +++ b/tools/webcam/README.md @@ -5,7 +5,7 @@ What's needed: - Python 3.8.2 - GPU (recommended) - Two USB webcams, at least 720p and 78 degrees FOV (e.g. Logitech C920/C615) -- [Car harness](https://comma.ai/shop/products/comma-car-harness) with black panda (or the outdated grey panda/giraffe combo) to connect to your car +- [Car harness](https://comma.ai/shop/products/comma-car-harness) with black panda to connect to your car - [Panda paw](https://comma.ai/shop/products/panda-paw) (or USB-A to USB-A cable) to connect panda to your computer - Tape, Charger, ... That's it!