Speed limit controller

Added toggle to control the cruise set speed according to speed limit supplied by OSM, NOO, or the vehicle itself.

Co-Authored-By: Jacob Pfeifer <jacob@pfeifer.dev>
Co-Authored-By: Efini <19368997+efini@users.noreply.github.com>
Co-Authored-By: Kumar <36933347+rav4kumar@users.noreply.github.com>
Co-Authored-By: Jason Wen <haibin.wen3@gmail.com>
This commit is contained in:
FrogAi
2024-02-27 16:34:47 -07:00
parent 6907410750
commit 3a926ddfbe
23 changed files with 703 additions and 29 deletions

View File

@@ -3,6 +3,7 @@ from openpilot.common.numpy_fast import interp
from openpilot.selfdrive.frogpilot.functions.frogpilot_functions import CITY_SPEED_LIMIT, CRUISING_SPEED, MovingAverageCalculator, PROBABILITY
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
# Lookup table for stop sign / stop light detection
SLOW_DOWN_BP = [0., 10., 20., 30., 40., 50., 55., 60.]
@@ -74,6 +75,11 @@ class ConditionalExperimentalMode:
self.status_value = 7 if frogpilotNavigation.approachingIntersection else 8
return True
# Speed Limit Controller check
if SpeedLimitController.experimental_mode:
self.status_value = 9
return True
# Speed check
if (not self.lead_detected and v_ego <= self.limit) or (self.lead_detected and v_ego <= self.limit_lead):
self.status_value = 10 if self.lead_detected else 11

View File

@@ -12,6 +12,7 @@ from openpilot.selfdrive.frogpilot.functions.frogpilot_functions import CRUISING
from openpilot.selfdrive.frogpilot.functions.conditional_experimental_mode import ConditionalExperimentalMode
from openpilot.selfdrive.frogpilot.functions.map_turn_speed_controller import MapTurnSpeedController
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
class FrogPilotPlanner:
@@ -24,8 +25,12 @@ class FrogPilotPlanner:
self.cem = ConditionalExperimentalMode(self.params_memory)
self.mtsc = MapTurnSpeedController()
self.override_slc = False
self.overridden_speed = 0
self.mtsc_target = 0
self.road_curvature = 0
self.slc_target = 0
self.stop_distance = 0
self.v_cruise = 0
@@ -106,7 +111,40 @@ class FrogPilotPlanner:
else:
self.mtsc_target = v_cruise
targets = [self.mtsc_target]
# Pfeiferj's Speed Limit Controller
if self.speed_limit_controller:
SpeedLimitController.update_speed_limits()
unconfirmed_slc_target = SpeedLimitController.desired_speed_limit
# Check if the new speed limit has been confirmed by the user
if self.speed_limit_confirmation:
if self.params_memory.get_bool("SLCConfirmed") or self.slc_target == 0:
self.slc_target = unconfirmed_slc_target
self.params_memory.put_bool("SLCConfirmed", False)
else:
self.slc_target = unconfirmed_slc_target
# Override SLC upon gas pedal press and reset upon brake/cancel button
self.override_slc &= self.overridden_speed > self.slc_target
self.override_slc |= carState.gasPressed and v_ego > self.slc_target > CRUISING_SPEED
self.override_slc &= enabled and not carState.standstill
# Use the override speed if SLC is being overridden
if self.override_slc:
if self.speed_limit_controller_override == 1:
# Set the speed limit to the manual set speed
if carState.gasPressed:
self.overridden_speed = v_ego + v_ego_diff
self.overridden_speed = np.clip(self.overridden_speed, self.slc_target, v_cruise + v_cruise_diff)
elif self.speed_limit_controller_override == 2:
# Set the speed limit to the max set speed
self.overridden_speed = v_cruise + v_cruise_diff
else:
self.overridden_speed = 0
else:
self.slc_target = v_cruise
targets = [self.mtsc_target, max(self.overridden_speed, self.slc_target) - v_ego_diff]
filtered_targets = [target for target in targets if target > CRUISING_SPEED]
return min(filtered_targets) if filtered_targets else v_cruise
@@ -129,6 +167,12 @@ class FrogPilotPlanner:
frogpilotPlan.redLight = self.cem.red_light_detected
frogpilotPlan.slcOverridden = bool(self.override_slc)
frogpilotPlan.slcOverriddenSpeed = float(self.overridden_speed)
frogpilotPlan.slcSpeedLimit = float(self.slc_target)
frogpilotPlan.slcSpeedLimitOffset = SpeedLimitController.offset
frogpilotPlan.unconfirmedSlcSpeedLimit = SpeedLimitController.desired_speed_limit
pm.send('frogpilotPlan', frogpilot_plan_send)
def update_frogpilot_params(self, params):
@@ -171,3 +215,8 @@ class FrogPilotPlanner:
self.mtsc_curvature_check = params.get_bool("MTSCCurvatureCheck")
self.mtsc_limit = params.get_float("MTSCLimit") * (CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS)
self.params_memory.put_float("MapTargetLatA", 2 * (params.get_int("MTSCAggressiveness") / 100))
self.speed_limit_controller = params.get_bool("SpeedLimitController")
if self.speed_limit_controller:
self.speed_limit_confirmation = params.get_bool("SLCConfirmation")
self.speed_limit_controller_override = params.get_int("SLCOverride")

