FrogPilot Setup

This commit is contained in:
FrogAi
2024-03-01 09:26:59 -07:00
parent 505ad1fbfe
commit 6c946fc97a
106 changed files with 2349 additions and 185 deletions

View File

@@ -34,7 +34,7 @@ class CarController:
torque -= deadband
return torque
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
torque_l = 0
torque_r = 0

View File

@@ -6,7 +6,7 @@ from openpilot.selfdrive.car.body.values import DBC
STARTUP_TICKS = 100
class CarState(CarStateBase):
def update(self, cp):
def update(self, cp, frogpilot_variables):
ret = car.CarState.new_message()
ret.wheelSpeeds.fl = cp.vl['MOTORS_DATA']['SPEED_L']

View File

@@ -7,7 +7,7 @@ from openpilot.selfdrive.car.body.values import SPEED_FROM_RPM
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.notCar = True
ret.carName = "body"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.body)]
@@ -29,8 +29,8 @@ class CarInterface(CarInterfaceBase):
return ret
def _update(self, c):
ret = self.CS.update(self.cp)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, frogpilot_variables)
# wait for everything to init first
if self.frame > int(5. / DT_CTRL):
@@ -42,5 +42,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -5,7 +5,7 @@ from typing import Callable, Dict, List, Optional, Tuple
from cereal import car
from openpilot.common.params import Params
from openpilot.common.basedir import BASEDIR
from openpilot.system.version import is_comma_remote, is_tested_branch
from openpilot.system.version import get_short_branch, is_comma_remote, is_tested_branch
from openpilot.selfdrive.car.interfaces import get_interface_attr
from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars
from openpilot.selfdrive.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN
@@ -193,14 +193,20 @@ def fingerprint(logcan, sendcan, num_pandas):
def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1):
params = Params()
dongle_id = params.get("DongleId", encoding='utf-8')
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas)
if candidate is None:
cloudlog.event("car doesn't match any fingerprints", fingerprints=repr(fingerprints), error=True)
candidate = "mock"
if get_short_branch() == "FrogPilot-Development" and not Params("/persist/comma/params").get_bool("FrogsGoMoo"):
candidate = "mock"
CarInterface, CarController, CarState = interfaces[candidate]
CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False)
CP = CarInterface.get_params(params, candidate, fingerprints, car_fw, experimental_long_allowed, docs=False)
CP.carVin = vin
CP.carFw = car_fw
CP.fingerprintSource = source

View File

@@ -19,7 +19,7 @@ class CarController:
self.packer = CANPacker(dbc_name)
self.params = CarControllerParams(CP)
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
can_sends = []
lkas_active = CC.latActive and self.lkas_control_bit_prev

View File

@@ -21,7 +21,7 @@ class CarState(CarStateBase):
else:
self.shifter_values = can_define.dv["GEAR"]["PRNDL"]
def update(self, cp, cp_cam):
def update(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()

View File

@@ -8,7 +8,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "chrysler"
ret.dashcamOnly = candidate in RAM_HD
@@ -88,11 +88,11 @@ class CarInterface(CarInterfaceBase):
return ret
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
# events
events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low])
events = self.create_common_events(ret, frogpilot_variables, extra_gears=[car.CarState.GearShifter.low])
# Low speed steer alert hysteresis logic
if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 0.5):
@@ -106,5 +106,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -35,7 +35,7 @@ class CarController:
self.lkas_enabled_last = False
self.steer_alert_last = False
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
can_sends = []
actuators = CC.actuators

View File

