from opendbc . can . can_define import CANDefine
from opendbc . can . parser import CANParser
selfdrive/car: ban cereal and capnp (#33208)
* ban cereal and msgq
* common too
* do toyota/values.py
* do all fingerprints
* example without builder
* this still works, but no type checking anymore
* stash
* wtf, how does this work
* okay actually not bad
* safe
* epic!
* stash data_structures.py
* some clean up
* hell yeah
* clean up old file
* add to delete
* delete
This reverts commit 90239b7797ace31ee647a2fdbd67e0c3faa98dcf.
* switch more CarParams stuff over
remove unused
* fix car tests by removing cereal! mypy forgets about dataclass if we wrap it :(
* fix this too
* fix this too
* remove more cereal and add some good hyundai tests
* bunch more typing
* override default with 20hz radar
* temp capnp converter helper
* more lateralTuning
* small union replicator is better than what i was trying, and fixes mypy dynamic typing issues
* can keep all this the same now!
* type ret: CarParams, add more missing structs, revert lateralTuning changes (smaller diff!)
* revert more
* get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :(
would have been `CarParams.NetworkLocation()`
* Revert "get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :("
This reverts commit bb28b228becba932052d2fc5a4389784027435b1.
* remove cereal from car_helpers (TODO: caching)
* remove a bunch of temp lines
* use dataclass_transform!
* remove some car.CarParams from the interfaces
* remove rest of car.CarParams from the interfaces
* same which() API
* sort
* from cereal/cache from fingerprinting!
* more typing
* dataclass to capnp helper for CarParams, cached it since it's kinda slow
* (partial) fix process replay fingerprintig for new API
* latcontrollers take capnp
* forgot this
* fix test_models
* fix unit tests
* not here
* VehicleModel and controller still takes capnp CP since they get it from Params()
* fix modeld test
* more fix
* need to namespace to structs, since CarState is both class and struct
* this was never in the base class?!
* clean that up again
* fix import error
fix import error
* cmts and more structs
* remove some more cereal from toyota + convert CarState to capnp
* bruh this was wrong
* replace more cereal
* EventName is one of the last things...
* replace a bunch more cereal.car
* missing imports
* more
* can fix this typing now
* proper toyota+others CS typing!
* mypy can detect return type of CS.update() now
* fix redeclaration of cruise_buttons type
* mypy is only complaining about events now
* temp fix
* add carControl struct
* replace CarControl
i hope there's no circular imports in hyundai's CC
* fine now
* lol this was wrong too
* fix crash
* include my failed attempts at recursively converting to dataclass (doesn't implicitly convert types/recursively :( )
but attrs does, maybe will switch in the future
* clean up
* try out attr.s for its converter (doesn't work recursively yet, but interesting!)
* Revert "try out attr.s for its converter (doesn't work recursively yet, but interesting!)"
This reverts commit ff2434f7bbd45a4d4bfb21f7d6712d1f1c3bcde9.
* test processes doesn't fail anymore (on toyota)!
* fix honda crash
* stash
* Revert "stash"
This reverts commit c1762af4e776790e4ad1322ad4ce0610157346e0.
* remove a bunch more cereal!
* LET'S GOOO
* fix these tests
* and these
* and that
* stash, something is wrong with hyundai enable
* Revert "stash, something is wrong with hyundai enable"
This reverts commit 39cf327def258e2959fe23cd7a550a858f6d8f03.
* forgot these
* remove cereal from fw_versions
* Revert "remove cereal from fw_versions"
This reverts commit 232b37cd409b55d04b1afc90d4a80c49e710eb56.
* remove rest of the cereal exceptions!
* fix that
* add typing to radard since I didn't realize RI.update() switched from cereal to structs
* and here too!
* add TODO for slots
* needed CS to be capnp, fix comparisons, and type hint car_specific so it's easier to catch type issues (capnp isn't detected by mypy :( )
* remove the struct converter
* save ~4-5% CPU at 100hz, we don't modify after so no need to deepcopy
btw pickle.loads(pickle.dumps()) is faster by ~1% CPU
* deepcopy -> copy: we can technically make a reference, but copy is almost free and less error-prone
saves ~1% CPU
* add non-copying asdict function
* should save ~3% CPU (still 4% above baseline)
* fix that, no dict support
* ~27% decrease in time for 20k iterations on 3X (3.37857 -> 2.4821s)
* give a better name
* fix
* dont support none, capitalize
* sheesh, this called type() on every field
* remove CS.events, clean up
* bump card %
* this was a bug on master!
* add a which enum
* default to pid
* revert
* update refs
* not needed, but consistent
* just Ecu
* don't need to do this in this pr
* clean up
* no cast
* consistent typing
* rm
* fix
* can do this if we're desperate for the last few %
* Revert "can do this if we're desperate for the last few %"
This reverts commit 18e11ac7883a0a56583750b1cc5a2b13011e7299.
* type this
* don't need to convert carControl
* i guess don't support set either
* fix CP type hint
* simplify that
old-commit-hash: 6a15c42143a4764e79df851d797f950a6212f464
9 months ago
from openpilot . selfdrive . car import create_button_events , structs
from openpilot . selfdrive . car . common . conversions import Conversions as CV
from openpilot . selfdrive . car . ford . fordcan import CanBus
from openpilot . selfdrive . car . ford . values import DBC , CarControllerParams , FordFlags
from openpilot . selfdrive . car . interfaces import CarStateBase
selfdrive/car: ban cereal and capnp (#33208)
* ban cereal and msgq
* common too
* do toyota/values.py
* do all fingerprints
* example without builder
* this still works, but no type checking anymore
* stash
* wtf, how does this work
* okay actually not bad
* safe
* epic!
* stash data_structures.py
* some clean up
* hell yeah
* clean up old file
* add to delete
* delete
This reverts commit 90239b7797ace31ee647a2fdbd67e0c3faa98dcf.
* switch more CarParams stuff over
remove unused
* fix car tests by removing cereal! mypy forgets about dataclass if we wrap it :(
* fix this too
* fix this too
* remove more cereal and add some good hyundai tests
* bunch more typing
* override default with 20hz radar
* temp capnp converter helper
* more lateralTuning
* small union replicator is better than what i was trying, and fixes mypy dynamic typing issues
* can keep all this the same now!
* type ret: CarParams, add more missing structs, revert lateralTuning changes (smaller diff!)
* revert more
* get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :(
would have been `CarParams.NetworkLocation()`
* Revert "get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :("
This reverts commit bb28b228becba932052d2fc5a4389784027435b1.
* remove cereal from car_helpers (TODO: caching)
* remove a bunch of temp lines
* use dataclass_transform!
* remove some car.CarParams from the interfaces
* remove rest of car.CarParams from the interfaces
* same which() API
* sort
* from cereal/cache from fingerprinting!
* more typing
* dataclass to capnp helper for CarParams, cached it since it's kinda slow
* (partial) fix process replay fingerprintig for new API
* latcontrollers take capnp
* forgot this
* fix test_models
* fix unit tests
* not here
* VehicleModel and controller still takes capnp CP since they get it from Params()
* fix modeld test
* more fix
* need to namespace to structs, since CarState is both class and struct
* this was never in the base class?!
* clean that up again
* fix import error
fix import error
* cmts and more structs
* remove some more cereal from toyota + convert CarState to capnp
* bruh this was wrong
* replace more cereal
* EventName is one of the last things...
* replace a bunch more cereal.car
* missing imports
* more
* can fix this typing now
* proper toyota+others CS typing!
* mypy can detect return type of CS.update() now
* fix redeclaration of cruise_buttons type
* mypy is only complaining about events now
* temp fix
* add carControl struct
* replace CarControl
i hope there's no circular imports in hyundai's CC
* fine now
* lol this was wrong too
* fix crash
* include my failed attempts at recursively converting to dataclass (doesn't implicitly convert types/recursively :( )
but attrs does, maybe will switch in the future
* clean up
* try out attr.s for its converter (doesn't work recursively yet, but interesting!)
* Revert "try out attr.s for its converter (doesn't work recursively yet, but interesting!)"
This reverts commit ff2434f7bbd45a4d4bfb21f7d6712d1f1c3bcde9.
* test processes doesn't fail anymore (on toyota)!
* fix honda crash
* stash
* Revert "stash"
This reverts commit c1762af4e776790e4ad1322ad4ce0610157346e0.
* remove a bunch more cereal!
* LET'S GOOO
* fix these tests
* and these
* and that
* stash, something is wrong with hyundai enable
* Revert "stash, something is wrong with hyundai enable"
This reverts commit 39cf327def258e2959fe23cd7a550a858f6d8f03.
* forgot these
* remove cereal from fw_versions
* Revert "remove cereal from fw_versions"
This reverts commit 232b37cd409b55d04b1afc90d4a80c49e710eb56.
* remove rest of the cereal exceptions!
* fix that
* add typing to radard since I didn't realize RI.update() switched from cereal to structs
* and here too!
* add TODO for slots
* needed CS to be capnp, fix comparisons, and type hint car_specific so it's easier to catch type issues (capnp isn't detected by mypy :( )
* remove the struct converter
* save ~4-5% CPU at 100hz, we don't modify after so no need to deepcopy
btw pickle.loads(pickle.dumps()) is faster by ~1% CPU
* deepcopy -> copy: we can technically make a reference, but copy is almost free and less error-prone
saves ~1% CPU
* add non-copying asdict function
* should save ~3% CPU (still 4% above baseline)
* fix that, no dict support
* ~27% decrease in time for 20k iterations on 3X (3.37857 -> 2.4821s)
* give a better name
* fix
* dont support none, capitalize
* sheesh, this called type() on every field
* remove CS.events, clean up
* bump card %
* this was a bug on master!
* add a which enum
* default to pid
* revert
* update refs
* not needed, but consistent
* just Ecu
* don't need to do this in this pr
* clean up
* no cast
* consistent typing
* rm
* fix
* can do this if we're desperate for the last few %
* Revert "can do this if we're desperate for the last few %"
This reverts commit 18e11ac7883a0a56583750b1cc5a2b13011e7299.
* type this
* don't need to convert carControl
* i guess don't support set either
* fix CP type hint
* simplify that
old-commit-hash: 6a15c42143a4764e79df851d797f950a6212f464
9 months ago
ButtonType = structs . CarState . ButtonEvent . Type
GearShifter = structs . CarState . GearShifter
TransmissionType = structs . CarParams . TransmissionType
class CarState ( CarStateBase ) :
def __init__ ( self , CP ) :
super ( ) . __init__ ( CP )
can_define = CANDefine ( DBC [ CP . carFingerprint ] [ " pt " ] )
if CP . transmissionType == TransmissionType . automatic :
self . shifter_values = can_define . dv [ " PowertrainData_10 " ] [ " TrnRng_D_Rq " ]
self . distance_button = 0
selfdrive/car: ban cereal and capnp (#33208)
* ban cereal and msgq
* common too
* do toyota/values.py
* do all fingerprints
* example without builder
* this still works, but no type checking anymore
* stash
* wtf, how does this work
* okay actually not bad
* safe
* epic!
* stash data_structures.py
* some clean up
* hell yeah
* clean up old file
* add to delete
* delete
This reverts commit 90239b7797ace31ee647a2fdbd67e0c3faa98dcf.
* switch more CarParams stuff over
remove unused
* fix car tests by removing cereal! mypy forgets about dataclass if we wrap it :(
* fix this too
* fix this too
* remove more cereal and add some good hyundai tests
* bunch more typing
* override default with 20hz radar
* temp capnp converter helper
* more lateralTuning
* small union replicator is better than what i was trying, and fixes mypy dynamic typing issues
* can keep all this the same now!
* type ret: CarParams, add more missing structs, revert lateralTuning changes (smaller diff!)
* revert more
* get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :(
would have been `CarParams.NetworkLocation()`
* Revert "get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :("
This reverts commit bb28b228becba932052d2fc5a4389784027435b1.
* remove cereal from car_helpers (TODO: caching)
* remove a bunch of temp lines
* use dataclass_transform!
* remove some car.CarParams from the interfaces
* remove rest of car.CarParams from the interfaces
* same which() API
* sort
* from cereal/cache from fingerprinting!
* more typing
* dataclass to capnp helper for CarParams, cached it since it's kinda slow
* (partial) fix process replay fingerprintig for new API
* latcontrollers take capnp
* forgot this
* fix test_models
* fix unit tests
* not here
* VehicleModel and controller still takes capnp CP since they get it from Params()
* fix modeld test
* more fix
* need to namespace to structs, since CarState is both class and struct
* this was never in the base class?!
* clean that up again
* fix import error
fix import error
* cmts and more structs
* remove some more cereal from toyota + convert CarState to capnp
* bruh this was wrong
* replace more cereal
* EventName is one of the last things...
* replace a bunch more cereal.car
* missing imports
* more
* can fix this typing now
* proper toyota+others CS typing!
* mypy can detect return type of CS.update() now
* fix redeclaration of cruise_buttons type
* mypy is only complaining about events now
* temp fix
* add carControl struct
* replace CarControl
i hope there's no circular imports in hyundai's CC
* fine now
* lol this was wrong too
* fix crash
* include my failed attempts at recursively converting to dataclass (doesn't implicitly convert types/recursively :( )
but attrs does, maybe will switch in the future
* clean up
* try out attr.s for its converter (doesn't work recursively yet, but interesting!)
* Revert "try out attr.s for its converter (doesn't work recursively yet, but interesting!)"
This reverts commit ff2434f7bbd45a4d4bfb21f7d6712d1f1c3bcde9.
* test processes doesn't fail anymore (on toyota)!
* fix honda crash
* stash
* Revert "stash"
This reverts commit c1762af4e776790e4ad1322ad4ce0610157346e0.
* remove a bunch more cereal!
* LET'S GOOO
* fix these tests
* and these
* and that
* stash, something is wrong with hyundai enable
* Revert "stash, something is wrong with hyundai enable"
This reverts commit 39cf327def258e2959fe23cd7a550a858f6d8f03.
* forgot these
* remove cereal from fw_versions
* Revert "remove cereal from fw_versions"
This reverts commit 232b37cd409b55d04b1afc90d4a80c49e710eb56.
* remove rest of the cereal exceptions!
* fix that
* add typing to radard since I didn't realize RI.update() switched from cereal to structs
* and here too!
* add TODO for slots
* needed CS to be capnp, fix comparisons, and type hint car_specific so it's easier to catch type issues (capnp isn't detected by mypy :( )
* remove the struct converter
* save ~4-5% CPU at 100hz, we don't modify after so no need to deepcopy
btw pickle.loads(pickle.dumps()) is faster by ~1% CPU
* deepcopy -> copy: we can technically make a reference, but copy is almost free and less error-prone
saves ~1% CPU
* add non-copying asdict function
* should save ~3% CPU (still 4% above baseline)
* fix that, no dict support
* ~27% decrease in time for 20k iterations on 3X (3.37857 -> 2.4821s)
* give a better name
* fix
* dont support none, capitalize
* sheesh, this called type() on every field
* remove CS.events, clean up
* bump card %
* this was a bug on master!
* add a which enum
* default to pid
* revert
* update refs
* not needed, but consistent
* just Ecu
* don't need to do this in this pr
* clean up
* no cast
* consistent typing
* rm
* fix
* can do this if we're desperate for the last few %
* Revert "can do this if we're desperate for the last few %"
This reverts commit 18e11ac7883a0a56583750b1cc5a2b13011e7299.
* type this
* don't need to convert carControl
* i guess don't support set either
* fix CP type hint
* simplify that
old-commit-hash: 6a15c42143a4764e79df851d797f950a6212f464
9 months ago
def update ( self , cp , cp_cam , * _ ) - > structs . CarState :
ret = structs . CarState ( )
# 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
ret . vehicleSensorsInvalid = cp . vl [ " SteeringPinion_Data " ] [ " StePinCompAnEst_D_Qf " ] != 3
# car speed
ret . vEgoRaw = cp . vl [ " BrakeSysFeatures " ] [ " Veh_V_ActlBrk " ] * CV . KPH_TO_MS
ret . vEgo , ret . aEgo = self . update_speed_kf ( ret . vEgoRaw )
ret . yawRate = cp . vl [ " Yaw_Data_FD1 " ] [ " VehYaw_W_Actl " ]
ret . standstill = cp . vl [ " DesiredTorqBrk " ] [ " VehStop_D_Stat " ] == 1
# gas pedal
ret . gas = cp . vl [ " EngVehicleSpThrottle " ] [ " ApedPos_Pc_ActlArb " ] / 100.
ret . gasPressed = ret . gas > 1e-6
# brake pedal
ret . brake = cp . vl [ " BrakeSnData_4 " ] [ " BrkTot_Tq_Actl " ] / 32756. # torque in Nm
ret . brakePressed = cp . vl [ " EngBrakeData " ] [ " BpedDrvAppl_D_Actl " ] == 2
ret . parkingBrake = cp . vl [ " DesiredTorqBrk " ] [ " PrkBrkStatus " ] in ( 1 , 2 )
# steering wheel
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
ret . steerFaultPermanent = cp . vl [ " EPAS_INFO " ] [ " EPAS_Failure " ] in ( 2 , 3 )
ret . espDisabled = cp . vl [ " Cluster_Info1_FD1 " ] [ " DrvSlipCtlMde_D_Rq " ] != 0 # 0 is default mode
if self . CP . flags & FordFlags . CANFD :
# this signal is always 0 on non-CAN FD cars
ret . steerFaultTemporary | = cp . vl [ " Lane_Assist_Data3_FD1 " ] [ " LatCtlSte_D_Stat " ] not in ( 1 , 2 , 3 )
# cruise state
is_metric = cp . vl [ " INSTRUMENT_PANEL " ] [ " METRIC_UNITS " ] == 1 if not self . CP . flags & FordFlags . CANFD else False
ret . cruiseState . speed = cp . vl [ " EngBrakeData " ] [ " Veh_V_DsplyCcSet " ] * ( CV . KPH_TO_MS if is_metric else CV . MPH_TO_MS )
ret . cruiseState . enabled = cp . vl [ " EngBrakeData " ] [ " CcStat_D_Actl " ] in ( 4 , 5 )
ret . cruiseState . available = cp . vl [ " EngBrakeData " ] [ " CcStat_D_Actl " ] in ( 3 , 4 , 5 )
ret . cruiseState . nonAdaptive = cp . vl [ " Cluster_Info1_FD1 " ] [ " AccEnbl_B_RqDrv " ] == 0
ret . cruiseState . standstill = cp . vl [ " EngBrakeData " ] [ " AccStopMde_D_Rq " ] == 3
ret . accFaulted = cp . vl [ " EngBrakeData " ] [ " CcStat_D_Actl " ] in ( 1 , 2 )
if not self . CP . openpilotLongitudinalControl :
ret . accFaulted = ret . accFaulted or cp_cam . vl [ " ACCDATA " ] [ " CmbbDeny_B_Actl " ] == 1
# gear
if self . CP . transmissionType == TransmissionType . automatic :
gear = self . shifter_values . get ( cp . vl [ " PowertrainData_10 " ] [ " TrnRng_D_Rq " ] )
ret . gearShifter = self . parse_gear_shifter ( gear )
elif self . CP . transmissionType == TransmissionType . manual :
ret . clutchPressed = cp . vl [ " Engine_Clutch_Data " ] [ " CluPdlPos_Pc_Meas " ] > 0
if bool ( cp . vl [ " BCM_Lamp_Stat_FD1 " ] [ " RvrseLghtOn_B_Stat " ] ) :
ret . gearShifter = GearShifter . reverse
else :
ret . gearShifter = GearShifter . drive
# safety
ret . stockFcw = bool ( cp_cam . vl [ " ACCDATA_3 " ] [ " FcwVisblWarn_B_Rq " ] )
ret . stockAeb = bool ( cp_cam . vl [ " ACCDATA_2 " ] [ " CmbbBrkDecel_B_Rq " ] )
# button presses
ret . leftBlinker = cp . vl [ " Steering_Data_FD1 " ] [ " TurnLghtSwtch_D_Stat " ] == 1
ret . rightBlinker = cp . vl [ " Steering_Data_FD1 " ] [ " TurnLghtSwtch_D_Stat " ] == 2
# TODO: block this going to the camera otherwise it will enable stock TJA
ret . genericToggle = bool ( cp . vl [ " Steering_Data_FD1 " ] [ " TjaButtnOnOffPress " ] )
prev_distance_button = self . distance_button
self . distance_button = cp . vl [ " Steering_Data_FD1 " ] [ " AccButtnGapTogglePress " ]
# lock info
ret . doorOpen = any ( [ cp . vl [ " BodyInfo_3_FD1 " ] [ " DrStatDrv_B_Actl " ] , cp . vl [ " BodyInfo_3_FD1 " ] [ " DrStatPsngr_B_Actl " ] ,
cp . vl [ " BodyInfo_3_FD1 " ] [ " DrStatRl_B_Actl " ] , cp . vl [ " BodyInfo_3_FD1 " ] [ " DrStatRr_B_Actl " ] ] )
ret . seatbeltUnlatched = cp . vl [ " RCMStatusMessage2_FD1 " ] [ " FirstRowBuckleDriver " ] == 2
# blindspot sensors
if self . CP . enableBsm :
cp_bsm = cp_cam if self . CP . flags & FordFlags . CANFD else cp
ret . leftBlindspot = cp_bsm . vl [ " Side_Detect_L_Stat " ] [ " SodDetctLeft_D_Stat " ] != 0
ret . rightBlindspot = cp_bsm . vl [ " Side_Detect_R_Stat " ] [ " SodDetctRight_D_Stat " ] != 0
# Stock steering buttons so that we can passthru blinkers etc.
self . buttons_stock_values = cp . vl [ " Steering_Data_FD1 " ]
# Stock values from IPMA so that we can retain some stock functionality
self . acc_tja_status_stock_values = cp_cam . vl [ " ACCDATA_3 " ]
self . lkas_status_stock_values = cp_cam . vl [ " IPMA_Data " ]
ret . buttonEvents = create_button_events ( self . distance_button , prev_distance_button , { 1 : ButtonType . gapAdjustCruise } )
return ret
@staticmethod
def get_can_parser ( CP ) :
messages = [
# sig_address, frequency
( " VehicleOperatingModes " , 100 ) ,
( " BrakeSysFeatures " , 50 ) ,
( " Yaw_Data_FD1 " , 100 ) ,
( " DesiredTorqBrk " , 50 ) ,
( " EngVehicleSpThrottle " , 100 ) ,
( " BrakeSnData_4 " , 50 ) ,
( " EngBrakeData " , 10 ) ,
( " Cluster_Info1_FD1 " , 10 ) ,
( " SteeringPinion_Data " , 100 ) ,
( " EPAS_INFO " , 50 ) ,
( " Steering_Data_FD1 " , 10 ) ,
( " BodyInfo_3_FD1 " , 2 ) ,
( " RCMStatusMessage2_FD1 " , 10 ) ,
]
if CP . flags & FordFlags . CANFD :
messages + = [
( " Lane_Assist_Data3_FD1 " , 33 ) ,
]
else :
messages + = [
( " INSTRUMENT_PANEL " , 1 ) ,
]
if CP . transmissionType == TransmissionType . automatic :
messages + = [
( " PowertrainData_10 " , 10 ) ,
]
elif CP . transmissionType == TransmissionType . manual :
messages + = [
( " Engine_Clutch_Data " , 33 ) ,
( " BCM_Lamp_Stat_FD1 " , 1 ) ,
]
if CP . enableBsm and not ( CP . flags & FordFlags . CANFD ) :
messages + = [
( " Side_Detect_L_Stat " , 5 ) ,
( " Side_Detect_R_Stat " , 5 ) ,
]
return CANParser ( DBC [ CP . carFingerprint ] [ " pt " ] , messages , CanBus ( CP ) . main )
@staticmethod
def get_cam_can_parser ( CP ) :
messages = [
# sig_address, frequency
( " ACCDATA " , 50 ) ,
( " ACCDATA_2 " , 50 ) ,
( " ACCDATA_3 " , 5 ) ,
( " IPMA_Data " , 1 ) ,
]
if CP . enableBsm and CP . flags & FordFlags . CANFD :
messages + = [
( " Side_Detect_L_Stat " , 5 ) ,
( " Side_Detect_R_Stat " , 5 ) ,
]
return CANParser ( DBC [ CP . carFingerprint ] [ " pt " ] , messages , CanBus ( CP ) . camera )