View File

@@ -0,0 +1,117 @@
import json
from openpilot.common.conversions import Conversions as CV
from openpilot.common.params import Params
params = Params()
params_memory = Params("/dev/shm/params")
class SpeedLimitController:
car_speed_limit: float = 0 # m/s
map_speed_limit: float = 0 # m/s
nav_speed_limit: float = 0 # m/s
prv_speed_limit: float = 0 # m/s
def __init__(self) -> None:
self.update_frogpilot_params()
def update_speed_limits(self):
self.car_speed_limit = json.loads(params_memory.get("CarSpeedLimit") or '0')
self.map_speed_limit = json.loads(params_memory.get("MapSpeedLimit") or '0')
self.nav_speed_limit = json.loads(params_memory.get("NavSpeedLimit") or '0')
if params_memory.get_bool("FrogPilotTogglesUpdated"):
self.update_frogpilot_params()
@property
def offset(self) -> float:
if self.speed_limit < 14:
return self.offset1
elif self.speed_limit < 24:
return self.offset2
elif self.speed_limit < 29:
return self.offset3
else:
return self.offset4
@property
def speed_limit(self) -> float:
limits = [self.car_speed_limit, self.map_speed_limit, self.nav_speed_limit]
filtered_limits = [limit for limit in limits if limit >= 1]
if self.highest and filtered_limits:
return max(filtered_limits)
elif self.lowest and filtered_limits:
return min(filtered_limits)
speed_limits = {
"Dashboard": self.car_speed_limit,
"Navigation": self.nav_speed_limit,
"Offline Maps": self.map_speed_limit,
}
priorities = [
self.speed_limit_priority1,
self.speed_limit_priority2,
self.speed_limit_priority3,
]
for priority in priorities:
speed_limit_value = speed_limits.get(priority, 0)
if speed_limit_value >= 1:
return speed_limit_value
if self.use_previous_limit:
return self.prv_speed_limit
return 0
def update_previous_limit(self, speed_limit: float):
if self.prv_speed_limit != speed_limit:
params.put_float("PreviousSpeedLimit", speed_limit)
self.prv_speed_limit = speed_limit
@property
def desired_speed_limit(self) -> float:
if self.speed_limit != 0:
self.update_previous_limit(self.speed_limit)
return self.speed_limit + self.offset
else:
return 0
@property
def experimental_mode(self) -> bool:
return self.speed_limit == 0 and self.use_experimental_mode
def write_car_state(self):
params_memory.put("CarSpeedLimit", json.dumps(self.car_speed_limit))
def write_map_state(self):
params_memory.put("MapSpeedLimit", json.dumps(self.map_speed_limit))
def write_nav_state(self):
params_memory.put("NavSpeedLimit", json.dumps(self.nav_speed_limit))
def update_frogpilot_params(self):
conversion = CV.KPH_TO_MS if params.get_bool("IsMetric") else CV.MPH_TO_MS
self.offset1 = params.get_int("Offset1") * conversion
self.offset2 = params.get_int("Offset2") * conversion
self.offset3 = params.get_int("Offset3") * conversion
self.offset4 = params.get_int("Offset4") * conversion
self.speed_limit_priority1 = params.get("SLCPriority1", encoding='utf-8')
self.speed_limit_priority2 = params.get("SLCPriority2", encoding='utf-8')
self.speed_limit_priority3 = params.get("SLCPriority3", encoding='utf-8')
self.highest = self.speed_limit_priority1 == "Highest"
self.lowest = self.speed_limit_priority1 == "Lowest"
slc_fallback = params.get_int("SLCFallback")
self.use_experimental_mode = slc_fallback == 1
self.use_previous_limit = slc_fallback == 2
self.prv_speed_limit = params.get_float("PreviousSpeedLimit")
SpeedLimitController = SpeedLimitController()

