Skip to content

Commit

Permalink
November 2024 Update
Browse files Browse the repository at this point in the history
  • Loading branch information
FrogAi committed Oct 31, 2024
1 parent d9aaed3 commit 9bea8f1
Show file tree
Hide file tree
Showing 129 changed files with 4,040 additions and 3,311 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ FrogPilot is a fully open-sourced fork of openpilot, featuring clear and concise
------
FrogPilot was last updated on:

**October 21st, 2024**
**November 1st, 2024**

Features
------
Expand Down
20 changes: 11 additions & 9 deletions cereal/car.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,15 @@ struct CarEvent @0x9b1657f34caf3ad3 {
openpilotCrashedRandomEvent @137;
pedalInterceptorNoBrake @138;
speedLimitChanged @139;
torqueNNLoad @140;
trafficModeActive @141;
trafficModeInactive @142;
turningLeft @143;
turningRight @144;
vCruise69 @145;
yourFrogTriedToKillMe @146;
youveGotMail @147;
thisIsFineSteerSaturated @140;
torqueNNLoad @141;
trafficModeActive @142;
trafficModeInactive @143;
turningLeft @144;
turningRight @145;
vCruise69 @146;
yourFrogTriedToKillMe @147;
youveGotMail @148;

radarCanErrorDEPRECATED @15;
communityFeatureDisallowedDEPRECATED @62;
Expand Down Expand Up @@ -453,7 +454,8 @@ struct CarControl {
mail @16;
nessie @17;
noice @18;
uwu @19;
thisIsFine @19;
uwu @20;
}
}

Expand Down
44 changes: 23 additions & 21 deletions cereal/custom.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,29 @@ struct FrogPilotPlan @0x80ae746ee2596b11 {
desiredFollowDistance @4 :Float32;
experimentalMode @5 :Bool;
forcingStop @6 :Bool;
frogpilotEvents @7 :List(Car.CarEvent);
lateralCheck @8 :Bool;
laneWidthLeft @9 :Float32;
laneWidthRight @10 :Float32;
maxAcceleration @11 :Float32;
minAcceleration @12 :Float32;
redLight @13 :Bool;
safeObstacleDistance @14 :Int32;
safeObstacleDistanceStock @15 :Int32;
slcOverridden @16 :Bool;
slcOverriddenSpeed @17 :Float32;
slcSpeedLimit @18 :Float32;
slcSpeedLimitOffset @19 :Float32;
speedJerk @20 :Float32;
speedJerkStock @21 :Float32;
speedLimitChanged @22 :Bool;
stoppedEquivalenceFactor @23 :Int32;
tFollow @24 :Float32;
unconfirmedSlcSpeedLimit @25 :Float32;
vCruise @26 :Float32;
vtscControllingCurve @27 :Bool;
forcingStopLength @7 :Float32;
frogpilotEvents @8 :List(Car.CarEvent);
lateralCheck @9 :Bool;
laneWidthLeft @10 :Float32;
laneWidthRight @11 :Float32;
maxAcceleration @12 :Float32;
minAcceleration @13 :Float32;
redLight @14 :Bool;
safeObstacleDistance @15 :Int32;
safeObstacleDistanceStock @16 :Int32;
slcOverridden @17 :Bool;
slcOverriddenSpeed @18 :Float32;
slcSpeedLimit @19 :Float32;
slcSpeedLimitOffset @20 :Float32;
speedJerk @21 :Float32;
speedJerkStock @22 :Float32;
speedLimitChanged @23 :Bool;
stoppedEquivalenceFactor @24 :Int32;
tFollow @25 :Float32;
togglesUpdated @26 :Bool;
unconfirmedSlcSpeedLimit @27 :Float32;
vCruise @28 :Float32;
vtscControllingCurve @29 :Bool;
}

