from cereal import car
from selfdrive . car . ford . values import CANBUS
HUDControl = car . CarControl . HUDControl
def create_lka_msg ( packer ) :
"""
Creates an empty CAN message for the Ford LKA Command .
This command can apply " Lane Keeping Aid " manoeuvres , which are subject to the PSCM lockout .
Frequency is 20 Hz .
"""
return packer . make_can_msg ( " Lane_Assist_Data1 " , CANBUS . main , { } )
def create_lat_ctl_msg ( packer , lat_active : bool , path_offset : float , path_angle : float , curvature : float , curvature_rate : float ) :
"""
Creates a CAN message for the Ford TJA / LCA Command .
This command can apply " Lane Centering " manoeuvres : continuous lane centering for traffic jam assist and highway
driving . It is not subject to the PSCM lockout .
Ford lane centering command uses a third order polynomial to describe the road centerline . The polynomial is defined
by the following coefficients :
c0 : lateral offset between the vehicle and the centerline ( positive is right )
c1 : heading angle between the vehicle and the centerline ( positive is right )
c2 : curvature of the centerline ( positive is left )
c3 : rate of change of curvature of the centerline
As the PSCM combines this information with other sensor data , such as the vehicle ' s yaw rate and speed, the steering
angle cannot be easily controlled .
The PSCM should be configured to accept TJA / LCA commands before these commands will be processed . This can be done
using tools such as Forscan .
Frequency is 20 Hz .
"""
values = {
" LatCtlRng_L_Max " : 0 , # Unknown [0|126] meter
" HandsOffCnfm_B_Rq " : 0 , # Unknown: 0=Inactive, 1=Active [0|1]
" LatCtl_D_Rq " : 1 if lat_active else 0 , # Mode: 0=None, 1=ContinuousPathFollowing, 2=InterventionLeft,
# 3=InterventionRight, 4-7=NotUsed [0|7]
" LatCtlRampType_D_Rq " : 0 , # Ramp speed: 0=Slow, 1=Medium, 2=Fast, 3=Immediate [0|3]
# Makes no difference with curvature control
" LatCtlPrecision_D_Rq " : 1 , # Precision: 0=Comfortable, 1=Precise, 2/3=NotUsed [0|3]
# The stock system always uses comfortable
" LatCtlPathOffst_L_Actl " : path_offset , # Path offset [-5.12|5.11] meter
" LatCtlPath_An_Actl " : path_angle , # Path angle [-0.5|0.5235] radians
" LatCtlCurv_NoRate_Actl " : curvature_rate , # Curvature rate [-0.001024|0.00102375] 1/meter^2
" LatCtlCurv_No_Actl " : curvature , # Curvature [-0.02|0.02094] 1/meter
}
return packer . make_can_msg ( " LateralMotionControl " , CANBUS . main , values )
def create_lkas_ui_msg ( packer , main_on : bool , enabled : bool , steer_alert : bool , hud_control , stock_values : dict ) :
"""
Creates a CAN message for the Ford IPC IPMA / LKAS status .
Show the LKAS status with the " driver assist " lines in the IPC .
Stock functionality is maintained by passing through unmodified signals .
Frequency is 1 Hz .
"""
# LaActvStats_D_Dsply
# R Intvn Warn Supprs Avail No
# L
# Intvn 24 19 14 9 4
# Warn 23 18 13 8 3
# Supprs 22 17 12 7 2
# Avail 21 16 11 6 1
# No 20 15 10 5 0
#
# TODO: test suppress state
if enabled :
lines = 0 # NoLeft_NoRight
if hud_control . leftLaneDepart :
lines + = 4
elif hud_control . leftLaneVisible :
lines + = 1
if hud_control . rightLaneDepart :
lines + = 20
elif hud_control . rightLaneVisible :
lines + = 5
elif main_on :
lines = 0
else :
if hud_control . leftLaneDepart :
lines = 3 # WarnLeft_NoRight
elif hud_control . rightLaneDepart :
lines = 15 # NoLeft_WarnRight
else :
lines = 30 # LA_Off
# TODO: use level 1 for no sound when less severe?
hands_on_wheel_dsply = 2 if steer_alert else 0
values = {
* * stock_values ,
" LaActvStats_D_Dsply " : lines , # LKAS status (lines) [0|31]
" LaHandsOff_D_Dsply " : hands_on_wheel_dsply , # 0=HandsOn, 1=Level1 (w/o chime), 2=Level2 (w/ chime), 3=Suppressed
}
return packer . make_can_msg ( " IPMA_Data " , CANBUS . main , values )
def create_acc_ui_msg ( packer , main_on : bool , enabled : bool , hud_control , stock_values : dict ) :
"""
Creates a CAN message for the Ford IPC adaptive cruise , forward collision warning and traffic jam assist status .
Stock functionality is maintained by passing through unmodified signals .
Frequency is 20 Hz .
"""
# Tja_D_Stat
if enabled :
if hud_control . leftLaneDepart :
status = 3 # ActiveInterventionLeft
elif hud_control . rightLaneDepart :
status = 4 # ActiveInterventionRight
else :
status = 2 # Active
elif main_on :
if hud_control . leftLaneDepart :
status = 5 # ActiveWarningLeft
elif hud_control . rightLaneDepart :
status = 6 # ActiveWarningRight
else :
status = 1 # Standby
else :
status = 0 # Off
values = {
* * stock_values ,
" Tja_D_Stat " : status ,
}
return packer . make_can_msg ( " ACCDATA_3 " , CANBUS . main , values )
def create_button_msg ( packer , stock_values : dict , cancel = False , resume = False , tja_toggle = False ,
bus : int = CANBUS . camera ) :
"""
Creates a CAN message for the Ford SCCM buttons / switches .
Includes cruise control buttons , turn lights and more .
"""
values = {
* * stock_values ,
" CcAslButtnCnclPress " : 1 if cancel else 0 , # CC cancel button
" CcAsllButtnResPress " : 1 if resume else 0 , # CC resume button
" TjaButtnOnOffPress " : 1 if tja_toggle else 0 , # TJA toggle button
}
return packer . make_can_msg ( " Steering_Data_FD1 " , bus , values )