View File

@@ -60,6 +60,23 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"PauseLateralOnSignal", "Pause Lateral On Turn Signal Below", "Temporarily disable lateral control during turn signal use below the set speed.", ""},
{"ReverseCruise", "Reverse Cruise Increase", "Reverses the 'long press' functionality when increasing the max set speed. Useful to increase the max speed quickly.", ""},
{"SetSpeedOffset", "Set Speed Offset", "Set an offset for your desired set speed.", ""},
{"SpeedLimitController", "Speed Limit Controller", "Automatically adjust vehicle speed to match speed limits using 'Open Street Map's, 'Navigate On openpilot', or your car's dashboard (TSS2 Toyotas only).", "../assets/offroad/icon_speed_limit.png"},
{"SLCControls", "Controls Settings", "Manage settings for the controls.", ""},
{"Offset1", "Speed Limit Offset (0-34 mph)", "Speed limit offset for speed limits between 0-34 mph.", ""},
{"Offset2", "Speed Limit Offset (35-54 mph)", "Speed limit offset for speed limits between 35-54 mph.", ""},
{"Offset3", "Speed Limit Offset (55-64 mph)", "Speed limit offset for speed limits between 55-64 mph.", ""},
{"Offset4", "Speed Limit Offset (65-99 mph)", "Speed limit offset for speed limits between 65-99 mph.", ""},
{"SLCFallback", "Fallback Method", "Choose your fallback method for when there are no speed limits currently being obtained from Navigation, OSM, and the car's dashboard.", ""},
{"SLCOverride", "Override Method", "Choose your preferred method to override the current speed limit.", ""},
{"SLCPriority", "Priority Order", "Determine the priority order for what speed limits to use.", ""},
{"SLCQOL", "Quality of Life Settings", "Manage quality of life settings.", ""},
{"SLCConfirmation", "Confirm New Speed Limits", "Don't automatically start using the new speed limit until it's been manually confirmed first.", ""},
{"ForceMPHDashboard", "Force MPH From Dashboard Readings", "Force MPH readings from the dashboard. Only use this if you live in an area where the speed limits from your dashboard are in KPH but you use MPH.", ""},
{"SetSpeedLimit", "Use Current Speed Limit As Set Speed", "Sets your max speed to the current speed limit if one is populated when you initially enable openpilot.", ""},
{"SLCVisuals", "Visuals Settings", "Manage visual settings.", ""},
{"ShowSLCOffset", "Show Speed Limit Offset", "Show the speed limit offset seperated from the speed limit in the onroad UI when using 'Speed Limit Controller'.", ""},
{"UseVienna", "Use Vienna Speed Limit Signs", "Use the Vienna (EU) speed limit style signs as opposed to MUTCD (US).", ""},
};
for (const auto &[param, title, desc, icon] : controlToggles) {
@@ -307,6 +324,116 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
} else if (param == "LaneDetectionWidth") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, " feet", 10);
} else if (param == "SpeedLimitController") {
FrogPilotParamManageControl *speedLimitControllerToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(speedLimitControllerToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end());
}
});
toggle = speedLimitControllerToggle;
} else if (param == "SLCControls") {
FrogPilotParamManageControl *manageSLCControlsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true);
QObject::connect(manageSLCControlsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(speedLimitControllerControlsKeys.find(key.c_str()) != speedLimitControllerControlsKeys.end());
subParentToggleClicked();
}
slcPriorityButton->setVisible(true);
});
toggle = manageSLCControlsToggle;
} else if (param == "SLCQOL") {
FrogPilotParamManageControl *manageSLCQOLToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true);
QObject::connect(manageSLCQOLToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(speedLimitControllerQOLKeys.find(key.c_str()) != speedLimitControllerQOLKeys.end());
subParentToggleClicked();
}
});
toggle = manageSLCQOLToggle;
} else if (param == "SLCConfirmation") {
std::vector<QString> slcConfirmationToggles{"SLCConfirmationLower", "SLCConfirmationHigher"};
std::vector<QString> slcConfirmationNames{tr("Lower Limits"), tr("Higher Limits")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, slcConfirmationToggles, slcConfirmationNames);
} else if (param == "SLCVisuals") {
FrogPilotParamManageControl *manageSLCVisualsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true);
QObject::connect(manageSLCVisualsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(speedLimitControllerVisualsKeys.find(key.c_str()) != speedLimitControllerVisualsKeys.end());
subParentToggleClicked();
}
});
toggle = manageSLCVisualsToggle;
} else if (param == "Offset1" || param == "Offset2" || param == "Offset3" || param == "Offset4") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, -99, 99, std::map<int, QString>(), this, false, " mph");
} else if (param == "ShowSLCOffset") {
std::vector<QString> slcOffsetToggles{"ShowSLCOffsetUI"};
std::vector<QString> slcOffsetToggleNames{tr("Control Via UI")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, slcOffsetToggles, slcOffsetToggleNames);
} else if (param == "SLCFallback") {
std::vector<QString> fallbackOptions{tr("Set Speed"), tr("Experimental Mode"), tr("Previous Limit")};
FrogPilotButtonParamControl *fallbackSelection = new FrogPilotButtonParamControl(param, title, desc, icon, fallbackOptions);
toggle = fallbackSelection;
} else if (param == "SLCOverride") {
std::vector<QString> overrideOptions{tr("None"), tr("Manual Set Speed"), tr("Set Speed")};
FrogPilotButtonParamControl *overrideSelection = new FrogPilotButtonParamControl(param, title, desc, icon, overrideOptions);
toggle = overrideSelection;
} else if (param == "SLCPriority") {
slcPriorityButton = new ButtonControl(title, tr("SELECT"), desc);
QStringList primaryPriorities = {"None", "Dashboard", "Navigation", "Offline Maps", "Highest", "Lowest"};
QStringList secondaryTertiaryPriorities = {"None", "Dashboard", "Navigation", "Offline Maps"};
QStringList priorityPrompts = {tr("Select your primary priority"), tr("Select your secondary priority"), tr("Select your tertiary priority")};
QObject::connect(slcPriorityButton, &ButtonControl::clicked, this, [this, primaryPriorities, secondaryTertiaryPriorities, priorityPrompts]() {
QStringList availablePriorities = primaryPriorities;
QStringList selectedPriorities;
for (int i = 1; i <= 3; ++i) {
QStringList currentPriorities = (i == 1) ? availablePriorities : secondaryTertiaryPriorities;
for (const QString &selectedPriority : selectedPriorities) {
currentPriorities.removeAll(selectedPriority);
}
QString priorityKey = QString("SLCPriority%1").arg(i);
QString selection = MultiOptionDialog::getSelection(priorityPrompts[i - 1], currentPriorities, "", this);
if (!selection.isEmpty()) {
params.put(priorityKey.toStdString(), selection.toStdString());
selectedPriorities.append(selection);
if (i == 1 && (selection == "Highest" || selection == "Lowest" || selection == "None")) {
for (int j = i + 1; j <= 3; ++j) {
QString remainingPriorityKeys = QString("SLCPriority%1").arg(j);
params.putInt(remainingPriorityKeys.toStdString(), 0);
}
break;
}
updateToggles();
} else {
break;
}
}
selectedPriorities.removeAll("None");
slcPriorityButton->setValue(selectedPriorities.join(", "));
});
QStringList initialPriorities;
for (int i = 1; i <= 3; ++i) {
QString priorityKey = QString("SLCPriority%1").arg(i);
std::string priorityValue = params.get(priorityKey.toStdString());
QString priorityString = QString::fromStdString(priorityValue);
if (!priorityString.isEmpty() && primaryPriorities.contains(priorityString) && priorityString != "None") {
initialPriorities.append(priorityString);
}
}
slcPriorityButton->setValue(initialPriorities.join(", "));
addItem(slcPriorityButton);
} else {
toggle = new ParamControl(param, title, desc, icon, this);
}
@@ -399,6 +526,10 @@ void FrogPilotControlsPanel::updateMetric() {
params.putIntNonBlocking("CESpeedLead", std::nearbyint(params.getInt("CESpeedLead") * speedConversion));
params.putIntNonBlocking("LaneDetectionWidth", std::nearbyint(params.getInt("LaneDetectionWidth") * distanceConversion));
params.putIntNonBlocking("MTSCLimit", std::nearbyint(params.getInt("MTSCLimit") * speedConversion));
params.putIntNonBlocking("Offset1", std::nearbyint(params.getInt("Offset1") * speedConversion));
params.putIntNonBlocking("Offset2", std::nearbyint(params.getInt("Offset2") * speedConversion));
params.putIntNonBlocking("Offset3", std::nearbyint(params.getInt("Offset3") * speedConversion));
params.putIntNonBlocking("Offset4", std::nearbyint(params.getInt("Offset4") * speedConversion));
params.putIntNonBlocking("PauseLateralOnSignal", std::nearbyint(params.getInt("PauseLateralOnSignal") * speedConversion));
params.putIntNonBlocking("SetSpeedOffset", std::nearbyint(params.getInt("SetSpeedOffset") * speedConversion));
params.putIntNonBlocking("StoppingDistance", std::nearbyint(params.getInt("StoppingDistance") * distanceConversion));
@@ -406,22 +537,58 @@ void FrogPilotControlsPanel::updateMetric() {
FrogPilotParamValueControl *laneWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["LaneDetectionWidth"]);
FrogPilotParamValueControl *mtscLimitToggle = static_cast<FrogPilotParamValueControl*>(toggles["MTSCLimit"]);
FrogPilotParamValueControl *offset1Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset1"]);
FrogPilotParamValueControl *offset2Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset2"]);
FrogPilotParamValueControl *offset3Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset3"]);
FrogPilotParamValueControl *offset4Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset4"]);
FrogPilotParamValueControl *pauseLateralToggle = static_cast<FrogPilotParamValueControl*>(toggles["PauseLateralOnSignal"]);
FrogPilotParamValueControl *setSpeedOffsetToggle = static_cast<FrogPilotParamValueControl*>(toggles["SetSpeedOffset"]);
FrogPilotParamValueControl *stoppingDistanceToggle = static_cast<FrogPilotParamValueControl*>(toggles["StoppingDistance"]);
if (isMetric) {
offset1Toggle->setTitle("Speed Limit Offset (0-34 kph)");
offset2Toggle->setTitle("Speed Limit Offset (35-54 kph)");
offset3Toggle->setTitle("Speed Limit Offset (55-64 kph)");
offset4Toggle->setTitle("Speed Limit Offset (65-99 kph)");
offset1Toggle->setDescription("Set speed limit offset for limits between 0-34 kph.");
offset2Toggle->setDescription("Set speed limit offset for limits between 35-54 kph.");
offset3Toggle->setDescription("Set speed limit offset for limits between 55-64 kph.");
offset4Toggle->setDescription("Set speed limit offset for limits between 65-99 kph.");
laneWidthToggle->updateControl(0, 30, " meters", 10);
mtscLimitToggle->updateControl(0, 99, " kph");
offset1Toggle->updateControl(-99, 99, " kph");
offset2Toggle->updateControl(-99, 99, " kph");
offset3Toggle->updateControl(-99, 99, " kph");
offset4Toggle->updateControl(-99, 99, " kph");
pauseLateralToggle->updateControl(0, 150, " kph");
setSpeedOffsetToggle->updateControl(0, 150, " kph");
stoppingDistanceToggle->updateControl(0, 5, " meters");
} else {
offset1Toggle->setTitle("Speed Limit Offset (0-34 mph)");
offset2Toggle->setTitle("Speed Limit Offset (35-54 mph)");
offset3Toggle->setTitle("Speed Limit Offset (55-64 mph)");
offset4Toggle->setTitle("Speed Limit Offset (65-99 mph)");
offset1Toggle->setDescription("Set speed limit offset for limits between 0-34 mph.");
offset2Toggle->setDescription("Set speed limit offset for limits between 35-54 mph.");
offset3Toggle->setDescription("Set speed limit offset for limits between 55-64 mph.");
offset4Toggle->setDescription("Set speed limit offset for limits between 65-99 mph.");
laneWidthToggle->updateControl(0, 100, " feet", 10);
mtscLimitToggle->updateControl(0, 99, " mph");
offset1Toggle->updateControl(-99, 99, " mph");
offset2Toggle->updateControl(-99, 99, " mph");
offset3Toggle->updateControl(-99, 99, " mph");
offset4Toggle->updateControl(-99, 99, " mph");
pauseLateralToggle->updateControl(0, 99, " mph");
setSpeedOffsetToggle->updateControl(0, 99, " mph");
@@ -430,6 +597,10 @@ void FrogPilotControlsPanel::updateMetric() {
laneWidthToggle->refresh();
mtscLimitToggle->refresh();
offset1Toggle->refresh();
offset2Toggle->refresh();
offset3Toggle->refresh();
offset4Toggle->refresh();
pauseLateralToggle->refresh();
setSpeedOffsetToggle->refresh();
stoppingDistanceToggle->refresh();
@@ -442,6 +613,7 @@ void FrogPilotControlsPanel::parentToggleClicked() {
conditionalSpeedsImperial->setVisible(false);
conditionalSpeedsMetric->setVisible(false);
modelSelectorButton->setVisible(false);
slcPriorityButton->setVisible(false);
standardProfile->setVisible(false);
relaxedProfile->setVisible(false);
@@ -457,6 +629,7 @@ void FrogPilotControlsPanel::hideSubToggles() {
conditionalSpeedsImperial->setVisible(false);
conditionalSpeedsMetric->setVisible(false);
modelSelectorButton->setVisible(true);
slcPriorityButton->setVisible(false);
standardProfile->setVisible(false);
relaxedProfile->setVisible(false);
@@ -471,6 +644,9 @@ void FrogPilotControlsPanel::hideSubToggles() {
mtscKeys.find(key.c_str()) != mtscKeys.end() ||
qolKeys.find(key.c_str()) != qolKeys.end() ||
speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end() ||
speedLimitControllerControlsKeys.find(key.c_str()) != speedLimitControllerControlsKeys.end() ||
speedLimitControllerQOLKeys.find(key.c_str()) != speedLimitControllerQOLKeys.end() ||
speedLimitControllerVisualsKeys.find(key.c_str()) != speedLimitControllerVisualsKeys.end() ||
visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end();
toggle->setVisible(!subToggles);
}
@@ -479,8 +655,10 @@ void FrogPilotControlsPanel::hideSubToggles() {
}
void FrogPilotControlsPanel::hideSubSubToggles() {
slcPriorityButton->setVisible(false);
for (auto &[key, toggle] : toggles) {
bool isVisible = false;
bool isVisible = speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end();
toggle->setVisible(isVisible);
}

View File

@@ -29,6 +29,8 @@ private:
void updateState(const UIState &s);
void updateToggles();
ButtonControl *slcPriorityButton;
FrogPilotButtonIconControl *modelSelectorButton;
FrogPilotDualParamControl *aggressiveProfile;
@@ -46,10 +48,10 @@ private:
std::set<QString> longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "AggressiveAcceleration", "SmoothBraking", "StoppingDistance"};
std::set<QString> mtscKeys = {"DisableMTSCSmoothing", "MTSCAggressiveness", "MTSCCurvatureCheck", "MTSCLimit"};
std::set<QString> qolKeys = {"DisableOnroadUploads", "HigherBitrate", "NavChill", "PauseLateralOnSignal", "ReverseCruise", "SetSpeedOffset"};
std::set<QString> speedLimitControllerKeys = {};
std::set<QString> speedLimitControllerControlsKeys = {};
std::set<QString> speedLimitControllerQOLKeys = {};
std::set<QString> speedLimitControllerVisualsKeys = {};
std::set<QString> speedLimitControllerKeys = {"SLCControls", "SLCQOL", "SLCVisuals"};
std::set<QString> speedLimitControllerControlsKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "SLCFallback", "SLCOverride", "SLCPriority"};
std::set<QString> speedLimitControllerQOLKeys = {"SLCConfirmation", "ForceMPHDashboard", "SetSpeedLimit"};
std::set<QString> speedLimitControllerVisualsKeys = {"ShowSLCOffset", "UseVienna"};
std::set<QString> visionTurnControlKeys = {};
std::map<std::string, ParamControl*> toggles;

View File

@@ -25,6 +25,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
{"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", ""},
{"LeadDepartingAlert", "Lead Departing Alert", "Get an alert when your lead vehicle starts departing when you're at a standstill.", ""},
{"LoudBlindspotAlert", "Loud Blindspot Alert", "Enable a louder alert for when a vehicle is detected in your blindspot when attempting to change lanes.", ""},
{"SpeedLimitChangedAlert", "Speed Limit Changed Alert", "Trigger an alert whenever the current speed limit changes.", ""},
{"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"},
{"AccelerationPath", "Acceleration Path", "Visualize the car's intended acceleration or deceleration with a color-coded path.", ""},

View File

@@ -29,7 +29,7 @@ private:
void updateToggles();
std::set<QString> alertVolumeControlKeys = {"EngageVolume", "DisengageVolume", "RefuseVolume", "PromptVolume", "PromptDistractedVolume", "WarningSoftVolume", "WarningImmediateVolume"};
std::set<QString> customAlertsKeys = {"GreenLightAlert", "LeadDepartingAlert", "LoudBlindspotAlert"};
std::set<QString> customAlertsKeys = {"GreenLightAlert", "LeadDepartingAlert", "LoudBlindspotAlert", "SpeedLimitChangedAlert"};
std::set<QString> customOnroadUIKeys = {"AccelerationPath", "AdjacentPath", "BlindSpotPath", "FPSCounter", "LeadInfo", "PedalsOnUI", "RoadNameUI"};
std::set<QString> customThemeKeys = {"HolidayThemes", "CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"};
std::set<QString> modelUIKeys = {"DynamicPathWidth", "HideLeadMarker", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"};