Totally random events
Added toggle to enable a small chance of a random event occuring when certain conditions are met.
This commit is contained in:
@@ -118,16 +118,22 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
|||||||
paramsdPermanentError @119;
|
paramsdPermanentError @119;
|
||||||
|
|
||||||
# FrogPilot events
|
# FrogPilot events
|
||||||
frogSteerSaturated @122;
|
accel30 @120;
|
||||||
greenLight @123;
|
accel35 @121;
|
||||||
holidayActive @124;
|
firefoxSteerSaturated @122;
|
||||||
laneChangeBlockedLoud @125;
|
frogSteerSaturated @123;
|
||||||
leadDeparting @126;
|
greenLight @124;
|
||||||
noLaneAvailable @127;
|
holidayActive @125;
|
||||||
openpilotCrashed @128;
|
laneChangeBlockedLoud @126;
|
||||||
pedalInterceptorNoBrake @130;
|
leadDeparting @127;
|
||||||
speedLimitChanged @131;
|
noLaneAvailable @128;
|
||||||
torqueNNLoad @132;
|
openpilotCrashed @129;
|
||||||
|
openpilotCrashedRandomEvents @130;
|
||||||
|
pedalInterceptorNoBrake @131;
|
||||||
|
speedLimitChanged @132;
|
||||||
|
torqueNNLoad @133;
|
||||||
|
vCruise69 @136;
|
||||||
|
yourFrogTriedToKillMe @137;
|
||||||
|
|
||||||
radarCanErrorDEPRECATED @15;
|
radarCanErrorDEPRECATED @15;
|
||||||
communityFeatureDisallowedDEPRECATED @62;
|
communityFeatureDisallowedDEPRECATED @62;
|
||||||
@@ -420,6 +426,17 @@ struct CarControl {
|
|||||||
prompt @6;
|
prompt @6;
|
||||||
promptRepeat @7;
|
promptRepeat @7;
|
||||||
promptDistracted @8;
|
promptDistracted @8;
|
||||||
|
|
||||||
|
# Random Events
|
||||||
|
angry @9;
|
||||||
|
fart @10;
|
||||||
|
firefox @11;
|
||||||
|
nessie @12;
|
||||||
|
noice @13;
|
||||||
|
uwu @14;
|
||||||
|
|
||||||
|
# Other
|
||||||
|
goat @15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"ConditionalExperimental", PERSISTENT},
|
{"ConditionalExperimental", PERSISTENT},
|
||||||
{"CrosstrekTorque", PERSISTENT},
|
{"CrosstrekTorque", PERSISTENT},
|
||||||
{"CurrentHolidayTheme", PERSISTENT},
|
{"CurrentHolidayTheme", PERSISTENT},
|
||||||
|
{"CurrentRandomEvent", PERSISTENT},
|
||||||
{"CustomAlerts", PERSISTENT},
|
{"CustomAlerts", PERSISTENT},
|
||||||
{"CustomColors", PERSISTENT},
|
{"CustomColors", PERSISTENT},
|
||||||
{"CustomIcons", PERSISTENT},
|
{"CustomIcons", PERSISTENT},
|
||||||
@@ -358,6 +359,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"PromptDistractedVolume", PERSISTENT},
|
{"PromptDistractedVolume", PERSISTENT},
|
||||||
{"QOLControls", PERSISTENT},
|
{"QOLControls", PERSISTENT},
|
||||||
{"QOLVisuals", PERSISTENT},
|
{"QOLVisuals", PERSISTENT},
|
||||||
|
{"RandomEvents", PERSISTENT},
|
||||||
{"RefuseVolume", PERSISTENT},
|
{"RefuseVolume", PERSISTENT},
|
||||||
{"RelaxedFollow", PERSISTENT},
|
{"RelaxedFollow", PERSISTENT},
|
||||||
{"RelaxedJerk", PERSISTENT},
|
{"RelaxedJerk", PERSISTENT},
|
||||||
|
|||||||
@@ -181,13 +181,18 @@ class Controls:
|
|||||||
self.frogpilot_variables = SimpleNamespace()
|
self.frogpilot_variables = SimpleNamespace()
|
||||||
|
|
||||||
self.driving_gear = False
|
self.driving_gear = False
|
||||||
|
self.fcw_random_event_triggered = False
|
||||||
self.holiday_theme_alerted = False
|
self.holiday_theme_alerted = False
|
||||||
self.previously_enabled = False
|
self.previously_enabled = False
|
||||||
self.openpilot_crashed = False
|
self.openpilot_crashed = False
|
||||||
|
self.previously_enabled = False
|
||||||
|
self.random_event_triggered = False
|
||||||
self.stopped_for_light_previously = False
|
self.stopped_for_light_previously = False
|
||||||
|
|
||||||
|
self.max_acceleration = 0
|
||||||
self.previous_lead_distance = 0
|
self.previous_lead_distance = 0
|
||||||
self.previous_speed_limit = SpeedLimitController.desired_speed_limit
|
self.previous_speed_limit = SpeedLimitController.desired_speed_limit
|
||||||
|
self.random_event_timer = 0
|
||||||
|
|
||||||
ignore = self.sensor_packets + ['testJoystick']
|
ignore = self.sensor_packets + ['testJoystick']
|
||||||
if SIMULATION:
|
if SIMULATION:
|
||||||
@@ -331,7 +336,9 @@ class Controls:
|
|||||||
# Show crash log event if openpilot crashed
|
# Show crash log event if openpilot crashed
|
||||||
if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')):
|
if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')):
|
||||||
self.events.add(EventName.openpilotCrashed)
|
self.events.add(EventName.openpilotCrashed)
|
||||||
return
|
if self.random_events and not self.openpilot_crashed:
|
||||||
|
self.events.add(EventName.openpilotCrashedRandomEvents)
|
||||||
|
self.openpilot_crashed = True
|
||||||
|
|
||||||
# Show holiday related event to indicate which holiday is active
|
# Show holiday related event to indicate which holiday is active
|
||||||
if self.sm.frame >= 1000 and self.holiday_themes and self.params_memory.get_int("CurrentHolidayTheme") != 0 and not self.holiday_theme_alerted:
|
if self.sm.frame >= 1000 and self.holiday_themes and self.params_memory.get_int("CurrentHolidayTheme") != 0 and not self.holiday_theme_alerted:
|
||||||
@@ -538,6 +545,11 @@ class Controls:
|
|||||||
planner_fcw = self.sm['longitudinalPlan'].fcw and self.enabled
|
planner_fcw = self.sm['longitudinalPlan'].fcw and self.enabled
|
||||||
if planner_fcw or model_fcw:
|
if planner_fcw or model_fcw:
|
||||||
self.events.add(EventName.fcw)
|
self.events.add(EventName.fcw)
|
||||||
|
self.fcw_random_event_triggered = True
|
||||||
|
elif self.fcw_random_event_triggered and self.random_events:
|
||||||
|
self.events.add(EventName.yourFrogTriedToKillMe)
|
||||||
|
self.fcw_random_event_triggered = False
|
||||||
|
self.random_event_triggered = True
|
||||||
|
|
||||||
for m in messaging.drain_sock(self.log_sock, wait_for_one=False):
|
for m in messaging.drain_sock(self.log_sock, wait_for_one=False):
|
||||||
try:
|
try:
|
||||||
@@ -562,6 +574,26 @@ class Controls:
|
|||||||
if self.sm['modelV2'].frameDropPerc > 20:
|
if self.sm['modelV2'].frameDropPerc > 20:
|
||||||
self.events.add(EventName.modeldLagging)
|
self.events.add(EventName.modeldLagging)
|
||||||
|
|
||||||
|
# Acceleration Random Event alerts
|
||||||
|
if self.random_events:
|
||||||
|
acceleration = CS.aEgo
|
||||||
|
|
||||||
|
if not CS.gasPressed:
|
||||||
|
self.max_acceleration = max(acceleration, self.max_acceleration)
|
||||||
|
else:
|
||||||
|
self.max_acceleration = 0
|
||||||
|
|
||||||
|
if 3.5 > self.max_acceleration >= 3.0 and acceleration < 1.5:
|
||||||
|
self.events.add(EventName.accel30)
|
||||||
|
self.params_memory.put_int("CurrentRandomEvent", 2)
|
||||||
|
self.random_event_triggered = True
|
||||||
|
self.max_acceleration = 0
|
||||||
|
elif self.max_acceleration >= 3.5 and acceleration < 1.5:
|
||||||
|
self.events.add(EventName.accel35)
|
||||||
|
self.params_memory.put_int("CurrentRandomEvent", 3)
|
||||||
|
self.random_event_triggered = True
|
||||||
|
self.max_acceleration = 0
|
||||||
|
|
||||||
# Green light alert
|
# Green light alert
|
||||||
if self.green_light_alert:
|
if self.green_light_alert:
|
||||||
stopped_for_light = frogpilot_plan.redLight and CS.standstill
|
stopped_for_light = frogpilot_plan.redLight and CS.standstill
|
||||||
@@ -633,6 +665,19 @@ class Controls:
|
|||||||
else:
|
else:
|
||||||
self.FPCC.speedLimitChanged = False
|
self.FPCC.speedLimitChanged = False
|
||||||
|
|
||||||
|
# vCruise set to 69 Random Event alert
|
||||||
|
if self.random_events:
|
||||||
|
conversion = 1 if self.is_metric else CV.KPH_TO_MPH
|
||||||
|
v_cruise = self.v_cruise_helper.v_cruise_cluster_kph if self.v_cruise_helper.v_cruise_cluster_kph != 0.0 else self.v_cruise_helper.v_cruise_kph
|
||||||
|
v_cruise *= conversion
|
||||||
|
|
||||||
|
if 70 > v_cruise >= 69:
|
||||||
|
if not self.vCruise69_alert_played:
|
||||||
|
self.events.add(EventName.vCruise69)
|
||||||
|
self.vCruise69_alert_played = True
|
||||||
|
else:
|
||||||
|
self.vCruise69_alert_played = False
|
||||||
|
|
||||||
def data_sample(self):
|
def data_sample(self):
|
||||||
"""Receive data from sockets and update carState"""
|
"""Receive data from sockets and update carState"""
|
||||||
|
|
||||||
@@ -793,6 +838,14 @@ class Controls:
|
|||||||
# FrogPilot functions
|
# FrogPilot functions
|
||||||
frogpilot_plan = self.sm['frogpilotPlan']
|
frogpilot_plan = self.sm['frogpilotPlan']
|
||||||
|
|
||||||
|
# Reset the Random Event flag after 5 seconds
|
||||||
|
if self.random_event_triggered:
|
||||||
|
self.random_event_timer += 1
|
||||||
|
if self.random_event_timer * DT_CTRL >= 4:
|
||||||
|
self.random_event_triggered = False
|
||||||
|
self.random_event_timer = 0
|
||||||
|
self.params_memory.remove("CurrentRandomEvent")
|
||||||
|
|
||||||
# Update Experimental Mode
|
# Update Experimental Mode
|
||||||
if self.frogpilot_variables.conditional_experimental_mode:
|
if self.frogpilot_variables.conditional_experimental_mode:
|
||||||
self.experimental_mode = frogpilot_plan.conditionalExperimental
|
self.experimental_mode = frogpilot_plan.conditionalExperimental
|
||||||
@@ -883,8 +936,13 @@ class Controls:
|
|||||||
turning = abs(lac_log.desiredLateralAccel) > 1.0
|
turning = abs(lac_log.desiredLateralAccel) > 1.0
|
||||||
good_speed = CS.vEgo > 5
|
good_speed = CS.vEgo > 5
|
||||||
max_torque = abs(self.last_actuators.steer) > 0.99
|
max_torque = abs(self.last_actuators.steer) > 0.99
|
||||||
if undershooting and turning and good_speed and max_torque:
|
if undershooting and turning and good_speed and max_torque and not self.random_event_triggered:
|
||||||
lac_log.active and self.events.add(EventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated)
|
if self.sm.frame % 10000 == 0 and self.random_events:
|
||||||
|
lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
|
||||||
|
self.params_memory.put_int("CurrentRandomEvent", 1)
|
||||||
|
self.random_event_triggered = True
|
||||||
|
else:
|
||||||
|
lac_log.active and self.events.add(EventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated)
|
||||||
elif lac_log.saturated:
|
elif lac_log.saturated:
|
||||||
# TODO probably should not use dpath_points but curvature
|
# TODO probably should not use dpath_points but curvature
|
||||||
dpath_points = model_v2.position.y
|
dpath_points = model_v2.position.y
|
||||||
@@ -1156,6 +1214,8 @@ class Controls:
|
|||||||
self.frogpilot_variables.reverse_cruise_increase = quality_of_life and self.params.get_bool("ReverseCruise")
|
self.frogpilot_variables.reverse_cruise_increase = quality_of_life and self.params.get_bool("ReverseCruise")
|
||||||
self.frogpilot_variables.set_speed_offset = self.params.get_int("SetSpeedOffset") * (1 if self.is_metric else CV.MPH_TO_KPH) if quality_of_life else 0
|
self.frogpilot_variables.set_speed_offset = self.params.get_int("SetSpeedOffset") * (1 if self.is_metric else CV.MPH_TO_KPH) if quality_of_life else 0
|
||||||
|
|
||||||
|
self.random_events = self.params.get_bool("RandomEvents")
|
||||||
|
|
||||||
self.speed_limit_controller = self.params.get_bool("SpeedLimitController")
|
self.speed_limit_controller = self.params.get_bool("SpeedLimitController")
|
||||||
self.frogpilot_variables.force_mph_dashboard = self.speed_limit_controller and self.params.get_bool("ForceMPHDashboard")
|
self.frogpilot_variables.force_mph_dashboard = self.speed_limit_controller and self.params.get_bool("ForceMPHDashboard")
|
||||||
self.frogpilot_variables.set_speed_limit = self.speed_limit_controller and self.params.get_bool("SetSpeedLimit")
|
self.frogpilot_variables.set_speed_limit = self.speed_limit_controller and self.params.get_bool("SetSpeedLimit")
|
||||||
|
|||||||
@@ -1014,7 +1014,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
|
|||||||
"Turn Exceeds Steering Limit",
|
"Turn Exceeds Steering Limit",
|
||||||
"JESUS TAKE THE WHEEL!!",
|
"JESUS TAKE THE WHEEL!!",
|
||||||
AlertStatus.userPrompt, AlertSize.mid,
|
AlertStatus.userPrompt, AlertSize.mid,
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.warningSoft, 2.),
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.goat, 2.),
|
||||||
},
|
},
|
||||||
|
|
||||||
EventName.greenLight: {
|
EventName.greenLight: {
|
||||||
@@ -1076,6 +1076,55 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
|
|||||||
EventName.torqueNNLoad: {
|
EventName.torqueNNLoad: {
|
||||||
ET.PERMANENT: torque_nn_load_alert,
|
ET.PERMANENT: torque_nn_load_alert,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# Random Events
|
||||||
|
EventName.accel30: {
|
||||||
|
ET.WARNING: Alert(
|
||||||
|
"UwU u went a bit fast there!",
|
||||||
|
"(⁄ ⁄•⁄ω⁄•⁄ ⁄)",
|
||||||
|
AlertStatus.frogpilot, AlertSize.mid,
|
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.uwu, 4.),
|
||||||
|
},
|
||||||
|
|
||||||
|
EventName.accel35: {
|
||||||
|
ET.WARNING: Alert(
|
||||||
|
"I ain't giving you no tree-fiddy",
|
||||||
|
"you damn Loch Ness monsta!",
|
||||||
|
AlertStatus.frogpilot, AlertSize.mid,
|
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.nessie, 4.),
|
||||||
|
},
|
||||||
|
|
||||||
|
EventName.firefoxSteerSaturated: {
|
||||||
|
ET.WARNING: Alert(
|
||||||
|
"Turn Exceeds Steering Limit",
|
||||||
|
"IE Has Stopped Responding...",
|
||||||
|
AlertStatus.userPrompt, AlertSize.mid,
|
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.firefox, 4.),
|
||||||
|
},
|
||||||
|
|
||||||
|
EventName.openpilotCrashedRandomEvents: {
|
||||||
|
ET.PERMANENT: Alert(
|
||||||
|
"openpilot crashed 💩",
|
||||||
|
"Please post the error log in the FrogPilot Discord!",
|
||||||
|
AlertStatus.normal, AlertSize.mid,
|
||||||
|
Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 4.),
|
||||||
|
},
|
||||||
|
|
||||||
|
EventName.vCruise69: {
|
||||||
|
ET.PERMANENT: Alert(
|
||||||
|
"Lol 69",
|
||||||
|
"",
|
||||||
|
AlertStatus.frogpilot, AlertSize.small,
|
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.noice, 2.),
|
||||||
|
},
|
||||||
|
|
||||||
|
EventName.yourFrogTriedToKillMe: {
|
||||||
|
ET.PERMANENT: Alert(
|
||||||
|
"Your frog tried to kill me...",
|
||||||
|
"😡",
|
||||||
|
AlertStatus.frogpilot, AlertSize.mid,
|
||||||
|
Priority.MID, VisualAlert.none, AudibleAlert.angry, 5.),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
selfdrive/frogpilot/assets/random_events/images/firefox.png
Normal file
BIN
selfdrive/frogpilot/assets/random_events/images/firefox.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
BIN
selfdrive/frogpilot/assets/random_events/images/tree_fiddy.gif
Normal file
BIN
selfdrive/frogpilot/assets/random_events/images/tree_fiddy.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 KiB |
BIN
selfdrive/frogpilot/assets/random_events/images/weeb_wheel.gif
Normal file
BIN
selfdrive/frogpilot/assets/random_events/images/weeb_wheel.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
BIN
selfdrive/frogpilot/assets/random_events/sounds/angry.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/angry.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/random_events/sounds/fart.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/fart.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/random_events/sounds/firefox.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/firefox.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/random_events/sounds/nessie.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/nessie.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/random_events/sounds/noice.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/noice.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/random_events/sounds/uwu.wav
Normal file
BIN
selfdrive/frogpilot/assets/random_events/sounds/uwu.wav
Normal file
Binary file not shown.
BIN
selfdrive/frogpilot/assets/toggle_icons/icon_random.png
Normal file
BIN
selfdrive/frogpilot/assets/toggle_icons/icon_random.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -55,6 +55,8 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
|
|||||||
{"HideSpeed", "Hide Speed", "Hide the speed indicator in the onroad UI. Additional toggle allows it to be hidden/shown via tapping the speed itself.", ""},
|
{"HideSpeed", "Hide Speed", "Hide the speed indicator in the onroad UI. Additional toggle allows it to be hidden/shown via tapping the speed itself.", ""},
|
||||||
{"MapStyle", "Map Style", "Use a custom map style to be used for 'Navigate on openpilot'.", ""},
|
{"MapStyle", "Map Style", "Use a custom map style to be used for 'Navigate on openpilot'.", ""},
|
||||||
|
|
||||||
|
{"RandomEvents", "Random Events", "Enjoy a bit of unpredictability with random events that can occur during certain driving conditions.", "../frogpilot/assets/toggle_icons/icon_random.png"},
|
||||||
|
|
||||||
{"ScreenManagement", "Screen Management", "Manage your screen's brightness, timeout settings, and hide specific onroad UI elements.", "../frogpilot/assets/toggle_icons/icon_light.png"},
|
{"ScreenManagement", "Screen Management", "Manage your screen's brightness, timeout settings, and hide specific onroad UI elements.", "../frogpilot/assets/toggle_icons/icon_light.png"},
|
||||||
{"HideUIElements", "Hide UI Elements", "Hide the selected UI elements from the onroad screen.", ""},
|
{"HideUIElements", "Hide UI Elements", "Hide the selected UI elements from the onroad screen.", ""},
|
||||||
{"ScreenBrightness", "Screen Brightness", "Customize your screen brightness when offroad.", ""},
|
{"ScreenBrightness", "Screen Brightness", "Customize your screen brightness when offroad.", ""},
|
||||||
|
|||||||
@@ -18,18 +18,7 @@
|
|||||||
#include "selfdrive/ui/qt/maps/map_panel.h"
|
#include "selfdrive/ui/qt/maps/map_panel.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity) {
|
static void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity, const int angle = 0) {
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
|
||||||
p.setOpacity(1.0); // bg dictates opacity of ellipse
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(bg);
|
|
||||||
p.drawEllipse(center, btn_size / 2, btn_size / 2);
|
|
||||||
p.setOpacity(opacity);
|
|
||||||
p.drawPixmap(center - QPoint(img.width() / 2, img.height() / 2), img);
|
|
||||||
p.setOpacity(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawIconRotate(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity, const int angle) {
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
p.setOpacity(1.0); // bg dictates opacity of ellipse
|
p.setOpacity(1.0); // bg dictates opacity of ellipse
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
@@ -44,6 +33,18 @@ static void drawIconRotate(QPainter &p, const QPoint ¢er, const QPixmap &img
|
|||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drawIconGif(QPainter &p, const QPoint ¢er, const QMovie &img, const QBrush &bg, float opacity) {
|
||||||
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
|
p.setOpacity(1.0); // bg dictates opacity of ellipse
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(bg);
|
||||||
|
p.drawEllipse(center.x() - btn_size / 2, center.y() - btn_size / 2, btn_size, btn_size);
|
||||||
|
p.setOpacity(opacity);
|
||||||
|
QPixmap currentFrame = img.currentPixmap();
|
||||||
|
p.drawPixmap(center - QPoint(currentFrame.width() / 2, currentFrame.height() / 2), currentFrame);
|
||||||
|
p.setOpacity(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->scene) {
|
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->scene) {
|
||||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||||
main_layout->setMargin(UI_BORDER_SIZE);
|
main_layout->setMargin(UI_BORDER_SIZE);
|
||||||
@@ -387,8 +388,12 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
|
|||||||
{3, loadPixmap("../frogpilot/assets/wheel_images/frog.png", {img_size, img_size})},
|
{3, loadPixmap("../frogpilot/assets/wheel_images/frog.png", {img_size, img_size})},
|
||||||
{4, loadPixmap("../frogpilot/assets/wheel_images/rocket.png", {img_size, img_size})},
|
{4, loadPixmap("../frogpilot/assets/wheel_images/rocket.png", {img_size, img_size})},
|
||||||
{5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})},
|
{5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})},
|
||||||
{6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})}
|
{6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})},
|
||||||
|
{7, loadPixmap("../frogpilot/assets/random_events/images/firefox.png", {img_size, img_size})},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wheelImagesGif[1] = new QMovie("../frogpilot/assets/random_events/images/weeb_wheel.gif", QByteArray(), this);
|
||||||
|
wheelImagesGif[2] = new QMovie("../frogpilot/assets/random_events/images/tree_fiddy.gif", QByteArray(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExperimentalButton::changeMode() {
|
void ExperimentalButton::changeMode() {
|
||||||
@@ -416,15 +421,59 @@ void ExperimentalButton::updateState(const UIState &s, bool leadInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FrogPilot variables
|
// FrogPilot variables
|
||||||
|
firefoxRandomEventTriggered = scene.current_random_event == 1;
|
||||||
|
treeFiddyRandomEventTriggered = scene.current_random_event == 3;
|
||||||
|
weebRandomEventTriggered = scene.current_random_event == 2;
|
||||||
rotatingWheel = scene.rotating_wheel;
|
rotatingWheel = scene.rotating_wheel;
|
||||||
wheelIcon = scene.wheel_icon;
|
wheelIcon = scene.wheel_icon;
|
||||||
|
wheelIconGif = 0;
|
||||||
|
|
||||||
y_offset = leadInfo ? 10 : 0;
|
y_offset = leadInfo ? 10 : 0;
|
||||||
|
|
||||||
// Update the icon so the steering wheel rotates in real time
|
if (firefoxRandomEventTriggered) {
|
||||||
if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
|
static int rotationDegree = 0;
|
||||||
steeringAngleDeg = scene.steering_angle_deg;
|
rotationDegree = (rotationDegree + 36) % 360;
|
||||||
|
steeringAngleDeg = rotationDegree;
|
||||||
|
wheelIcon = 7;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
} else if (treeFiddyRandomEventTriggered || weebRandomEventTriggered) {
|
||||||
|
if (!gifLabel) {
|
||||||
|
gifLabel = new QLabel(this);
|
||||||
|
QMovie *movie;
|
||||||
|
|
||||||
|
if (treeFiddyRandomEventTriggered) {
|
||||||
|
movie = wheelImagesGif[2];
|
||||||
|
} else if (weebRandomEventTriggered) {
|
||||||
|
movie = wheelImagesGif[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movie) {
|
||||||
|
gifLabel->setMovie(movie);
|
||||||
|
gifLabel->setFixedSize(img_size, img_size);
|
||||||
|
gifLabel->move((width() - gifLabel->width()) / 2, (height() - gifLabel->height()) / 2 + y_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gifLabel->movie()) {
|
||||||
|
gifLabel->movie()->start();
|
||||||
|
}
|
||||||
|
gifLabel->show();
|
||||||
|
wheelIconGif = weebRandomEventTriggered ? 1 : 2;
|
||||||
|
update();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (gifLabel) {
|
||||||
|
gifLabel->hide();
|
||||||
|
}
|
||||||
|
if (rotatingWheel) {
|
||||||
|
// Update the icon so the steering wheel rotates in real time
|
||||||
|
if (steeringAngleDeg != scene.steering_angle_deg) {
|
||||||
|
steeringAngleDeg = scene.steering_angle_deg;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
steeringAngleDeg = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,18 +487,21 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
|||||||
engage_img = wheelImages[wheelIcon];
|
engage_img = wheelImages[wheelIcon];
|
||||||
QPixmap img = wheelIcon ? engage_img : (experimental_mode ? experimental_img : engage_img);
|
QPixmap img = wheelIcon ? engage_img : (experimental_mode ? experimental_img : engage_img);
|
||||||
|
|
||||||
QColor background_color = wheelIcon && !isDown() && engageable ?
|
QMovie *gif = wheelImagesGif[wheelIconGif];
|
||||||
(scene.always_on_lateral_active ? QColor(10, 186, 181, 255) :
|
|
||||||
(scene.conditional_status == 1 ? QColor(255, 246, 0, 255) :
|
QColor background_color = wheelIcon != 0 && !isDown() && engageable ?
|
||||||
(experimental_mode ? QColor(218, 111, 37, 241) :
|
(scene.always_on_lateral_active ? QColor(10, 186, 181, 255) :
|
||||||
(scene.navigate_on_openpilot ? QColor(49, 161, 238, 255) : QColor(0, 0, 0, 166))))) :
|
(scene.conditional_status == 1 ? QColor(255, 246, 0, 255) :
|
||||||
QColor(0, 0, 0, 166);
|
(experimental_mode ? QColor(218, 111, 37, 241) :
|
||||||
|
(scene.navigate_on_openpilot ? QColor(49, 161, 238, 255) : QColor(0, 0, 0, 166)))))) :
|
||||||
|
QColor(0, 0, 0, 166);
|
||||||
|
|
||||||
if (!(scene.show_driver_camera || scene.map_open && scene.full_map)) {
|
if (!(scene.show_driver_camera || scene.map_open && scene.full_map)) {
|
||||||
if (rotatingWheel) {
|
if (wheelIconGif != 0) {
|
||||||
drawIconRotate(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || !(engageable || scene.always_on_lateral_active)) ? 0.6 : 1.0, steeringAngleDeg);
|
QBrush backgroundBrush(background_color);
|
||||||
|
drawIconGif(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), *gif, backgroundBrush, 1.0);
|
||||||
} else {
|
} else {
|
||||||
drawIcon(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || !(engageable || scene.always_on_lateral_active)) ? 0.6 : 1.0);
|
drawIcon(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || !(engageable || scene.always_on_lateral_active)) ? 0.6 : 1.0, steeringAngleDeg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <QMovie>
|
||||||
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QStackedLayout>
|
#include <QStackedLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
@@ -78,11 +80,20 @@ private:
|
|||||||
// FrogPilot variables
|
// FrogPilot variables
|
||||||
UIScene &scene;
|
UIScene &scene;
|
||||||
|
|
||||||
std::map<int, QPixmap> wheelImages;
|
QMap<int, QPixmap> wheelImages;
|
||||||
|
QMap<int, QMovie*> wheelImagesGif;
|
||||||
|
|
||||||
|
QMovie engage_gif;
|
||||||
|
QLabel *gifLabel;
|
||||||
|
|
||||||
|
bool firefoxRandomEventTriggered;
|
||||||
bool rotatingWheel;
|
bool rotatingWheel;
|
||||||
|
bool treeFiddyRandomEventTriggered;
|
||||||
|
bool weebRandomEventTriggered;
|
||||||
|
|
||||||
int steeringAngleDeg;
|
int steeringAngleDeg;
|
||||||
int wheelIcon;
|
int wheelIcon;
|
||||||
|
int wheelIconGif;
|
||||||
int y_offset;
|
int y_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import wave
|
import wave
|
||||||
|
|
||||||
@@ -40,6 +41,17 @@ sound_list: Dict[int, Tuple[str, Optional[int], float]] = {
|
|||||||
|
|
||||||
AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME),
|
AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME),
|
||||||
AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME),
|
AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME),
|
||||||
|
|
||||||
|
# Random Events
|
||||||
|
AudibleAlert.angry: ("angry.wav", 1, MAX_VOLUME),
|
||||||
|
AudibleAlert.fart: ("fart.wav", 1, MAX_VOLUME),
|
||||||
|
AudibleAlert.firefox: ("firefox.wav", 1, MAX_VOLUME),
|
||||||
|
AudibleAlert.noice: ("noice.wav", 1, MAX_VOLUME),
|
||||||
|
AudibleAlert.nessie: ("nessie.wav", 1, MAX_VOLUME),
|
||||||
|
AudibleAlert.uwu: ("uwu.wav", 1, MAX_VOLUME),
|
||||||
|
|
||||||
|
# Other
|
||||||
|
AudibleAlert.goat: ("goat.wav", 1, MAX_VOLUME),
|
||||||
}
|
}
|
||||||
|
|
||||||
def check_controls_timeout_alert(sm):
|
def check_controls_timeout_alert(sm):
|
||||||
@@ -58,6 +70,8 @@ class Soundd:
|
|||||||
self.params = Params()
|
self.params = Params()
|
||||||
self.params_memory = Params("/dev/shm/params")
|
self.params_memory = Params("/dev/shm/params")
|
||||||
|
|
||||||
|
self.random_events_directory = BASEDIR + "/selfdrive/frogpilot/assets/random_events/sounds/"
|
||||||
|
|
||||||
self.update_frogpilot_params()
|
self.update_frogpilot_params()
|
||||||
|
|
||||||
self.load_sounds()
|
self.load_sounds()
|
||||||
@@ -77,7 +91,10 @@ class Soundd:
|
|||||||
for sound in sound_list:
|
for sound in sound_list:
|
||||||
filename, play_count, volume = sound_list[sound]
|
filename, play_count, volume = sound_list[sound]
|
||||||
|
|
||||||
wavefile = wave.open(self.sound_directory + filename, 'r')
|
if os.path.exists(os.path.join(self.random_events_directory, filename)):
|
||||||
|
wavefile = wave.open(self.random_events_directory + filename, 'r')
|
||||||
|
else:
|
||||||
|
wavefile = wave.open(self.sound_directory + filename, 'r')
|
||||||
|
|
||||||
assert wavefile.getnchannels() == 1
|
assert wavefile.getnchannels() == 1
|
||||||
assert wavefile.getsampwidth() == 2
|
assert wavefile.getsampwidth() == 2
|
||||||
@@ -160,6 +177,10 @@ class Soundd:
|
|||||||
elif self.alert_volume_control and self.current_alert in self.volume_map:
|
elif self.alert_volume_control and self.current_alert in self.volume_map:
|
||||||
self.current_volume = self.volume_map[self.current_alert] / 100.0
|
self.current_volume = self.volume_map[self.current_alert] / 100.0
|
||||||
|
|
||||||
|
# Increase the volume for Random Events
|
||||||
|
elif self.current_alert in self.random_events_map:
|
||||||
|
self.current_volume = self.random_events_map[self.current_alert]
|
||||||
|
|
||||||
self.get_audible_alert(sm)
|
self.get_audible_alert(sm)
|
||||||
|
|
||||||
rk.keep_time()
|
rk.keep_time()
|
||||||
@@ -171,6 +192,15 @@ class Soundd:
|
|||||||
self.update_frogpilot_params()
|
self.update_frogpilot_params()
|
||||||
|
|
||||||
def update_frogpilot_params(self):
|
def update_frogpilot_params(self):
|
||||||
|
self.random_events_map = {
|
||||||
|
AudibleAlert.angry: MAX_VOLUME,
|
||||||
|
AudibleAlert.fart: MAX_VOLUME,
|
||||||
|
AudibleAlert.firefox: MAX_VOLUME,
|
||||||
|
AudibleAlert.nessie: MAX_VOLUME,
|
||||||
|
AudibleAlert.noice: MAX_VOLUME,
|
||||||
|
AudibleAlert.uwu: MAX_VOLUME,
|
||||||
|
}
|
||||||
|
|
||||||
self.alert_volume_control = self.params.get_bool("AlertVolumeControl")
|
self.alert_volume_control = self.params.get_bool("AlertVolumeControl")
|
||||||
|
|
||||||
self.volume_map = {
|
self.volume_map = {
|
||||||
@@ -183,7 +213,9 @@ class Soundd:
|
|||||||
AudibleAlert.promptDistracted: self.params.get_int("PromptDistractedVolume"),
|
AudibleAlert.promptDistracted: self.params.get_int("PromptDistractedVolume"),
|
||||||
|
|
||||||
AudibleAlert.warningSoft: self.params.get_int("WarningSoftVolume"),
|
AudibleAlert.warningSoft: self.params.get_int("WarningSoftVolume"),
|
||||||
AudibleAlert.warningImmediate: self.params.get_int("WarningImmediateVolume")
|
AudibleAlert.warningImmediate: self.params.get_int("WarningImmediateVolume"),
|
||||||
|
|
||||||
|
AudibleAlert.goat: self.params.get_int("WarningSoftVolume"),
|
||||||
}
|
}
|
||||||
|
|
||||||
custom_theme = self.params.get_bool("CustomTheme")
|
custom_theme = self.params.get_bool("CustomTheme")
|
||||||
|
|||||||
@@ -371,6 +371,7 @@ void ui_update_frogpilot_params(UIState *s) {
|
|||||||
scene.map_style = quality_of_life_visuals ? params.getInt("MapStyle") : 0;
|
scene.map_style = quality_of_life_visuals ? params.getInt("MapStyle") : 0;
|
||||||
|
|
||||||
scene.personalities_via_screen = params.getBool("PersonalitiesViaScreen") && params.getBool("AdjustablePersonalities");
|
scene.personalities_via_screen = params.getBool("PersonalitiesViaScreen") && params.getBool("AdjustablePersonalities");
|
||||||
|
scene.random_events = params.getBool("RandomEvents");
|
||||||
scene.rotating_wheel = params.getBool("RotatingWheel");
|
scene.rotating_wheel = params.getBool("RotatingWheel");
|
||||||
|
|
||||||
bool screen_management = params.getBool("ScreenManagement");
|
bool screen_management = params.getBool("ScreenManagement");
|
||||||
@@ -474,6 +475,9 @@ void UIState::update() {
|
|||||||
if (scene.holiday_themes) {
|
if (scene.holiday_themes) {
|
||||||
scene.current_holiday_theme = paramsMemory.getInt("CurrentHolidayTheme");
|
scene.current_holiday_theme = paramsMemory.getInt("CurrentHolidayTheme");
|
||||||
}
|
}
|
||||||
|
if (scene.random_events) {
|
||||||
|
scene.current_random_event = paramsMemory.getInt("CurrentRandomEvent");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIState::setPrimeType(PrimeType type) {
|
void UIState::setPrimeType(PrimeType type) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ struct Alert {
|
|||||||
alert = {"openpilot crashed", "Please post the error log in the FrogPilot Discord!",
|
alert = {"openpilot crashed", "Please post the error log in the FrogPilot Discord!",
|
||||||
"controlsWaiting", cereal::ControlsState::AlertSize::MID,
|
"controlsWaiting", cereal::ControlsState::AlertSize::MID,
|
||||||
cereal::ControlsState::AlertStatus::NORMAL,
|
cereal::ControlsState::AlertStatus::NORMAL,
|
||||||
AudibleAlert::NONE};
|
Params().getBool("RandomEvents") ? AudibleAlert::FART : AudibleAlert::NONE};
|
||||||
} else if (controls_frame < started_frame) {
|
} else if (controls_frame < started_frame) {
|
||||||
// car is started, but controlsState hasn't been seen at all
|
// car is started, but controlsState hasn't been seen at all
|
||||||
alert = {"openpilot Unavailable", "Waiting for controls to start",
|
alert = {"openpilot Unavailable", "Waiting for controls to start",
|
||||||
@@ -211,6 +211,7 @@ typedef struct UIScene {
|
|||||||
bool parked;
|
bool parked;
|
||||||
bool pedals_on_ui;
|
bool pedals_on_ui;
|
||||||
bool personalities_via_screen;
|
bool personalities_via_screen;
|
||||||
|
bool random_events;
|
||||||
bool reverse_cruise;
|
bool reverse_cruise;
|
||||||
bool reverse_cruise_ui;
|
bool reverse_cruise_ui;
|
||||||
bool right_hand_drive;
|
bool right_hand_drive;
|
||||||
@@ -252,6 +253,7 @@ typedef struct UIScene {
|
|||||||
int conditional_speed_lead;
|
int conditional_speed_lead;
|
||||||
int conditional_status;
|
int conditional_status;
|
||||||
int current_holiday_theme;
|
int current_holiday_theme;
|
||||||
|
int current_random_event;
|
||||||
int custom_colors;
|
int custom_colors;
|
||||||
int custom_icons;
|
int custom_icons;
|
||||||
int custom_signals;
|
int custom_signals;
|
||||||
|
|||||||
Reference in New Issue
Block a user