Merge remote-tracking branch 'upstream/master' into fuzzy-panda-carstate

pull/30443/head
Shane Smiskol 1 year ago
commit 16b6035d94
  1. 17
      selfdrive/car/README.md
  2. 9
      selfdrive/car/ford/carstate.py
  3. 10
      selfdrive/car/ford/interface.py
  4. 19
      selfdrive/car/ford/values.py
  5. 1
      selfdrive/car/tests/routes.py
  6. 1
      selfdrive/car/torque_data/override.yaml

@ -1,11 +1,10 @@
# selfdrive/car
### Check out this blogpost for a high level overview of car ports
https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/
Check out [this blog post](https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/) for a high-level overview of porting a car.
## Useful car porting utilities
Testing car ports in your car is very time consuming! Checkout these utilities to do basic checks on your work before running it in your car.
Testing car ports in your car is very time-consuming. Check out these utilities to do basic checks on your work before running it in your car.
### [Cabana](/tools/cabana/README.md)
@ -28,12 +27,12 @@ Attempting to add fw version for: SUBARU OUTBACK 6TH GEN
### [selfdrive/car/tests/test_car_interfaces.py](/selfdrive/car/tests/test_car_interfaces.py)
Finds common bugs for car interfaces, without even requiring a route!
Finds common bugs for car interfaces, without even requiring a route.
#### Example: Typo in signal name
```bash
> pytest selfdrive/car/tests/test_car_interfaces.py -k subaru # (replace with the brand you are working on!)
> pytest selfdrive/car/tests/test_car_interfaces.py -k subaru # replace with the brand you are working on
=====================================================================
FAILED selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS'
@ -42,9 +41,9 @@ FAILED selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_i
### [selfdrive/debug/test_car_model.py](/selfdrive/debug/test_car_model.py)
Given a route, runs most of the car interface to check for common errors like missing signals, blocked panda messages, and mismatches.
Given a route, runs most of the car interface to check for common errors like missing signals, blocked panda messages, and safety mismatches.
#### Example: Panda safety mismatch for gasPressed
#### Example: panda safety mismatch for gasPressed
```bash
> python selfdrive/debug/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21'
@ -59,7 +58,7 @@ AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'ga
```
## Car Port structure
## Car port structure
### interface.py
Generic interface to send and receive messages from CAN (controlsd uses this to communicate with car)
@ -71,7 +70,7 @@ Builds CAN messages to send to car
Reads CAN from car and builds openpilot CarState message
##### values.py
Fingerprints, limits for actuation, car doc information, etc
Fingerprints, limits for actuation, and supported car documentation
##### radar_interface.py
Interface for parsing radar points from the car

@ -18,15 +18,16 @@ class CarState(CarStateBase):
self.shifter_values = can_define.dv["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"]
self.vehicle_sensors_valid = False
self.hybrid_platform = False
self.unsupported_platform = False
def update(self, cp, cp_cam):
ret = car.CarState.new_message()
# Hybrid variants experience a bug where a message from the PCM sends invalid checksums,
# we do not support these cars at this time.
# Ford Q3 hybrid variants experience a bug where a message from the PCM sends invalid checksums,
# this must be root-caused before enabling support. Ford Q4 hybrids do not have this problem.
# TrnAin_Tq_Actl and its quality flag are only set on ICE platform variants
self.hybrid_platform = cp.vl["VehicleOperatingModes"]["TrnAinTq_D_Qf"] == 0
self.unsupported_platform = (cp.vl["VehicleOperatingModes"]["TrnAinTq_D_Qf"] == 0 and
self.CP.carFingerprint not in CANFD_CAR)
# Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement
# The vehicle usually recovers out of this state within a minute of normal driving

@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "ford"
ret.dashcamOnly = candidate in {CAR.F_150_MK14}
ret.dashcamOnly = candidate in CANFD_CAR
ret.radarUnavailable = True
ret.steerControlType = car.CarParams.SteerControlType.angle
@ -56,6 +56,12 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 17.0
ret.mass = 2000
elif candidate == CAR.F_150_LIGHTNING_MK1:
# required trim only on SuperCrew
ret.wheelbase = 3.70
ret.steerRatio = 16.9
ret.mass = 2948
elif candidate == CAR.FOCUS_MK4:
ret.wheelbase = 2.7
ret.steerRatio = 15.0
@ -94,7 +100,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic])
if not self.CS.vehicle_sensors_valid:
events.add(car.CarEvent.EventName.vehicleSensorsInvalid)
if self.CS.hybrid_platform:
if self.CS.unsupported_platform:
events.add(car.CarEvent.EventName.startupNoControl)
ret.events = events.to_msg()

@ -47,9 +47,10 @@ class CAR(StrEnum):
F_150_MK14 = "FORD F-150 14TH GEN"
FOCUS_MK4 = "FORD FOCUS 4TH GEN"
MAVERICK_MK1 = "FORD MAVERICK 1ST GEN"
F_150_LIGHTNING_MK1 = "FORD F-150 LIGHTNING 1ST GEN"
CANFD_CAR = {CAR.F_150_MK14}
CANFD_CAR = {CAR.F_150_MK14, CAR.F_150_LIGHTNING_MK1}
class RADAR:
@ -61,6 +62,7 @@ DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict("ford_lincoln_base
# F-150 radar is not yet supported
DBC[CAR.F_150_MK14] = dbc_dict("ford_lincoln_base_pt", None)
DBC[CAR.F_150_LIGHTNING_MK1] = dbc_dict("ford_lincoln_base_pt", None)
class Footnote(Enum):
@ -94,6 +96,7 @@ CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {
FordCarInfo("Lincoln Aviator 2020-21", "Co-Pilot360 Plus"),
],
CAR.F_150_MK14: FordCarInfo("Ford F-150 2023", "Co-Pilot360 Active 2.0"),
CAR.F_150_LIGHTNING_MK1: FordCarInfo("Ford F-150 Lightning 2021-23", "Co-Pilot360 Active 2.0"),
CAR.FOCUS_MK4: FordCarInfo("Ford Focus 2018", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS]),
CAR.MAVERICK_MK1: [
FordCarInfo("Ford Maverick 2022", "LARIAT Luxury"),
@ -236,6 +239,20 @@ FW_VERSIONS = {
(Ecu.engine, 0x7E0, None): [
b'PL3A-14C204-BRB\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
CAR.F_150_LIGHTNING_MK1: {
(Ecu.abs, 0x760, None): [
b'PL38-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdCamera, 0x706, None): [
b'ML3T-14H102-ABT\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdRadar, 0x764, None): [
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.engine, 0x7E0, None): [
b'NL3A-14C204-BAR\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
CAR.FOCUS_MK4: {
(Ecu.eps, 0x730, None): [

@ -52,6 +52,7 @@ routes = [
CarTestRoute("62241b0c7fea4589|2022-09-01--15-32-49", FORD.EXPLORER_MK6),
CarTestRoute("e886087f430e7fe7|2023-06-16--23-06-36", FORD.FOCUS_MK4),
CarTestRoute("bd37e43731e5964b|2023-04-30--10-42-26", FORD.MAVERICK_MK1),
CarTestRoute("112e4d6e0cad05e1|2023-11-14--08-21-43", FORD.F_150_LIGHTNING_MK1),
#TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION),
CarTestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.ACADIA),

@ -26,6 +26,7 @@ FORD EXPLORER 6TH GEN: [.nan, 1.5, .nan]
FORD F-150 14TH GEN: [.nan, 1.5, .nan]
FORD FOCUS 4TH GEN: [.nan, 1.5, .nan]
FORD MAVERICK 1ST GEN: [.nan, 1.5, .nan]
FORD F-150 LIGHTNING 1ST GEN: [.nan, 1.5, .nan]
###
# No steering wheel

Loading…
Cancel
Save