From 57ebaa16568820f056d6db5c7d5cfe837565a89f Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:39:30 -0700 Subject: [PATCH] Green light alert Added toggle to alert the user when a red light turns to green. --- cereal/custom.capnp | 2 ++ common/params.cc | 1 + selfdrive/controls/controlsd.py | 13 +++++++++++++ selfdrive/controls/lib/events.py | 8 ++++++++ .../assets/toggle_icons/icon_green_light.png | Bin 0 -> 28527 bytes .../frogpilot/functions/frogpilot_planner.py | 1 + selfdrive/frogpilot/ui/visual_settings.cc | 1 + 7 files changed, 26 insertions(+) create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_green_light.png diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 578fc8b..b3e6f71 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -19,6 +19,7 @@ struct FrogPilotDeviceState @0xaedffd8f31e7b55d { enum FrogPilotEvents @0xf35cc4560bbf6ec2 { frogSteerSaturated @0; + greenLight @1; } struct FrogPilotLateralPlan @0xda96579883444c35 { @@ -30,6 +31,7 @@ struct FrogPilotLongitudinalPlan @0x80ae746ee2596b11 { conditionalExperimental @1 :Bool; desiredFollowDistance @2 :Int16; distances @3 :List(Float32); + redLight @4 :Bool; safeObstacleDistance @5 :Int16; safeObstacleDistanceStock @6 :Int16; stoppedEquivalenceFactor @11 :Int16; diff --git a/common/params.cc b/common/params.cc index b1f020f..87959b0 100644 --- a/common/params.cc +++ b/common/params.cc @@ -253,6 +253,7 @@ std::unordered_map keys = { {"FrogPilotTogglesUpdated", PERSISTENT}, {"GasRegenCmd", PERSISTENT}, {"GoatScream", PERSISTENT}, + {"GreenLightAlert", PERSISTENT}, {"LaneLinesWidth", PERSISTENT}, {"LateralTune", PERSISTENT}, {"LeadInfo", PERSISTENT}, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index fea72a4..3300c09 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -82,6 +82,8 @@ class Controls: fire_the_babysitter = self.params.get_bool("FireTheBabysitter") mute_dm = fire_the_babysitter and self.params.get_bool("MuteDM") + self.stopped_for_light_previously = False + ignore = self.sensor_packets + ['testJoystick'] if SIMULATION: ignore += ['driverCameraState', 'managerState'] @@ -448,6 +450,15 @@ class Controls: if self.sm['modelV2'].frameDropPerc > 20: self.events.add(EventName.modeldLagging) + # Green light alert + if self.green_light_alert and self.enabled: + stopped_for_light = self.sm['frogpilotLongitudinalPlan'].redLight and CS.standstill + green_light = not stopped_for_light and self.stopped_for_light_previously + self.stopped_for_light_previously = stopped_for_light + + if green_light and not CS.gasPressed: + self.events.add(FrogPilotEventName.greenLight) + def data_sample(self): """Receive data from sockets and update carState""" @@ -964,6 +975,8 @@ class Controls: frog_sounds = custom_sounds == 1 self.goat_scream = self.params.get_bool("GoatScream") and frog_sounds + self.green_light_alert = self.params.get_bool("GreenLightAlert") + longitudinal_tune = self.params.get_bool("LongitudinalTune") self.sport_plus = self.params.get_int("AccelerationProfile") == 3 and longitudinal_tune diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 5cf1458..f3dd4cf 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -975,6 +975,14 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { Priority.LOW, VisualAlert.steerRequired, AudibleAlert.warningSoft, 2.), }, + FrogPilotEventName.greenLight: { + ET.PERMANENT: Alert( + "Light turned green", + "", + AlertStatus.frogpilot, AlertSize.small, + Priority.LOW, VisualAlert.none, AudibleAlert.prompt, 3.), + }, + } diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_green_light.png b/selfdrive/frogpilot/assets/toggle_icons/icon_green_light.png new file mode 100644 index 0000000000000000000000000000000000000000..f43b2ed1702473009f5a3f7fde26a963f95472ea GIT binary patch literal 28527 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 ZhjqXCClQxU?gN286-7;jGI`5a{}1A#SkwRj literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/functions/frogpilot_planner.py b/selfdrive/frogpilot/functions/frogpilot_planner.py index 4aa9cb0..14666dd 100644 --- a/selfdrive/frogpilot/functions/frogpilot_planner.py +++ b/selfdrive/frogpilot/functions/frogpilot_planner.py @@ -105,6 +105,7 @@ class FrogPilotPlanner: frogpilotLongitudinalPlan.conditionalExperimental = self.cem.experimental_mode frogpilotLongitudinalPlan.distances = self.x_desired_trajectory.tolist() + frogpilotLongitudinalPlan.redLight = bool(self.cem.red_light_detected) frogpilotLongitudinalPlan.safeObstacleDistance = mpc.safe_obstacle_distance frogpilotLongitudinalPlan.stoppedEquivalenceFactor = mpc.stopped_equivalence_factor diff --git a/selfdrive/frogpilot/ui/visual_settings.cc b/selfdrive/frogpilot/ui/visual_settings.cc index 8cbe770..a3f8e64 100644 --- a/selfdrive/frogpilot/ui/visual_settings.cc +++ b/selfdrive/frogpilot/ui/visual_settings.cc @@ -18,6 +18,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot {"LeadInfo", "Lead Info and Logics", "Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance.", ""}, {"DriverCamera", "Driver Camera On Reverse", "Show the driver's camera feed when you shift to reverse.", "../assets/img_driver_face_static.png"}, + {"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", "../frogpilot/assets/toggle_icons/icon_green_light.png"}, {"ModelUI", "Model UI", "Personalize how the model's visualizations appear on your screen.", "../assets/offroad/icon_calibration.png"}, {"AccelerationPath", "Acceleration Path", "Visualize the car's intended acceleration or deceleration with a color-coded path.", ""},