Experimental Mode activation via steering wheel / onroad UI
Added toggle to enable or disable Experimental Mode from the steering wheel or onroad UI.
This commit is contained in:
@@ -255,6 +255,10 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"DriveStats", PERSISTENT},
|
{"DriveStats", PERSISTENT},
|
||||||
{"DynamicPathWidth", PERSISTENT},
|
{"DynamicPathWidth", PERSISTENT},
|
||||||
{"EngageVolume", PERSISTENT},
|
{"EngageVolume", PERSISTENT},
|
||||||
|
{"ExperimentalModeActivation", PERSISTENT},
|
||||||
|
{"ExperimentalModeViaDistance", PERSISTENT},
|
||||||
|
{"ExperimentalModeViaLKAS", PERSISTENT},
|
||||||
|
{"ExperimentalModeViaScreen", PERSISTENT},
|
||||||
{"FrogPilotTogglesUpdated", PERSISTENT},
|
{"FrogPilotTogglesUpdated", PERSISTENT},
|
||||||
{"FrogsGoMoo", PERSISTENT},
|
{"FrogsGoMoo", PERSISTENT},
|
||||||
{"GoatScream", PERSISTENT},
|
{"GoatScream", PERSISTENT},
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ class Panda:
|
|||||||
FLAG_HYUNDAI_CANFD_ALT_BUTTONS = 32
|
FLAG_HYUNDAI_CANFD_ALT_BUTTONS = 32
|
||||||
FLAG_HYUNDAI_ALT_LIMITS = 64
|
FLAG_HYUNDAI_ALT_LIMITS = 64
|
||||||
FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128
|
FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128
|
||||||
|
FLAG_HYUNDAI_LFA_BTN = 256
|
||||||
|
|
||||||
FLAG_TESLA_POWERTRAIN = 1
|
FLAG_TESLA_POWERTRAIN = 1
|
||||||
FLAG_TESLA_LONG_CONTROL = 2
|
FLAG_TESLA_LONG_CONTROL = 2
|
||||||
|
|||||||
@@ -152,6 +152,20 @@ class CarState(CarStateBase):
|
|||||||
ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
|
ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
|
||||||
ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
|
ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
|
||||||
|
|
||||||
|
# Toggle Experimental Mode from steering wheel function
|
||||||
|
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available:
|
||||||
|
if self.CP.carFingerprint in SDGM_CAR:
|
||||||
|
lkas_pressed = cam_cp.vl["ASCMSteeringButton"]["LKAButton"]
|
||||||
|
else:
|
||||||
|
lkas_pressed = pt_cp.vl["ASCMSteeringButton"]["LKAButton"]
|
||||||
|
|
||||||
|
if lkas_pressed and not self.lkas_previously_pressed:
|
||||||
|
if frogpilot_variables.conditional_experimental_mode:
|
||||||
|
self.fpf.update_cestatus_lkas()
|
||||||
|
else:
|
||||||
|
self.fpf.update_experimental_mode()
|
||||||
|
self.lkas_previously_pressed = lkas_pressed
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -263,6 +263,16 @@ class CarState(CarStateBase):
|
|||||||
ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]["BSM_ALERT"] == 1
|
ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]["BSM_ALERT"] == 1
|
||||||
ret.rightBlindspot = cp_body.vl["BSM_STATUS_RIGHT"]["BSM_ALERT"] == 1
|
ret.rightBlindspot = cp_body.vl["BSM_STATUS_RIGHT"]["BSM_ALERT"] == 1
|
||||||
|
|
||||||
|
# Toggle Experimental Mode from steering wheel function
|
||||||
|
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available:
|
||||||
|
lkas_pressed = self.cruise_setting == 1
|
||||||
|
if lkas_pressed and not self.lkas_previously_pressed:
|
||||||
|
if frogpilot_variables.conditional_experimental_mode:
|
||||||
|
self.fpf.update_cestatus_lkas()
|
||||||
|
else:
|
||||||
|
self.fpf.update_experimental_mode()
|
||||||
|
self.lkas_previously_pressed = lkas_pressed
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_can_parser(self, CP):
|
def get_can_parser(self, CP):
|
||||||
|
|||||||
@@ -170,6 +170,16 @@ class CarState(CarStateBase):
|
|||||||
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
|
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
|
||||||
self.main_enabled = not self.main_enabled
|
self.main_enabled = not self.main_enabled
|
||||||
|
|
||||||
|
# Toggle Experimental Mode from steering wheel function
|
||||||
|
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available and self.CP.flags & HyundaiFlags.CAN_LFA_BTN:
|
||||||
|
lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"]
|
||||||
|
if lkas_pressed and not self.lkas_previously_pressed:
|
||||||
|
if frogpilot_variables.conditional_experimental_mode:
|
||||||
|
self.fpf.update_cestatus_lkas()
|
||||||
|
else:
|
||||||
|
self.fpf.update_experimental_mode()
|
||||||
|
self.lkas_previously_pressed = lkas_pressed
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def update_canfd(self, cp, cp_cam, frogpilot_variables):
|
def update_canfd(self, cp, cp_cam, frogpilot_variables):
|
||||||
@@ -255,6 +265,13 @@ class CarState(CarStateBase):
|
|||||||
self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING
|
self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING
|
||||||
else cp_cam.vl["CAM_0x2a4"])
|
else cp_cam.vl["CAM_0x2a4"])
|
||||||
|
|
||||||
|
# Toggle Experimental Mode from steering wheel function
|
||||||
|
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available:
|
||||||
|
lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
|
||||||
|
if lkas_pressed and not self.lkas_previously_pressed:
|
||||||
|
self.fpf.lkas_button_function(frogpilot_variables.conditional_experimental_mode)
|
||||||
|
self.lkas_previously_pressed = lkas_pressed
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_can_parser(self, CP):
|
def get_can_parser(self, CP):
|
||||||
@@ -304,6 +321,9 @@ class CarState(CarStateBase):
|
|||||||
else:
|
else:
|
||||||
messages.append(("LVR12", 100))
|
messages.append(("LVR12", 100))
|
||||||
|
|
||||||
|
if CP.flags & HyundaiFlags.CAN_LFA_BTN:
|
||||||
|
messages.append(("BCM_PO_11", 50))
|
||||||
|
|
||||||
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
|
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -316,6 +316,10 @@ class CarInterface(CarInterfaceBase):
|
|||||||
if candidate in CAMERA_SCC_CAR:
|
if candidate in CAMERA_SCC_CAR:
|
||||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
|
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
|
||||||
|
|
||||||
|
if 0x391 in fingerprint[0]:
|
||||||
|
ret.flags |= HyundaiFlags.CAN_LFA_BTN.value
|
||||||
|
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LFA_BTN
|
||||||
|
|
||||||
if ret.openpilotLongitudinalControl:
|
if ret.openpilotLongitudinalControl:
|
||||||
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG
|
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG
|
||||||
if ret.flags & HyundaiFlags.HYBRID:
|
if ret.flags & HyundaiFlags.HYBRID:
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class HyundaiFlags(IntFlag):
|
|||||||
CANFD_HDA2_ALT_STEERING = 512
|
CANFD_HDA2_ALT_STEERING = 512
|
||||||
HYBRID = 1024
|
HYBRID = 1024
|
||||||
EV = 2048
|
EV = 2048
|
||||||
|
CAN_LFA_BTN = 4096
|
||||||
|
|
||||||
|
|
||||||
class CAR(StrEnum):
|
class CAR(StrEnum):
|
||||||
|
|||||||
@@ -373,6 +373,12 @@ class CarStateBase(ABC):
|
|||||||
# FrogPilot variables
|
# FrogPilot variables
|
||||||
self.fpf = FrogPilotFunctions()
|
self.fpf = FrogPilotFunctions()
|
||||||
|
|
||||||
|
self.distance_button = False
|
||||||
|
self.distance_previously_pressed = False
|
||||||
|
self.lkas_previously_pressed = False
|
||||||
|
|
||||||
|
self.distance_pressed_counter = 0
|
||||||
|
|
||||||
def update_speed_kf(self, v_ego_raw):
|
def update_speed_kf(self, v_ego_raw):
|
||||||
if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed
|
if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed
|
||||||
self.v_ego_kf.set_x([[v_ego_raw], [0.0]])
|
self.v_ego_kf.set_x([[v_ego_raw], [0.0]])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from opendbc.can.parser import CANParser
|
|||||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||||
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
|
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
|
||||||
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR
|
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR
|
||||||
|
from openpilot.selfdrive.controls.lib.drive_helpers import CRUISE_LONG_PRESS
|
||||||
|
|
||||||
SteerControlType = car.CarParams.SteerControlType
|
SteerControlType = car.CarParams.SteerControlType
|
||||||
|
|
||||||
@@ -166,6 +167,34 @@ class CarState(CarStateBase):
|
|||||||
if self.CP.carFingerprint != CAR.PRIUS_V:
|
if self.CP.carFingerprint != CAR.PRIUS_V:
|
||||||
self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"])
|
self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"])
|
||||||
|
|
||||||
|
# Experimental Mode via double clicking the LKAS button function
|
||||||
|
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available and self.CP.carFingerprint != CAR.PRIUS_V:
|
||||||
|
message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"]
|
||||||
|
lkas_pressed = any(self.lkas_hud.get(key) == 1 for key in message_keys)
|
||||||
|
|
||||||
|
if lkas_pressed and not self.lkas_previously_pressed:
|
||||||
|
if frogpilot_variables.conditional_experimental_mode:
|
||||||
|
self.fpf.update_cestatus_distance()
|
||||||
|
else:
|
||||||
|
self.fpf.update_experimental_mode()
|
||||||
|
|
||||||
|
self.lkas_previously_pressed = lkas_pressed
|
||||||
|
|
||||||
|
# Experimental Mode via long pressing the distance button function
|
||||||
|
if ret.cruiseState.available:
|
||||||
|
if distance_pressed:
|
||||||
|
self.distance_pressed_counter += 1
|
||||||
|
elif self.distance_previously_pressed:
|
||||||
|
self.distance_pressed_counter = 0
|
||||||
|
|
||||||
|
if self.distance_pressed_counter == CRUISE_LONG_PRESS and frogpilot_variables.experimental_mode_via_distance:
|
||||||
|
if frogpilot_variables.conditional_experimental_mode:
|
||||||
|
self.fpf.update_cestatus_lkas()
|
||||||
|
else:
|
||||||
|
self.fpf.update_experimental_mode()
|
||||||
|
|
||||||
|
self.distance_previously_pressed = distance_pressed
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -1023,6 +1023,10 @@ class Controls:
|
|||||||
frog_sounds = custom_sounds == 1
|
frog_sounds = custom_sounds == 1
|
||||||
self.goat_scream = frog_sounds and self.params.get_bool("GoatScream")
|
self.goat_scream = frog_sounds and self.params.get_bool("GoatScream")
|
||||||
|
|
||||||
|
experimental_mode_activation = self.params.get_bool("ExperimentalModeActivation")
|
||||||
|
self.frogpilot_variables.experimental_mode_via_distance = experimental_mode_activation and self.params.get_bool("ExperimentalModeViaDistance")
|
||||||
|
self.frogpilot_variables.experimental_mode_via_lkas = experimental_mode_activation and self.params.get_bool("ExperimentalModeViaLKAS")
|
||||||
|
|
||||||
lateral_tune = self.params.get_bool("LateralTune")
|
lateral_tune = self.params.get_bool("LateralTune")
|
||||||
|
|
||||||
longitudinal_tune = self.params.get_bool("LongitudinalTune")
|
longitudinal_tune = self.params.get_bool("LongitudinalTune")
|
||||||
|
|||||||
@@ -37,15 +37,22 @@ class ConditionalExperimentalMode:
|
|||||||
lead = radarState.leadOne
|
lead = radarState.leadOne
|
||||||
v_lead = lead.vLead
|
v_lead = lead.vLead
|
||||||
|
|
||||||
|
# Set the value of "overridden"
|
||||||
|
if self.experimental_mode_via_press:
|
||||||
|
overridden = self.params_memory.get_int("CEStatus")
|
||||||
|
else:
|
||||||
|
overridden = 0
|
||||||
|
|
||||||
# Update Experimental Mode based on the current driving conditions
|
# Update Experimental Mode based on the current driving conditions
|
||||||
condition_met = self.check_conditions(carState, frogpilotNavigation, lead, modelData, stop_distance, v_ego)
|
condition_met = self.check_conditions(carState, frogpilotNavigation, lead, modelData, stop_distance, v_ego)
|
||||||
if (not self.experimental_mode and condition_met) and enabled:
|
if ((not self.experimental_mode and condition_met and overridden not in (1, 3, 5)) or overridden in (2, 4, 6)) and enabled:
|
||||||
self.experimental_mode = True
|
self.experimental_mode = True
|
||||||
elif (self.experimental_mode and not condition_met) or not enabled:
|
elif (self.experimental_mode and not condition_met and overridden not in (2, 4, 6)) or overridden in (1, 3, 5) or not enabled:
|
||||||
self.experimental_mode = False
|
self.experimental_mode = False
|
||||||
self.status_value = 0
|
self.status_value = 0
|
||||||
|
|
||||||
# Update the onroad status bar
|
# Update the onroad status bar
|
||||||
|
self.status_value = overridden if overridden in (1, 2, 3, 4, 5, 6) else self.status_value
|
||||||
if self.status_value != self.previous_status_value:
|
if self.status_value != self.previous_status_value:
|
||||||
self.params_memory.put_int("CEStatus", self.status_value)
|
self.params_memory.put_int("CEStatus", self.status_value)
|
||||||
self.previous_status_value = self.status_value
|
self.previous_status_value = self.status_value
|
||||||
@@ -177,6 +184,8 @@ class ConditionalExperimentalMode:
|
|||||||
self.curves = params.get_bool("CECurves")
|
self.curves = params.get_bool("CECurves")
|
||||||
self.curves_lead = self.curves and params.get_bool("CECurvesLead")
|
self.curves_lead = self.curves and params.get_bool("CECurvesLead")
|
||||||
|
|
||||||
|
self.experimental_mode_via_press = params.get_bool("ExperimentalModeActivation")
|
||||||
|
|
||||||
self.limit = params.get_int("CESpeed") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
self.limit = params.get_int("CESpeed") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
||||||
self.limit_lead = params.get_int("CESpeedLead") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
self.limit_lead = params.get_int("CESpeedLead") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,25 @@ class FrogPilotFunctions:
|
|||||||
|
|
||||||
return min(distance_to_lane, distance_to_road_edge)
|
return min(distance_to_lane, distance_to_road_edge)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_cestatus_distance(self):
|
||||||
|
# Set "CEStatus" to work with "Conditional Experimental Mode"
|
||||||
|
conditional_status = params_memory.get_int("CEStatus")
|
||||||
|
override_value = 0 if conditional_status in (1, 2, 3, 4, 5, 6) else 3 if conditional_status >= 7 else 4
|
||||||
|
params_memory.put_int("CEStatus", override_value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_cestatus_lkas(self):
|
||||||
|
# Set "CEStatus" to work with "Conditional Experimental Mode"
|
||||||
|
conditional_status = params_memory.get_int("CEStatus")
|
||||||
|
override_value = 0 if conditional_status in (1, 2, 3, 4, 5, 6) else 5 if conditional_status >= 7 else 6
|
||||||
|
params_memory.put_int("CEStatus", override_value)
|
||||||
|
|
||||||
|
def update_experimental_mode(self):
|
||||||
|
experimental_mode = self.params.get_bool("ExperimentalMode")
|
||||||
|
# Invert the value of "ExperimentalMode"
|
||||||
|
self.params.put_bool("ExperimentalMode", not experimental_mode)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def road_curvature(modelData, v_ego):
|
def road_curvature(modelData, v_ego):
|
||||||
predicted_velocities = np.array(modelData.velocity.x)
|
predicted_velocities = np.array(modelData.velocity.x)
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
|||||||
{"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"},
|
{"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"},
|
||||||
{"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"},
|
{"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"},
|
||||||
|
|
||||||
|
{"ExperimentalModeActivation", "Experimental Mode Activation", "Toggle Experimental Mode with either buttons on ethe steering wheel or the screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"},
|
||||||
|
{"ExperimentalModeViaLKAS", "Double Clicking the LKAS Button", "Enable/disable 'Experimental Mode' by double clicking the 'LKAS' button on your steering wheel.", ""},
|
||||||
|
{"ExperimentalModeViaScreen", "Double Taping the Onroad UI", "Enable/disable 'Experimental Mode' by double taping the onroad UI within a 0.5 second time frame.", ""},
|
||||||
|
{"ExperimentalModeViaDistance", "Long Pressing the Distance Button", "Enable/disable 'Experimental Mode' by holding down the 'distance' button on your steering wheel for 0.5 seconds.", ""},
|
||||||
|
|
||||||
{"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"},
|
{"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"},
|
||||||
|
|
||||||
{"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"},
|
{"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"},
|
||||||
@@ -142,6 +147,16 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
|||||||
}
|
}
|
||||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false);
|
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false);
|
||||||
|
|
||||||
|
} else if (param == "ExperimentalModeActivation") {
|
||||||
|
FrogPilotParamManageControl *experimentalModeActivationToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||||
|
QObject::connect(experimentalModeActivationToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||||
|
parentToggleClicked();
|
||||||
|
for (auto &[key, toggle] : toggles) {
|
||||||
|
toggle->setVisible(experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toggle = experimentalModeActivationToggle;
|
||||||
|
|
||||||
} else if (param == "LateralTune") {
|
} else if (param == "LateralTune") {
|
||||||
FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||||
QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||||
@@ -293,6 +308,7 @@ void FrogPilotControlsPanel::hideSubToggles() {
|
|||||||
|
|
||||||
for (auto &[key, toggle] : toggles) {
|
for (auto &[key, toggle] : toggles) {
|
||||||
bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() ||
|
bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() ||
|
||||||
|
experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end() ||
|
||||||
fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end() ||
|
fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end() ||
|
||||||
laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() ||
|
laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() ||
|
||||||
lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() ||
|
lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() ||
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ private:
|
|||||||
FrogPilotDualParamControl *relaxedProfile;
|
FrogPilotDualParamControl *relaxedProfile;
|
||||||
|
|
||||||
std::set<QString> conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"};
|
std::set<QString> conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"};
|
||||||
|
std::set<QString> experimentalModeActivationKeys = {"ExperimentalModeViaDistance", "ExperimentalModeViaLKAS", "ExperimentalModeViaScreen"};
|
||||||
std::set<QString> fireTheBabysitterKeys = {};
|
std::set<QString> fireTheBabysitterKeys = {};
|
||||||
std::set<QString> laneChangeKeys = {};
|
std::set<QString> laneChangeKeys = {};
|
||||||
std::set<QString> lateralTuneKeys = {};
|
std::set<QString> lateralTuneKeys = {};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
|
||||||
@@ -66,6 +67,12 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->
|
|||||||
QObject::connect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState);
|
QObject::connect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState);
|
||||||
QObject::connect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition);
|
QObject::connect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition);
|
||||||
QObject::connect(uiState(), &UIState::primeChanged, this, &OnroadWindow::primeChanged);
|
QObject::connect(uiState(), &UIState::primeChanged, this, &OnroadWindow::primeChanged);
|
||||||
|
|
||||||
|
QObject::connect(&clickTimer, &QTimer::timeout, this, [this]() {
|
||||||
|
clickTimer.stop();
|
||||||
|
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, timeoutPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||||
|
QApplication::postEvent(this, event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnroadWindow::updateState(const UIState &s) {
|
void OnroadWindow::updateState(const UIState &s) {
|
||||||
@@ -98,13 +105,34 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) {
|
|||||||
// FrogPilot clickable widgets
|
// FrogPilot clickable widgets
|
||||||
bool widgetClicked = false;
|
bool widgetClicked = false;
|
||||||
|
|
||||||
|
// If the click wasn't for anything specific, change the value of "ExperimentalMode"
|
||||||
|
if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
|
||||||
|
if (clickTimer.isActive()) {
|
||||||
|
clickTimer.stop();
|
||||||
|
|
||||||
|
if (scene.conditional_experimental) {
|
||||||
|
int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 1 : 2;
|
||||||
|
paramsMemory.putIntNonBlocking("CEStatus", override_value);
|
||||||
|
} else {
|
||||||
|
bool experimentalMode = params.getBool("ExperimentalMode");
|
||||||
|
params.putBoolNonBlocking("ExperimentalMode", !experimentalMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
clickTimer.start(500);
|
||||||
|
}
|
||||||
|
widgetClicked = true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_MAPS
|
#ifdef ENABLE_MAPS
|
||||||
if (map != nullptr && !widgetClicked) {
|
if (map != nullptr && !widgetClicked) {
|
||||||
// Switch between map and sidebar when using navigate on openpilot
|
// Switch between map and sidebar when using navigate on openpilot
|
||||||
bool sidebarVisible = geometry().x() > 0;
|
bool sidebarVisible = geometry().x() > 0;
|
||||||
bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible;
|
bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible;
|
||||||
|
if (!clickTimer.isActive()) {
|
||||||
map->setVisible(show_map && !map->isVisible());
|
map->setVisible(show_map && !map->isVisible());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// propagation event to parent(HomeWindow)
|
// propagation event to parent(HomeWindow)
|
||||||
if (!widgetClicked) {
|
if (!widgetClicked) {
|
||||||
@@ -234,10 +262,15 @@ void ExperimentalButton::changeMode() {
|
|||||||
Params paramsMemory = Params("/dev/shm/params");
|
Params paramsMemory = Params("/dev/shm/params");
|
||||||
|
|
||||||
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
|
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
|
||||||
bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed");
|
bool can_change = hasLongitudinalControl(cp) && (params.getBool("ExperimentalModeConfirmed") || scene.experimental_mode_via_screen);
|
||||||
if (can_change) {
|
if (can_change) {
|
||||||
|
if (scene.conditional_experimental) {
|
||||||
|
int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 4) ? 0 : scene.conditional_status >= 5 ? 3 : 4;
|
||||||
|
paramsMemory.putIntNonBlocking("ConditionalStatus", override_value);
|
||||||
|
} else {
|
||||||
params.putBool("ExperimentalMode", !experimental_mode);
|
params.putBool("ExperimentalMode", !experimental_mode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExperimentalButton::updateState(const UIState &s, bool leadInfo) {
|
void ExperimentalButton::updateState(const UIState &s, bool leadInfo) {
|
||||||
@@ -1136,15 +1169,17 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
|
|||||||
{2, "Experimental Mode manually activated"},
|
{2, "Experimental Mode manually activated"},
|
||||||
{3, "Conditional Experimental overridden"},
|
{3, "Conditional Experimental overridden"},
|
||||||
{4, "Experimental Mode manually activated"},
|
{4, "Experimental Mode manually activated"},
|
||||||
{5, "Experimental Mode activated for" + (mapOpen ? " intersection" : QString(" upcoming intersection"))},
|
{5, "Conditional Experimental overridden"},
|
||||||
{6, "Experimental Mode activated for" + (mapOpen ? " turn" : QString(" upcoming turn"))},
|
{6, "Experimental Mode manually activated"},
|
||||||
{7, "Experimental Mode activated due to" + (mapOpen ? "SLC" : QString(" no speed limit set"))},
|
{7, "Experimental Mode activated for" + (mapOpen ? " intersection" : QString(" upcoming intersection"))},
|
||||||
{8, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeedLead) + (is_metric ? " kph" : " mph"))},
|
{8, "Experimental Mode activated for" + (mapOpen ? " turn" : QString(" upcoming turn"))},
|
||||||
{9, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeed) + (is_metric ? " kph" : " mph"))},
|
{9, "Experimental Mode activated due to" + (mapOpen ? "SLC" : QString(" no speed limit set"))},
|
||||||
{10, "Experimental Mode activated for slower lead"},
|
{10, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeedLead) + (is_metric ? " kph" : " mph"))},
|
||||||
{11, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))},
|
{11, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeed) + (is_metric ? " kph" : " mph"))},
|
||||||
{12, "Experimental Mode activated for curve"},
|
{12, "Experimental Mode activated for slower lead"},
|
||||||
{13, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))},
|
{13, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))},
|
||||||
|
{14, "Experimental Mode activated for curve"},
|
||||||
|
{15, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update status text
|
// Update status text
|
||||||
@@ -1154,6 +1189,21 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
|
|||||||
newStatus = conditionalStatusMap[status != STATUS_DISENGAGED ? conditionalStatus : 0];
|
newStatus = conditionalStatusMap[status != STATUS_DISENGAGED ? conditionalStatus : 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append suffix to the status
|
||||||
|
QString distanceSuffix = ". Long press the \"distance\" button to revert";
|
||||||
|
QString lkasSuffix = ". Double press the \"LKAS\" button to revert";
|
||||||
|
QString screenSuffix = ". Double tap the screen to revert";
|
||||||
|
|
||||||
|
if (!alwaysOnLateral && !mapOpen && status != STATUS_DISENGAGED && !newStatus.isEmpty()) {
|
||||||
|
if (conditionalStatus == 1 || conditionalStatus == 2) {
|
||||||
|
newStatus += screenSuffix;
|
||||||
|
} else if (conditionalStatus == 3 || conditionalStatus == 4) {
|
||||||
|
newStatus += distanceSuffix;
|
||||||
|
} else if (conditionalStatus == 5 || conditionalStatus == 6) {
|
||||||
|
newStatus += lkasSuffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if status has changed
|
// Check if status has changed
|
||||||
if (newStatus != lastShownStatus) {
|
if (newStatus != lastShownStatus) {
|
||||||
displayStatusText = true;
|
displayStatusText = true;
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ private:
|
|||||||
UIScene &scene;
|
UIScene &scene;
|
||||||
Params paramsMemory{"/dev/shm/params"};
|
Params paramsMemory{"/dev/shm/params"};
|
||||||
|
|
||||||
|
QPoint timeoutPoint = QPoint(420, 69);
|
||||||
|
QTimer clickTimer;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void offroadTransition(bool offroad);
|
void offroadTransition(bool offroad);
|
||||||
void primeChanged(bool prime);
|
void primeChanged(bool prime);
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ void ui_update_frogpilot_params(UIState *s) {
|
|||||||
scene.custom_signals = custom_theme ? params.getInt("CustomSignals") : 0;
|
scene.custom_signals = custom_theme ? params.getInt("CustomSignals") : 0;
|
||||||
|
|
||||||
scene.driver_camera = params.getBool("DriverCamera");
|
scene.driver_camera = params.getBool("DriverCamera");
|
||||||
|
scene.experimental_mode_via_screen = params.getBool("ExperimentalModeViaScreen") && params.getBool("ExperimentalModeActivation");
|
||||||
|
|
||||||
scene.model_ui = params.getBool("ModelUI");
|
scene.model_ui = params.getBool("ModelUI");
|
||||||
scene.dynamic_path_width = scene.model_ui && params.getBool("DynamicPathWidth");
|
scene.dynamic_path_width = scene.model_ui && params.getBool("DynamicPathWidth");
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ typedef struct UIScene {
|
|||||||
bool dynamic_path_width;
|
bool dynamic_path_width;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool experimental_mode;
|
bool experimental_mode;
|
||||||
|
bool experimental_mode_via_screen;
|
||||||
bool lead_info;
|
bool lead_info;
|
||||||
bool map_open;
|
bool map_open;
|
||||||
bool model_ui;
|
bool model_ui;
|
||||||
|
|||||||
Reference in New Issue
Block a user