@@ -20,7 +20,7 @@ class CarState(CarStateBase):
self.vehicle_sensors_valid = False
self.unsupported_platform = False
def update(self, cp, cp_cam):
def update(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
# Ford Q3 hybrid variants experience a bug where a message from the PCM sends invalid checksums,

View File

@@ -12,7 +12,7 @@ GearShifter = car.CarState.GearShifter
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "ford"
ret.dashcamOnly = candidate in CANFD_CAR
@@ -103,10 +103,10 @@ class CarInterface(CarInterfaceBase):
ret.centerToFront = ret.wheelbase * 0.44
return ret
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic])
events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.manumatic])
if not self.CS.vehicle_sensors_valid:
events.add(car.CarEvent.EventName.vehicleSensorsInvalid)
if self.CS.unsupported_platform:
@@ -116,5 +116,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -38,7 +38,9 @@ class CarController:
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis'])
def update(self, CC, CS, now_nanos):
# FrogPilot variables
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
hud_alert = hud_control.visualAlert

View File

@@ -26,7 +26,9 @@ class CarState(CarStateBase):
self.cam_lka_steering_cmd_counter = 0
self.buttons_counter = 0
def update(self, pt_cp, cam_cp, loopback_cp):
# FrogPilot variables
def update(self, pt_cp, cam_cp, loopback_cp, frogpilot_variables):
ret = car.CarState.new_message()
self.prev_cruise_buttons = self.cruise_buttons

View File

@@ -83,7 +83,7 @@ class CarInterface(CarInterfaceBase):
return self.torque_from_lateral_accel_linear
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "gm"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
ret.autoResumeSng = False
@@ -271,8 +271,8 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback, frogpilot_variables)
# Don't add event if transitioning from INIT, unless it's to an actual button
if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT:
@@ -280,7 +280,7 @@ class CarInterface(CarInterfaceBase):
unpressed_btn=CruiseButtons.UNPRESS)
# The ECM allows enabling on falling edge of set, but only rising edge of resume
events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low,
events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.sport, GearShifter.low,
GearShifter.eco, GearShifter.manumatic],
pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,))
if not self.CP.pcmCruise:
@@ -302,5 +302,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -4,6 +4,7 @@ from enum import Enum, StrEnum
from typing import Dict, List, Union
from cereal import car
from openpilot.common.params import Params
from openpilot.selfdrive.car import dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

View File

@@ -124,7 +124,7 @@ class CarController:
self.brake = 0.0
self.last_steer = 0.0
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
conversion = hondacan.get_cruise_speed_conversion(self.CP.carFingerprint, CS.is_metric)

View File

@@ -108,7 +108,7 @@ class CarState(CarStateBase):
# However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX)
self.dash_speed_seen = False
def update(self, cp, cp_cam, cp_body):
def update(self, cp, cp_cam, cp_body, frogpilot_variables):
ret = car.CarState.new_message()
# car params

View File

@@ -33,7 +33,7 @@ class CarInterface(CarInterfaceBase):
return CarControllerParams.NIDEC_ACCEL_MIN, interp(current_speed, ACCEL_MAX_BP, ACCEL_MAX_VALS)
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "honda"
if candidate in HONDA_BOSCH:
@@ -310,8 +310,8 @@ class CarInterface(CarInterfaceBase):
disable_ecu(logcan, sendcan, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03')
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body, frogpilot_variables)
ret.buttonEvents = [
*create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT),
@@ -319,7 +319,7 @@ class CarInterface(CarInterfaceBase):
]
# events
events = self.create_common_events(ret, pcm_enable=False)
events = self.create_common_events(ret, frogpilot_variables, pcm_enable=False)
if self.CP.pcmCruise and ret.vEgo < self.CP.minEnableSpeed:
events.add(EventName.belowEngageSpeed)
@@ -344,5 +344,5 @@ class CarInterface(CarInterfaceBase):
# pass in a car.CarControl
# to be called @ 100hz
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -56,7 +56,7 @@ class CarController:
self.car_fingerprint = CP.carFingerprint
self.last_button_frame = 0
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl

View File