struct CustomReserved5 @0xa5cd762cd951a455 {
Expand Down
4 changes: 4 additions & 0 deletions cereal/log.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@ struct RadarState @0x9a185389d6fdd05f {

leadOne @3 :LeadData;
leadTwo @4 :LeadData;
leadLeft @13 :LeadData;
leadRight @14 :LeadData;
leadLeftFar @15 :LeadData;
leadRightFar @16 :LeadData;
cumLagMs @5 :Float32;

struct LeadData {
Expand Down
14 changes: 7 additions & 7 deletions cereal/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ def __init__(self, should_log: bool, frequency: float, decimation: Optional[int]
"userFlag": (True, 0., 1),
"microphone": (True, 10., 10),

# FrogPilot
"frogpilotCarControl": (True, 100., 10),
"frogpilotCarState": (True, 100., 10),
"frogpilotDeviceState": (True, 2., 1),
"frogpilotNavigation": (True, 1., 10),
"frogpilotPlan": (True, 20., 5),

# debug
"uiDebug": (True, 0., 1),
"testJoystick": (True, 0.),
Expand All @@ -97,6 +90,13 @@ def __init__(self, should_log: bool, frequency: float, decimation: Optional[int]
"customReservedRawData0": (True, 0.),
"customReservedRawData1": (True, 0.),
"customReservedRawData2": (True, 0.),

# FrogPilot
"frogpilotCarControl": (True, 100., 10),
"frogpilotCarState": (True, 100., 10),
"frogpilotDeviceState": (True, 2., 1),
"frogpilotNavigation": (True, 1., 10),
"frogpilotPlan": (True, 20., 5),
}
SERVICE_LIST = {name: Service(*vals) for
idx, (name, vals) in enumerate(_services.items())}
Expand Down
2 changes: 0 additions & 2 deletions common/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class Conversions:
KNOTS_TO_MS = 1. / MS_TO_KNOTS

# Distance
KM_TO_MILES = KPH_TO_MPH
MILES_TO_KM = MPH_TO_KPH
METER_TO_FOOT = 3.28084
FOOT_TO_METER = 1. / METER_TO_FOOT
CM_TO_INCH = 1. / 2.54
Expand Down
23 changes: 11 additions & 12 deletions common/params.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,11 @@ std::unordered_map<std::string, uint32_t> keys = {
// FrogPilot parameters
{"AccelerationPath", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"AccelerationProfile", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AdjacentLeadsUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AdjacentPath", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"AdjacentPathMetrics", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"AdvancedCustomUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"AdvancedLateralTune", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AdvancedLongitudinalTune", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AdvancedQOLDriving", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AggressiveFollow", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AggressiveJerkAcceleration", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"AggressiveJerkDanger", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
Expand All @@ -240,7 +239,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"BlindSpotMetrics", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"BlindSpotPath", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"BorderMetrics", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"CameraFPS", PERSISTENT},
{"CameraView", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"CancelModelDownload", PERSISTENT},
{"CancelThemeDownload", PERSISTENT},
Expand All @@ -266,6 +264,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CESpeedLead", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"CEStatus", CLEAR_ON_OFFROAD_TRANSITION},
{"CEStoppedLead", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ClassicModels", PERSISTENT},
{"ClusterOffset", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
{"ColorToDownload", PERSISTENT},
{"Compass", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
Expand All @@ -281,7 +280,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CustomCruiseLong", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"CustomDistanceIcons", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"CustomIcons", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"CustomPaths", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"CustomizationLevel", PERSISTENT},
{"CustomizationLevelConfirmed", PERSISTENT},
{"CustomPersonalities", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"CustomSignals", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"CustomSounds", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
Expand All @@ -293,6 +293,10 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DisableCurveSpeedSmoothing", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DisableOnroadUploads", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DisableOpenpilotLongitudinal", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
{"DissolvedOxygenCalibrationParams", PERSISTENT},
{"DissolvedOxygenDrives", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DissolvedOxygenLiveTorqueParameters", PERSISTENT},
{"DissolvedOxygenScore", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DistanceIconToDownload", PERSISTENT},
{"DisengageVolume", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"DoToggleReset", PERSISTENT},
Expand All @@ -303,10 +307,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DownloadableSounds", PERSISTENT},
{"DownloadableWheels", PERSISTENT},
{"DownloadAllModels", PERSISTENT},
{"DragonPilotTune", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
{"DriveRated", CLEAR_ON_ONROAD_TRANSITION},
{"DriverCamera", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"DrivingPersonalities", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DuckAmigoCalibrationParams", PERSISTENT},
{"DuckAmigoDrives", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"DuckAmigoLiveTorqueParameters", PERSISTENT},
Expand Down Expand Up @@ -334,6 +336,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"FrogPilotDrives", PERSISTENT | FROGPILOT_TRACKING},
{"FrogPilotKilometers", PERSISTENT | FROGPILOT_TRACKING},
{"FrogPilotMinutes", PERSISTENT | FROGPILOT_TRACKING},
{"FrogPilotToggles", PERSISTENT},
{"FrogPilotTogglesUpdated", PERSISTENT},
{"FrogsGoMoo", PERSISTENT},
{"FrogsGoMoosTweak", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
Expand All @@ -353,8 +356,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"HideMapIcon", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HideMaxSpeed", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HideSpeed", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HideSpeedUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HideUIElements", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HolidayThemes", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"HumanAcceleration", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"HumanFollowing", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
Expand Down Expand Up @@ -397,16 +398,15 @@ std::unordered_map<std::string, uint32_t> keys = {
{"MinimumLaneChangeSpeed", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"Model", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelDownloadProgress", PERSISTENT},
{"ModelManagement", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelName", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelRandomizer", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelsDownloaded", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelSelector", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ModelToDownload", PERSISTENT},
{"ModelUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"MTSCCurvatureCheck", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"MTSCEnabled", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"NavigationModels", PERSISTENT},
{"NavigationUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"NextMapSpeedLimit", PERSISTENT},
{"NewLongAPI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
{"NewLongAPIGM", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
Expand Down Expand Up @@ -493,7 +493,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"ShowIP", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"ShowMemoryUsage", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"ShowSLCOffset", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ShowSLCOffsetUI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"ShowSteering", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"ShowStoppingPoint", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"ShowStoppingPointMetrics", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
Expand Down Expand Up @@ -541,6 +540,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"TacoTune", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"TetheringEnabled", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_OTHER},
{"ThemeDownloadProgress", PERSISTENT},
{"ThemeUpdated", PERSISTENT},
{"TombRaiderCalibrationParams", PERSISTENT},
{"TombRaiderDrives", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"TombRaiderLiveTorqueParameters", PERSISTENT},
Expand All @@ -564,7 +564,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"UseSI", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
{"UseStockColors", CLEAR_ON_MANAGER_START},
{"UseVienna", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"VelocityModels", PERSISTENT},
{"VisionTurnControl", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_CONTROLS},
{"VoltSNG", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VEHICLES},
{"WarningImmediateVolume", PERSISTENT | FROGPILOT_STORAGE | FROGPILOT_VISUALS},
Expand Down
19 changes: 8 additions & 11 deletions selfdrive/car/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.controls.lib.events import Events

from openpilot.selfdrive.frogpilot.frogpilot_variables import FrogPilotVariables
from openpilot.selfdrive.frogpilot.frogpilot_utilities import update_frogpilot_toggles
from openpilot.selfdrive.frogpilot.frogpilot_variables import get_frogpilot_toggles

REPLAY = "REPLAY" in os.environ

Expand All @@ -28,7 +29,7 @@ class Car:

def __init__(self, CI=None):
self.can_sock = messaging.sub_sock('can', timeout=20)
self.sm = messaging.SubMaster(['pandaStates', 'carControl', 'onroadEvents'])
self.sm = messaging.SubMaster(['pandaStates', 'carControl', 'onroadEvents', 'frogpilotPlan'])
self.pm = messaging.PubMaster(['sendcan', 'carState', 'carParams', 'carOutput', 'frogpilotCarState'])

self.can_rcv_cum_timeout_counter = 0
Expand Down Expand Up @@ -74,10 +75,7 @@ def __init__(self, CI=None):
self.rk = Ratekeeper(100, print_delay_threshold=None)

# FrogPilot variables
self.frogpilot_toggles = FrogPilotVariables.toggles
FrogPilotVariables.update_frogpilot_params()

self.update_toggles = False
self.frogpilot_toggles = get_frogpilot_toggles(True)

# set alternative experiences from parameters
self.disengage_on_accelerator = self.params.get_bool("DisengageOnAccelerator")
Expand All @@ -97,6 +95,8 @@ def __init__(self, CI=None):
self.params.put_nonblocking("CarParamsCache", cp_bytes)
self.params.put_nonblocking("CarParamsPersistent", cp_bytes)

update_frogpilot_toggles()

def state_update(self) -> car.CarState:
"""carState update loop, driven by can"""

Expand Down Expand Up @@ -199,11 +199,8 @@ def card_thread(self):
self.rk.monitor_time()

# Update FrogPilot parameters
if FrogPilotVariables.toggles_updated:
self.update_toggles = True
elif self.update_toggles:
FrogPilotVariables.update_frogpilot_params()
self.update_toggles = False
if self.sm['frogpilotPlan'].togglesUpdated:
self.frogpilot_toggles = get_frogpilot_toggles()

def main():
config_realtime_process(4, Priority.CTRL_HIGH)
Expand Down
4 changes: 2 additions & 2 deletions selfdrive/car/ford/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ def update(self, CC, CS, now_nanos, frogpilot_toggles):
if self.CP.openpilotLongitudinalControl and (self.frame % CarControllerParams.ACC_CONTROL_STEP) == 0:
# Both gas and accel are in m/s^2, accel is used solely for braking
if frogpilot_toggles.sport_plus:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, get_max_allowed_accel(CS.out.vEgo)))
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, get_max_allowed_accel(CS.out.vEgo)))
else:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, CarControllerParams.ACCEL_MAX))
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, CarControllerParams.ACCEL_MAX))
gas = accel
if not CC.longActive or gas < CarControllerParams.MIN_GAS:
gas = CarControllerParams.INACTIVE_GAS
Expand Down
4 changes: 2 additions & 2 deletions selfdrive/car/honda/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ def update(self, CC, CS, now_nanos, frogpilot_toggles):

if self.CP.carFingerprint in HONDA_BOSCH:
if frogpilot_toggles.sport_plus:
self.accel = clip(accel, self.params.BOSCH_ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, get_max_allowed_accel(CS.out.vEgo)))
self.accel = clip(accel, self.params.BOSCH_ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, get_max_allowed_accel(CS.out.vEgo)))
else:
self.accel = clip(accel, self.params.BOSCH_ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, self.params.BOSCH_ACCEL_MAX))
self.accel = clip(accel, self.params.BOSCH_ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, self.params.BOSCH_ACCEL_MAX))
self.gas = interp(accel, self.params.BOSCH_GAS_LOOKUP_BP, self.params.BOSCH_GAS_LOOKUP_V)

stopping = actuators.longControlState == LongCtrlState.stopping
Expand Down
4 changes: 2 additions & 2 deletions selfdrive/car/hyundai/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ def update(self, CC, CS, now_nanos, frogpilot_toggles):

# accel + longitudinal
if frogpilot_toggles.sport_plus:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, get_max_allowed_accel(CS.out.vEgo)))
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, get_max_allowed_accel(CS.out.vEgo)))
else:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_accel, CarControllerParams.ACCEL_MAX))
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, min(frogpilot_toggles.max_desired_acceleration, CarControllerParams.ACCEL_MAX))
stopping = actuators.longControlState == LongCtrlState.stopping
set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH)

Expand Down
Loading

0 comments on commit 9bea8f1

Please sign in to comment.