diff --git a/selfdrive/ui/qt/offroad/sunnypilot_settings.cc b/selfdrive/ui/qt/offroad/sunnypilot_settings.cc
index 8ea7105f59..d10b6e772f 100644
--- a/selfdrive/ui/qt/offroad/sunnypilot_settings.cc
+++ b/selfdrive/ui/qt/offroad/sunnypilot_settings.cc
@@ -28,7 +28,7 @@ SPGeneralPanel::SPGeneralPanel(QWidget *parent) : QWidget(parent) {
// General: Green Traffic Light Chime
endToEndLongAlert = new ParamControl(
- "EndToEndLongAlert",
+ "EndToEndLongAlertLight",
tr("Green Traffic Light Chime (Beta)"),
QString("%1
"
"
%2
")
@@ -40,6 +40,18 @@ SPGeneralPanel::SPGeneralPanel(QWidget *parent) : QWidget(parent) {
main_layout->addWidget(horizontal_line());
main_layout->addWidget(endToEndLongAlert);
+ // General: Lead Vehicle Departure Alert
+ main_layout->addWidget(horizontal_line());
+ main_layout->addWidget(new ParamControl(
+ "EndToEndLongAlertLead",
+ tr("Lead Vehicle Departure Alert"),
+ QString("%1
"
+ "%2
")
+ .arg(tr("Enable this will notify when the leading vehicle drives away."))
+ .arg(tr("Note: This chime is only designed as a notification. It is the driver's responsibility to observe their environment and make decisions accordingly.")),
+ "../assets/offroad/icon_road.png"
+ ));
+
// General: Custom Boot Screen
main_layout->addWidget(horizontal_line());
main_layout->addWidget(new ParamControl(
diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc
index 31f7b2061b..6a562d37c5 100644
--- a/selfdrive/ui/qt/onroad.cc
+++ b/selfdrive/ui/qt/onroad.cc
@@ -568,6 +568,8 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
static bool chime_sent = false;
static int chime_count = 0;
int chime_prompt = 0;
+ static float last_lead_distance = -1;
+ const float lead_distance = radar_state.getLeadOne().getDRel();
if (!s.scene.e2e_long_alert_ui) {
e2eLStatus = 0;
@@ -579,18 +581,33 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
e2eLStatus = 0;
}
- if (!s.scene.e2e_long_alert || radar_state.getLeadOne().getStatus()) {
+ if (!car_state.getStandstill()) {
chime_prompt = 0;
chime_sent = false;
chime_count = 0;
- } else if (e2eLStatus == 2) {
+
+ if (last_lead_distance != -1) {
+ last_lead_distance = -1;
+ }
+ }
+
+ if (e2eLStatus == 2) {
if ((car_state.getCruiseState().getEnabled() || car_state.getBrakeLights()) && !car_state.getGasPressed() && car_state.getStandstill()) {
if (chime_sent) {
chime_count = 0;
} else {
chime_count += 1;
}
- if (chime_count >= 2 && !chime_sent) {
+ if (radar_state.getLeadOne().getStatus()) {
+ if ((last_lead_distance == -1) || (lead_distance < last_lead_distance)) {
+ last_lead_distance = lead_distance;
+ } else if (s.scene.e2e_long_alert_lead && (lead_distance - last_lead_distance > 1.0) && !chime_sent) {
+ chime_prompt = 2;
+ chime_sent = true;
+ } else {
+ chime_prompt = 0;
+ }
+ } else if (s.scene.e2e_long_alert_light && chime_count >= 2 && !chime_sent) {
chime_prompt = 1;
chime_sent = true;
} else {
@@ -598,15 +615,6 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
}
}
} else {
- chime_prompt = 0;
- chime_sent = false;
- chime_count = 0;
- }
-
- if (!car_state.getStandstill()) {
- chime_prompt = 0;
- chime_sent = false;
- chime_count = 0;
}
setProperty("e2eStatus", chime_prompt);
diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc
index c0b4d3f1be..9b95332201 100644
--- a/selfdrive/ui/ui.cc
+++ b/selfdrive/ui/ui.cc
@@ -255,7 +255,8 @@ void ui_update_params(UIState *s) {
s->scene.dev_ui_info = std::atoi(params.get("DevUIInfo").c_str());
s->scene.button_auto_hide = params.getBool("ButtonAutoHide");
s->scene.reverse_dm_cam = params.getBool("ReverseDmCam");
- s->scene.e2e_long_alert = params.getBool("EndToEndLongAlert");
+ s->scene.e2e_long_alert_light = params.getBool("EndToEndLongAlertLight");
+ s->scene.e2e_long_alert_lead = params.getBool("EndToEndLongAlertLead");
s->scene.e2e_long_alert_ui = params.getBool("EndToEndLongAlertUI");
if (s->scene.onroadScreenOff > 0) {
diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h
index fe6f054e2f..2ae16985d8 100644
--- a/selfdrive/ui/ui.h
+++ b/selfdrive/ui/ui.h
@@ -186,7 +186,7 @@ typedef struct UIScene {
bool reverse_dm_cam;
- bool e2e_long_alert, e2e_long_alert_ui;
+ bool e2e_long_alert_light, e2e_long_alert_lead, e2e_long_alert_ui;
float e2eX[13] = {0};
} UIScene;