@@ -52,9 +52,11 @@ class CarState(CarStateBase):
self.params = CarControllerParams(CP)
def update(self, cp, cp_cam):
# FrogPilot variables
def update(self, cp, cp_cam, frogpilot_variables):
if self.CP.carFingerprint in CANFD_CAR:
return self.update_canfd(cp, cp_cam)
return self.update_canfd(cp, cp_cam, frogpilot_variables)
ret = car.CarState.new_message()
cp_cruise = cp_cam if self.CP.carFingerprint in CAMERA_SCC_CAR else cp
@@ -166,7 +168,7 @@ class CarState(CarStateBase):
return ret
def update_canfd(self, cp, cp_cam):
def update_canfd(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1

View File

@@ -20,7 +20,7 @@ BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: Bu
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "hyundai"
ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
@@ -343,8 +343,8 @@ class CarInterface(CarInterfaceBase):
if CP.flags & HyundaiFlags.ENABLE_BLINKERS:
disable_ecu(logcan, sendcan, bus=CanBus(CP).ECAN, addr=0x7B1, com_cont_req=b'\x28\x83\x01')
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
if self.CS.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)
@@ -353,7 +353,7 @@ class CarInterface(CarInterfaceBase):
# To avoid re-engaging when openpilot cancels, check user engagement intention via buttons
# Main button also can trigger an engagement on these cars
allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons)
events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable)
events = self.create_common_events(ret, frogpilot_variables, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable)
# low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s)
if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.:
@@ -367,5 +367,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -11,12 +11,15 @@ from openpilot.common.basedir import BASEDIR
from openpilot.common.conversions import Conversions as CV
from openpilot.common.simple_kalman import KF1D, get_kalman_gain
from openpilot.common.numpy_fast import clip
from openpilot.common.params import Params
from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG
from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction
from openpilot.selfdrive.controls.lib.events import Events
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel
from openpilot.selfdrive.frogpilot.functions.frogpilot_functions import FrogPilotFunctions
ButtonType = car.CarState.ButtonEvent.Type
GearShifter = car.CarState.GearShifter
EventName = car.CarEvent.EventName
@@ -95,6 +98,9 @@ class CarInterfaceBase(ABC):
if CarController is not None:
self.CC = CarController(self.cp.dbc_name, CP, self.VM)
# FrogPilot variables
params = Params()
@staticmethod
def get_pid_accel_limits(CP, current_speed, cruise_speed):
return ACCEL_MIN, ACCEL_MAX
@@ -107,9 +113,9 @@ class CarInterfaceBase(ABC):
return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False)
@classmethod
def get_params(cls, candidate: str, fingerprint: Dict[int, Dict[int, int]], car_fw: List[car.CarParams.CarFw], experimental_long: bool, docs: bool):
def get_params(cls, params, candidate: str, fingerprint: Dict[int, Dict[int, int]], car_fw: List[car.CarParams.CarFw], experimental_long: bool, docs: bool):
ret = CarInterfaceBase.get_std_params(candidate)
ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs)
ret = cls._get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs)
# Vehicle mass is published curb weight plus assumed payload such as a human driver; notCars have no assumed payload
if not ret.notCar:
@@ -204,14 +210,14 @@ class CarInterfaceBase(ABC):
def _update(self, c: car.CarControl) -> car.CarState:
pass
def update(self, c: car.CarControl, can_strings: List[bytes]) -> car.CarState:
def update(self, c: car.CarControl, can_strings: List[bytes], frogpilot_variables) -> car.CarState:
# parse can
for cp in self.can_parsers:
if cp is not None:
cp.update_strings(can_strings)
# get CarState
ret = self._update(c)
ret = self._update(c, frogpilot_variables)
ret.canValid = all(cp.can_valid for cp in self.can_parsers if cp is not None)
ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers if cp is not None)
@@ -241,7 +247,7 @@ class CarInterfaceBase(ABC):
def apply(self, c: car.CarControl, now_nanos: int) -> Tuple[car.CarControl.Actuators, List[bytes]]:
pass
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True,
def create_common_events(self, cs_out, frogpilot_variables, extra_gears=None, pcm_enable=True, allow_enable=True,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
events = Events()
@@ -354,6 +360,9 @@ class CarStateBase(ABC):
K = get_kalman_gain(DT_CTRL, np.array(A), np.array(C), np.array(Q), R)
self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K)
# FrogPilot variables
self.fpf = FrogPilotFunctions()
def update_speed_kf(self, v_ego_raw):
if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed
self.v_ego_kf.set_x([[v_ego_raw], [0.0]])

View File

@@ -15,7 +15,7 @@ class CarController:
self.brake_counter = 0
self.frame = 0
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
can_sends = []
apply_steer = 0

View File

@@ -18,7 +18,7 @@ class CarState(CarStateBase):
self.lkas_allowed_speed = False
self.lkas_disabled = False
def update(self, cp, cp_cam):
def update(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
ret.wheelSpeeds = self.get_wheel_speeds(

View File

@@ -11,7 +11,7 @@ EventName = car.CarEvent.EventName
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "mazda"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.mazda)]
ret.radarUnavailable = True
@@ -49,11 +49,11 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
# events
events = self.create_common_events(ret)
events = self.create_common_events(ret, frogpilot_variables)
if self.CS.lkas_disabled:
events.add(EventName.lkasDisabled)
@@ -64,5 +64,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase):
self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal'])
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "mock"
ret.mass = 1700.
ret.wheelbase = 2.70
@@ -20,7 +20,7 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 13.
return ret
def _update(self, c):
def _update(self, c, frogpilot_variables):
self.sm.update(0)
gps_sock = 'gpsLocationExternal' if self.sm.recv_frame['gpsLocationExternal'] > 1 else 'gpsLocation'
@@ -30,6 +30,6 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
def apply(self, c, now_nanos, frogpilot_variables):
actuators = car.CarControl.Actuators.new_message()
return actuators, []

View File

@@ -18,7 +18,7 @@ class CarController:
self.packer = CANPacker(dbc_name)
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
pcm_cancel_cmd = CC.cruiseControl.cancel

View File

@@ -20,7 +20,7 @@ class CarState(CarStateBase):
self.steeringTorqueSamples = deque(TORQUE_SAMPLES*[0], TORQUE_SAMPLES)
self.shifter_values = can_define.dv["GEARBOX"]["GEAR_SHIFTER"]
def update(self, cp, cp_adas, cp_cam):
def update(self, cp, cp_adas, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA):

View File

@@ -8,7 +8,7 @@ from openpilot.selfdrive.car.nissan.values import CAR
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "nissan"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.nissan)]
ret.autoResumeSng = False
@@ -39,15 +39,15 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam, frogpilot_variables)
buttonEvents = []
be = car.CarState.ButtonEvent.new_message()
be.type = car.CarState.ButtonEvent.Type.accelCruise
buttonEvents.append(be)
events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.brake])
events = self.create_common_events(ret, frogpilot_variables, extra_gears=[car.CarState.GearShifter.brake])
if self.CS.lkas_enabled:
events.add(car.CarEvent.EventName.invalidLkasSetting)
@@ -56,5 +56,5 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -23,7 +23,7 @@ class CarController:
self.p = CarControllerParams(CP)
self.packer = CANPacker(DBC[CP.carFingerprint]['pt'])
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
pcm_cancel_cmd = CC.cruiseControl.cancel

View File

@@ -16,7 +16,7 @@ class CarState(CarStateBase):
self.angle_rate_calulator = CanSignalRateCalculator(50)
def update(self, cp, cp_cam, cp_body):
def update(self, cp, cp_cam, cp_body, frogpilot_variables):
ret = car.CarState.new_message()
throttle_msg = cp.vl["Throttle"] if self.car_fingerprint not in HYBRID_CARS else cp_body.vl["Throttle_Hybrid"]

View File

@@ -9,7 +9,7 @@ from openpilot.selfdrive.car.subaru.values import CAR, GLOBAL_ES_ADDR, LKAS_ANGL
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "subaru"
ret.radarUnavailable = True
# for HYBRID CARS to be upstreamed, we need:
@@ -136,11 +136,11 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c):
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body, frogpilot_variables)
ret.events = self.create_common_events(ret).to_msg()
ret.events = self.create_common_events(ret, frogpilot_variables).to_msg()
return ret
@@ -149,5 +149,5 @@ class CarInterface(CarInterfaceBase):
if CP.flags & SubaruFlags.DISABLE_EYESIGHT:
disable_ecu(logcan, sendcan, bus=2, addr=GLOBAL_ES_ADDR, com_cont_req=b'\x28\x03\x01')
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -4,6 +4,7 @@ from typing import Dict, List, Union
from cereal import car
from panda.python import uds
from openpilot.common.params import Params
from openpilot.selfdrive.car import dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Tool, Column
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16

View File

@@ -14,7 +14,7 @@ class CarController:
self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt'])
self.tesla_can = TeslaCAN(self.packer, self.pt_packer)
def update(self, CC, CS, now_nanos):
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
pcm_cancel_cmd = CC.cruiseControl.cancel

View File

@@ -20,7 +20,7 @@ class CarState(CarStateBase):
self.acc_state = 0
self.das_control_counters = deque(maxlen=32)
def update(self, cp, cp_cam):
def update(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
# Vehicle speed

View File

@@ -8,7 +8,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "tesla"
# There is no safe way to do steer blending with user torque,
@@ -51,12 +51,12 @@ class CarInterface(CarInterfaceBase):
return ret
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
ret.events = self.create_common_events(ret).to_msg()
ret.events = self.create_common_events(ret, frogpilot_variables).to_msg()
return ret
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -9,6 +9,7 @@ from parameterized import parameterized
from cereal import car, messaging
from openpilot.common.realtime import DT_CTRL
from openpilot.common.params import Params
from openpilot.selfdrive.car import gen_empty_fingerprint
from openpilot.selfdrive.car.car_helpers import interfaces
from openpilot.selfdrive.car.fingerprints import all_known_cars
@@ -18,6 +19,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.controls.controlsd import Controls
from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator
ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()})
@@ -44,7 +46,6 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict:
params['car_fw'] = [car.CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0) for fw in params['car_fw']]
return params
class TestCarInterfaces(unittest.TestCase):
# FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause
# many generated examples to overrun when max_examples > ~20, don't use it
@@ -56,9 +57,11 @@ class TestCarInterfaces(unittest.TestCase):
CarInterface, CarController, CarState = interfaces[car_name]
args = get_fuzzy_car_interface_args(data.draw)
params = Params()
car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
car_params = CarInterface.get_params(params, car_name, args['fingerprints'], args['car_fw'],
experimental_long=args['experimental_long'], docs=False)
car_interface = CarInterface(car_params, CarController, CarState)
assert car_params
assert car_interface
@@ -94,18 +97,19 @@ class TestCarInterfaces(unittest.TestCase):
# Run car interface
now_nanos = 0
CC = car.CarControl.new_message(**cc_msg)
controls = Controls(CI=car_interface)
for _ in range(10):
car_interface.update(CC, [])
car_interface.apply(CC, now_nanos)
car_interface.apply(CC, now_nanos)
car_interface.update(CC, [], controls.frogpilot_variables)
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
now_nanos += DT_CTRL * 1e9 # 10 ms
CC = car.CarControl.new_message(**cc_msg)
CC.enabled = True
for _ in range(10):
car_interface.update(CC, [])
car_interface.apply(CC, now_nanos)
car_interface.apply(CC, now_nanos)
car_interface.update(CC, [], controls.frogpilot_variables)
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
now_nanos += DT_CTRL * 1e9 # 10ms
# Test controller initialization

View File

@@ -1,5 +1,6 @@
from cereal import car
from openpilot.common.numpy_fast import clip, interp
from openpilot.common.params import Params
from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \
create_gas_interceptor_command, make_can_msg
from openpilot.selfdrive.car.toyota import toyotacan
@@ -41,7 +42,10 @@ class CarController:
self.gas = 0
self.accel = 0
def update(self, CC, CS, now_nanos):
# FrogPilot variables
params = Params()
def update(self, CC, CS, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
pcm_cancel_cmd = CC.cruiseControl.cancel
@@ -142,10 +146,12 @@ class CarController:
if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR:
can_sends.append(toyotacan.create_acc_cancel_command(self.packer))
elif self.CP.openpilotLongitudinalControl:
can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert))
can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert,
frogpilot_variables))
self.accel = pcm_accel_cmd
else:
can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False))
can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False,
frogpilot_variables))
if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl:
# send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd.

View File

@@ -44,7 +44,9 @@ class CarState(CarStateBase):
self.acc_type = 1
self.lkas_hud = {}
def update(self, cp, cp_cam):
# FrogPilot variables
def update(self, cp, cp_cam, frogpilot_variables):
ret = car.CarState.new_message()
ret.doorOpen = any([cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FL"], cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FR"],

View File

@@ -18,7 +18,7 @@ class CarInterface(CarInterfaceBase):
return CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "toyota"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)]
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
@@ -289,11 +289,11 @@ class CarInterface(CarInterfaceBase):
disable_ecu(logcan, sendcan, bus=0, addr=0x750, sub_addr=0xf, com_cont_req=communication_control)
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
# events
events = self.create_common_events(ret)
events = self.create_common_events(ret, frogpilot_variables)
# Lane Tracing Assist control is unavailable (EPS_STATUS->LTA_STATE=0) until
# the more accurate angle sensor signal is initialized
@@ -320,5 +320,5 @@ class CarInterface(CarInterfaceBase):
# pass in a car.CarControl
# to be called @ 100hz
def apply(self, c, now_nanos):
return self.CC.update(c, self.CS, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
return self.CC.update(c, self.CS, now_nanos, frogpilot_variables)

View File

@@ -33,7 +33,7 @@ def create_lta_steer_command(packer, steer_control_type, steer_angle, steer_req,
return packer.make_can_msg("STEERING_LTA", 0, values)
def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert):
def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert, frogpilot_variables):
# TODO: find the exact canceling bit that does not create a chime
values = {
"ACCEL_CMD": accel,

View File

@@ -25,7 +25,7 @@ class CarController:
self.hca_frame_timer_running = 0
self.hca_frame_same_torque = 0
def update(self, CC, CS, ext_bus, now_nanos):
def update(self, CC, CS, ext_bus, now_nanos, frogpilot_variables):
actuators = CC.actuators
hud_control = CC.hudControl
can_sends = []

View File

@@ -30,9 +30,9 @@ class CarState(CarStateBase):
return button_events
def update(self, pt_cp, cam_cp, ext_cp, trans_type):
def update(self, pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables):
if self.CP.carFingerprint in PQ_CARS:
return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type)
return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables)
ret = car.CarState.new_message()
# Update vehicle speed and acceleration from ABS wheel speeds.
@@ -153,7 +153,7 @@ class CarState(CarStateBase):
return ret
def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type):
def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables):
ret = car.CarState.new_message()
# Update vehicle speed and acceleration from ABS wheel speeds.
ret.wheelSpeeds = self.get_wheel_speeds(

View File

@@ -23,7 +23,7 @@ class CarInterface(CarInterfaceBase):
self.eps_timer_soft_disable_alert = False
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "volkswagen"
ret.radarUnavailable = True
@@ -225,10 +225,10 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType)
def _update(self, c, frogpilot_variables):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType, frogpilot_variables)
events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=not self.CS.CP.openpilotLongitudinalControl,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
@@ -253,6 +253,6 @@ class CarInterface(CarInterfaceBase):
return ret
def apply(self, c, now_nanos):
new_actuators, can_sends, self.eps_timer_soft_disable_alert = self.CC.update(c, self.CS, self.ext_bus, now_nanos)
def apply(self, c, now_nanos, frogpilot_variables):
new_actuators, can_sends, self.eps_timer_soft_disable_alert = self.CC.update(c, self.CS, self.ext_bus, now_nanos, frogpilot_variables)
return new_actuators, can_sends