grey panda is unsupported (#2458)
parent
029be49012
commit
47c21f10f5
|
@ -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!
|
||||
|
||||
|
|
BIN
apk/ai.comma.plus.offroad.apk (Stored with Git LFS)
BIN
apk/ai.comma.plus.offroad.apk (Stored with Git LFS)
Binary file not shown.
2
cereal
2
cereal
|
@ -1 +1 @@
|
|||
Subproject commit d87b4bbef90404ef4d2629db11499d163d0d15aa
|
||||
Subproject commit eb0ede91af24aba72adcefa545233107e4a970fe
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -91,8 +91,3 @@ DBC = {
|
|||
}
|
||||
|
||||
STEER_THRESHOLD = 120
|
||||
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [0x292], # lkas cmd
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'),
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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, has_relay):
|
||||
return 1 if car_fingerprint in HONDA_BOSCH and has_relay else 0
|
||||
def get_pt_bus(car_fingerprint):
|
||||
return 1 if car_fingerprint in HONDA_BOSCH 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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -71,10 +71,6 @@ FINGERPRINTS = {
|
|||
],
|
||||
}
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [579], # steer torque cmd
|
||||
}
|
||||
|
||||
|
||||
DBC = {
|
||||
CAR.CX5: dbc_dict('mazda_2017', None),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -1 +1 @@
|
|||
f863303a303348b27d624a1e301857ec0b432e17
|
||||
f863303a303348b27d624a1e301857ec0b432e17
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue