Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ford: Car Port for Edge 2nd Generation #30762

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/CARS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.

# 274 Supported Cars
# 275 Supported Cars

|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br>&nbsp;|Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
Expand Down Expand Up @@ -33,6 +33,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Chrysler|Pacifica Hybrid 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Chrysler&model=Pacifica Hybrid 2019-23">Buy Here</a></sub></details>||
|comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None||
|Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Ford&model=Bronco Sport 2021-22">Buy Here</a></sub></details>||
|Ford|Edge 2020-23|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Ford&model=Edge 2020-23">Buy Here</a></sub></details>||
|Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Ford&model=Escape 2020-22">Buy Here</a></sub></details>||
|Ford|Explorer 2020-23|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Ford&model=Explorer 2020-23">Buy Here</a></sub></details>||
|Ford|Focus 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Ford&model=Focus 2018">Buy Here</a></sub></details>||
Expand Down
29 changes: 23 additions & 6 deletions selfdrive/car/ford/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.ford.fordcan import CanBus
from openpilot.selfdrive.car.ford.values import CANFD_CAR, CarControllerParams, DBC
from openpilot.selfdrive.car.ford.values import CANFD_CAR, CAN_EDGE, CarControllerParams, DBC

GearShifter = car.CarState.GearShifter
TransmissionType = car.CarParams.TransmissionType
Expand All @@ -29,9 +29,14 @@ def update(self, cp, cp_cam):
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
self.vehicle_sensors_valid = cp.vl["SteeringPinion_Data"]["StePinCompAnEst_D_Qf"] == 3
if self.CP.carFingerprint in CAN_EDGE:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any idea why the EDGE is different?

Copy link
Author

@MikeDoyal MikeDoyal Dec 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why. I checked with other Ford drivers and they confirmed that the F-150's have no data at ExtSteeringAngleReq2. Likewise, my Edge has no data at StePinCompAnEst_D_Qf or StePinComp_An_Est. There's another Edge user that just bought a C3x. He has a different ABS fingerprint, the rest matches, and his data matches with mine. SteeringPinion_Data shows up at a different ID in the Edges as well. I originally created a new DBC, changing ID from 7e to 85, but abandoned that once I found StePinComp_An_Est has no data. That changed CAN ID may indicate a larger change to the PSCM?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm this is working with my Ford Edge Titanium 2022. Stock openpilot:master did not work after fingerprinting and required these extra steps. I can provide logs if they would be helpful.

# Ford Edge calibrated steering wheel angle comes from the IPMA_ADAS instead of PSCM
# Check for Ford Edge Unknown/Invalid steering wheel position
self.vehicle_sensors_valid = cp.vl["ParkAid_Data"]["ExtSteeringAngleReq2"] < 32766
Copy link
Contributor

