From f5492336110ebb7438086f3a2eefab813009a132 Mon Sep 17 00:00:00 2001 From: James <91348155+FrogAi@users.noreply.github.com> Date: Tue, 9 Dec 2025 05:34:44 -0700 Subject: [PATCH] FrogPilot variables --- common/params_keys.h | 355 +++++++++++++ frogpilot/common/frogpilot_functions.py | 5 + frogpilot/common/frogpilot_variables.py | 499 ++++++++++++++++++ frogpilot/controls/frogpilot_card.py | 2 +- frogpilot/controls/frogpilot_planner.py | 14 +- frogpilot/controls/lib/frogpilot_events.py | 2 +- frogpilot/controls/lib/frogpilot_following.py | 2 +- frogpilot/controls/lib/frogpilot_vcruise.py | 2 +- frogpilot/frogpilot_process.py | 39 +- frogpilot/system/frogpilot_stats.py | 4 +- frogpilot/system/frogpilot_tracking.py | 4 +- frogpilot/ui/frogpilot_ui.cc | 7 + frogpilot/ui/frogpilot_ui.h | 2 + .../ui/qt/onroad/frogpilot_annotated_camera.h | 2 + frogpilot/ui/qt/onroad/frogpilot_onroad.h | 2 + frogpilot/ui/qt/widgets/frogpilot_controls.cc | 5 + frogpilot/ui/qt/widgets/frogpilot_controls.h | 1 + .../opendbc/car/body/carcontroller.py | 2 +- opendbc_repo/opendbc/car/body/carstate.py | 2 +- opendbc_repo/opendbc/car/car_helpers.py | 6 +- .../opendbc/car/chrysler/carcontroller.py | 2 +- opendbc_repo/opendbc/car/chrysler/carstate.py | 2 +- .../opendbc/car/ford/carcontroller.py | 2 +- opendbc_repo/opendbc/car/ford/carstate.py | 2 +- opendbc_repo/opendbc/car/gm/carcontroller.py | 2 +- opendbc_repo/opendbc/car/gm/carstate.py | 2 +- .../opendbc/car/honda/carcontroller.py | 2 +- opendbc_repo/opendbc/car/honda/carstate.py | 2 +- .../opendbc/car/hyundai/carcontroller.py | 2 +- opendbc_repo/opendbc/car/interfaces.py | 17 +- .../opendbc/car/mazda/carcontroller.py | 2 +- opendbc_repo/opendbc/car/mazda/carstate.py | 2 +- .../opendbc/car/mock/carcontroller.py | 2 +- .../opendbc/car/nissan/carcontroller.py | 2 +- opendbc_repo/opendbc/car/nissan/carstate.py | 2 +- opendbc_repo/opendbc/car/psa/carcontroller.py | 2 +- opendbc_repo/opendbc/car/psa/carstate.py | 2 +- .../opendbc/car/rivian/carcontroller.py | 2 +- opendbc_repo/opendbc/car/rivian/carstate.py | 2 +- .../opendbc/car/subaru/carcontroller.py | 2 +- opendbc_repo/opendbc/car/subaru/carstate.py | 2 +- .../opendbc/car/tesla/carcontroller.py | 2 +- opendbc_repo/opendbc/car/tesla/carstate.py | 2 +- .../opendbc/car/toyota/carcontroller.py | 2 +- opendbc_repo/opendbc/car/toyota/carstate.py | 2 +- .../opendbc/car/volkswagen/carcontroller.py | 2 +- .../opendbc/car/volkswagen/carstate.py | 2 +- selfdrive/car/card.py | 19 +- selfdrive/car/cruise.py | 10 +- selfdrive/controls/controlsd.py | 10 +- selfdrive/controls/lib/desire_helper.py | 2 +- selfdrive/controls/lib/latcontrol.py | 3 +- selfdrive/controls/lib/latcontrol_angle.py | 2 +- selfdrive/controls/lib/latcontrol_pid.py | 2 +- selfdrive/controls/lib/latcontrol_torque.py | 2 +- selfdrive/controls/lib/longcontrol.py | 6 +- .../controls/lib/longitudinal_planner.py | 6 +- selfdrive/controls/plannerd.py | 7 +- selfdrive/controls/radard.py | 18 +- selfdrive/locationd/lagd.py | 5 + selfdrive/locationd/paramsd.py | 5 + selfdrive/locationd/torqued.py | 7 + selfdrive/modeld/modeld.py | 6 +- selfdrive/selfdrived/events.py | 49 +- selfdrive/selfdrived/selfdrived.py | 7 +- selfdrive/ui/qt/home.cc | 3 + selfdrive/ui/qt/offroad/settings.cc | 11 + selfdrive/ui/qt/onroad/alerts.h | 2 + selfdrive/ui/qt/onroad/annotated_camera.cc | 5 + selfdrive/ui/qt/onroad/annotated_camera.h | 2 + selfdrive/ui/qt/onroad/buttons.h | 2 + selfdrive/ui/qt/onroad/driver_monitoring.h | 2 + selfdrive/ui/qt/onroad/hud.h | 2 + selfdrive/ui/qt/onroad/model.h | 2 + selfdrive/ui/qt/onroad/onroad_home.cc | 6 + selfdrive/ui/qt/sidebar.cc | 3 + selfdrive/ui/qt/window.cc | 1 + selfdrive/ui/soundd.py | 9 + selfdrive/ui/ui.cc | 4 + system/hardware/hardwared.py | 7 +- system/hardware/power_monitoring.py | 4 +- system/loggerd/uploader.py | 5 + system/manager/manager.py | 8 +- system/manager/process.py | 9 +- system/manager/process_config.py | 28 +- system/updated/updated.py | 3 + 86 files changed, 1169 insertions(+), 141 deletions(-) create mode 100644 frogpilot/common/frogpilot_variables.py mode change 100755 => 100644 selfdrive/controls/controlsd.py mode change 100755 => 100644 selfdrive/selfdrived/events.py diff --git a/common/params_keys.h b/common/params_keys.h index e7979f51f..6df11934f 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -133,4 +133,359 @@ inline static std::unordered_map keys = { {"Version", {PERSISTENT, STRING}}, // FrogPilot variables + {"AccelerationPath", {PERSISTENT, BOOL, "1", "0", 2}}, + {"AccelerationProfile", {PERSISTENT, INT, "2", "0", 0}}, + {"AdjacentLeadsUI", {PERSISTENT, BOOL, "1", "0", 3}}, + {"AdjacentPath", {PERSISTENT, BOOL, "0", "0", 3}}, + {"AdjacentPathMetrics", {PERSISTENT, BOOL, "0", "0", 3}}, + {"AdvancedCustomUI", {PERSISTENT, BOOL, "0", "0", 2}}, + {"AdvancedLateralTune", {PERSISTENT, BOOL, "0", "0", 3}}, + {"AdvancedLongitudinalTune", {PERSISTENT, BOOL, "0", "0", 3}}, + {"AggressiveFollow", {PERSISTENT, FLOAT, "1.25", "1.25", 2}}, + {"AggressiveJerkAcceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"AggressiveJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"AggressiveJerkDeceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"AggressiveJerkSpeed", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"AggressiveJerkSpeedDecrease", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"AlertVolumeControl", {PERSISTENT, BOOL, "0", "0", 2}}, + {"AlwaysOnLateral", {PERSISTENT, BOOL, "1", "0", 0}}, + {"AlwaysOnLateralLKAS", {PERSISTENT, BOOL, "1", "0", 2}}, + {"ApiCache_DriveStats", {PERSISTENT, JSON, "{}", "{}"}}, + {"AutomaticallyDownloadModels", {PERSISTENT, BOOL, "1", "0", 1}}, + {"AutomaticUpdates", {PERSISTENT, BOOL, "1", "1", 0}}, + {"AvailableModelNames", {PERSISTENT, STRING, "", "", 1}}, + {"AvailableModels", {PERSISTENT, STRING, "", "", 1}}, + {"BlacklistedModels", {PERSISTENT, STRING, "", "", 2}}, + {"BlindSpotMetrics", {PERSISTENT, BOOL, "1", "0", 3}}, + {"BlindSpotPath", {PERSISTENT, BOOL, "1", "0", 1}}, + {"BorderMetrics", {PERSISTENT, BOOL, "0", "0", 3}}, + {"CalibratedLateralAcceleration", {PERSISTENT, FLOAT, "2.0", "2.0", 2}}, + {"CalibrationProgress", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"CameraView", {PERSISTENT, INT, "3", "0", 2}}, + {"CancelModelDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"CancelThemeDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"CarMake", {PERSISTENT, STRING, "mock", "mock", 0}}, + {"CarModel", {PERSISTENT, STRING, "MOCK", "MOCK", 0}}, + {"CarModelName", {PERSISTENT, STRING, "", "", 0}}, + {"CECurves", {PERSISTENT, BOOL, "0", "0", 1}}, + {"CECurvesLead", {PERSISTENT, BOOL, "0", "0", 1}}, + {"CELead", {PERSISTENT, BOOL, "0", "0", 1}}, + {"CEModelStopTime", {PERSISTENT, FLOAT, "8.0", "0.0", 2}}, + {"CESignalLaneDetection", {PERSISTENT, BOOL, "1", "0", 2}}, + {"CESignalSpeed", {PERSISTENT, FLOAT, "55.0", "0.0", 2}}, + {"CESlowerLead", {PERSISTENT, BOOL, "0", "0", 1}}, + {"CESpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1}}, + {"CESpeedLead", {PERSISTENT, FLOAT, "0.0", "0.0", 1}}, + {"CEStatus", {CLEAR_ON_OFFROAD_TRANSITION, INT, "0", "0"}}, + {"CEStopLights", {PERSISTENT, BOOL, "1", "0", 1}}, + {"CEStoppedLead", {PERSISTENT, BOOL, "0", "0", 1}}, + {"ClusterOffset", {PERSISTENT, FLOAT, "1.015", "1.015", 2}}, + {"ColorScheme", {PERSISTENT, STRING, "frog", "stock", 0}}, + {"ColorToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"Compass", {PERSISTENT, BOOL, "0", "0", 1}}, + {"ConditionalExperimental", {PERSISTENT, BOOL, "1", "0", 1}}, + {"CurvatureData", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}}, + {"CurveSpeedController", {PERSISTENT, BOOL, "1", "0", 1}}, + {"CustomAlerts", {PERSISTENT, BOOL, "0", "0", 0}}, + {"CustomCruise", {PERSISTENT, FLOAT, "1.0", "1.0", 2}}, + {"CustomCruiseLong", {PERSISTENT, FLOAT, "5.0", "5.0", 2}}, + {"CustomPersonalities", {PERSISTENT, BOOL, "0", "0", 2}}, + {"CustomThemes", {PERSISTENT, BOOL, "1", "0", 0}}, + {"CustomUI", {PERSISTENT, BOOL, "1", "0", 1}}, + {"DebugMode", {CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}}, + {"DecelerationProfile", {PERSISTENT, INT, "1", "0", 2}}, + {"DeveloperMetrics", {PERSISTENT, BOOL, "1", "0", 3}}, + {"DeveloperSidebar", {PERSISTENT, BOOL, "1", "0", 3}}, + {"DeveloperSidebarMetric1", {PERSISTENT, INT, "1", "0", 3}}, + {"DeveloperSidebarMetric2", {PERSISTENT, INT, "2", "0", 3}}, + {"DeveloperSidebarMetric3", {PERSISTENT, INT, "3", "0", 3}}, + {"DeveloperSidebarMetric4", {PERSISTENT, INT, "4", "0", 3}}, + {"DeveloperSidebarMetric5", {PERSISTENT, INT, "5", "0", 3}}, + {"DeveloperSidebarMetric6", {PERSISTENT, INT, "6", "0", 3}}, + {"DeveloperSidebarMetric7", {PERSISTENT, INT, "7", "0", 3}}, + {"DeveloperUI", {PERSISTENT, BOOL, "0", "0", 3}}, + {"DeveloperWidgets", {PERSISTENT, BOOL, "1", "0", 3}}, + {"DeviceManagement", {PERSISTENT, BOOL, "1", "0", 1}}, + {"DeviceShutdown", {PERSISTENT, INT, "9", "33", 1}}, + {"DisableOnroadUploads", {PERSISTENT, BOOL, "0", "0", 2}}, + {"DisableOpenpilotLongitudinal", {PERSISTENT, BOOL, "0", "0", 0}}, + {"DiscordUsername", {PERSISTENT, STRING, "", "", 0}}, + {"DistanceButtonControl", {PERSISTENT, INT, "1", "0", 2}}, + {"DistanceIconPack", {PERSISTENT, STRING, "stock", "stock", 0}}, + {"DistanceIconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"DisengageVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"DownloadableColors", {PERSISTENT, STRING, "", ""}}, + {"DownloadableDistanceIcons", {PERSISTENT, STRING, "", ""}}, + {"DownloadableIcons", {PERSISTENT, STRING, "", ""}}, + {"DownloadableSignals", {PERSISTENT, STRING, "", ""}}, + {"DownloadableSounds", {PERSISTENT, STRING, "", ""}}, + {"DownloadableWheels", {PERSISTENT, STRING, "", ""}}, + {"DownloadAllModels", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"DriverCamera", {PERSISTENT, BOOL, "0", "0", 1}}, + {"DrivingModel", {PERSISTENT, STRING, "wmi-model_default", "wmi-model_default", 1}}, + {"DrivingModelName", {PERSISTENT, STRING, "WMI model (Default)", "WMI model (Default)", 1}}, + {"DrivingModelVersion", {PERSISTENT, STRING, "v9", "v9", 1}}, + {"DynamicPathWidth", {PERSISTENT, BOOL, "0", "0", 2}}, + {"DynamicPedalsOnUI", {PERSISTENT, BOOL, "1", "0", 1}}, + {"EngageVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"Fahrenheit", {PERSISTENT, BOOL, "0", "0", 3}}, + {"FlashPanda", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"ForceAutoTune", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ForceAutoTuneOff", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ForceFingerprint", {PERSISTENT, BOOL, "0", "0", 2}}, + {"ForceOffroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"ForceOnroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"ForceStops", {PERSISTENT, BOOL, "0", "0", 2}}, + {"ForceTorqueController", {PERSISTENT, BOOL, "0", "0", 3}}, + {"FPSCounter", {PERSISTENT, BOOL, "1", "0", 3}}, + {"FrogPilotCarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES, "", ""}}, + {"FrogPilotCarParamsPersistent", {PERSISTENT, BYTES, "", ""}}, + {"FrogPilotDongleId", {PERSISTENT | DONT_LOG, STRING, "", "", 0}}, + {"FrogPilotStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}}, + {"FrogPilotTogglesUpdated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"FrogsGoMoosTweak", {PERSISTENT, BOOL, "1", "0", 2}}, + {"GoatScream", {PERSISTENT, BOOL, "0", "0", 1}}, + {"GreenLightAlert", {PERSISTENT, BOOL, "0", "0", 0}}, + {"HideAlerts", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HideLeadMarker", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HideMaxSpeed", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HideSpeed", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HideSpeedLimit", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HigherBitrate", {PERSISTENT, BOOL, "0", "0", 2}}, + {"HolidayThemes", {PERSISTENT, BOOL, "1", "0", 0}}, + {"HumanAcceleration", {PERSISTENT, BOOL, "1", "0", 2}}, + {"HumanFollowing", {PERSISTENT, BOOL, "1", "0", 2}}, + {"HumanLaneChanges", {PERSISTENT, BOOL, "1", "0", 2}}, + {"IconPack", {PERSISTENT, STRING, "frog-animated", "stock", 0}}, + {"IconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"IncreasedStoppedDistance", {PERSISTENT, FLOAT, "0.0", "0.0", 1}}, + {"IncreasedStoppedDistanceLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreasedStoppedDistanceRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreasedStoppedDistanceRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreasedStoppedDistanceSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreaseFollowingLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreaseFollowingRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreaseFollowingRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreaseFollowingSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"IncreaseThermalLimits", {PERSISTENT, BOOL, "0", "0", 2}}, + {"IssueReported", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}}, + {"KonikDongleId", {PERSISTENT, STRING, "", "", 0}}, + {"KonikMinutes", {PERSISTENT, INT, "0", "0", 0}}, + {"LaneChanges", {PERSISTENT, BOOL, "1", "1", 0}}, + {"LaneChangeTime", {PERSISTENT, FLOAT, "1.0", "0.0", 1}}, + {"LaneDetectionWidth", {PERSISTENT, FLOAT, "0.0", "0.0", 1}}, + {"LaneLinesWidth", {PERSISTENT, FLOAT, "4.0", "2.0", 2}}, + {"LastMapsUpdate", {PERSISTENT, STRING, "", ""}}, + {"LateralTune", {PERSISTENT, BOOL, "1", "0", 1}}, + {"LeadDepartingAlert", {PERSISTENT, BOOL, "0", "0", 0}}, + {"LeadDetectionThreshold", {PERSISTENT, INT, "35", "50", 3}}, + {"LeadInfo", {PERSISTENT, BOOL, "1", "0", 3}}, + {"LKASButtonControl", {PERSISTENT, INT, "5", "0", 2}}, + {"LockDoors", {PERSISTENT, BOOL, "1", "0", 0}}, + {"LockDoorsTimer", {PERSISTENT, INT, "0", "0", 0}}, + {"LongDistanceButtonControl", {PERSISTENT, INT, "5", "0", 2}}, + {"LongitudinalActuatorDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"LongitudinalActuatorDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"LongitudinalTune", {PERSISTENT, BOOL, "1", "0", 0}}, + {"LoudBlindspotAlert", {PERSISTENT, BOOL, "0", "0", 0}}, + {"LowVoltageShutdown", {PERSISTENT, FLOAT, "11.8", "11.8", 3}}, + {"ManualUpdateInitiated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"MapAcceleration", {PERSISTENT, BOOL, "0", "0", 1}}, + {"MapboxPublicKey", {PERSISTENT | DONT_LOG, STRING, "", "", 0}}, + {"MapBoxRequests", {PERSISTENT, JSON, "{}", "{}"}}, + {"MapboxSecretKey", {PERSISTENT | DONT_LOG, STRING, "", "", 0}}, + {"MapDeceleration", {PERSISTENT, BOOL, "0", "0", 1}}, + {"MapdLogLevel", {CLEAR_ON_MANAGER_START, STRING, "0", "0"}}, + {"MapGears", {PERSISTENT, BOOL, "0", "0", 2}}, + {"MapsSelected", {PERSISTENT, JSON, "{}", "{}", 0}}, + {"MapSpeedLimit", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}}, + {"MaxDesiredAcceleration", {PERSISTENT, FLOAT, "4.0", "2.0", 2}}, + {"MinimumBackupSize", {PERSISTENT, INT, "0", "0"}}, + {"MinimumLaneChangeSpeed", {PERSISTENT, FLOAT, "20.0", "20.0", 2}}, + {"ModelDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"ModelDrivesAndScores", {PERSISTENT, JSON, "{}", "{}"}}, + {"ModelRandomizer", {PERSISTENT, BOOL, "0", "0", 2}}, + {"ModelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"ModelUI", {PERSISTENT, BOOL, "1", "0", 2}}, + {"NavigationUI", {PERSISTENT, BOOL, "1", "0", 1}}, + {"NextMapSpeedLimit", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}}, + {"NNFF", {PERSISTENT, BOOL, "1", "0", 2}}, + {"NNFFLite", {PERSISTENT, BOOL, "1", "0", 2}}, + {"NNFFModelName", {CLEAR_ON_MANAGER_START, STRING, "", "", 0}}, + {"NoLogging", {PERSISTENT, BOOL, "0", "0", 2}}, + {"NoUploads", {PERSISTENT, BOOL, "0", "0", 2}}, + {"NudgelessLaneChange", {PERSISTENT, BOOL, "1", "0", 0}}, + {"NumericalTemp", {PERSISTENT, BOOL, "1", "0", 3}}, + {"Offset1", {PERSISTENT, FLOAT, "5.0", "0.0", 0}}, + {"Offset2", {PERSISTENT, FLOAT, "5.0", "0.0", 0}}, + {"Offset3", {PERSISTENT, FLOAT, "5.0", "0.0", 0}}, + {"Offset4", {PERSISTENT, FLOAT, "5.0", "0.0", 0}}, + {"Offset5", {PERSISTENT, FLOAT, "10.0", "0.0", 0}}, + {"Offset6", {PERSISTENT, FLOAT, "10.0", "0.0", 0}}, + {"Offset7", {PERSISTENT, FLOAT, "10.0", "0.0", 0}}, + {"OneLaneChange", {PERSISTENT, BOOL, "1", "0", 2}}, + {"OnroadDistanceButton", {PERSISTENT, BOOL, "0", "0", 0}}, + {"OnroadDistanceButtonPressed", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"openpilotMinutes", {PERSISTENT, INT, "0", "0", 0}}, + {"OSMDownloadLocations", {PERSISTENT, JSON, "{}", "{}"}}, + {"OSMDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"OverpassRequests", {PERSISTENT, JSON, "{}", "{}"}}, + {"PathEdgeWidth", {PERSISTENT, FLOAT, "20", "0", 2}}, + {"PathWidth", {PERSISTENT, FLOAT, "6.1", "5.9", 2}}, + {"PauseAOLOnBrake", {PERSISTENT, BOOL, "0", "0", 1}}, + {"PauseLateralOnSignal", {PERSISTENT, BOOL, "0", "0", 1}}, + {"PauseLateralSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1}}, + {"PedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1}}, + {"PreferredSchedule", {PERSISTENT, INT, "2", "0", 0}}, + {"PreviousSpeedLimit", {PERSISTENT, FLOAT, "0.0", "0.0"}}, + {"PromptDistractedVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"PromptVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"QOLLateral", {PERSISTENT, BOOL, "1", "0", 1}}, + {"QOLLongitudinal", {PERSISTENT, BOOL, "1", "0", 1}}, + {"QOLVisuals", {PERSISTENT, BOOL, "1", "0", 0}}, + {"RadarTracksUI", {PERSISTENT, BOOL, "0", "0", 3}}, + {"RainbowPath", {PERSISTENT, BOOL, "0", "0", 1}}, + {"RandomEvents", {PERSISTENT, BOOL, "0", "0", 1}}, + {"RandomThemes", {PERSISTENT, BOOL, "0", "0", 1}}, + {"RandomThemesHolidays", {PERSISTENT, BOOL, "0", "0", 1}}, + {"ReduceAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceAccelerationRain", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceAccelerationSnow", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceLateralAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceLateralAccelerationRain", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceLateralAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2}}, + {"ReduceLateralAccelerationSnow", {PERSISTENT, INT, "0", "0", 2}}, + {"RefuseVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"RelaxedFollow", {PERSISTENT, FLOAT, "1.75", "1.75", 2}}, + {"RelaxedJerkAcceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"RelaxedJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"RelaxedJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"RelaxedJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"RelaxedJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"ReverseCruise", {PERSISTENT, BOOL, "0", "0", 1}}, + {"RoadEdgesWidth", {PERSISTENT, FLOAT, "2.0", "2.0", 2}}, + {"RoadName", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"RoadNameUI", {PERSISTENT, BOOL, "1", "0", 1}}, + {"RotatingWheel", {PERSISTENT, BOOL, "1", "0", 1}}, + {"ScreenBrightness", {PERSISTENT, INT, "101", "101", 2}}, + {"ScreenBrightnessOnroad", {PERSISTENT, INT, "101", "101", 2}}, + {"ScreenManagement", {PERSISTENT, BOOL, "1", "0", 1}}, + {"ScreenRecorder", {PERSISTENT, BOOL, "1", "0", 2}}, + {"ScreenTimeout", {PERSISTENT, INT, "30", "30", 2}}, + {"ScreenTimeoutOnroad", {PERSISTENT, INT, "30", "10", 2}}, + {"SecOCKeys", {PERSISTENT | DONT_LOG, STRING, "", "", 0}}, + {"SetSpeedLimit", {PERSISTENT, BOOL, "0", "0", 1}}, + {"SetSpeedOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 2}}, + {"ShowCEMStatus", {PERSISTENT, BOOL, "1", "0", 2}}, + {"ShowCPU", {PERSISTENT, BOOL, "1", "0", 3}}, + {"ShowCSCStatus", {PERSISTENT, BOOL, "1", "0", 2}}, + {"ShowGPU", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ShowIP", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ShowMemoryUsage", {PERSISTENT, BOOL, "1", "0", 3}}, + {"ShownToggleDescriptions", {PERSISTENT, JSON, "{}", "{}"}}, + {"ShowSLCOffset", {PERSISTENT, BOOL, "1", "0", 0}}, + {"ShowSpeedLimits", {PERSISTENT, BOOL, "1", "0", 1}}, + {"ShowSteering", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ShowStoppingPoint", {PERSISTENT, BOOL, "1", "0", 3}}, + {"ShowStoppingPointMetrics", {PERSISTENT, BOOL, "1", "0", 3}}, + {"ShowStorageLeft", {PERSISTENT, BOOL, "0", "0", 3}}, + {"ShowStorageUsed", {PERSISTENT, BOOL, "0", "0", 3}}, + {"SidebarMetrics", {PERSISTENT, BOOL, "1", "0", 3}}, + {"SidebarOpen", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SignalAnimation", {PERSISTENT, STRING, "frog", "stock", 0}}, + {"SignalMetrics", {PERSISTENT, BOOL, "0", "0", 3}}, + {"SignalToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"SLCConfirmation", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SLCConfirmationHigher", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SLCConfirmationLower", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SLCFallback", {PERSISTENT, INT, "2", "0", 1}}, + {"SLCLookaheadHigher", {PERSISTENT, INT, "0", "0", 2}}, + {"SLCLookaheadLower", {PERSISTENT, INT, "0", "0", 2}}, + {"SLCMapboxFiller", {PERSISTENT, BOOL, "1", "0", 1}}, + {"SLCOverride", {PERSISTENT, INT, "1", "0", 1}}, + {"SLCPriority", {PERSISTENT, STRING, "", "", 2}}, + {"SLCPriority1", {PERSISTENT, STRING, "Map Data", "Map Data", 2}}, + {"SLCPriority2", {PERSISTENT, STRING, "Dashboard", "Dashboard", 2}}, + {"SNGHack", {PERSISTENT, BOOL, "1", "0", 2}}, + {"SoundPack", {PERSISTENT, STRING, "frog", "stock", 0}}, + {"SoundToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"SpeedLimitAccepted", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"SpeedLimitChangedAlert", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SpeedLimitController", {PERSISTENT, BOOL, "1", "0", 0}}, + {"SpeedLimitFiller", {PERSISTENT, BOOL, "0", "0", 0}}, + {"SpeedLimits", {PERSISTENT | DONT_LOG, JSON, "[]", "[]"}}, + {"SpeedLimitsFiltered", {PERSISTENT | DONT_LOG, JSON, "[]", "[]"}}, + {"SpeedLimitSources", {PERSISTENT, BOOL, "0", "0", 3}}, + {"StandardFollow", {PERSISTENT, FLOAT, "1.45", "1.45", 2}}, + {"StandardJerkAcceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"StandardJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"StandardJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"StandardJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"StandardJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"StandbyMode", {PERSISTENT, BOOL, "0", "0", 1}}, + {"StartAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StartAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StartupMessageBottom", {PERSISTENT, STRING, "Human-tested, frog-approved 🐸", "Always keep hands on wheel and eyes on road", 0}}, + {"StartupMessageTop", {PERSISTENT, STRING, "Hop in and buckle up!", "Be ready to take over at any time", 0}}, + {"StaticPedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1}}, + {"SteerDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerFriction", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerFrictionStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerKP", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerKPStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerLatAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerLatAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerRatio", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SteerRatioStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StockDongleId", {PERSISTENT, STRING, "", ""}}, + {"StopAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StopAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StoppedTimer", {PERSISTENT, BOOL, "0", "0", 1}}, + {"StoppingDecelRate", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"StoppingDecelRateStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"SubaruSNG", {PERSISTENT, BOOL, "1", "0", 2}}, + {"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}}, + {"TacoTuneHacks", {PERSISTENT, BOOL, "0", "0", 2}}, + {"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"TetheringEnabled", {PERSISTENT, INT, "0", "0", 0}}, + {"ThemeDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"ThemesDownloaded", {PERSISTENT, JSON, "{}", "{}"}}, + {"Timezone", {PERSISTENT, STRING, "", ""}}, + {"TinygradUpdateAvailable", {PERSISTENT, BOOL, "0", "0", 1}}, + {"ToyotaDoors", {PERSISTENT, BOOL, "1", "0", 0}}, + {"TrafficFollow", {PERSISTENT, FLOAT, "0.5", "0.5", 2}}, + {"TrafficJerkAcceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"TrafficJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}}, + {"TrafficJerkDeceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"TrafficJerkSpeed", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"TrafficJerkSpeedDecrease", {PERSISTENT, FLOAT, "50.0", "50.0", 3}}, + {"TuningLevel", {PERSISTENT, INT, "0", "0", 0}}, + {"TuningLevelConfirmed", {PERSISTENT, BOOL, "0", "0", 0}}, + {"TurnDesires", {PERSISTENT, BOOL, "0", "0", 2}}, + {"UnlockDoors", {PERSISTENT, BOOL, "1", "0", 0}}, + {"Updated", {PERSISTENT, STRING, "0", "0"}}, + {"UpdateSpeedLimits", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"UpdateSpeedLimitsStatus", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, + {"UpdateTinygrad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"UpdateWheelImage", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"UseActiveTheme", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, + {"UseKonikServer", {PERSISTENT, BOOL, "0", "0", 2}}, + {"UseSI", {PERSISTENT, BOOL, "1", "1", 3}}, + {"UseVienna", {PERSISTENT, BOOL, "0", "0", 1}}, + {"VEgoStarting", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"VEgoStartingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"VEgoStopping", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"VEgoStoppingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}}, + {"VeryLongDistanceButtonControl", {PERSISTENT, INT, "6", "0", 2}}, + {"VoltSNG", {PERSISTENT, BOOL, "0", "0", 2}}, + {"WarningImmediateVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"WarningSoftVolume", {PERSISTENT, INT, "101", "101", 2}}, + {"WeatherPresets", {PERSISTENT, BOOL, "0", "0", 2}}, + {"WeatherToken", {PERSISTENT | DONT_LOG, STRING, "", "", 2}}, + {"WheelControls", {PERSISTENT, STRING, "", "", 2}}, + {"WheelIcon", {PERSISTENT, STRING, "frog", "stock", 0}}, + {"WheelSpeed", {PERSISTENT, BOOL, "0", "0", 2}}, + {"WheelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}}, }; diff --git a/frogpilot/common/frogpilot_functions.py b/frogpilot/common/frogpilot_functions.py index 4ed384743..0da69573c 100644 --- a/frogpilot/common/frogpilot_functions.py +++ b/frogpilot/common/frogpilot_functions.py @@ -12,11 +12,16 @@ from openpilot.common.time_helpers import system_time_valid from openpilot.system.hardware import HARDWARE from openpilot.frogpilot.common.frogpilot_utilities import run_cmd +from openpilot.frogpilot.common.frogpilot_variables import ( + FrogPilotVariables +) def frogpilot_boot_functions(params): params_memory = Params(memory=True) + FrogPilotVariables() + def boot_thread(): while not system_time_valid(): print("Waiting for system time to become valid...") diff --git a/frogpilot/common/frogpilot_variables.py b/frogpilot/common/frogpilot_variables.py new file mode 100644 index 000000000..ddcd95f60 --- /dev/null +++ b/frogpilot/common/frogpilot_variables.py @@ -0,0 +1,499 @@ +#!/usr/bin/env python3 +import json +import math +import os +import random + +from functools import cache +from pathlib import Path +from types import SimpleNamespace + +import cereal.messaging as messaging + +from cereal import car, custom, log +from opendbc.car import gen_empty_fingerprint +from opendbc.car.car_helpers import interfaces +from opendbc.car.gm.values import GMFlags +from opendbc.car.interfaces import CarInterfaceBase, GearShifter +from opendbc.car.mock.values import CAR as MOCK +from opendbc.car.subaru.values import SubaruFlags +from opendbc.car.toyota.values import ToyotaFrogPilotFlags +from openpilot.common.basedir import BASEDIR +from openpilot.common.constants import CV +from openpilot.common.params import Params +from openpilot.selfdrive.modeld.constants import ModelConstants +from openpilot.system.hardware import HARDWARE +from openpilot.system.hardware.power_monitoring import VBATT_PAUSE_CHARGING +from openpilot.system.version import get_build_metadata + +CITY_SPEED_LIMIT = 25 # 55mph is typically the minimum speed for highways +CRUISING_SPEED = 5 # Roughly the speed cars go when not touching the gas while in drive +DEFAULT_LATERAL_ACCELERATION = 2.0 # m/s^2, typical lateral acceleration when taking curves +DISPLAY_MENU_TIMER = 350 # The length of time the following distance menu appears on some GM vehicles to prevent things getting out of sync +EARTH_RADIUS = 6378137 # Radius of the Earth in meters +MAX_ACCELERATION = 4.0 # ISO 15622:2018 +MAX_T_FOLLOW = 3.0 # Maximum allowed following duration. Larger values risk losing track of the lead but may be increased as models improve +MINIMUM_LATERAL_ACCELERATION = 1.3 # m/s^2, typical minimum lateral acceleration when taking curves +PLANNER_TIME = ModelConstants.T_IDXS[-1] # Length of time the model projects out for +THRESHOLD = 1 - 1 / math.e # Requires the condition to be true for ~1 second + +NON_DRIVING_GEARS = [GearShifter.neutral, GearShifter.park, GearShifter.reverse, GearShifter.unknown] + +DISCORD_WEBHOOK_URL_REPORT = os.getenv("DISCORD_WEBHOOK_URL_REPORT") +DISCORD_WEBHOOK_URL_THEME = os.getenv("DISCORD_WEBHOOK_URL_THEME") + +RESOURCES_REPO = "FrogAi/FrogPilot-Resources" + +ACTIVE_THEME_PATH = Path(BASEDIR) / "frogpilot/assets/active_theme" +METADATAS_PATH = Path(BASEDIR) / "frogpilot/assets/model_metadata" +MODELS_PATH = Path("/data/models") +RANDOM_EVENTS_PATH = Path(BASEDIR) / "frogpilot/assets/random_events" +STOCK_THEME_PATH = Path(BASEDIR) / "frogpilot/assets/stock_theme" +THEME_COLORS_PATH = (ACTIVE_THEME_PATH / "colors/colors.json") +THEME_SAVE_PATH = Path("/data/themes") + +ERROR_LOGS_PATH = Path("/data/error_logs") +SCREEN_RECORDINGS_PATH = Path("/data/media/screen_recordings") +VIDEO_CACHE_PATH = Path("/data/video_cache") + +BACKUP_PATH = Path("/cache/on_backup") +FROGPILOT_BACKUPS = Path("/data/backups") +TOGGLE_BACKUPS = Path("/data/toggle_backups") + +MAPD_PATH = Path("/data/media/0/osm/mapd") +MAPS_PATH = Path("/data/media/0/osm/offline") + +BUTTON_FUNCTIONS = { + "NOTHING": 0, + "PERSONALITY_PROFILE": 1, + "FORCE_COAST": 2, + "PAUSE_LATERAL": 3, + "PAUSE_LONGITUDINAL": 4, + "EXPERIMENTAL_MODE": 5, + "TRAFFIC_MODE": 6 +} + +EXCLUDED_KEYS = { + "AvailableModelNames", + "AvailableModels", + "CalibratedLateralAcceleration", + "CalibrationProgress", + "CarBatteryCapacity", + "CarParamsPersistent", + "CurvatureData", + "ExperimentalLongitudinalEnabled", + "FrogPilotCarParamsPersistent", + "KonikMinutes", + "LastUpdateTime", + "MapBoxRequests", + "ModelDrivesAndScores", + "openpilotMinutes", + "OverpassRequests", + "PandaSignatures", + "SpeedLimits", + "SpeedLimitsFiltered", + "UpdateFailedCount", + "UpdaterAvailableBranches", + "UpdaterCurrentDescription", + "UpdaterCurrentReleaseNotes", + "UpdaterFetchAvailable", + "UpdaterTargetBranch", + "UptimeOffroad" +} + +TUNING_LEVELS = { + "MINIMAL": 0, + "STANDARD": 1, + "ADVANCED": 2, + "DEVELOPER": 3 +} + +def get_frogpilot_toggles(sm=messaging.SubMaster(["frogpilotPlan"])): + return process_frogpilot_toggles(sm["frogpilotPlan"].frogpilotToggles) + +@cache +def process_frogpilot_toggles(toggles): + if toggles: + return SimpleNamespace(**json.loads(toggles)) + return FrogPilotVariables().frogpilot_toggles + +def update_frogpilot_toggles(): + if not hasattr(update_frogpilot_toggles, "_params_memory"): + update_frogpilot_toggles._params_memory = Params(memory=True) + + update_frogpilot_toggles._params_memory.put_bool("FrogPilotTogglesUpdated", True) + +class FrogPilotVariables: + def __init__(self): + self.params = Params(return_defaults=True) + self.params_memory = Params(memory=True) + + self.frogpilot_toggles = SimpleNamespace() + toggle = self.frogpilot_toggles + + self.default_values = {key.decode(): self.params.get_default_value(key) for key in self.params.all_keys()} + self.tuning_levels = {key.decode(): self.params.get_tuning_level(key) for key in self.params.all_keys()} + + branch = get_build_metadata().channel + self.development_branch = branch == "FrogPilot-Development" + self.release_branch = branch == "FrogPilot" + self.staging_branch = branch == "FrogPilot-Staging" + self.testing_branch = branch == "FrogPilot-Testing" + self.vetting_branch = branch == "FrogPilot-Vetting" + + self.update() + + def get_value(self, key, cast=bool, condition=True, conversion=None, default=None, min=None, max=None): + if not condition or (self.tuning_level < self.tuning_levels.get(key, 0)): + if default is not None: + return default + return False if cast is bool else self.default_values.get(key) + + if cast is bool: + value = self.params.get_bool(key) + else: + value = self.params.get(key) + + if value is not None: + if cast is not bool and cast is not None: + try: + value = cast(value) + except (TypeError, ValueError): + value = self.default_values.get(key) + elif default is not None: + value = default + + if conversion is not None and isinstance(value, (int, float)): + value *= conversion + + if min is not None and value < min: + value = min + elif max is not None and value > max: + value = max + + return value + + def update(self, started=False): + toggle = self.frogpilot_toggles + self.tuning_level = self.params.get("TuningLevel") if self.params.get_bool("TuningLevelConfirmed") else TUNING_LEVELS["ADVANCED"] + + msg_bytes = self.params.get("CarParams" if started else "CarParamsPersistent", block=started) + if msg_bytes: + CP = messaging.log_from_bytes(msg_bytes, car.CarParams) + else: + CP = interfaces[MOCK.MOCK].get_params(MOCK.MOCK, gen_empty_fingerprint(), [], False, False, False, toggle).as_reader() + + is_torque_car = CP.lateralTuning.which() == "torque" + if not is_torque_car: + CP_builder = CP.as_builder() + CarInterfaceBase.configure_torque_tune(MOCK.MOCK, CP_builder.lateralTuning) + CP = CP_builder.as_reader() + + fpmsg_bytes = self.params.get("FrogPilotCarParams" if started else "FrogPilotCarParamsPersistent", block=started) + if fpmsg_bytes: + FPCP = messaging.log_from_bytes(fpmsg_bytes, custom.FrogPilotCarParams) + else: + FPCP = interfaces[MOCK.MOCK].get_frogpilot_params(MOCK.MOCK, gen_empty_fingerprint(), [], CP, toggle) + + toggle.car_make = CP.brand + toggle.car_model = CP.carFingerprint + has_bsm = CP.enableBsm + toggle.has_pedal = CP.enableGasInterceptorDEPRECATED + has_radar = not CP.radarUnavailable + toggle.has_sdsu = toggle.car_make == "toyota" and bool(FPCP.flags & ToyotaFrogPilotFlags.SMART_DSU.value) + has_sng = CP.autoResumeSng + toggle.has_zss = toggle.car_make == "toyota" and bool(FPCP.flags & ToyotaFrogPilotFlags.ZSS.value) + toggle.openpilot_longitudinal = CP.openpilotLongitudinalControl and not toggle.disable_openpilot_long + pcm_cruise = CP.pcmCruise + + msg_bytes = self.params.get("LiveTorqueParameters") + if msg_bytes: + LTP = messaging.log_from_bytes(msg_bytes, log.LiveTorqueParametersData) + else: + + toggle.is_metric = self.params.get_bool("IsMetric") + distance_conversion = 1 if toggle.is_metric else CV.FOOT_TO_METER + small_distance_conversion = 1 if toggle.is_metric else CV.INCH_TO_CM + speed_conversion = CV.KPH_TO_MS if toggle.is_metric else CV.MPH_TO_MS + + advanced_custom_ui = self.get_value("AdvancedCustomUI") + toggle.hide_alerts = self.get_value("HideAlerts", condition=advanced_custom_ui) + toggle.hide_lead_marker = self.get_value("HideLeadMarker", condition=advanced_custom_ui and toggle.openpilot_longitudinal) + toggle.hide_max_speed = self.get_value("HideMaxSpeed", condition=advanced_custom_ui) + toggle.hide_speed = self.get_value("HideSpeed", condition=advanced_custom_ui) + toggle.hide_speed_limit = self.get_value("HideSpeedLimit", condition=advanced_custom_ui) + toggle.use_wheel_speed = self.get_value("WheelSpeed", condition=advanced_custom_ui) + + toggle.alert_volume_controller = self.get_value("AlertVolumeControl") + toggle.disengage_volume = self.get_value("DisengageVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.engage_volume = self.get_value("EngageVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.prompt_volume = self.get_value("PromptVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.promptDistracted_volume = self.get_value("PromptDistractedVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.refuse_volume = self.get_value("RefuseVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.warningSoft_volume = self.get_value("WarningSoftVolume", cast=float, condition=toggle.alert_volume_controller) + toggle.warningImmediate_volume = max(self.get_value("WarningImmediateVolume", cast=float, condition=toggle.alert_volume_controller, default=25), 25) + + toggle.automatic_updates = self.get_value("AutomaticUpdates", condition=(self.release_branch or self.vetting_branch), default=True) and not BACKUP_PATH.is_file() + + car_model = self.params.get("CarModel") + toggle.force_fingerprint = self.get_value("ForceFingerprint", condition=car_model != self.default_values["CarModel"]) + if toggle.force_fingerprint: + toggle.car_model = car_model + + toggle.cluster_offset = self.get_value("ClusterOffset", cast=float, condition=toggle.car_make == "toyota") + + toggle.conditional_experimental_mode = toggle.openpilot_longitudinal and self.get_value("ConditionalExperimental") + toggle.conditional_curves = self.get_value("CECurves", condition=toggle.conditional_experimental_mode) + toggle.conditional_curves_lead = self.get_value("CECurvesLead", condition=toggle.conditional_curves) + toggle.conditional_lead = self.get_value("CELead", condition=toggle.conditional_experimental_mode) + toggle.conditional_slower_lead = self.get_value("CESlowerLead", condition=toggle.conditional_lead) + toggle.conditional_stopped_lead = self.get_value("CEStoppedLead", condition=toggle.conditional_lead) + toggle.conditional_limit = self.get_value("CESpeed", cast=float, condition=toggle.conditional_experimental_mode, conversion=speed_conversion) + toggle.conditional_limit_lead = self.get_value("CESpeedLead", cast=float, condition=toggle.conditional_experimental_mode, conversion=speed_conversion) + toggle.conditional_model_stop_time = self.get_value("CEModelStopTime", cast=float, condition=toggle.conditional_experimental_mode and self.get_value("CEStopLights")) + toggle.conditional_signal = self.get_value("CESignalSpeed", cast=float, condition=toggle.conditional_experimental_mode, conversion=speed_conversion) + toggle.conditional_signal_lane_detection = self.get_value("CESignalLaneDetection", condition=toggle.conditional_signal != 0) + toggle.cem_status = self.get_value("ShowCEMStatus", condition=toggle.conditional_experimental_mode) + + toggle.curve_speed_controller = toggle.openpilot_longitudinal and self.get_value("CurveSpeedController") + toggle.csc_status = self.get_value("ShowCSCStatus", condition=toggle.curve_speed_controller) + + custom_alerts = self.get_value("CustomAlerts") + toggle.goat_scream_alert = self.get_value("GoatScream", condition=custom_alerts) + toggle.green_light_alert = self.get_value("GreenLightAlert", condition=custom_alerts) + toggle.lead_departing_alert = self.get_value("LeadDepartingAlert", condition=custom_alerts) + toggle.loud_blindspot_alert = self.get_value("LoudBlindspotAlert", condition=custom_alerts and has_bsm) + toggle.speed_limit_changed_alert = self.get_value("SpeedLimitChangedAlert", condition=custom_alerts) + + toggle.custom_personalities = toggle.openpilot_longitudinal and self.get_value("CustomPersonalities") + toggle.aggressive_jerk_acceleration = self.get_value("AggressiveJerkAcceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.aggressive_jerk_deceleration = self.get_value("AggressiveJerkDeceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.aggressive_jerk_danger = self.get_value("AggressiveJerkDanger", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.aggressive_jerk_speed = self.get_value("AggressiveJerkSpeed", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.aggressive_jerk_speed_decrease = self.get_value("AggressiveJerkSpeedDecrease", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.aggressive_follow = self.get_value("AggressiveFollow", cast=float, condition=toggle.custom_personalities, min=1, max=MAX_T_FOLLOW) + toggle.standard_jerk_acceleration = self.get_value("StandardJerkAcceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.standard_jerk_deceleration = self.get_value("StandardJerkDeceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.standard_jerk_danger = self.get_value("StandardJerkDanger", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.standard_jerk_speed = self.get_value("StandardJerkSpeed", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.standard_jerk_speed_decrease = self.get_value("StandardJerkSpeedDecrease", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.standard_follow = self.get_value("StandardFollow", cast=float, condition=toggle.custom_personalities, min=1, max=MAX_T_FOLLOW) + toggle.relaxed_jerk_acceleration = self.get_value("RelaxedJerkAcceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.relaxed_jerk_deceleration = self.get_value("RelaxedJerkDeceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.relaxed_jerk_danger = self.get_value("RelaxedJerkDanger", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.relaxed_jerk_speed = self.get_value("RelaxedJerkSpeed", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.relaxed_jerk_speed_decrease = self.get_value("RelaxedJerkSpeedDecrease", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0) + toggle.relaxed_follow = self.get_value("RelaxedFollow", cast=float, condition=toggle.custom_personalities, min=1, max=MAX_T_FOLLOW) + toggle.traffic_mode_jerk_acceleration = [self.get_value("TrafficJerkAcceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0), toggle.aggressive_jerk_acceleration] + toggle.traffic_mode_jerk_deceleration = [self.get_value("TrafficJerkDeceleration", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0), toggle.aggressive_jerk_deceleration] + toggle.traffic_mode_jerk_danger = [self.get_value("TrafficJerkDanger", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0), toggle.aggressive_jerk_danger] + toggle.traffic_mode_jerk_speed = [self.get_value("TrafficJerkSpeed", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0), toggle.aggressive_jerk_speed] + toggle.traffic_mode_jerk_speed_decrease = [self.get_value("TrafficJerkSpeedDecrease", cast=float, condition=toggle.custom_personalities, conversion=0.01, min=0.25, max=2.0), toggle.aggressive_jerk_speed_decrease] + toggle.traffic_mode_follow = [self.get_value("TrafficFollow", cast=float, condition=toggle.custom_personalities, min=0.5, max=MAX_T_FOLLOW), toggle.aggressive_follow] + + custom_ui = self.get_value("CustomUI") + toggle.acceleration_path = toggle.openpilot_longitudinal and (self.get_value("AccelerationPath", condition=custom_ui)) + toggle.adjacent_paths = self.get_value("AdjacentPath", condition=custom_ui) + toggle.blind_spot_path = has_bsm and self.get_value("BlindSpotPath", condition=custom_ui) + toggle.compass = self.get_value("Compass", condition=custom_ui) + toggle.pedals_on_ui = self.get_value("PedalsOnUI", condition=custom_ui and toggle.openpilot_longitudinal) + toggle.dynamic_pedals_on_ui = self.get_value("DynamicPedalsOnUI", condition=toggle.pedals_on_ui) + toggle.static_pedals_on_ui = self.get_value("StaticPedalsOnUI", condition=toggle.pedals_on_ui) + toggle.rotating_wheel = self.get_value("RotatingWheel", condition=custom_ui) + + toggle.developer_ui = self.get_value("DeveloperUI") + developer_metrics = self.get_value("DeveloperMetrics", condition=toggle.developer_ui) + border_metrics = self.get_value("BorderMetrics", condition=developer_metrics) + toggle.blind_spot_metrics = has_bsm and self.get_value("BlindSpotMetrics", condition=border_metrics) + toggle.signal_metrics = self.get_value("SignalMetrics", condition=border_metrics) + toggle.steering_metrics = self.get_value("ShowSteering", condition=border_metrics) + toggle.show_fps = self.get_value("FPSCounter", condition=developer_metrics) + toggle.adjacent_path_metrics = self.get_value("AdjacentPathMetrics", condition=developer_metrics) + toggle.lead_info = self.get_value("LeadInfo", condition=developer_metrics) + toggle.numerical_temp = self.get_value("NumericalTemp", condition=developer_metrics) + toggle.fahrenheit = self.get_value("Fahrenheit", condition=toggle.numerical_temp) + toggle.cpu_metrics = self.get_value("ShowCPU", condition=developer_metrics) + toggle.gpu_metrics = self.get_value("ShowGPU", condition=developer_metrics) + toggle.ip_metrics = self.get_value("ShowIP", condition=developer_metrics) + toggle.memory_metrics = self.get_value("ShowMemoryUsage", condition=developer_metrics) + toggle.storage_left_metrics = self.get_value("ShowStorageLeft", condition=developer_metrics) + toggle.storage_used_metrics = self.get_value("ShowStorageUsed", condition=developer_metrics) + toggle.use_si_metrics = self.get_value("UseSI", condition=developer_metrics) + toggle.developer_sidebar = self.get_value("DeveloperSidebar", condition=toggle.developer_ui) + developer_widgets = self.get_value("DeveloperWidgets", condition=toggle.developer_ui) + toggle.adjacent_lead_tracking = has_radar and (self.get_value("AdjacentLeadsUI", condition=developer_widgets)) + toggle.radar_tracks = has_radar and (self.get_value("RadarTracksUI", condition=developer_widgets)) + toggle.show_stopping_point = toggle.openpilot_longitudinal and (self.get_value("ShowStoppingPoint", condition=developer_widgets)) + toggle.show_stopping_point_metrics = self.get_value("ShowStoppingPointMetrics", condition=toggle.show_stopping_point) + + device_management = self.get_value("DeviceManagement") + toggle.increase_thermal_limits = self.get_value("IncreaseThermalLimits", condition=device_management) + toggle.low_voltage_shutdown = self.get_value("LowVoltageShutdown", cast=float, condition=device_management, min=VBATT_PAUSE_CHARGING, max=12.5) + toggle.no_logging = self.get_value("NoLogging", condition=device_management and not self.vetting_branch) + toggle.no_uploads = self.get_value("NoUploads", condition=device_management and not self.vetting_branch) + toggle.no_onroad_uploads = self.get_value("DisableOnroadUploads", condition=toggle.no_uploads) + + distance_button_control = self.get_value("DistanceButtonControl", cast=float) + toggle.experimental_mode_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["EXPERIMENTAL_MODE"] + toggle.experimental_mode_via_press = toggle.experimental_mode_via_distance + toggle.force_coast_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["FORCE_COAST"] + toggle.pause_lateral_via_distance = distance_button_control == BUTTON_FUNCTIONS["PAUSE_LATERAL"] + toggle.pause_longitudinal_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["PAUSE_LONGITUDINAL"] + toggle.personality_profile_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["PERSONALITY_PROFILE"] + toggle.traffic_mode_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["TRAFFIC_MODE"] + + distance_button_control_long = self.get_value("LongDistanceButtonControl", cast=float) + toggle.experimental_mode_via_distance_long = toggle.openpilot_longitudinal and distance_button_control_long == BUTTON_FUNCTIONS["EXPERIMENTAL_MODE"] + toggle.experimental_mode_via_press |= toggle.experimental_mode_via_distance_long + toggle.force_coast_via_distance_long = toggle.openpilot_longitudinal and distance_button_control_long == BUTTON_FUNCTIONS["FORCE_COAST"] + toggle.pause_lateral_via_distance_long = distance_button_control_long == BUTTON_FUNCTIONS["PAUSE_LATERAL"] + toggle.pause_longitudinal_via_distance_long = toggle.openpilot_longitudinal and distance_button_control_long == BUTTON_FUNCTIONS["PAUSE_LONGITUDINAL"] + toggle.personality_profile_via_distance_long = toggle.openpilot_longitudinal and distance_button_control_long == BUTTON_FUNCTIONS["PERSONALITY_PROFILE"] + toggle.traffic_mode_via_distance_long = toggle.openpilot_longitudinal and distance_button_control_long == BUTTON_FUNCTIONS["TRAFFIC_MODE"] + + distance_button_control_very_long = self.get_value("VeryLongDistanceButtonControl", cast=float) + toggle.experimental_mode_via_distance_very_long = toggle.openpilot_longitudinal and distance_button_control_very_long == BUTTON_FUNCTIONS["EXPERIMENTAL_MODE"] + toggle.experimental_mode_via_press |= toggle.experimental_mode_via_distance_very_long + toggle.force_coast_via_distance_very_long = toggle.openpilot_longitudinal and distance_button_control_very_long == BUTTON_FUNCTIONS["FORCE_COAST"] + toggle.pause_lateral_via_distance_very_long = distance_button_control_very_long == BUTTON_FUNCTIONS["PAUSE_LATERAL"] + toggle.pause_longitudinal_via_distance_very_long = toggle.openpilot_longitudinal and distance_button_control_very_long == BUTTON_FUNCTIONS["PAUSE_LONGITUDINAL"] + toggle.personality_profile_via_distance_very_long = toggle.openpilot_longitudinal and distance_button_control_very_long == BUTTON_FUNCTIONS["PERSONALITY_PROFILE"] + toggle.traffic_mode_via_distance_very_long = toggle.openpilot_longitudinal and distance_button_control_very_long == BUTTON_FUNCTIONS["TRAFFIC_MODE"] + + toggle.lane_changes = self.get_value("LaneChanges") + toggle.lane_change_delay = self.get_value("LaneChangeTime", cast=float, condition=toggle.lane_changes) + toggle.lane_detection_width = self.get_value("LaneDetectionWidth", cast=float, condition=toggle.lane_changes, conversion=distance_conversion) + toggle.minimum_lane_change_speed = self.get_value("MinimumLaneChangeSpeed", cast=float, condition=toggle.lane_changes, conversion=speed_conversion) + toggle.nudgeless = self.get_value("NudgelessLaneChange", condition=toggle.lane_changes) + toggle.one_lane_change = self.get_value("OneLaneChange", condition=toggle.lane_changes) + + lateral_tuning = self.get_value("LateralTune") + toggle.use_turn_desires = self.get_value("TurnDesires", condition=lateral_tuning) + + lkas_button_control = self.get_value("LKASButtonControl", cast=float, condition=toggle.car_make != "subaru") + toggle.experimental_mode_via_lkas = toggle.openpilot_longitudinal and lkas_button_control == BUTTON_FUNCTIONS["EXPERIMENTAL_MODE"] + toggle.experimental_mode_via_press |= toggle.experimental_mode_via_lkas + toggle.force_coast_via_lkas = toggle.openpilot_longitudinal and lkas_button_control == BUTTON_FUNCTIONS["FORCE_COAST"] + toggle.pause_lateral_via_lkas = lkas_button_control == BUTTON_FUNCTIONS["PAUSE_LATERAL"] + toggle.pause_longitudinal_via_lkas = toggle.openpilot_longitudinal and lkas_button_control == BUTTON_FUNCTIONS["PAUSE_LONGITUDINAL"] + toggle.personality_profile_via_lkas = toggle.openpilot_longitudinal and lkas_button_control == BUTTON_FUNCTIONS["PERSONALITY_PROFILE"] + toggle.traffic_mode_via_lkas = toggle.openpilot_longitudinal and lkas_button_control == BUTTON_FUNCTIONS["TRAFFIC_MODE"] + + toggle.lock_doors_timer = self.get_value("LockDoorsTimer", cast=float, condition=(toggle.car_make == "toyota")) + + longitudinal_tuning = toggle.openpilot_longitudinal and self.get_value("LongitudinalTune") + toggle.acceleration_profile = self.get_value("AccelerationProfile", cast=float, condition=longitudinal_tuning) + toggle.deceleration_profile = self.get_value("DecelerationProfile", cast=float, condition=longitudinal_tuning) + toggle.human_acceleration = self.get_value("HumanAcceleration", condition=longitudinal_tuning) + toggle.human_following = self.get_value("HumanFollowing", condition=longitudinal_tuning) + toggle.human_lane_changes = has_radar and self.get_value("HumanLaneChanges", condition=longitudinal_tuning) + toggle.lead_detection_probability = self.get_value("LeadDetectionThreshold", cast=float, condition=longitudinal_tuning, conversion=0.01, min=0.25, max=0.5) + toggle.taco_tune = self.get_value("TacoTune", condition=longitudinal_tuning) + + toggle.model_ui = self.get_value("ModelUI") + toggle.dynamic_path_width = self.get_value("DynamicPathWidth", condition=toggle.model_ui) + toggle.lane_line_width = self.get_value("LaneLinesWidth", cast=float, condition=toggle.model_ui, conversion=small_distance_conversion / 200) + toggle.path_edge_width = self.get_value("PathEdgeWidth", cast=float, condition=toggle.model_ui) + toggle.path_width = self.get_value("PathWidth", cast=float, condition=toggle.model_ui, conversion=distance_conversion / 2) + toggle.road_edge_width = self.get_value("RoadEdgesWidth", cast=float, condition=toggle.model_ui, conversion=small_distance_conversion / 200) + + navigation_ui = self.get_value("NavigationUI") + toggle.road_name_ui = self.get_value("RoadNameUI", condition=navigation_ui) + toggle.show_speed_limits = self.get_value("ShowSpeedLimits", condition=navigation_ui) + toggle.speed_limit_vienna = self.get_value("UseVienna", condition=navigation_ui) + + quality_of_life_lateral = self.get_value("QOLLateral") + toggle.pause_lateral_below_speed = self.get_value("PauseLateralSpeed", cast=float, condition=quality_of_life_lateral, conversion=speed_conversion) + toggle.pause_lateral_below_signal = self.get_value("PauseLateralOnSignal", condition=toggle.pause_lateral_below_speed != 0) + + quality_of_life_longitudinal = toggle.openpilot_longitudinal and self.get_value("QOLLongitudinal") + toggle.cruise_increase = self.get_value("CustomCruise", cast=float, condition=(quality_of_life_longitudinal and not pcm_cruise)) + toggle.cruise_increase_long = self.get_value("CustomCruiseLong", cast=float, condition=(quality_of_life_longitudinal and not pcm_cruise)) + toggle.force_stops = self.get_value("ForceStops", condition=quality_of_life_longitudinal) + toggle.increase_stopped_distance = self.get_value("IncreasedStoppedDistance", cast=float, condition=quality_of_life_longitudinal, conversion=distance_conversion) + map_gears = self.get_value("MapGears", condition=quality_of_life_longitudinal) + toggle.map_acceleration = self.get_value("MapAcceleration", condition=map_gears) + toggle.map_deceleration = self.get_value("MapDeceleration", condition=map_gears) + toggle.reverse_cruise_increase = self.get_value("ReverseCruise", condition=quality_of_life_longitudinal and toggle.car_make == "toyota" and pcm_cruise) + toggle.set_speed_offset = self.get_value("SetSpeedOffset", cast=float, condition=(quality_of_life_longitudinal and not pcm_cruise), conversion=(1 if toggle.is_metric else CV.MPH_TO_KPH)) + toggle.weather_presets = self.get_value("WeatherPresets", condition=quality_of_life_longitudinal) + toggle.increase_following_distance_low_visibility = self.get_value("IncreaseFollowingLowVisibility", cast=float, condition=toggle.weather_presets) + toggle.increase_following_distance_rain = self.get_value("IncreaseFollowingRain", cast=float, condition=toggle.weather_presets) + toggle.increase_following_distance_rain_storm = self.get_value("IncreaseFollowingRainStorm", cast=float, condition=toggle.weather_presets) + toggle.increase_following_distance_snow = self.get_value("IncreaseFollowingSnow", cast=float, condition=toggle.weather_presets) + toggle.increase_stopped_distance_low_visibility = self.get_value("IncreasedStoppedDistanceLowVisibility", cast=float, condition=toggle.weather_presets, conversion=distance_conversion) + toggle.increase_stopped_distance_rain = self.get_value("IncreasedStoppedDistanceRain", cast=float, condition=toggle.weather_presets, conversion=distance_conversion) + toggle.increase_stopped_distance_rain_storm = self.get_value("IncreasedStoppedDistanceRainStorm", cast=float, condition=toggle.weather_presets, conversion=distance_conversion) + toggle.increase_stopped_distance_snow = self.get_value("IncreasedStoppedDistanceSnow", cast=float, condition=toggle.weather_presets, conversion=distance_conversion) + toggle.reduce_acceleration_low_visibility = self.get_value("ReduceAccelerationLowVisibility", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_acceleration_rain = self.get_value("ReduceAccelerationRain", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_acceleration_rain_storm = self.get_value("ReduceAccelerationRainStorm", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_acceleration_snow = self.get_value("ReduceAccelerationSnow", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_lateral_acceleration_low_visibility = self.get_value("ReduceLateralAccelerationLowVisibility", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_lateral_acceleration_rain = self.get_value("ReduceLateralAccelerationRain", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_lateral_acceleration_rain_storm = self.get_value("ReduceLateralAccelerationRainStorm", cast=float, condition=toggle.weather_presets, conversion=0.01) + toggle.reduce_lateral_acceleration_snow = self.get_value("ReduceLateralAccelerationSnow", cast=float, condition=toggle.weather_presets, conversion=0.01) + + quality_of_life_visuals = self.get_value("QOLVisuals") + toggle.camera_view = self.get_value("CameraView", cast=float, condition=quality_of_life_visuals) + toggle.driver_camera_in_reverse = self.get_value("DriverCamera", condition=quality_of_life_visuals) + toggle.onroad_distance_button = toggle.openpilot_longitudinal and (self.get_value("OnroadDistanceButton", condition=quality_of_life_visuals)) + toggle.stopped_timer = self.get_value("StoppedTimer", condition=quality_of_life_visuals) + + toggle.rainbow_path = self.get_value("RainbowPath") + + toggle.random_events = self.get_value("RandomEvents") + + screen_management = self.get_value("ScreenManagement") + toggle.screen_brightness = max(self.get_value("ScreenBrightness", cast=float, condition=screen_management), 1) + toggle.screen_brightness_onroad = self.get_value("ScreenBrightnessOnroad", cast=float, condition=(screen_management)) + toggle.screen_recorder = self.get_value("ScreenRecorder", condition=screen_management) + toggle.screen_timeout = self.get_value("ScreenTimeout", cast=float, condition=screen_management) + toggle.screen_timeout_onroad = self.get_value("ScreenTimeoutOnroad", cast=float, condition=screen_management) + toggle.standby_mode = self.get_value("StandbyMode", condition=screen_management) + + toggle.sng_hack = self.get_value("SNGHack", condition=toggle.openpilot_longitudinal and toggle.car_make == "toyota" and not toggle.has_pedal and not has_sng) + + toggle.speed_limit_controller = toggle.openpilot_longitudinal and self.get_value("SpeedLimitController") + toggle.map_speed_lookahead_higher = self.get_value("SLCLookaheadHigher", cast=float, condition=toggle.speed_limit_controller) + toggle.map_speed_lookahead_lower = self.get_value("SLCLookaheadLower", cast=float, condition=toggle.speed_limit_controller) + toggle.set_speed_limit = self.get_value("SetSpeedLimit", condition=toggle.speed_limit_controller) + toggle.show_speed_limit_offset = self.get_value("ShowSLCOffset", condition=toggle.speed_limit_controller) + slc_fallback_method = self.get_value("SLCFallback", cast=float, condition=toggle.speed_limit_controller) + toggle.slc_fallback_experimental_mode = slc_fallback_method == 1 + toggle.slc_fallback_previous_speed_limit = slc_fallback_method == 2 + toggle.slc_fallback_set_speed = slc_fallback_method == 0 + toggle.slc_mapbox_filler = self.get_value("SLCMapboxFiller", condition=(toggle.show_speed_limits or toggle.speed_limit_controller) and self.params.get("MapboxSecretKey") is not None) + speed_limit_confirmation = self.get_value("SLCConfirmation", condition=toggle.speed_limit_controller) + toggle.speed_limit_confirmation_higher = self.get_value("SLCConfirmationHigher", condition=speed_limit_confirmation) + toggle.speed_limit_confirmation_lower = self.get_value("SLCConfirmationLower", condition=speed_limit_confirmation) + slc_override_method = self.get_value("SLCOverride", cast=float, condition=toggle.speed_limit_controller) + toggle.speed_limit_controller_override_manual = slc_override_method == 1 + toggle.speed_limit_controller_override_set_speed = slc_override_method == 2 + toggle.speed_limit_offset1 = self.get_value("Offset1", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset2 = self.get_value("Offset2", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset3 = self.get_value("Offset3", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset4 = self.get_value("Offset4", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset5 = self.get_value("Offset5", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset6 = self.get_value("Offset6", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_offset7 = self.get_value("Offset7", cast=float, condition=toggle.speed_limit_controller, conversion=speed_conversion) + toggle.speed_limit_priority1 = self.get_value("SLCPriority1", cast=None, condition=toggle.speed_limit_controller) + toggle.speed_limit_priority2 = self.get_value("SLCPriority2", cast=None, condition=toggle.speed_limit_controller) + toggle.speed_limit_priority_highest = toggle.speed_limit_priority1 == "Highest" + toggle.speed_limit_priority_lowest = toggle.speed_limit_priority1 == "Lowest" + toggle.speed_limit_sources = self.get_value("SpeedLimitSources", condition=toggle.speed_limit_controller) + + toggle.speed_limit_filler = self.get_value("SpeedLimitFiller") + + toggle.startup_alert_top = self.get_value("StartupMessageTop", cast=str, default="") + toggle.startup_alert_bottom = self.get_value("StartupMessageBottom", cast=str, default="") + + toggle.tethering_config = self.get_value("TetheringEnabled", cast=float) + + toyota_doors = self.get_value("ToyotaDoors", condition=toggle.car_make == "toyota") + toggle.lock_doors = self.get_value("LockDoors", condition=toyota_doors) + toggle.unlock_doors = self.get_value("UnlockDoors", condition=toyota_doors) + + toggle.volt_sng = self.get_value("VoltSNG", condition=toggle.car_model == "CHEVROLET_VOLT") + + self.params_memory.remove("FrogPilotTogglesUpdated") diff --git a/frogpilot/controls/frogpilot_card.py b/frogpilot/controls/frogpilot_card.py index 1bfeae5c5..3dd99e0f9 100644 --- a/frogpilot/controls/frogpilot_card.py +++ b/frogpilot/controls/frogpilot_card.py @@ -12,7 +12,7 @@ class FrogPilotCard: self.accel_pressed = False self.decel_pressed = False - def update(self, carState, frogpilotCarState, sm): + def update(self, carState, frogpilotCarState, sm, frogpilot_toggles): if sm.updated["frogpilotPlan"] or any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in carState.buttonEvents): self.accel_pressed = any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in carState.buttonEvents) diff --git a/frogpilot/controls/frogpilot_planner.py b/frogpilot/controls/frogpilot_planner.py index b198c36e7..0b89912ac 100644 --- a/frogpilot/controls/frogpilot_planner.py +++ b/frogpilot/controls/frogpilot_planner.py @@ -40,7 +40,7 @@ class FrogPilotPlanner: self.tracking_lead_filter = FirstOrderFilter(0, 0.5, DT_MDL) - def update(self, now, time_validated, sm): + def update(self, now, time_validated, sm, frogpilot_toggles): self.lead_one = sm["radarState"].leadOne long_control_active = sm["carControl"].longActive @@ -49,14 +49,14 @@ class FrogPilotPlanner: v_ego = max(sm["carState"].vEgo, 0) if long_control_active: - self.frogpilot_acceleration.update(v_ego, sm) + self.frogpilot_acceleration.update(v_ego, sm, frogpilot_toggles) else: self.frogpilot_acceleration.max_accel = 0 self.frogpilot_acceleration.min_accel = 0 - self.frogpilot_events.update(v_cruise, sm) + self.frogpilot_events.update(v_cruise, sm, frogpilot_toggles) - self.frogpilot_following.update(long_control_active, v_ego, sm) + self.frogpilot_following.update(long_control_active, v_ego, sm, frogpilot_toggles) gps_location = sm[self.gps_location_service] self.gps_position = { @@ -75,7 +75,7 @@ class FrogPilotPlanner: if not sm["carState"].standstill: self.tracking_lead = self.update_lead_status() - self.v_cruise = self.frogpilot_vcruise.update(long_control_active, now, time_validated, v_cruise, v_ego, sm) + self.v_cruise = self.frogpilot_vcruise.update(long_control_active, now, time_validated, v_cruise, v_ego, sm, frogpilot_toggles) def update_lead_status(self): following_lead = self.lead_one.status @@ -84,7 +84,7 @@ class FrogPilotPlanner: self.tracking_lead_filter.update(following_lead) return self.tracking_lead_filter.x >= THRESHOLD - def publish(self, sm, pm): + def publish(self, sm, pm, frogpilot_toggles): frogpilot_plan_send = messaging.new_message("frogpilotPlan") frogpilot_plan_send.valid = sm.all_checks(service_list=["carState", "controlsState", "selfdriveState", "radarState"]) frogpilotPlan = frogpilot_plan_send.frogpilotPlan @@ -97,6 +97,8 @@ class FrogPilotPlanner: frogpilotPlan.frogpilotEvents = self.frogpilot_events.events.to_msg() + frogpilotPlan.frogpilotToggles = json.dumps(vars(frogpilot_toggles)) + frogpilotPlan.lateralCheck = self.lateral_check frogpilotPlan.maxAcceleration = float(self.frogpilot_acceleration.max_accel) diff --git a/frogpilot/controls/lib/frogpilot_events.py b/frogpilot/controls/lib/frogpilot_events.py index 28cbe9247..89117c524 100644 --- a/frogpilot/controls/lib/frogpilot_events.py +++ b/frogpilot/controls/lib/frogpilot_events.py @@ -13,7 +13,7 @@ class FrogPilotEvents: self.played_events = set() - def update(self, v_cruise, sm): + def update(self, v_cruise, sm, frogpilot_toggles): current_alert = sm["selfdriveState"].alertType current_frogpilot_alert = sm["selfdriveState"].alertType diff --git a/frogpilot/controls/lib/frogpilot_following.py b/frogpilot/controls/lib/frogpilot_following.py index 0c61c88a6..f54f79957 100644 --- a/frogpilot/controls/lib/frogpilot_following.py +++ b/frogpilot/controls/lib/frogpilot_following.py @@ -14,7 +14,7 @@ class FrogPilotFollowing: self.speed_jerk = 0 self.t_follow = 0 - def update(self, long_control_active, v_ego, sm): + def update(self, long_control_active, v_ego, sm, frogpilot_toggles): if long_control_active: if sm["carState"].aEgo >= 0: self.base_acceleration_jerk, self.base_danger_jerk, self.base_speed_jerk = get_jerk_factor( diff --git a/frogpilot/controls/lib/frogpilot_vcruise.py b/frogpilot/controls/lib/frogpilot_vcruise.py index 79687e0c1..e2acad096 100644 --- a/frogpilot/controls/lib/frogpilot_vcruise.py +++ b/frogpilot/controls/lib/frogpilot_vcruise.py @@ -7,7 +7,7 @@ class FrogPilotVCruise: def __init__(self, FrogPilotPlanner): self.frogpilot_planner = FrogPilotPlanner - def update(self, long_control_active, now, time_validated, v_cruise, v_ego, sm): + def update(self, long_control_active, now, time_validated, v_cruise, v_ego, sm, frogpilot_toggles): v_cruise_cluster = max(sm["carState"].vCruiseCluster * CV.KPH_TO_MS, v_cruise) v_cruise_diff = v_cruise_cluster - v_cruise diff --git a/frogpilot/frogpilot_process.py b/frogpilot/frogpilot_process.py index 0a73326c5..79f7c16bd 100644 --- a/frogpilot/frogpilot_process.py +++ b/frogpilot/frogpilot_process.py @@ -9,28 +9,35 @@ from openpilot.common.realtime import DT_MDL, Priority, Ratekeeper, config_realt from openpilot.common.time_helpers import system_time_valid from openpilot.frogpilot.common.frogpilot_utilities import ThreadManager, is_url_pingable +from openpilot.frogpilot.common.frogpilot_variables import FrogPilotVariables from openpilot.frogpilot.controls.frogpilot_planner import FrogPilotPlanner from openpilot.frogpilot.system.frogpilot_stats import send_stats from openpilot.frogpilot.system.frogpilot_tracking import FrogPilotTracking ASSET_CHECK_RATE = (1 / DT_MDL) -def check_assets(thread_manager, params_memory): +def check_assets(thread_manager, params_memory, frogpilot_toggles): -def transition_offroad(frogpilot_planner, thread_manager, time_validated, sm, params): +def transition_offroad(frogpilot_planner, thread_manager, time_validated, sm, params, frogpilot_toggles): params.put("LastGPSPosition", json.dumps(frogpilot_planner.gps_position)) if time_validated: - thread_manager.run_with_lock(send_stats, (params)) + thread_manager.run_with_lock(send_stats, (params, frogpilot_toggles)) def transition_onroad(): -def update_checks(now, thread_manager, params, params_memory, boot_run=False): +def update_checks(now, thread_manager, params, params_memory, frogpilot_toggles, boot_run=False): while not (is_url_pingable("https://github.com") or is_url_pingable("https://gitlab.com")): time.sleep(60) time.sleep(1) +def update_toggles(frogpilot_variables, started): + frogpilot_variables.update(started) + frogpilot_toggles = frogpilot_variables.frogpilot_toggles + + return frogpilot_toggles + def frogpilot_thread(): rate_keeper = Ratekeeper(1 / DT_MDL, None) @@ -46,8 +53,11 @@ def frogpilot_thread(): params = Params(return_defaults=True) params_memory = Params(memory=True) + frogpilot_variables = FrogPilotVariables() thread_manager = ThreadManager() + frogpilot_toggles = frogpilot_variables.frogpilot_toggles + run_update_checks = False started_previously = False time_validated = False @@ -60,7 +70,8 @@ def frogpilot_thread(): started = sm["deviceState"].started if not started and started_previously: - transition_offroad(frogpilot_planner, thread_manager, time_validated, sm, params) + frogpilot_toggles = update_toggles(frogpilot_variables, started) + transition_offroad(frogpilot_planner, thread_manager, time_validated, sm, params, frogpilot_toggles) run_update_checks = True elif started and not started_previously: @@ -70,24 +81,28 @@ def frogpilot_thread(): transition_onroad() if started and sm.updated["modelV2"]: - frogpilot_planner.update(now, time_validated, sm) - frogpilot_planner.publish(sm, pm) + frogpilot_planner.update(now, time_validated, sm, frogpilot_toggles) + frogpilot_planner.publish(sm, pm, frogpilot_toggles) - frogpilot_tracking.update(now, time_validated, sm) + frogpilot_tracking.update(now, time_validated, sm, frogpilot_toggles) elif not started: frogpilot_plan_send = messaging.new_message("frogpilotPlan") + frogpilot_plan_send.frogpilotPlan.frogpilotToggles = json.dumps(vars(frogpilot_toggles)) pm.send("frogpilotPlan", frogpilot_plan_send) started_previously = started if rate_keeper.frame % ASSET_CHECK_RATE == 0: - check_assets(thread_manager, params_memory) + check_assets(thread_manager, params_memory, frogpilot_toggles) + + if params_memory.get_bool("FrogPilotTogglesUpdated"): + frogpilot_toggles = update_toggles(frogpilot_variables, started) run_update_checks |= now.second == 0 and (now.minute % 60 == 0) run_update_checks &= time_validated if run_update_checks: - thread_manager.run_with_lock(update_checks, (now, thread_manager, params, params_memory)) + thread_manager.run_with_lock(update_checks, (now, thread_manager, params, params_memory, frogpilot_toggles)) run_update_checks = False elif not time_validated: @@ -95,8 +110,8 @@ def frogpilot_thread(): if not time_validated: continue - thread_manager.run_with_lock(send_stats, (params)) - thread_manager.run_with_lock(update_checks, (now, thread_manager, params, params_memory, True)) + thread_manager.run_with_lock(send_stats, (params, frogpilot_toggles)) + thread_manager.run_with_lock(update_checks, (now, thread_manager, params, params_memory, frogpilot_toggles, True)) rate_keeper.keep_time() diff --git a/frogpilot/system/frogpilot_stats.py b/frogpilot/system/frogpilot_stats.py index 3a74359b2..8e4246c23 100644 --- a/frogpilot/system/frogpilot_stats.py +++ b/frogpilot/system/frogpilot_stats.py @@ -14,7 +14,6 @@ from openpilot.system.version import get_build_metadata from openpilot.frogpilot.common.frogpilot_download_utilities import github_rate_limited from openpilot.frogpilot.common.frogpilot_utilities import clean_model_name, is_url_pingable -from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles BUCKET = os.environ.get("STATS_BUCKET", "") ORG_ID = os.environ.get("STATS_ORG_ID", "") @@ -137,12 +136,11 @@ def get_city_center(latitude, longitude): return (0.0, 0.0, "N/A", "N/A", "N/A") -def send_stats(params): +def send_stats(params, frogpilot_toggles): if not is_url_pingable(os.environ.get("STATS_URL", "")): return build_metadata = get_build_metadata() - frogpilot_toggles = get_frogpilot_toggles() car_params = "{}" msg_bytes = params.get("CarParamsPersistent") diff --git a/frogpilot/system/frogpilot_tracking.py b/frogpilot/system/frogpilot_tracking.py index 1833c30fb..42e87051f 100644 --- a/frogpilot/system/frogpilot_tracking.py +++ b/frogpilot/system/frogpilot_tracking.py @@ -12,7 +12,7 @@ from openpilot.frogpilot.controls.lib.frogpilot_events import RANDOM_EVENT_END, from openpilot.frogpilot.controls.lib.weather_checker import WEATHER_CATEGORIES class FrogPilotTracking: - def __init__(self, frogpilot_planner): + def __init__(self, frogpilot_planner, frogpilot_toggles): self.params = frogpilot_planner.params self.frogpilot_events = frogpilot_planner.frogpilot_events @@ -36,7 +36,7 @@ class FrogPilotTracking: self.model_name = clean_model_name(frogpilot_toggles.model_name) - def update(self, now, time_validated, sm): + def update(self, now, time_validated, sm, frogpilot_toggles): v_cruise = min(sm["carState"].vCruiseCluster, V_CRUISE_MAX) * CV.KPH_TO_MS v_ego = max(sm["carState"].vEgo, 0) diff --git a/frogpilot/ui/frogpilot_ui.cc b/frogpilot/ui/frogpilot_ui.cc index f1d12eda3..c67ba2abd 100644 --- a/frogpilot/ui/frogpilot_ui.cc +++ b/frogpilot/ui/frogpilot_ui.cc @@ -15,6 +15,13 @@ static void update_state(FrogPilotUIState *fs) { } if (fpsm.updated("frogpilotPlan")) { const cereal::FrogPilotPlan::Reader &frogpilotPlan = fpsm["frogpilotPlan"].getFrogpilotPlan(); + capnp::Text::Reader toggles = frogpilotPlan.getFrogpilotToggles(); + QByteArray current_toggles(toggles.cStr(), toggles.size()); + static QByteArray previous_toggles; + if (previous_toggles != current_toggles) { + frogpilot_scene.frogpilot_toggles = QJsonDocument::fromJson(current_toggles).object(); + previous_toggles = current_toggles; + } } if (fpsm.updated("selfdriveState")) { const cereal::SelfdriveState::Reader &selfdriveState = fpsm["selfdriveState"].getSelfdriveState(); diff --git a/frogpilot/ui/frogpilot_ui.h b/frogpilot/ui/frogpilot_ui.h index 5738166f5..cdfe78eba 100644 --- a/frogpilot/ui/frogpilot_ui.h +++ b/frogpilot/ui/frogpilot_ui.h @@ -14,6 +14,8 @@ struct FrogPilotUIScene { bool standstill; int started_timer; + + QJsonObject frogpilot_toggles; }; class FrogPilotUIState : public QObject { diff --git a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h index a1b3944a4..11c00c38a 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h +++ b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h @@ -27,6 +27,8 @@ public: QColor purpleColor(int alpha = 255) { return QColor(128, 0, 128, alpha); } QColor whiteColor(int alpha = 255) { return QColor(255, 255, 255, alpha); } + QJsonObject frogpilot_toggles; + QPoint dmIconPosition; QPoint experimentalButtonPosition; diff --git a/frogpilot/ui/qt/onroad/frogpilot_onroad.h b/frogpilot/ui/qt/onroad/frogpilot_onroad.h index 49bb02c47..5964e9653 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_onroad.h +++ b/frogpilot/ui/qt/onroad/frogpilot_onroad.h @@ -14,6 +14,8 @@ public: QColor bg; + QJsonObject frogpilot_toggles; + private: void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); diff --git a/frogpilot/ui/qt/widgets/frogpilot_controls.cc b/frogpilot/ui/qt/widgets/frogpilot_controls.cc index 1edea9ca7..ef8c73486 100644 --- a/frogpilot/ui/qt/widgets/frogpilot_controls.cc +++ b/frogpilot/ui/qt/widgets/frogpilot_controls.cc @@ -112,3 +112,8 @@ void openDescriptions(bool forceOpenDescriptions, std::map &movie, const QSize &size, QWidget *parent); void loadImage(const QString &basePath, QPixmap &pixmap, QSharedPointer &movie, const QSize &size, QWidget *parent); void openDescriptions(bool forceOpenDescriptions, std::map toggles); +void updateFrogPilotToggles(); const QString buttonStyle = R"( QPushButton { diff --git a/opendbc_repo/opendbc/car/body/carcontroller.py b/opendbc_repo/opendbc/car/body/carcontroller.py index 3739af24f..bcdf10ae9 100644 --- a/opendbc_repo/opendbc/car/body/carcontroller.py +++ b/opendbc_repo/opendbc/car/body/carcontroller.py @@ -34,7 +34,7 @@ class CarController(CarControllerBase): torque -= deadband return torque - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): torque_l = 0 torque_r = 0 diff --git a/opendbc_repo/opendbc/car/body/carstate.py b/opendbc_repo/opendbc/car/body/carstate.py index 92c8f682e..d6912a2c0 100644 --- a/opendbc_repo/opendbc/car/body/carstate.py +++ b/opendbc_repo/opendbc/car/body/carstate.py @@ -6,7 +6,7 @@ from opendbc.car.body.values import DBC class CarState(CarStateBase): - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.main] ret = structs.CarState() diff --git a/opendbc_repo/opendbc/car/car_helpers.py b/opendbc_repo/opendbc/car/car_helpers.py index 34b9d31ae..3871ada0b 100644 --- a/opendbc_repo/opendbc/car/car_helpers.py +++ b/opendbc_repo/opendbc/car/car_helpers.py @@ -1,6 +1,8 @@ import os import time +from types import SimpleNamespace + from cereal import custom from opendbc.car import gen_empty_fingerprint from opendbc.car.can_definitions import CanRecvCallable, CanSendCallable @@ -153,7 +155,7 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, alpha_long_allowed: bool, - is_release: bool, num_pandas: int = 1, cached_params: CarParamsT | None = None): + is_release: bool, num_pandas: int = 1, cached_params: CarParamsT | None = None, frogpilot_toggles: SimpleNamespace = None): candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params) if candidate is None: @@ -161,7 +163,7 @@ def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multip candidate = "MOCK" CarInterface = interfaces[candidate] - CP: CarParams = CarInterface.get_params(candidate, fingerprints, car_fw, alpha_long_allowed, is_release, docs=False) + CP: CarParams = CarInterface.get_params(candidate, fingerprints, car_fw, alpha_long_allowed, is_release, docs=False, frogpilot_toggles=frogpilot_toggles) CP.carVin = vin CP.carFw = car_fw CP.fingerprintSource = source diff --git a/opendbc_repo/opendbc/car/chrysler/carcontroller.py b/opendbc_repo/opendbc/car/chrysler/carcontroller.py index bed77c827..3078124aa 100644 --- a/opendbc_repo/opendbc/car/chrysler/carcontroller.py +++ b/opendbc_repo/opendbc/car/chrysler/carcontroller.py @@ -19,7 +19,7 @@ class CarController(CarControllerBase): self.packer = CANPacker(dbc_names[Bus.pt]) self.params = CarControllerParams(CP) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): can_sends = [] lkas_active = CC.latActive and self.lkas_control_bit_prev diff --git a/opendbc_repo/opendbc/car/chrysler/carstate.py b/opendbc_repo/opendbc/car/chrysler/carstate.py index 1d1b87c5f..d553278ec 100644 --- a/opendbc_repo/opendbc/car/chrysler/carstate.py +++ b/opendbc_repo/opendbc/car/chrysler/carstate.py @@ -30,7 +30,7 @@ class CarState(CarStateBase): # FrogPilot variables - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] diff --git a/opendbc_repo/opendbc/car/ford/carcontroller.py b/opendbc_repo/opendbc/car/ford/carcontroller.py index 914668256..2e7d91ec0 100644 --- a/opendbc_repo/opendbc/car/ford/carcontroller.py +++ b/opendbc_repo/opendbc/car/ford/carcontroller.py @@ -75,7 +75,7 @@ class CarController(CarControllerBase): self.lead_distance_bars_last = None self.distance_bar_frame = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): can_sends = [] actuators = CC.actuators diff --git a/opendbc_repo/opendbc/car/ford/carstate.py b/opendbc_repo/opendbc/car/ford/carstate.py index e2a9b3ec4..98081b760 100644 --- a/opendbc_repo/opendbc/car/ford/carstate.py +++ b/opendbc_repo/opendbc/car/ford/carstate.py @@ -21,7 +21,7 @@ class CarState(CarStateBase): self.distance_button = 0 self.lc_button = 0 - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index fb2d48c02..4029e4c01 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -57,7 +57,7 @@ class CarController(CarControllerBase): return pedal_gas - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl hud_alert = hud_control.visualAlert diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index 0c6293df6..601c3f1da 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -49,7 +49,7 @@ class CarState(CarStateBase): return True return False - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: pt_cp = can_parsers[Bus.pt] cam_cp = can_parsers[Bus.cam] loopback_cp = can_parsers[Bus.loopback] diff --git a/opendbc_repo/opendbc/car/honda/carcontroller.py b/opendbc_repo/opendbc/car/honda/carcontroller.py index 4319b5c28..ff0c86eb6 100644 --- a/opendbc_repo/opendbc/car/honda/carcontroller.py +++ b/opendbc_repo/opendbc/car/honda/carcontroller.py @@ -109,7 +109,7 @@ class CarController(CarControllerBase): self.brake = 0.0 self.last_torque = 0.0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl hud_v_cruise = hud_control.setSpeed / CS.v_cruise_factor if hud_control.speedVisible else 255 diff --git a/opendbc_repo/opendbc/car/honda/carstate.py b/opendbc_repo/opendbc/car/honda/carstate.py index 3c342c4d3..cb15e7948 100644 --- a/opendbc_repo/opendbc/car/honda/carstate.py +++ b/opendbc_repo/opendbc/car/honda/carstate.py @@ -50,7 +50,7 @@ class CarState(CarStateBase): # However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX) self.dash_speed_seen = False - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] if self.CP.enableBsm: diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 6d6aa8ad9..06ff59506 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -55,7 +55,7 @@ class CarController(CarControllerBase): self.car_fingerprint = CP.carFingerprint self.last_button_frame = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl diff --git a/opendbc_repo/opendbc/car/interfaces.py b/opendbc_repo/opendbc/car/interfaces.py index d849a94f6..d8b2663b1 100644 --- a/opendbc_repo/opendbc/car/interfaces.py +++ b/opendbc_repo/opendbc/car/interfaces.py @@ -7,6 +7,7 @@ from enum import StrEnum from typing import Any from collections.abc import Callable from functools import cache +from types import SimpleNamespace from cereal import custom from opendbc.car import DT_CTRL, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG @@ -125,10 +126,10 @@ class CarInterfaceBase(ABC): self.params_memory = Params(memory=True) - def apply(self, c: structs.CarControl, now_nanos: int | None = None) -> tuple[structs.CarControl.Actuators, list[CanData]]: + def apply(self, c: structs.CarControl, now_nanos: int | None = None, frogpilot_toggles: SimpleNamespace = None) -> tuple[structs.CarControl.Actuators, list[CanData]]: if now_nanos is None: now_nanos = int(time.monotonic() * 1e9) - return self.CC.update(c, self.CS, now_nanos) + return self.CC.update(c, self.CS, now_nanos, frogpilot_toggles) @staticmethod def get_pid_accel_limits(CP, current_speed, cruise_speed): @@ -139,11 +140,11 @@ class CarInterfaceBase(ABC): """ Parameters essential to controlling the car may be incomplete or wrong without FW versions or fingerprints. """ - return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False, False) + return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False, False, None) @classmethod def get_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw], - alpha_long: bool, is_release: bool, docs: bool) -> structs.CarParams: + alpha_long: bool, is_release: bool, docs: bool, frogpilot_toggles: SimpleNamespace) -> structs.CarParams: ret = CarInterfaceBase.get_std_params(candidate) platform = PLATFORMS[candidate] @@ -172,7 +173,7 @@ class CarInterfaceBase(ABC): # FrogPilot variables @classmethod - def get_frogpilot_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw], CP: structs.CarParams): + def get_frogpilot_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw], CP: structs.CarParams, frogpilot_toggles: SimpleNamespace): fp_ret = custom.FrogPilotCarParams.new_message() platform = PLATFORMS[candidate] @@ -282,14 +283,14 @@ class CarInterfaceBase(ABC): tune.torque.latAccelOffset = 0.0 tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg - def update(self, can_packets: list[tuple[int, list[CanData]]]) -> structs.CarState: + def update(self, can_packets: list[tuple[int, list[CanData]]], frogpilot_toggles: SimpleNamespace) -> structs.CarState: # parse can for cp in self.can_parsers.values(): if cp is not None: cp.update(can_packets) # get CarState - ret, fp_ret = self.CS.update(self.can_parsers) + ret, fp_ret = self.CS.update(self.can_parsers, frogpilot_toggles) ret.canValid = all(cp.can_valid for cp in self.can_parsers.values()) ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers.values()) @@ -348,7 +349,7 @@ class CarStateBase(ABC): self.CC: structs.CarControl = structs.CarControl.new_message() @abstractmethod - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: pass def parse_wheel_speeds(self, cs, fl, fr, rl, rr, unit=CV.KPH_TO_MS): diff --git a/opendbc_repo/opendbc/car/mazda/carcontroller.py b/opendbc_repo/opendbc/car/mazda/carcontroller.py index 453f3ee20..687c9d245 100644 --- a/opendbc_repo/opendbc/car/mazda/carcontroller.py +++ b/opendbc_repo/opendbc/car/mazda/carcontroller.py @@ -15,7 +15,7 @@ class CarController(CarControllerBase): self.packer = CANPacker(dbc_names[Bus.pt]) self.brake_counter = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): can_sends = [] apply_torque = 0 diff --git a/opendbc_repo/opendbc/car/mazda/carstate.py b/opendbc_repo/opendbc/car/mazda/carstate.py index 53287f858..7c8f89949 100644 --- a/opendbc_repo/opendbc/car/mazda/carstate.py +++ b/opendbc_repo/opendbc/car/mazda/carstate.py @@ -21,7 +21,7 @@ class CarState(CarStateBase): self.distance_button = 0 - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] diff --git a/opendbc_repo/opendbc/car/mock/carcontroller.py b/opendbc_repo/opendbc/car/mock/carcontroller.py index 6336dcfcb..eb75508e3 100644 --- a/opendbc_repo/opendbc/car/mock/carcontroller.py +++ b/opendbc_repo/opendbc/car/mock/carcontroller.py @@ -2,5 +2,5 @@ from opendbc.car.interfaces import CarControllerBase class CarController(CarControllerBase): - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): return CC.actuators.as_builder(), [] diff --git a/opendbc_repo/opendbc/car/nissan/carcontroller.py b/opendbc_repo/opendbc/car/nissan/carcontroller.py index 16f990a82..76ec2e744 100644 --- a/opendbc_repo/opendbc/car/nissan/carcontroller.py +++ b/opendbc_repo/opendbc/car/nissan/carcontroller.py @@ -17,7 +17,7 @@ class CarController(CarControllerBase): self.packer = CANPacker(dbc_names[Bus.pt]) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel diff --git a/opendbc_repo/opendbc/car/nissan/carstate.py b/opendbc_repo/opendbc/car/nissan/carstate.py index 0890742fe..f4f1e8470 100644 --- a/opendbc_repo/opendbc/car/nissan/carstate.py +++ b/opendbc_repo/opendbc/car/nissan/carstate.py @@ -27,7 +27,7 @@ class CarState(CarStateBase): # FrogPilot variables - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] cp_adas = can_parsers[Bus.adas] diff --git a/opendbc_repo/opendbc/car/psa/carcontroller.py b/opendbc_repo/opendbc/car/psa/carcontroller.py index 792deccee..93fbc2b36 100644 --- a/opendbc_repo/opendbc/car/psa/carcontroller.py +++ b/opendbc_repo/opendbc/car/psa/carcontroller.py @@ -13,7 +13,7 @@ class CarController(CarControllerBase): self.apply_angle_last = 0 self.status = 2 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): can_sends = [] actuators = CC.actuators diff --git a/opendbc_repo/opendbc/car/psa/carstate.py b/opendbc_repo/opendbc/car/psa/carstate.py index 20f3bc357..014857537 100644 --- a/opendbc_repo/opendbc/car/psa/carstate.py +++ b/opendbc_repo/opendbc/car/psa/carstate.py @@ -10,7 +10,7 @@ TransmissionType = structs.CarParams.TransmissionType class CarState(CarStateBase): - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.main] cp_adas = can_parsers[Bus.adas] cp_cam = can_parsers[Bus.cam] diff --git a/opendbc_repo/opendbc/car/rivian/carcontroller.py b/opendbc_repo/opendbc/car/rivian/carcontroller.py index 6e7c3a12f..888e62fb1 100644 --- a/opendbc_repo/opendbc/car/rivian/carcontroller.py +++ b/opendbc_repo/opendbc/car/rivian/carcontroller.py @@ -15,7 +15,7 @@ class CarController(CarControllerBase): self.cancel_frames = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators can_sends = [] diff --git a/opendbc_repo/opendbc/car/rivian/carstate.py b/opendbc_repo/opendbc/car/rivian/carstate.py index 63e2f40b5..acf205ecf 100644 --- a/opendbc_repo/opendbc/car/rivian/carstate.py +++ b/opendbc_repo/opendbc/car/rivian/carstate.py @@ -18,7 +18,7 @@ class CarState(CarStateBase): self.sccm_wheel_touch = None self.vdm_adas_status = None - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] cp_adas = can_parsers[Bus.adas] diff --git a/opendbc_repo/opendbc/car/subaru/carcontroller.py b/opendbc_repo/opendbc/car/subaru/carcontroller.py index 29cdd9821..fcb7c0d5e 100644 --- a/opendbc_repo/opendbc/car/subaru/carcontroller.py +++ b/opendbc_repo/opendbc/car/subaru/carcontroller.py @@ -27,7 +27,7 @@ class CarController(CarControllerBase): # FrogPilot variables - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel diff --git a/opendbc_repo/opendbc/car/subaru/carstate.py b/opendbc_repo/opendbc/car/subaru/carstate.py index 919436ed2..02151e007 100644 --- a/opendbc_repo/opendbc/car/subaru/carstate.py +++ b/opendbc_repo/opendbc/car/subaru/carstate.py @@ -16,7 +16,7 @@ class CarState(CarStateBase): self.angle_rate_calulator = CanSignalRateCalculator(50) - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] cp_alt = can_parsers[Bus.alt] diff --git a/opendbc_repo/opendbc/car/tesla/carcontroller.py b/opendbc_repo/opendbc/car/tesla/carcontroller.py index 986897f84..bdf45ae2e 100644 --- a/opendbc_repo/opendbc/car/tesla/carcontroller.py +++ b/opendbc_repo/opendbc/car/tesla/carcontroller.py @@ -25,7 +25,7 @@ class CarController(CarControllerBase): # Vehicle model used for lateral limiting self.VM = VehicleModel(get_safety_CP()) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators can_sends = [] diff --git a/opendbc_repo/opendbc/car/tesla/carstate.py b/opendbc_repo/opendbc/car/tesla/carstate.py index 58d515338..aed91805d 100644 --- a/opendbc_repo/opendbc/car/tesla/carstate.py +++ b/opendbc_repo/opendbc/car/tesla/carstate.py @@ -31,7 +31,7 @@ class CarState(CarStateBase): self.autopark_prev = autopark_now self.cruise_enabled_prev = cruise_enabled - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp_party = can_parsers[Bus.party] cp_ap_party = can_parsers[Bus.ap_party] ret = structs.CarState() diff --git a/opendbc_repo/opendbc/car/toyota/carcontroller.py b/opendbc_repo/opendbc/car/toyota/carcontroller.py index 65315fc37..b762253e9 100644 --- a/opendbc_repo/opendbc/car/toyota/carcontroller.py +++ b/opendbc_repo/opendbc/car/toyota/carcontroller.py @@ -82,7 +82,7 @@ class CarController(CarControllerBase): # FrogPilot variables - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators stopping = actuators.longControlState == LongCtrlState.stopping hud_control = CC.hudControl diff --git a/opendbc_repo/opendbc/car/toyota/carstate.py b/opendbc_repo/opendbc/car/toyota/carstate.py index 24546c73c..db060cbb4 100644 --- a/opendbc_repo/opendbc/car/toyota/carstate.py +++ b/opendbc_repo/opendbc/car/toyota/carstate.py @@ -56,7 +56,7 @@ class CarState(CarStateBase): # FrogPilot variables - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] diff --git a/opendbc_repo/opendbc/car/volkswagen/carcontroller.py b/opendbc_repo/opendbc/car/volkswagen/carcontroller.py index 387a10fa3..1d834f38c 100644 --- a/opendbc_repo/opendbc/car/volkswagen/carcontroller.py +++ b/opendbc_repo/opendbc/car/volkswagen/carcontroller.py @@ -32,7 +32,7 @@ class CarController(CarControllerBase): self.hca_frame_timer_running = 0 self.hca_frame_same_torque = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_toggles): actuators = CC.actuators hud_control = CC.hudControl can_sends = [] diff --git a/opendbc_repo/opendbc/car/volkswagen/carstate.py b/opendbc_repo/opendbc/car/volkswagen/carstate.py index 6ceacd6e9..fbbef8b07 100644 --- a/opendbc_repo/opendbc/car/volkswagen/carstate.py +++ b/opendbc_repo/opendbc/car/volkswagen/carstate.py @@ -43,7 +43,7 @@ class CarState(CarStateBase): return button_events - def update(self, can_parsers) -> structs.CarState: + def update(self, can_parsers, frogpilot_toggles) -> structs.CarState: pt_cp = can_parsers[Bus.pt] cam_cp = can_parsers[Bus.cam] ext_cp = pt_cp if self.CP.networkLocation == NetworkLocation.fwdCamera else cam_cp diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 301c89513..f6ddcac88 100644 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -21,6 +21,7 @@ from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp from openpilot.selfdrive.car.cruise import VCruiseHelper from openpilot.selfdrive.car.car_specific import MockCarState +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles, update_frogpilot_toggles from openpilot.frogpilot.controls.frogpilot_card import FrogPilotCard REPLAY = "REPLAY" in os.environ @@ -104,7 +105,7 @@ class Car: with car.CarParams.from_bytes(cached_params_raw) as _cached_params: cached_params = _cached_params - self.CI = get_car(*self.can_callbacks, obd_callback(self.params), alpha_long_allowed, is_release, num_pandas, cached_params) + self.CI = get_car(*self.can_callbacks, obd_callback(self.params), alpha_long_allowed, is_release, num_pandas, cached_params, get_frogpilot_toggles()) self.RI = interfaces[self.CI.CP.carFingerprint].RadarInterface(self.CI.CP) self.CP = self.CI.CP @@ -171,10 +172,14 @@ class Car: self.resume_prev_button = False # FrogPilot variables + self.frogpilot_toggles = get_frogpilot_toggles() + fpcp_bytes = self.FPCP.to_bytes() self.params.put("FrogPilotCarParams", fpcp_bytes) self.params.put_nonblocking("FrogPilotCarParamsPersistent", fpcp_bytes) + update_frogpilot_toggles() + self.frogpilot_card = FrogPilotCard(self.CP, self.FPCP) self.sm = self.sm.extend(['frogpilotOnroadEvents', 'frogpilotPlan', 'frogpilotSelfdriveState', 'liveCalibration', 'selfdriveState']) @@ -187,7 +192,7 @@ class Car: can_list = can_capnp_to_list(can_strs) # Update carState from CAN - CS, FPCS = self.CI.update(can_list) + CS, FPCS = self.CI.update(can_list, self.frogpilot_toggles) if self.CP.brand == 'mock': CS, FPCS = self.mock_carstate.update(CS, FPCS) @@ -205,10 +210,10 @@ class Car: if can_rcv_valid and REPLAY: self.can_log_mono_time = messaging.log_from_bytes(can_strs[0]).logMonoTime - self.v_cruise_helper.update_v_cruise(CS, self.sm['carControl'].enabled, self.is_metric) + self.v_cruise_helper.update_v_cruise(CS, self.sm['carControl'].enabled, self.is_metric, self.frogpilot_toggles) if self.sm['carControl'].enabled and not self.CC_prev.enabled: # Use CarState w/ buttons from the step selfdrived enables on - self.v_cruise_helper.initialize_v_cruise(self.CS_prev, self.experimental_mode, self.resume_prev_button) + self.v_cruise_helper.initialize_v_cruise(self.CS_prev, self.experimental_mode, self.resume_prev_button, self.frogpilot_toggles) # TODO: mirror the carState.cruiseState struct? CS.vCruise = float(self.v_cruise_helper.v_cruise_kph) @@ -221,7 +226,7 @@ class Car: self.resume_prev_button = False # FrogPilot variables - FPCS = self.frogpilot_card.update(CS, FPCS, self.sm) + FPCS = self.frogpilot_card.update(CS, FPCS, self.sm, self.frogpilot_toggles) return CS, RD, FPCS @@ -274,7 +279,7 @@ class Car: if self.sm.all_alive(['carControl']): # send car controls over can now_nanos = self.can_log_mono_time if REPLAY else int(time.monotonic() * 1e9) - self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos) + self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos, self.frogpilot_toggles) self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid)) self.CC_prev = CC @@ -295,6 +300,8 @@ class Car: # FrogPilot variables self.CI.CS.CC = self.sm['carControl'] + self.frogpilot_toggles = get_frogpilot_toggles(self.sm) + def params_thread(self, evt): while not evt.is_set(): self.is_metric = self.params.get_bool("IsMetric") diff --git a/selfdrive/car/cruise.py b/selfdrive/car/cruise.py index 187e13b8d..c31940271 100644 --- a/selfdrive/car/cruise.py +++ b/selfdrive/car/cruise.py @@ -1,6 +1,8 @@ import math import numpy as np +from types import SimpleNamespace + from cereal import car from opendbc.car.gm.values import CC_ONLY_CAR, GMFlags from openpilot.common.constants import CV @@ -45,13 +47,13 @@ class VCruiseHelper: def v_cruise_initialized(self): return self.v_cruise_kph != V_CRUISE_UNSET - def update_v_cruise(self, CS, enabled, is_metric): + def update_v_cruise(self, CS, enabled, is_metric, frogpilot_toggles): self.v_cruise_kph_last = self.v_cruise_kph if CS.cruiseState.available: if self.gm_cc_only or not self.CP.pcmCruise: # if stock cruise is completely disabled, then we can use our own set speed logic - self._update_v_cruise_non_pcm(CS, enabled, is_metric) + self._update_v_cruise_non_pcm(CS, enabled, is_metric, frogpilot_toggles) self.v_cruise_cluster_kph = self.v_cruise_kph self.update_button_timers(CS, enabled) else: @@ -67,7 +69,7 @@ class VCruiseHelper: self.v_cruise_kph = V_CRUISE_UNSET self.v_cruise_cluster_kph = V_CRUISE_UNSET - def _update_v_cruise_non_pcm(self, CS, enabled, is_metric): + def _update_v_cruise_non_pcm(self, CS, enabled, is_metric, frogpilot_toggles): # handle button presses. TODO: this should be in state_control, but a decelCruise press # would have the effect of both enabling and changing speed is checked after the state transition if not enabled: @@ -129,7 +131,7 @@ class VCruiseHelper: self.button_timers[b.type.raw] = 1 if b.pressed else 0 self.button_change_states[b.type.raw] = {"standstill": CS.cruiseState.standstill, "enabled": enabled} - def initialize_v_cruise(self, CS, experimental_mode: bool, resume_prev_button: bool) -> None: + def initialize_v_cruise(self, CS, experimental_mode: bool, resume_prev_button: bool, frogpilot_toggles: SimpleNamespace) -> None: # initializing is handled by the PCM if self.CP.pcmCruise and not self.gm_cc_only: return diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py old mode 100755 new mode 100644 index bb279d73c..f5edf68ad --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -20,6 +20,8 @@ from openpilot.selfdrive.controls.lib.longcontrol import LongControl from openpilot.selfdrive.modeld.modeld import LAT_SMOOTH_SECONDS from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + State = log.SelfdriveState.OpenpilotState LaneChangeState = log.LaneChangeState LaneChangeDirection = log.LaneChangeDirection @@ -62,6 +64,8 @@ class Controls: # FrogPilot variables self.sm = self.sm.extend(['liveDelay', 'frogpilotCarState', 'frogpilotPlan']) + self.frogpilot_toggles = get_frogpilot_toggles() + def update(self): self.sm.update(15) if self.sm.updated["liveCalibration"]: @@ -71,6 +75,7 @@ class Controls: self.calibrated_pose = self.pose_calibrator.build_calibrated_pose(device_pose) # FrogPilot variables + self.frogpilot_toggles = get_frogpilot_toggles(self.sm) def state_control(self): CS = self.sm['carState'] @@ -118,7 +123,7 @@ class Controls: # accel PID loop pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, CS.vEgo, CS.vCruise * CV.KPH_TO_MS) - actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits)) + actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits, self.frogpilot_toggles)) # Steering PID loop and lateral MPC # Reset desired curvature to current to avoid violating the limits on engage @@ -129,7 +134,8 @@ class Controls: actuators.curvature = self.desired_curvature steer, steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp, self.steer_limited_by_safety, self.desired_curvature, - curvature_limited, lat_delay) + curvature_limited, lat_delay, + self.frogpilot_toggles) actuators.torque = float(steer) actuators.steeringAngleDeg = float(steeringAngleDeg) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index afcf4cbf0..c87427fbc 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -48,7 +48,7 @@ class DesireHelper: def get_lane_change_direction(CS): return LaneChangeDirection.left if CS.leftBlinker else LaneChangeDirection.right - def update(self, carstate, lateral_active, lane_change_prob, frogpilotPlan): + def update(self, carstate, lateral_active, lane_change_prob, frogpilotPlan, frogpilot_toggles): v_ego = carstate.vEgo one_blinker = carstate.leftBlinker != carstate.rightBlinker below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN diff --git a/selfdrive/controls/lib/latcontrol.py b/selfdrive/controls/lib/latcontrol.py index d69796738..5e0a9d21d 100644 --- a/selfdrive/controls/lib/latcontrol.py +++ b/selfdrive/controls/lib/latcontrol.py @@ -1,5 +1,6 @@ import numpy as np from abc import abstractmethod, ABC +from types import SimpleNamespace class LatControl(ABC): @@ -13,7 +14,7 @@ class LatControl(ABC): self.steer_max = 1.0 @abstractmethod - def update(self, active: bool, CS, VM, params, steer_limited_by_safety: bool, desired_curvature: float, curvature_limited: bool, lat_delay: float): + def update(self, active: bool, CS, VM, params, steer_limited_by_safety: bool, desired_curvature: float, curvature_limited: bool, lat_delay: float, frogpilot_toggles: SimpleNamespace): pass def reset(self): diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/selfdrive/controls/lib/latcontrol_angle.py index 808c9a659..31abac86d 100644 --- a/selfdrive/controls/lib/latcontrol_angle.py +++ b/selfdrive/controls/lib/latcontrol_angle.py @@ -13,7 +13,7 @@ class LatControlAngle(LatControl): self.sat_check_min_speed = 5. self.use_steer_limited_by_safety = CP.brand == "tesla" - def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay): + def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, frogpilot_toggles): angle_log = log.ControlsState.LateralAngleState.new_message() if not active: diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py index 14ab9f21b..a5a1eb226 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -14,7 +14,7 @@ class LatControlPID(LatControl): self.ff_factor = CP.lateralTuning.pid.kf self.get_steer_feedforward = CI.get_steer_feedforward_function() - def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay): + def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, frogpilot_toggles): pid_log = log.ControlsState.LateralPIDState.new_message() pid_log.steeringAngleDeg = float(CS.steeringAngleDeg) pid_log.steeringRateDeg = float(CS.steeringRateDeg) diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 443fd1851..7b83682ae 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -54,7 +54,7 @@ class LatControlTorque(LatControl): self.pid.set_limits(self.lateral_accel_from_torque(self.steer_max, self.torque_params), self.lateral_accel_from_torque(-self.steer_max, self.torque_params)) - def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay): + def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, frogpilot_toggles): pid_log = log.ControlsState.LateralTorqueState.new_message() pid_log.version = VERSION if not active: diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index 62dbc842c..389cca307 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -11,7 +11,7 @@ LongCtrlState = car.CarControl.Actuators.LongControlState def long_control_state_trans(CP, active, long_control_state, v_ego, - should_stop, brake_pressed, cruise_standstill): + should_stop, brake_pressed, cruise_standstill, frogpilot_toggles): stopping_condition = should_stop starting_condition = (not should_stop and not cruise_standstill and @@ -56,14 +56,14 @@ class LongControl: def reset(self): self.pid.reset() - def update(self, active, CS, a_target, should_stop, accel_limits): + def update(self, active, CS, a_target, should_stop, accel_limits, frogpilot_toggles): """Update longitudinal control. This updates the state machine and runs a PID loop""" self.pid.neg_limit = accel_limits[0] self.pid.pos_limit = accel_limits[1] self.long_control_state = long_control_state_trans(self.CP, active, self.long_control_state, CS.vEgo, should_stop, CS.brakePressed, - CS.cruiseState.standstill) + CS.cruiseState.standstill, frogpilot_toggles) if self.long_control_state == LongCtrlState.off: self.reset() output_accel = 0. diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 76c4def8e..c3d155371 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -70,7 +70,7 @@ class LongitudinalPlanner: self.solverExecutionTime = 0.0 @staticmethod - def parse_model(model_msg): + def parse_model(model_msg, frogpilot_toggles): if (len(model_msg.position.x) == ModelConstants.IDX_N and len(model_msg.velocity.x) == ModelConstants.IDX_N and len(model_msg.acceleration.x) == ModelConstants.IDX_N): @@ -92,7 +92,7 @@ class LongitudinalPlanner: return x, v, a, j, throttle_prob - def update(self, sm): + def update(self, sm, frogpilot_toggles): mode = 'blended' if sm['selfdriveState'].experimentalMode else 'acc' if len(sm['carControl'].orientationNED) == 3: @@ -129,7 +129,7 @@ class LongitudinalPlanner: # Prevent divergence, smooth in current v_ego self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego)) - x, v, a, j, throttle_prob = self.parse_model(sm['modelV2']) + x, v, a, j, throttle_prob = self.parse_model(sm['modelV2'], frogpilot_toggles) # Don't clip at low speeds since throttle_prob doesn't account for creep self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 8c2cddea4..e53d8a795 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -7,6 +7,8 @@ from openpilot.selfdrive.controls.lib.ldw import LaneDepartureWarning from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner import cereal.messaging as messaging +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + def main(): config_realtime_process(5, Priority.CTRL_LOW) @@ -25,10 +27,12 @@ def main(): # FrogPilot variables sm = sm.extend(['frogpilotCarState', 'frogpilotPlan']) + frogpilot_toggles = get_frogpilot_toggles() + while True: sm.update() if sm.updated['modelV2']: - longitudinal_planner.update(sm) + longitudinal_planner.update(sm, frogpilot_toggles) longitudinal_planner.publish(sm, pm) ldw.update(sm.frame, sm['modelV2'], sm['carState'], sm['carControl']) @@ -39,6 +43,7 @@ def main(): pm.send('driverAssistance', msg) # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) if __name__ == "__main__": diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 125caa355..f2dcb0060 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -2,6 +2,7 @@ import math import numpy as np from collections import deque +from types import SimpleNamespace from typing import Any import capnp @@ -12,6 +13,8 @@ from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process from openpilot.common.swaglog import cloudlog from openpilot.common.simple_kalman import KF1D +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + # Default lead acceleration decay set to 50% at 1s _LEAD_ACCEL_TAU = 1.5 @@ -119,7 +122,7 @@ def laplacian_pdf(x: float, mu: float, b: float): return math.exp(-abs(x-mu)/b) -def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, tracks: dict[int, Track]): +def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, tracks: dict[int, Track], frogpilot_toggles: SimpleNamespace): # FrogPilot variables offset_vision_dist = lead.x[0] - RADAR_TO_CAMERA @@ -163,10 +166,12 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capnp._DynamicStructReader, - model_v_ego: float, low_speed_override: bool = True) -> dict[str, Any]: + model_v_ego: float, + frogpilot_toggles: SimpleNamespace, + low_speed_override: bool = True) -> dict[str, Any]: # Determine leads, this is where the essential logic happens if len(tracks) > 0 and ready and lead_msg.prob > .5: - track = match_vision_to_track(v_ego, lead_msg, tracks) + track = match_vision_to_track(v_ego, lead_msg, tracks, frogpilot_toggles) else: track = None @@ -212,6 +217,8 @@ class RadarD: # FrogPilot variables self.frogpilot_radar_state = custom.FrogPilotRadarState.new_message() + self.frogpilot_toggles = get_frogpilot_toggles() + def update(self, sm: messaging.SubMaster, rr: car.RadarData): self.ready = sm.seen['modelV2'] self.current_time = 1e-9*max(sm.logMonoTime.values()) @@ -253,10 +260,11 @@ class RadarD: model_v_ego = self.v_ego leads_v3 = sm['modelV2'].leadsV3 if len(leads_v3) > 1: - self.radar_state.leadOne = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[0], model_v_ego, low_speed_override=True) - self.radar_state.leadTwo = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[1], model_v_ego, low_speed_override=False) + self.radar_state.leadOne = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[0], model_v_ego, self.frogpilot_toggles, low_speed_override=True) + self.radar_state.leadTwo = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[1], model_v_ego, self.frogpilot_toggles, low_speed_override=False) # FrogPilot variables + self.frogpilot_toggles = get_frogpilot_toggles(sm) def publish(self, pm: messaging.PubMaster): assert self.radar_state is not None diff --git a/selfdrive/locationd/lagd.py b/selfdrive/locationd/lagd.py index 93be874cc..9e7b559ab 100755 --- a/selfdrive/locationd/lagd.py +++ b/selfdrive/locationd/lagd.py @@ -13,6 +13,8 @@ from openpilot.common.realtime import config_realtime_process from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose, fft_next_good_size, parabolic_peak_interp +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + BLOCK_SIZE = 100 BLOCK_NUM = 50 BLOCK_NUM_NEEDED = 5 @@ -377,6 +379,8 @@ def main(): # FrogPilot variables sm = sm.extend(['frogpilotPlan']) + lag_learner.frogpilot_toggles = get_frogpilot_toggles() + while True: sm.update() if sm.all_checks(): @@ -397,3 +401,4 @@ def main(): params.put_nonblocking("LiveDelay", lag_msg_dat) # FrogPilot variables + lag_learner.frogpilot_toggles = get_frogpilot_toggles(sm) diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 8dcef422b..921727172 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -12,6 +12,8 @@ from openpilot.selfdrive.locationd.models.constants import GENERATED_DIR from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose from openpilot.common.swaglog import cloudlog +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + MAX_ANGLE_OFFSET_DELTA = 20 * DT_MDL # Max 20 deg/s ROLL_MAX_DELTA = np.radians(20.0) * DT_MDL # 20deg in 1 second is well within curvature limits ROLL_MIN, ROLL_MAX = np.radians(-10), np.radians(10) @@ -286,6 +288,8 @@ def main(): # FrogPilot variables sm = sm.extend(['frogpilotPlan']) + learner.frogpilot_toggles = get_frogpilot_toggles() + while True: sm.update() if sm.all_checks(): @@ -304,6 +308,7 @@ def main(): pm.send('liveParameters', msg_dat) # FrogPilot variables + learner.frogpilot_toggles = get_frogpilot_toggles(sm) if __name__ == "__main__": diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py index ebc41657e..86f391c25 100755 --- a/selfdrive/locationd/torqued.py +++ b/selfdrive/locationd/torqued.py @@ -12,6 +12,8 @@ from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.locationd.helpers import PointBuckets, ParameterEstimator, PoseCalibrator, Pose +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + HISTORY = 5 # secs POINTS_PER_BUCKET = 1500 MIN_POINTS_TOTAL = 4000 @@ -254,6 +256,10 @@ def main(demo=False): # FrogPilot variables sm = sm.extend(['frogpilotPlan']) + frogpilot_toggles = get_frogpilot_toggles() + + estimator.frogpilot_toggles = frogpilot_toggles + while True: sm.update() if sm.all_checks(): @@ -272,6 +278,7 @@ def main(demo=False): params.put_nonblocking("LiveTorqueParameters", msg.to_bytes()) # FrogPilot variables + estimator.frogpilot_toggles = get_frogpilot_toggles(sm) if __name__ == "__main__": diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 2c32e2c13..202939c6b 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -31,6 +31,8 @@ from openpilot.selfdrive.modeld.constants import ModelConstants, Plan from openpilot.selfdrive.modeld.models.commonmodel_pyx import DrivingModelFrame, CLContext from openpilot.selfdrive.modeld.runners.tinygrad_helpers import qcom_tensor_from_opencl_address +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + PROCESS_NAME = "selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') @@ -226,6 +228,7 @@ def main(demo=False): cloudlog.warning("modeld init") # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles() if not USBGPU: # USB GPU currently saturates a core so can't do this yet, @@ -393,7 +396,7 @@ def main(demo=False): l_lane_change_prob = desire_state[log.Desire.laneChangeLeft] r_lane_change_prob = desire_state[log.Desire.laneChangeRight] lane_change_prob = l_lane_change_prob + r_lane_change_prob - DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob, sm['frogpilotPlan']) + DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob, sm['frogpilotPlan'], frogpilot_toggles) modelv2_send.modelV2.meta.laneChangeState = DH.lane_change_state modelv2_send.modelV2.meta.laneChangeDirection = DH.lane_change_direction drivingdata_send.drivingModelData.meta.laneChangeState = DH.lane_change_state @@ -411,6 +414,7 @@ def main(demo=False): last_vipc_frame_id = meta_main.frame_id # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) if __name__ == "__main__": diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py old mode 100755 new mode 100644 index c24a485c1..7fb045d18 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -4,6 +4,7 @@ import math import os from enum import IntEnum from collections.abc import Callable +from types import SimpleNamespace from cereal import log, car, custom import cereal.messaging as messaging @@ -234,31 +235,31 @@ AlertCallbackType = Callable[[car.CarParams, car.CarState, messaging.SubMaster, def soft_disable_alert(alert_text_2: str) -> AlertCallbackType: - def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: + def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: if soft_disable_time < int(0.5 / DT_CTRL): return ImmediateDisableAlert(alert_text_2) return SoftDisableAlert(alert_text_2) return func def user_soft_disable_alert(alert_text_2: str) -> AlertCallbackType: - def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: + def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: if soft_disable_time < int(0.5 / DT_CTRL): return ImmediateDisableAlert(alert_text_2) return UserSoftDisableAlert(alert_text_2) return func -def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: branch = get_short_branch() # Ensure get_short_branch is cached to avoid lags on startup if "REPLAY" in os.environ: branch = "replay" return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt) -def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage") -def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: return Alert( f"Steer Assist Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}", "", @@ -266,7 +267,7 @@ def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.S Priority.LOW, VisualAlert.none, AudibleAlert.prompt, 0.4) -def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: first_word = 'Recalibrating' if sm['liveCalibration'].calStatus == log.LiveCalibrationData.Status.recalibrating else 'Calibrating' return Alert( f"{first_word}: {sm['liveCalibration'].calPerc:.0f}%", @@ -275,7 +276,7 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2) -def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: duration = FEEDBACK_MAX_DURATION - ((sm['audioFeedback'].blockNum + 1) * SAMPLE_BUFFER / SAMPLE_RATE) return NormalPermanentAlert( "Recording Audio Feedback", @@ -285,37 +286,37 @@ def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM # *** debug alerts *** -def out_of_space_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def out_of_space_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: full_perc = round(100. - sm['deviceState'].freeSpacePercent) return NormalPermanentAlert("Out of Storage", f"{full_perc}% full") -def posenet_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def posenet_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: mdl = sm['modelV2'].velocity.x[0] if len(sm['modelV2'].velocity.x) else math.nan err = CS.vEgo - mdl msg = f"Speed Error: {err:.1f} m/s" return NoEntryAlert(msg, alert_text_1="Posenet Speed Invalid") -def process_not_running_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def process_not_running_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning] msg = ', '.join(not_running) return NoEntryAlert(msg, alert_text_1="Process Not Running") -def comm_issue_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def comm_issue_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: bs = [s for s in sm.data.keys() if not sm.all_checks([s, ])] msg = ', '.join(bs[:4]) # can't fit too many on one line return NoEntryAlert(msg, alert_text_1="Communication Issue Between Processes") -def camera_malfunction_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def camera_malfunction_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: all_cams = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState') bad_cams = [s.replace('State', '') for s in all_cams if s in sm.data.keys() and not sm.all_checks([s, ])] return NormalPermanentAlert("Camera Malfunction", ', '.join(bad_cams)) -def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: rpy = sm['liveCalibration'].rpyCalib yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan) pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan) @@ -323,7 +324,7 @@ def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging return NormalPermanentAlert("Calibration Invalid", angles) -def paramsd_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def paramsd_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: if not sm['liveParameters'].angleOffsetValid: angle_offset_deg = sm['liveParameters'].angleOffsetDeg title = "Steering misalignment detected" @@ -341,41 +342,41 @@ def paramsd_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.Sub return NoEntryAlert(alert_text_1=title, alert_text_2=text) -def overheat_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def overheat_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: cpu = max(sm['deviceState'].cpuTempC, default=0.) gpu = max(sm['deviceState'].gpuTempC, default=0.) temp = max((cpu, gpu, sm['deviceState'].memoryTempC)) return NormalPermanentAlert("System Overheated", f"{temp:.0f} °C") -def low_memory_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def low_memory_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: return NormalPermanentAlert("Low Memory", f"{sm['deviceState'].memoryUsagePercent}% used") -def high_cpu_usage_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def high_cpu_usage_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: x = max(sm['deviceState'].cpuUsagePercent, default=0.) return NormalPermanentAlert("High CPU Usage", f"{x}% used") -def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: return NormalPermanentAlert("Driving Model Lagging", f"{sm['modelV2'].frameDropPerc:.1f}% frames dropped") -def wrong_car_mode_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def wrong_car_mode_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: text = "Enable Adaptive Cruise to Engage" if CP.brand == "honda": text = "Enable Main Switch to Engage" return NoEntryAlert(text) -def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: gb = sm['carControl'].actuators.accel / 4. steer = sm['carControl'].actuators.torque vals = f"Gas: {round(gb * 100.)}%, Steer: {round(steer * 100.)}%" return NormalPermanentAlert("Joystick Mode", vals) -def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: ad = sm['alertDebug'] audible_alert = AudibleAlert.prompt if 'Active' in ad.alertText1 else AudibleAlert.none alert_status = AlertStatus.userPrompt if 'Active' in ad.alertText1 else AlertStatus.normal @@ -385,12 +386,12 @@ def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messagi Priority.LOW, VisualAlert.none, audible_alert, 0.2) -def personality_changed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def personality_changed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: personality = str(personality).title() return NormalPermanentAlert(f"Driving Personality: {personality}", duration=1.5) -def invalid_lkas_setting_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def invalid_lkas_setting_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: text = "Toggle stock LKAS on or off to engage" if CP.brand == "tesla": text = "Switch to Traffic-Aware Cruise Control to engage" @@ -402,7 +403,7 @@ def invalid_lkas_setting_alert(CP: car.CarParams, CS: car.CarState, sm: messagin # FrogPilot variables -def custom_startup_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: +def custom_startup_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality, frogpilot_toggles: SimpleNamespace) -> Alert: return StartupAlert(frogpilot_toggles.startup_alert_top, frogpilot_toggles.startup_alert_bottom, alert_status=FrogPilotAlertStatus.frogpilot) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index b710b2b77..3d4689002 100644 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -25,6 +25,7 @@ from openpilot.system.version import get_build_metadata from openpilot.system.hardware import HARDWARE from openpilot.frogpilot.common.frogpilot_utilities import contains_event_type +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles REPLAY = "REPLAY" in os.environ SIMULATION = "SIMULATION" in os.environ @@ -148,6 +149,8 @@ class SelfdriveD: self.sm = self.sm.extend(['frogpilotCarState', 'frogpilotPlan']) self.pm = self.pm.extend(['frogpilotOnroadEvents', 'frogpilotSelfdriveState']) + self.frogpilot_toggles = get_frogpilot_toggles() + self.frogpilot_AM = AlertManager() self.frogpilot_events = Events(frogpilot=True) @@ -482,7 +485,8 @@ class SelfdriveD: pers = LONGITUDINAL_PERSONALITY_MAP[self.personality] alerts = self.events.create_alerts(self.state_machine.current_alert_types, [self.CP, CS, self.sm, self.is_metric, - self.state_machine.soft_disable_timer, pers]) + self.state_machine.soft_disable_timer, pers, + self.frogpilot_toggles]) self.AM.add_many(self.sm.frame, alerts) self.AM.process_alerts(self.sm.frame, clear_event_types) @@ -556,6 +560,7 @@ class SelfdriveD: self.CS_prev = CS # FrogPilot variables + self.frogpilot_toggles = get_frogpilot_toggles(self.sm) def params_thread(self, evt): while not evt.is_set(): diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 505feb01b..50b3c4a4a 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -63,12 +63,14 @@ void HomeWindow::updateState(const UIState &s, const FrogPilotUIState &fs) { // FrogPilot variables const FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + const QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; } void HomeWindow::offroadTransition(bool offroad) { // FrogPilot variables FrogPilotUIState &fs = *frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; body->setEnabled(false); sidebar->setVisible(offroad); @@ -251,4 +253,5 @@ void OffroadHome::refresh() { // FrogPilot variables FrogPilotUIState &fs = *frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; } diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 63556cfde..f438e7970 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -212,6 +212,15 @@ void TogglesPanel::updateToggles() { // FrogPilot variables FrogPilotUIState &fs = *frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; + + auto disengage_on_accelerator_toggle = toggles["DisengageOnAccelerator"]; + disengage_on_accelerator_toggle->setVisible(!frogpilot_toggles.value("always_on_lateral").toBool()); + auto driver_camera_toggle = toggles["RecordFront"]; + driver_camera_toggle->setVisible(!frogpilot_toggles.value("no_logging").toBool()); + experimental_mode_toggle->setVisible(!frogpilot_toggles.value("conditional_experimental_mode").toBool()); + auto record_audio_toggle = toggles["RecordAudio"]; + record_audio_toggle->setVisible(!frogpilot_toggles.value("no_logging").toBool()); } DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { @@ -426,6 +435,8 @@ void SettingsWindow::hideEvent(QHideEvent *event) { subPanelOpen = false; subSubPanelOpen = false; subSubSubPanelOpen = false; + + updateFrogPilotToggles(); } void SettingsWindow::setCurrentPanel(int index, const QString ¶m) { diff --git a/selfdrive/ui/qt/onroad/alerts.h b/selfdrive/ui/qt/onroad/alerts.h index 5ffa83017..740e55486 100644 --- a/selfdrive/ui/qt/onroad/alerts.h +++ b/selfdrive/ui/qt/onroad/alerts.h @@ -15,6 +15,8 @@ public: // FrogPilot variables int alertHeight; + QJsonObject frogpilot_toggles; + protected: struct Alert { QString text1; diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index d179d7404..98c6321b1 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -146,6 +146,11 @@ void AnnotatedCameraWidget::paintGL() { experimental_btn->frogpilot_scene = frogpilot_scene; model.frogpilot_scene = frogpilot_scene; + dmon.frogpilot_toggles = frogpilot_toggles; + experimental_btn->frogpilot_toggles = frogpilot_toggles; + hud.frogpilot_toggles = frogpilot_toggles; + model.frogpilot_toggles = frogpilot_toggles; + model.draw(painter, rect()); dmon.draw(painter, rect()); hud.updateState(*s); diff --git a/selfdrive/ui/qt/onroad/annotated_camera.h b/selfdrive/ui/qt/onroad/annotated_camera.h index 8953f4cc0..3179b7a8d 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.h +++ b/selfdrive/ui/qt/onroad/annotated_camera.h @@ -22,6 +22,8 @@ public: FrogPilotUIScene frogpilot_scene; + QJsonObject frogpilot_toggles; + private: QVBoxLayout *main_layout; ExperimentalButton *experimental_btn; diff --git a/selfdrive/ui/qt/onroad/buttons.h b/selfdrive/ui/qt/onroad/buttons.h index e08538d3f..e1253f866 100644 --- a/selfdrive/ui/qt/onroad/buttons.h +++ b/selfdrive/ui/qt/onroad/buttons.h @@ -17,6 +17,8 @@ public: // FrogPilot variables FrogPilotUIScene frogpilot_scene; + QJsonObject frogpilot_toggles; + private: void paintEvent(QPaintEvent *event) override; void changeMode(); diff --git a/selfdrive/ui/qt/onroad/driver_monitoring.h b/selfdrive/ui/qt/onroad/driver_monitoring.h index 6a27fabcc..67e60f864 100644 --- a/selfdrive/ui/qt/onroad/driver_monitoring.h +++ b/selfdrive/ui/qt/onroad/driver_monitoring.h @@ -15,6 +15,8 @@ public: // FrogPilot variables FrogPilotAnnotatedCameraWidget *frogpilot_nvg; + QJsonObject frogpilot_toggles; + private: float driver_pose_vals[3] = {}; float driver_pose_diff[3] = {}; diff --git a/selfdrive/ui/qt/onroad/hud.h b/selfdrive/ui/qt/onroad/hud.h index 4457f24f9..b443425b3 100644 --- a/selfdrive/ui/qt/onroad/hud.h +++ b/selfdrive/ui/qt/onroad/hud.h @@ -16,6 +16,8 @@ public: // FrogPilot variables FrogPilotAnnotatedCameraWidget *frogpilot_nvg; + QJsonObject frogpilot_toggles; + private: void drawSetSpeed(QPainter &p, const QRect &surface_rect); void drawCurrentSpeed(QPainter &p, const QRect &surface_rect); diff --git a/selfdrive/ui/qt/onroad/model.h b/selfdrive/ui/qt/onroad/model.h index ddad6a134..71d2624b9 100644 --- a/selfdrive/ui/qt/onroad/model.h +++ b/selfdrive/ui/qt/onroad/model.h @@ -18,6 +18,8 @@ public: FrogPilotUIScene frogpilot_scene; + QJsonObject frogpilot_toggles; + private: bool mapToScreen(float in_x, float in_y, float in_z, QPointF *out); void mapLineToPolygon(const cereal::XYZTData::Reader &line, float y_off, float z_off, diff --git a/selfdrive/ui/qt/onroad/onroad_home.cc b/selfdrive/ui/qt/onroad/onroad_home.cc index e9bcfb022..9d75cf49c 100644 --- a/selfdrive/ui/qt/onroad/onroad_home.cc +++ b/selfdrive/ui/qt/onroad/onroad_home.cc @@ -68,6 +68,7 @@ void OnroadWindow::updateState(const UIState &s, const FrogPilotUIState &fs) { // FrogPilot variables const FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + const QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; frogpilot_nvg->alertHeight = alerts->alertHeight; @@ -79,6 +80,11 @@ void OnroadWindow::updateState(const UIState &s, const FrogPilotUIState &fs) { frogpilot_nvg->frogpilot_scene = frogpilot_scene; frogpilot_onroad->frogpilot_scene = frogpilot_scene; + alerts->frogpilot_toggles = frogpilot_toggles; + frogpilot_nvg->frogpilot_toggles = frogpilot_toggles; + frogpilot_onroad->frogpilot_toggles = frogpilot_toggles; + nvg->frogpilot_toggles = frogpilot_toggles; + frogpilot_onroad->setGeometry(rect()); frogpilot_nvg->updateState(s, fs); diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index ba0b34492..e7d346dc2 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -48,6 +48,7 @@ void Sidebar::mousePressEvent(QMouseEvent *event) { // FrogPilot variables FrogPilotUIState *fs = frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs->frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; if (onroad && home_btn.contains(event->pos())) { flag_pressed = true; @@ -87,6 +88,7 @@ void Sidebar::updateState(const UIState &s, const FrogPilotUIState &fs) { // FrogPilot variables const FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + const QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; const SubMaster &fpsm = *(fs.sm); @@ -157,6 +159,7 @@ void Sidebar::paintEvent(QPaintEvent *event) { // FrogPilot variables FrogPilotUIState *fs = frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs->frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; // network int x = 58; diff --git a/selfdrive/ui/qt/window.cc b/selfdrive/ui/qt/window.cc index fd416b5bc..b01d55eec 100644 --- a/selfdrive/ui/qt/window.cc +++ b/selfdrive/ui/qt/window.cc @@ -82,6 +82,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) { // FrogPilot variables FrogPilotUIState &fs = *frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; bool ignore = false; switch (event->type()) { diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index dfe0fef8a..b5779927a 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -15,6 +15,8 @@ from openpilot.common.swaglog import cloudlog from openpilot.system import micd from openpilot.system.hardware import HARDWARE +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + SAMPLE_RATE = 48000 SAMPLE_BUFFER = 4096 # (approx 100ms) MAX_VOLUME = 1.0 @@ -81,6 +83,8 @@ class Soundd: # FrogPilot variables self.params_memory = Params(memory=True) + self.frogpilot_toggles = get_frogpilot_toggles() + self.update_frogpilot_sounds() def load_sounds(self): @@ -185,6 +189,11 @@ class Soundd: assert stream.active # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) + if frogpilot_toggles != self.frogpilot_toggles: + self.frogpilot_toggles = frogpilot_toggles + + self.update_frogpilot_sounds() def update_frogpilot_sounds(self): diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index d3c1353fb..a7a713e92 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -87,6 +87,7 @@ void ui_update_params(UIState *s) { void UIState::updateStatus(FrogPilotUIState *fs) { // FrogPilot variables FrogPilotUIScene &frogpilot_scene = fs->frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; if (scene.started && sm->updated("selfdriveState")) { auto ss = (*sm)["selfdriveState"].getSelfdriveState(); @@ -149,6 +150,7 @@ void UIState::update() { // FrogPilot variables FrogPilotUIState *fs = frogpilotUIState(); FrogPilotUIScene &frogpilot_scene = fs->frogpilot_scene; + QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; if (frogpilot_scene.frogpilot_panel_active) { device()->resetInteractiveTimeout(); @@ -190,6 +192,7 @@ void Device::resetInteractiveTimeout(int timeout) { void Device::updateBrightness(const UIState &s, const FrogPilotUIState &fs) { // FrogPilot variables const FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + const QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; float clipped_brightness = offroad_brightness; if (s.scene.started && s.scene.light_sensor >= 0) { @@ -222,6 +225,7 @@ void Device::updateBrightness(const UIState &s, const FrogPilotUIState &fs) { void Device::updateWakefulness(const UIState &s, const FrogPilotUIState &fs) { // FrogPilot variables const FrogPilotUIScene &frogpilot_scene = fs.frogpilot_scene; + const QJsonObject &frogpilot_toggles = frogpilot_scene.frogpilot_toggles; bool ignition_just_turned_off = !s.scene.ignition && ignition_on; ignition_on = s.scene.ignition; diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 51a81f4cf..e997f9d79 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -26,6 +26,8 @@ from openpilot.system.hardware.fan_controller import TiciFanController from openpilot.system.version import terms_version, training_version from openpilot.system.athena.registration import UNREGISTERED_DONGLE_ID +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + ThermalStatus = log.DeviceState.ThermalStatus NetworkType = log.DeviceState.NetworkType NetworkStrength = log.DeviceState.NetworkStrength @@ -216,6 +218,8 @@ def hardware_thread(end_event, hw_queue) -> None: sm = sm.extend(['frogpilotPlan']) pm = pm.extend(['frogpilotDeviceState']) + frogpilot_toggles = get_frogpilot_toggles() + while not end_event.is_set(): sm.update(PANDA_STATES_TIMEOUT) @@ -404,7 +408,7 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.somPowerDrawW = som_power_draw # Check if we need to shut down - if power_monitor.should_shutdown(onroad_conditions["ignition"], in_car, off_ts, started_seen): + if power_monitor.should_shutdown(onroad_conditions["ignition"], in_car, off_ts, started_seen, frogpilot_toggles): cloudlog.warning(f"shutting device down, offroad since {off_ts}") params.put_bool("DoShutdown", True) @@ -477,6 +481,7 @@ def hardware_thread(end_event, hw_queue) -> None: should_start_prev = should_start # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) def main(): diff --git a/system/hardware/power_monitoring.py b/system/hardware/power_monitoring.py index f8b0e8b62..bcee29a36 100644 --- a/system/hardware/power_monitoring.py +++ b/system/hardware/power_monitoring.py @@ -1,6 +1,8 @@ import time import threading +from types import SimpleNamespace + from openpilot.common.params import Params from openpilot.system.hardware import HARDWARE from openpilot.common.swaglog import cloudlog @@ -105,7 +107,7 @@ class PowerMonitoring: return int(self.car_battery_capacity_uWh) # See if we need to shutdown - def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool): + def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool, frogpilot_toggles: SimpleNamespace): if offroad_timestamp is None: return False diff --git a/system/loggerd/uploader.py b/system/loggerd/uploader.py index c2c67bdc4..3c4bd7d2b 100755 --- a/system/loggerd/uploader.py +++ b/system/loggerd/uploader.py @@ -19,6 +19,8 @@ from openpilot.system.hardware.hw import Paths from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + NetworkType = log.DeviceState.NetworkType UPLOAD_ATTR_NAME = 'user.upload' UPLOAD_ATTR_VALUE = b'1' @@ -252,6 +254,8 @@ def main(exit_event: threading.Event = None) -> None: # FrogPilot variables sm = sm.extend(['frogpilotPlan']) + frogpilot_toggles = get_frogpilot_toggles() + while not exit_event.is_set(): sm.update(0) offroad = params.get_bool("IsOffroad") @@ -273,6 +277,7 @@ def main(exit_event: threading.Event = None) -> None: time.sleep(backoff + random.uniform(0, backoff)) # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) if __name__ == "__main__": diff --git a/system/manager/manager.py b/system/manager/manager.py index 92b899d7c..f5fbec1c7 100644 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -22,6 +22,7 @@ from openpilot.system.version import get_build_metadata, terms_version, training from openpilot.system.hardware.hw import Paths from openpilot.frogpilot.common.frogpilot_functions import frogpilot_boot_functions, install_frogpilot, uninstall_frogpilot +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles def manager_init() -> None: @@ -133,7 +134,7 @@ def manager_thread() -> None: pm = messaging.PubMaster(['managerState']) write_onroad_params(False, params) - ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) + ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore, frogpilot_toggles=get_frogpilot_toggles()) started_prev = False ignition_prev = False @@ -143,6 +144,8 @@ def manager_thread() -> None: params_memory = Params(memory=True) + frogpilot_toggles = get_frogpilot_toggles() + while True: sm.update(1000) @@ -170,7 +173,7 @@ def manager_thread() -> None: started_prev = started ignition_prev = ignition - ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore) + ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore, frogpilot_toggles=frogpilot_toggles) running = ' '.join("{}{}\u001b[0m".format("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) for p in managed_processes.values() if p.proc) @@ -202,6 +205,7 @@ def manager_thread() -> None: break # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles(sm) def main() -> None: diff --git a/system/manager/process.py b/system/manager/process.py index 5e86e87c7..d3d732a0b 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -7,6 +7,7 @@ import subprocess from collections.abc import Callable, ValuesView from abc import ABC, abstractmethod from multiprocessing import Process +from types import SimpleNamespace from setproctitle import setproctitle @@ -66,7 +67,7 @@ def join_process(process: Process, timeout: float) -> None: class ManagerProcess(ABC): daemon = False sigkill = False - should_run: Callable[[bool, Params, car.CarParams], bool] + should_run: Callable[[bool, Params, car.CarParams, SimpleNamespace], bool] proc: Process | None = None enabled = True name = "" @@ -241,7 +242,7 @@ class DaemonProcess(ManagerProcess): self.params = None @staticmethod - def should_run(started, params, CP): + def should_run(started, params, CP, frogpilot_toggles): return True def prepare(self) -> None: @@ -277,13 +278,13 @@ class DaemonProcess(ManagerProcess): def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None, - not_run: list[str] | None=None) -> list[ManagerProcess]: + not_run: list[str] | None=None, frogpilot_toggles: SimpleNamespace=None) -> list[ManagerProcess]: if not_run is None: not_run = [] running = [] for p in procs: - if p.enabled and p.name not in not_run and p.should_run(started, params, CP): + if p.enabled and p.name not in not_run and p.should_run(started, params, CP, frogpilot_toggles): running.append(p) else: p.stop(block=False) diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 54efc45bb..2c42ba1da 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -2,6 +2,8 @@ import os import operator import platform +from types import SimpleNamespace + from cereal import car from openpilot.common.params import Params from openpilot.system.hardware import HARDWARE, PC, TICI @@ -9,50 +11,50 @@ from openpilot.system.manager.process import PythonProcess, NativeProcess, Daemo WEBCAM = os.getenv("USE_WEBCAM") is not None -def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: +def driverview(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started or params.get_bool("IsDriverViewEnabled") -def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: +def notcar(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and CP.notCar -def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: +def iscar(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and not CP.notCar -def logging(started: bool, params: Params, CP: car.CarParams) -> bool: +def logging(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: run = (not CP.notCar) or not params.get_bool("DisableLogging") return started and run def ublox_available() -> bool: return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') -def ublox(started: bool, params: Params, CP: car.CarParams) -> bool: +def ublox(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: use_ublox = ublox_available() if use_ublox != params.get_bool("UbloxAvailable"): params.put_bool("UbloxAvailable", use_ublox) return started and use_ublox -def joystick(started: bool, params: Params, CP: car.CarParams) -> bool: +def joystick(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and params.get_bool("JoystickDebugMode") -def not_joystick(started: bool, params: Params, CP: car.CarParams) -> bool: +def not_joystick(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and not params.get_bool("JoystickDebugMode") -def long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: +def long_maneuver(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and params.get_bool("LongitudinalManeuverMode") -def not_long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: +def not_long_maneuver(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and not params.get_bool("LongitudinalManeuverMode") -def qcomgps(started: bool, params: Params, CP: car.CarParams) -> bool: +def qcomgps(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started and not ublox_available() -def always_run(started: bool, params: Params, CP: car.CarParams) -> bool: +def always_run(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return True -def only_onroad(started: bool, params: Params, CP: car.CarParams) -> bool: +def only_onroad(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return started -def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: +def only_offroad(started: bool, params: Params, CP: car.CarParams, frogpilot_toggles: SimpleNamespace) -> bool: return not started def or_(*fns): diff --git a/system/updated/updated.py b/system/updated/updated.py index 110fe8491..08d08ccfb 100644 --- a/system/updated/updated.py +++ b/system/updated/updated.py @@ -22,6 +22,8 @@ from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.system.hardware import AGNOS, HARDWARE from openpilot.system.version import get_build_metadata +from openpilot.frogpilot.common.frogpilot_variables import get_frogpilot_toggles + LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") @@ -460,6 +462,7 @@ def main() -> None: wait_helper.ready_event.clear() # FrogPilot variables + frogpilot_toggles = get_frogpilot_toggles() # Attempt an update exception = None