mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-23 17:23:44 +08:00
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,15 +118,19 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
paramsdPermanentError @119;
|
||||
|
||||
# FrogPilot events
|
||||
firefoxSteerSaturated @120;
|
||||
frogSteerSaturated @121;
|
||||
greenLight @122;
|
||||
laneChangeBlockedLoud @123;
|
||||
leadDeparting @124;
|
||||
noLaneAvailable @125;
|
||||
openpilotCrashed @126;
|
||||
openpilotCrashedRandomEvents @127;
|
||||
pedalInterceptorNoBrake @128;
|
||||
speedLimitChanged @129;
|
||||
torqueNNLoad @130;
|
||||
vCruise69 @133;
|
||||
yourFrogTriedToKillMe @134;
|
||||
|
||||
radarCanErrorDEPRECATED @15;
|
||||
communityFeatureDisallowedDEPRECATED @62;
|
||||
@@ -419,6 +423,12 @@ struct CarControl {
|
||||
prompt @6;
|
||||
promptRepeat @7;
|
||||
promptDistracted @8;
|
||||
|
||||
# Random Events
|
||||
angry @9;
|
||||
fart @10;
|
||||
firefox @11;
|
||||
noice @12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,6 +245,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"Compass", PERSISTENT},
|
||||
{"ConditionalExperimental", PERSISTENT},
|
||||
{"CrosstrekTorque", PERSISTENT},
|
||||
{"CurrentRandomEvent", PERSISTENT},
|
||||
{"CustomAlerts", PERSISTENT},
|
||||
{"CustomColors", PERSISTENT},
|
||||
{"CustomIcons", PERSISTENT},
|
||||
@@ -346,6 +347,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"PromptDistractedVolume", PERSISTENT},
|
||||
{"QOLControls", PERSISTENT},
|
||||
{"QOLVisuals", PERSISTENT},
|
||||
{"RandomEvents", PERSISTENT},
|
||||
{"RefuseVolume", PERSISTENT},
|
||||
{"RelaxedFollow", PERSISTENT},
|
||||
{"RelaxedJerk", PERSISTENT},
|
||||
|
||||
@@ -181,12 +181,16 @@ class Controls:
|
||||
self.frogpilot_variables = SimpleNamespace()
|
||||
|
||||
self.driving_gear = False
|
||||
self.previously_enabled = False
|
||||
self.fcw_random_event_triggered = False
|
||||
self.openpilot_crashed = False
|
||||
self.previously_enabled = False
|
||||
self.random_event_triggered = False
|
||||
self.stopped_for_light_previously = False
|
||||
self.vCruise69_alert_played = False
|
||||
|
||||
self.previous_lead_distance = 0
|
||||
self.previous_speed_limit = SpeedLimitController.desired_speed_limit
|
||||
self.random_event_timer = 0
|
||||
self.speed_limit_changed_timer = 0
|
||||
|
||||
self.green_light_mac = MovingAverageCalculator()
|
||||
@@ -334,6 +338,9 @@ class Controls:
|
||||
# Show crash log event if openpilot crashed
|
||||
if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')):
|
||||
self.events.add(EventName.openpilotCrashed)
|
||||
if self.random_events and not self.openpilot_crashed:
|
||||
self.events.add(EventName.openpilotCrashedRandomEvents)
|
||||
self.openpilot_crashed = True
|
||||
return
|
||||
|
||||
# Add joystick event, static on cars, dynamic on nonCars
|
||||
@@ -537,6 +544,11 @@ class Controls:
|
||||
planner_fcw = self.sm['longitudinalPlan'].fcw and self.enabled
|
||||
if planner_fcw or model_fcw:
|
||||
self.events.add(EventName.fcw)
|
||||
self.fcw_random_event_triggered = True
|
||||
elif self.fcw_random_event_triggered:
|
||||
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):
|
||||
try:
|
||||
@@ -633,6 +645,19 @@ class Controls:
|
||||
else:
|
||||
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):
|
||||
"""Receive data from sockets and update carState"""
|
||||
|
||||
@@ -793,6 +818,14 @@ class Controls:
|
||||
# FrogPilot functions
|
||||
frogpilot_plan = self.sm['frogpilotPlan']
|
||||
|
||||
# Reset the Random Event flag
|
||||
if self.random_event_triggered:
|
||||
self.random_event_timer += 1
|
||||
if self.random_event_timer >= 500:
|
||||
self.random_event_triggered = False
|
||||
self.random_event_timer = 0
|
||||
self.params_memory.remove("CurrentRandomEvent")
|
||||
|
||||
# Update Experimental Mode
|
||||
if self.frogpilot_variables.conditional_experimental_mode:
|
||||
self.experimental_mode = frogpilot_plan.conditionalExperimental
|
||||
@@ -883,8 +916,13 @@ class Controls:
|
||||
turning = abs(lac_log.desiredLateralAccel) > 1.0
|
||||
good_speed = CS.vEgo > 5
|
||||
max_torque = abs(self.last_actuators.steer) > 0.99
|
||||
if undershooting and turning and good_speed and max_torque:
|
||||
lac_log.active and self.events.add(EventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated)
|
||||
if undershooting and turning and good_speed and max_torque and not self.random_event_triggered:
|
||||
if self.sm.frame % 10000 == 0:
|
||||
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:
|
||||
# TODO probably should not use dpath_points but curvature
|
||||
dpath_points = model_v2.position.y
|
||||
@@ -1154,6 +1192,8 @@ class Controls:
|
||||
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.random_events = self.params.get_bool("RandomEvents")
|
||||
|
||||
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.set_speed_limit = self.speed_limit_controller and self.params.get_bool("SetSpeedLimit")
|
||||
|
||||
@@ -1047,6 +1047,39 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
|
||||
EventName.torqueNNLoad: {
|
||||
ET.PERMANENT: torque_nn_load_alert,
|
||||
},
|
||||
|
||||
# Random Events
|
||||
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.small,
|
||||
Priority.MID, VisualAlert.none, AudibleAlert.angry, 3.),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -53,6 +53,7 @@ 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.", ""},
|
||||
{"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"},
|
||||
{"ScreenBrightness", "Screen Brightness", "Customize your screen brightness.", "../frogpilot/assets/toggle_icons/icon_light.png"},
|
||||
|
||||
{"WheelIcon", "Steering Wheel Icon", "Replace the default steering wheel icon with a custom design, adding a unique touch to your interface.", "../assets/offroad/icon_openpilot.png"},
|
||||
|
||||
@@ -382,7 +382,8 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
|
||||
{3, loadPixmap("../frogpilot/assets/wheel_images/frog.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})},
|
||||
{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})}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -411,13 +412,20 @@ void ExperimentalButton::updateState(const UIState &s, bool leadInfo) {
|
||||
}
|
||||
|
||||
// FrogPilot variables
|
||||
firefoxRandomEventTriggered = scene.current_random_event == 1;
|
||||
rotatingWheel = scene.rotating_wheel;
|
||||
wheelIcon = scene.wheel_icon;
|
||||
|
||||
y_offset = leadInfo ? 10 : 0;
|
||||
|
||||
if (firefoxRandomEventTriggered) {
|
||||
static int rotationDegree = 0;
|
||||
rotationDegree = (rotationDegree + 36) % 360;
|
||||
steeringAngleDeg = rotationDegree;
|
||||
wheelIcon = 7;
|
||||
update();
|
||||
// Update the icon so the steering wheel rotates in real time
|
||||
if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
|
||||
} else if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
|
||||
steeringAngleDeg = scene.steering_angle_deg;
|
||||
update();
|
||||
}
|
||||
@@ -437,7 +445,7 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
QColor(0, 0, 0, 166);
|
||||
|
||||
if (!(scene.show_driver_camera || scene.map_open && scene.full_map)) {
|
||||
if (rotatingWheel) {
|
||||
if (rotatingWheel || firefoxRandomEventTriggered) {
|
||||
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);
|
||||
} 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);
|
||||
|
||||
@@ -80,6 +80,7 @@ private:
|
||||
|
||||
std::map<int, QPixmap> wheelImages;
|
||||
|
||||
bool firefoxRandomEventTriggered;
|
||||
bool rotatingWheel;
|
||||
int steeringAngleDeg;
|
||||
int wheelIcon;
|
||||
|
||||
+24
-1
@@ -1,5 +1,6 @@
|
||||
import math
|
||||
import numpy as np
|
||||
import os
|
||||
import time
|
||||
import wave
|
||||
|
||||
@@ -40,6 +41,12 @@ sound_list: Dict[int, Tuple[str, Optional[int], float]] = {
|
||||
|
||||
AudibleAlert.warningSoft: ("warning_soft.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),
|
||||
}
|
||||
|
||||
def check_controls_timeout_alert(sm):
|
||||
@@ -58,6 +65,8 @@ class Soundd:
|
||||
self.params = Params()
|
||||
self.params_memory = Params("/dev/shm/params")
|
||||
|
||||
self.random_events_directory = BASEDIR + "/selfdrive/frogpilot/assets/random_events/sounds/"
|
||||
|
||||
self.update_frogpilot_params()
|
||||
|
||||
self.load_sounds()
|
||||
@@ -77,7 +86,10 @@ class Soundd:
|
||||
for sound in sound_list:
|
||||
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.getsampwidth() == 2
|
||||
@@ -160,6 +172,10 @@ class Soundd:
|
||||
elif self.alert_volume_control and self.current_alert in self.volume_map:
|
||||
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)
|
||||
|
||||
rk.keep_time()
|
||||
@@ -171,6 +187,13 @@ class Soundd:
|
||||
self.update_frogpilot_params()
|
||||
|
||||
def update_frogpilot_params(self):
|
||||
self.random_events_map = {
|
||||
AudibleAlert.angry: MAX_VOLUME,
|
||||
AudibleAlert.fart: MAX_VOLUME,
|
||||
AudibleAlert.firefox: MAX_VOLUME,
|
||||
AudibleAlert.noice: MAX_VOLUME,
|
||||
}
|
||||
|
||||
self.alert_volume_control = self.params.get_bool("AlertVolumeControl")
|
||||
|
||||
self.volume_map = {
|
||||
|
||||
@@ -363,6 +363,7 @@ void ui_update_frogpilot_params(UIState *s) {
|
||||
scene.map_style = quality_of_life_visuals ? params.getInt("MapStyle") : 0;
|
||||
|
||||
scene.personalities_via_screen = params.getBool("PersonalitiesViaScreen") && params.getBool("AdjustablePersonalities");
|
||||
scene.random_events = params.getBool("RandomEvents");
|
||||
scene.rotating_wheel = params.getBool("RotatingWheel");
|
||||
scene.screen_brightness = params.getInt("ScreenBrightness");
|
||||
|
||||
@@ -446,6 +447,9 @@ void UIState::update() {
|
||||
if (scene.conditional_experimental) {
|
||||
scene.conditional_status = paramsMemory.getInt("CEStatus");
|
||||
}
|
||||
if (scene.random_events) {
|
||||
scene.current_random_event = paramsMemory.getInt("CurrentRandomEvent");
|
||||
}
|
||||
}
|
||||
|
||||
void UIState::setPrimeType(PrimeType type) {
|
||||
|
||||
+3
-1
@@ -81,7 +81,7 @@ struct Alert {
|
||||
alert = {"openpilot crashed", "Please post the error log in the FrogPilot Discord!",
|
||||
"controlsWaiting", cereal::ControlsState::AlertSize::MID,
|
||||
cereal::ControlsState::AlertStatus::NORMAL,
|
||||
AudibleAlert::NONE};
|
||||
Params().getBool("RandomEvents") ? AudibleAlert::FART : AudibleAlert::NONE};
|
||||
} else if (controls_frame < started_frame) {
|
||||
// car is started, but controlsState hasn't been seen at all
|
||||
alert = {"openpilot Unavailable", "Waiting for controls to start",
|
||||
@@ -202,6 +202,7 @@ typedef struct UIScene {
|
||||
bool numerical_temp;
|
||||
bool pedals_on_ui;
|
||||
bool personalities_via_screen;
|
||||
bool random_events;
|
||||
bool reverse_cruise;
|
||||
bool reverse_cruise_ui;
|
||||
bool right_hand_drive;
|
||||
@@ -239,6 +240,7 @@ typedef struct UIScene {
|
||||
int conditional_speed;
|
||||
int conditional_speed_lead;
|
||||
int conditional_status;
|
||||
int current_random_event;
|
||||
int custom_colors;
|
||||
int custom_icons;
|
||||
int custom_signals;
|
||||
|
||||
Reference in New Issue
Block a user