@sshane sshane Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saw your opendbc PR. If SteeringPinion_Data is on this car, but is just on another ID (and that ID doesn't conflict with any existing message), we can add it to the DBC with a prefix such as Alt, and detect the absence 0x7e to use the new alternate message. This is common for other brands, such as Hyundai where we support many different configurations by CAN fingerprint detection.

Copy link
Author

@MikeDoyal MikeDoyal Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can update the existing ford_lincoln_base_pt DBC with the alternate ID for documentation/future-use purposes. However, SteeringPinion_Data: StePinCompAnEst_D_Qf and SteeringPinion_Data: StePinComp_An_Est signals on the Edge are not used/available. They remain at 0:Faulty/-1600 deg, even when remapped to the new ID.

image

I initially tried using SteeringPinion_Data: StePinRelInit_An_Sns, but this signal is not calibrated 0=center. The offset changed every time the vehicle was started. OP would only function if the offset was within paramsd.OFFSET_MAX, which was very unreliable.

I found the signal ParkAid_Data: ExtSteeringAngleReq2 contains calibrated steering wheel angle on the Edge. I surveyed other drivers on the #ford Discord channel and no other models have any data at this signal. This leads me to believe the Edge has moved the calibrated steering wheel angle to the IPMA and it is not available in the PSCM. I was also able to confirm this with another 22' Ford Edge driver with a higher trim level and different ABS fwVersion (thank you @mikehundley). This is why I abandoned my new DBC since this data was already available in the original DBC.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dang, that's unfortunate. What about BrakeSnData_6->StePinOffst_An_Est?

Copy link
Contributor

@sshane sshane Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On our Bronco, when the Qf signal is invalid, StePinComp_An_Est is 0 degrees (0b011111010010000), but yours is just zero'd out as bytes (hence the -1600), that is a meaningful difference, and perhaps tells us that it isn't a signal that will ever be filled out, so we can potentially ignore using that.

  • Still should check that it never is not set across lots of Edge routes

Can you turn your car on and off repeatedly and then send the latest route? It took maybe 50 tries on our Bronco to get it into this state where the angle's offset was wrong. You can just turn the ignition to "on" you don't need to start the engine (as long as 3X goes onroad).

Copy link
Author

@MikeDoyal MikeDoyal Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No data at BrakeSnData_6

image

Are you asking about getting a wrong angle offset at SteeringPinion_Data->StePinRelInit_An_Sns? Reviewing a couple of routes, it looks like it's initialized to 0 at ignition so the offset is equal to steering wheel angle at ignition

image
image
image

The responses I mentioned receiving earlier from other Ford drivers on #ford Discord all seemed to be CAN_FD vehicles. I just found another route from a CAN vehicle, ParkAid_Data->ExtSteeringAngleReq2 was identical to SteeringPinion_Data->StePinComp_An_Est. Does your Bronco have data at ParkAid_Data->ExtSteeringAngleReq2, is that the common signal for all CAN vehicles rather than just EDGE?

Copy link
Author

@MikeDoyal MikeDoyal Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the route you asked for. I toggled the vehicle on and off 50 times and then left it on for about a minute to collect data. Accessory power only. The steering wheel is turned 90 to the left, so should read about +90 when calibrated
3d4e31f900dd3a88|2023-12-20--00-45-19

image

Copy link
Author

@MikeDoyal MikeDoyal Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Still should check that it never is not set across lots of Edge routes

Wrote a script to analyze the rlogs (or qlogs if rlogs not uploaded) for StePinComp_An_Est data for a list of routes. I ran this on about 500 miles worth of routes from my Edge. I also threw a couple of other Fords in as a control. Please let me know if you would like to see any more data

check_steering_data.py.zip
image

else:
# 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
self.vehicle_sensors_valid = cp.vl["SteeringPinion_Data"]["StePinCompAnEst_D_Qf"] == 3

# car speed
ret.vEgoRaw = cp.vl["BrakeSysFeatures"]["Veh_V_ActlBrk"] * CV.KPH_TO_MS
Expand All @@ -49,7 +54,10 @@ def update(self, cp, cp_cam):
ret.parkingBrake = cp.vl["DesiredTorqBrk"]["PrkBrkStatus"] in (1, 2)

# steering wheel
ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"]
if self.CP.carFingerprint in CAN_EDGE:
ret.steeringAngleDeg = cp.vl["ParkAid_Data"]["ExtSteeringAngleReq2"]
else:
ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"]
ret.steeringTorque = cp.vl["EPAS_INFO"]["SteeringColumnTorque"]
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5)
ret.steerFaultTemporary = cp.vl["EPAS_INFO"]["EPAS_Failure"] == 1
Expand Down Expand Up @@ -122,7 +130,6 @@ def get_can_parser(CP):
("BrakeSnData_4", 50),
("EngBrakeData", 10),
("Cluster_Info1_FD1", 10),
("SteeringPinion_Data", 100),
("EPAS_INFO", 50),
("Steering_Data_FD1", 10),
("BodyInfo_3_FD1", 2),
Expand All @@ -134,6 +141,16 @@ def get_can_parser(CP):
("Lane_Assist_Data3_FD1", 33),
]

# Ford Edge gets steering wheel angle from IPMA instead of PSCM
if CP.carFingerprint in CAN_EDGE:
messages += [
("ParkAid_Data", 50),
]
else:
messages += [
("SteeringPinion_Data", 100),
]

if CP.transmissionType == TransmissionType.automatic:
messages += [
("Gear_Shift_by_Wire_FD1", 10),
Expand Down
18 changes: 18 additions & 0 deletions selfdrive/car/ford/fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@
b'N1PA-14C204-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
CAR.EDGE_MK2: {
(Ecu.eps, 0x730, None): [
b'M2GC-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.abs, 0x760, None): [
b'M2GC-2D053-CB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'M2GC-2D053-EA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdRadar, 0x764, None): [
b'JX7T-14D049-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdCamera, 0x706, None): [
b'KT4T-14F397-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.engine, 0x7E0, None): [
b'N2GA-14C204-ND\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
CAR.ESCAPE_MK4: {
(Ecu.eps, 0x730, None): [
b'LX6C-14D003-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
Expand Down
5 changes: 5 additions & 0 deletions selfdrive/car/ford/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
ret.steerRatio = 17.7
ret.mass = 1625

elif candidate == CAR.EDGE_MK2:
ret.wheelbase = 2.824
ret.steerRatio = 15.3
ret.mass = 1933

elif candidate == CAR.ESCAPE_MK4:
ret.wheelbase = 2.71
ret.steerRatio = 16.7
Expand Down
3 changes: 3 additions & 0 deletions selfdrive/car/ford/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def __init__(self, CP):

class CAR(StrEnum):
BRONCO_SPORT_MK1 = "FORD BRONCO SPORT 1ST GEN"
EDGE_MK2 = "FORD EDGE 2ND GEN"
ESCAPE_MK4 = "FORD ESCAPE 4TH GEN"
EXPLORER_MK6 = "FORD EXPLORER 6TH GEN"
F_150_MK14 = "FORD F-150 14TH GEN"
Expand All @@ -52,6 +53,7 @@ class CAR(StrEnum):


CANFD_CAR = {CAR.F_150_MK14, CAR.F_150_LIGHTNING_MK1, CAR.MUSTANG_MACH_E_MK1}
CAN_EDGE = {CAR.EDGE_MK2}


class RADAR:
Expand Down Expand Up @@ -89,6 +91,7 @@ def init_make(self, CP: car.CarParams):

CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {
CAR.BRONCO_SPORT_MK1: FordCarInfo("Ford Bronco Sport 2021-22"),
CAR.EDGE_MK2: FordCarInfo("Ford Edge 2020-23", "Adaptive Cruise Control with Lane Centering"),
CAR.ESCAPE_MK4: [
FordCarInfo("Ford Escape 2020-22"),
FordCarInfo("Ford Kuga 2020-22", "Adaptive Cruise Control with Lane Centering"),
Expand Down
1 change: 1 addition & 0 deletions selfdrive/car/tests/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class CarTestRoute(NamedTuple):
CarTestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD, segment=6),

CarTestRoute("54827bf84c38b14f|2023-01-25--14-14-11", FORD.BRONCO_SPORT_MK1),
CarTestRoute("3d4e31f900dd3a88|2023-12-15--11-19-47", FORD.EDGE_MK2),
CarTestRoute("f8eaaccd2a90aef8|2023-05-04--15-10-09", FORD.ESCAPE_MK4),
CarTestRoute("62241b0c7fea4589|2022-09-01--15-32-49", FORD.EXPLORER_MK6),
CarTestRoute("e886087f430e7fe7|2023-06-16--23-06-36", FORD.FOCUS_MK4),
Expand Down
1 change: 1 addition & 0 deletions selfdrive/car/torque_data/override.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]

# Guess
"FORD BRONCO SPORT 1ST GEN" = [nan, 1.5, nan]
"FORD EDGE 2ND GEN" = [nan, 1.5, nan]
"FORD ESCAPE 4TH GEN" = [nan, 1.5, nan]
"FORD EXPLORER 6TH GEN" = [nan, 1.5, nan]
"FORD F-150 14TH GEN" = [nan, 1.5, nan]
Expand Down
Loading