wip
This commit is contained in:
21
selfdrive/oscarpilot/buttons.py
Normal file
21
selfdrive/oscarpilot/buttons.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import cereal.messaging as messaging
|
||||
import numpy as np
|
||||
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from openpilot.common.numpy_fast import clip, interp
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N, V_CRUISE_MAX
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import T_IDXS as T_IDXS_MPC
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_planner import A_CRUISE_MIN, A_CRUISE_MAX_VALS, A_CRUISE_MAX_BP, get_max_accel
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
|
||||
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 for intercepting when buttons are pressed, or dispatching buttons to be pressed
|
||||
|
||||
|
||||
class OscarPilotButtons:
|
||||
def __init__(self, params, params_memory):
|
||||
self.params_memory = params_memory
|
||||
|
||||
40
selfdrive/oscarpilot/events.py
Normal file
40
selfdrive/oscarpilot/events.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import cereal.messaging as messaging
|
||||
import numpy as np
|
||||
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from openpilot.common.numpy_fast import clip, interp
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N, V_CRUISE_MAX
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import T_IDXS as T_IDXS_MPC
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_planner import A_CRUISE_MIN, A_CRUISE_MAX_VALS, A_CRUISE_MAX_BP, get_max_accel
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
|
||||
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:
|
||||
# def __init__(self, params, params_memory):
|
||||
# self.params_memory = params_memory
|
||||
# self.cem = ConditionalExperimentalMode()
|
||||
# self.mtsc = MapTurnSpeedController()
|
||||
|
||||
# self.override_slc = False
|
||||
|
||||
# self.overridden_speed = 0
|
||||
# self.mtsc_target = 0
|
||||
# self.slc_target = 0
|
||||
# self.v_cruise = 0
|
||||
# self.vtsc_target = 0
|
||||
|
||||
# self.x_desired_trajectory = np.zeros(CONTROL_N)
|
||||
|
||||
# self.update_frogpilot_params(params, params_memory)
|
||||
|
||||
# def update(self, sm, mpc):
|
||||
# carState, controlsState, modelData = sm['carState'], sm['controlsState'], sm['modelV2']
|
||||
|
||||
# enabled = controlsState.enabled
|
||||
|
||||
# v_cruise_kph = min(controlsState.vCruise, V_CRUISE_MAX)
|
||||
# v_cruise = v_cruise_kph * CV.KPH_TO_MS
|
||||
# v_ego = carState.vEgo
|
||||
1
selfdrive/oscarpilot/settings/advanced.cc
Normal file
1
selfdrive/oscarpilot/settings/advanced.cc
Normal file
@@ -0,0 +1 @@
|
||||
// Should show a UI showing the settings menu for stock frogpilot
|
||||
0
selfdrive/oscarpilot/settings/advanced.h
Normal file
0
selfdrive/oscarpilot/settings/advanced.h
Normal file
242
selfdrive/oscarpilot/settings/basic.cc
Normal file
242
selfdrive/oscarpilot/settings/basic.cc
Normal file
@@ -0,0 +1,242 @@
|
||||
#include "selfdrive/frogpilot/ui/visual_settings.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
FrogPilotVisualsPanel::FrogPilotVisualsPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) {
|
||||
const std::vector<std::tuple<QString, QString, QString, QString>> visualToggles {
|
||||
{"CustomTheme", "Custom Themes", "Enable the ability to use custom themes.", "../frogpilot/assets/wheel_images/frog.png"},
|
||||
{"CustomColors", "Color Theme", "Switch out the standard openpilot color scheme with a custom color scheme.\n\nWant to submit your own color scheme? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
|
||||
{"CustomIcons", "Icon Pack", "Switch out the standard openpilot icons with a set of custom icons.\n\nWant to submit your own icon pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
|
||||
{"CustomSignals", "Turn Signals", "Add custom animations for your turn signals for a personal touch!\n\nWant to submit your own turn signal animation? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
|
||||
{"CustomSounds", "Sound Pack", "Switch out the standard openpilot sounds with a set of custom sounds.\n\nWant to submit your own sound pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
|
||||
|
||||
{"CameraView", "Camera View", "Choose your preferred camera view for the onroad UI. This is a visual change only and doesn't impact openpilot.", "../frogpilot/assets/toggle_icons/icon_camera.png"},
|
||||
{"Compass", "Compass", "Add a compass to your onroad UI.", "../frogpilot/assets/toggle_icons/icon_compass.png"},
|
||||
|
||||
{"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"},
|
||||
{"AdjacentPath", "Adjacent Paths", "Display paths to the left and right of your car, visualizing where the model detects lanes.", ""},
|
||||
{"BlindSpotPath", "Blind Spot Path", "Visualize your blind spots with a red path when another vehicle is detected nearby.", ""},
|
||||
{"ShowFPS", "FPS Counter", "Display the Frames Per Second (FPS) of your onroad UI for monitoring system performance.", ""},
|
||||
{"LeadInfo", "Lead Info and Logics", "Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance.", ""},
|
||||
{"RoadNameUI", "Road Name", "See the name of the road you're on at the bottom of your screen. Sourced from OpenStreetMap.", ""},
|
||||
{"UseVienna", "Use Vienna Speed Limit Signs", "Use the Vienna (EU) speed limit style signs as opposed to MUTCD (US).", ""},
|
||||
|
||||
{"DriverCamera", "Driver Camera On Reverse", "Show the driver's camera feed when you shift to reverse.", "../assets/img_driver_face_static.png"},
|
||||
{"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", "../frogpilot/assets/toggle_icons/icon_green_light.png"},
|
||||
|
||||
{"ModelUI", "Model UI", "Personalize how the model's visualizations appear on your screen.", "../assets/offroad/icon_calibration.png"},
|
||||
{"AccelerationPath", "Acceleration Path", "Visualize the car's intended acceleration or deceleration with a color-coded path.", ""},
|
||||
{"LaneLinesWidth", "Lane Lines", "Adjust the visual thickness of lane lines on your display.\n\nDefault matches the MUTCD average of 4 inches.", ""},
|
||||
{"PathEdgeWidth", "Path Edges", "Adjust the width of the path edges shown on your UI to represent different driving modes and statuses.\n\nDefault is 20% of the total path.\n\nBlue = Navigation\nLight Blue = Always On Lateral\nGreen = Default with 'FrogPilot Colors'\nLight Green = Default with stock colors\nOrange = Experimental Mode Active\nYellow = Conditional Overriden", ""},
|
||||
{"PathWidth", "Path Width", "Customize the width of the driving path shown on your UI.\n\nDefault matches the width of a 2019 Lexus ES 350.", ""},
|
||||
{"RoadEdgesWidth", "Road Edges", "Adjust the visual thickness of road edges on your display.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.", ""},
|
||||
{"UnlimitedLength", "'Unlimited' Road UI Length", "Extend the display of the path, lane lines, and road edges as far as the system can detect, providing a more expansive view of the road ahead.", ""},
|
||||
|
||||
{"QOLVisuals", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"},
|
||||
{"DriveStats", "Drive Stats In Home Screen", "Display your device's drive stats in the home screen.", ""},
|
||||
{"HideSpeed", "Hide Speed", "Hide the speed indicator in the onroad UI.", ""},
|
||||
{"ShowSLCOffset", "Show Speed Limit Offset", "Show the speed limit offset seperated from the speed limit in the onroad UI when using 'Speed Limit Controller'.", ""},
|
||||
|
||||
{"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"},
|
||||
{"SilentMode", "Silent Mode", "Mute openpilot sounds for a quieter driving experience.", "../frogpilot/assets/toggle_icons/icon_mute.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"},
|
||||
};
|
||||
|
||||
for (const auto &[param, title, desc, icon] : visualToggles) {
|
||||
ParamControl *toggle;
|
||||
|
||||
if (param == "CameraView") {
|
||||
std::vector<QString> cameraOptions{tr("Auto"), tr("Standard"), tr("Wide"), tr("Driver")};
|
||||
FrogPilotButtonParamControl *preferredCamera = new FrogPilotButtonParamControl(param, title, desc, icon, cameraOptions);
|
||||
toggle = preferredCamera;
|
||||
|
||||
} else if (param == "CustomTheme") {
|
||||
FrogPilotParamManageControl *customThemeToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
QObject::connect(customThemeToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||
parentToggleClicked();
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
toggle->setVisible(customThemeKeys.find(key.c_str()) != customThemeKeys.end());
|
||||
}
|
||||
});
|
||||
toggle = customThemeToggle;
|
||||
} else if (param == "CustomColors" || param == "CustomIcons" || param == "CustomSignals" || param == "CustomSounds") {
|
||||
std::vector<QString> themeOptions{tr("Stock"), tr("Frog"), tr("Tesla"), tr("Stalin")};
|
||||
FrogPilotButtonParamControl *themeSelection = new FrogPilotButtonParamControl(param, title, desc, icon, themeOptions);
|
||||
toggle = themeSelection;
|
||||
|
||||
if (param == "CustomSounds") {
|
||||
QObject::connect(static_cast<FrogPilotButtonParamControl*>(toggle), &FrogPilotButtonParamControl::buttonClicked, [this](int id) {
|
||||
if (id == 1) {
|
||||
if (FrogPilotConfirmationDialog::yesorno("Do you want to enable the bonus 'Goat' sound effect?", this)) {
|
||||
params.putBool("GoatScream", true);
|
||||
} else {
|
||||
params.putBool("GoatScream", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else if (param == "CustomUI") {
|
||||
FrogPilotParamManageControl *customUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
QObject::connect(customUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||
parentToggleClicked();
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
toggle->setVisible(customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end());
|
||||
}
|
||||
});
|
||||
toggle = customUIToggle;
|
||||
} else if (param == "LeadInfo") {
|
||||
std::vector<QString> leadInfoToggles{tr("UseSI")};
|
||||
std::vector<QString> leadInfoToggleNames{tr("Use SI Values")};
|
||||
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, leadInfoToggles, leadInfoToggleNames);
|
||||
|
||||
} else if (param == "ModelUI") {
|
||||
FrogPilotParamManageControl *modelUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
QObject::connect(modelUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||
parentToggleClicked();
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
toggle->setVisible(modelUIKeys.find(key.c_str()) != modelUIKeys.end());
|
||||
}
|
||||
});
|
||||
toggle = modelUIToggle;
|
||||
} else if (param == "LaneLinesWidth" || param == "RoadEdgesWidth") {
|
||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 24, std::map<int, QString>(), this, false, " inches");
|
||||
} else if (param == "PathEdgeWidth") {
|
||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, "%");
|
||||
} else if (param == "PathWidth") {
|
||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, " feet", 10);
|
||||
|
||||
} else if (param == "QOLVisuals") {
|
||||
FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
||||
parentToggleClicked();
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end());
|
||||
}
|
||||
});
|
||||
toggle = qolToggle;
|
||||
|
||||
} else if (param == "ScreenBrightness") {
|
||||
std::map<int, QString> brightnessLabels;
|
||||
for (int i = 0; i <= 101; ++i) {
|
||||
brightnessLabels[i] = i == 0 ? "Screen Off" : i == 101 ? "Auto" : QString::number(i) + "%";
|
||||
}
|
||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 101, brightnessLabels, this, false);
|
||||
|
||||
} else if (param == "WheelIcon") {
|
||||
std::vector<QString> wheelToggles{"RotatingWheel"};
|
||||
std::vector<QString> wheelToggleNames{tr("Rotating")};
|
||||
std::map<int, QString> steeringWheelLabels = {{0, "Stock"}, {1, "Lexus"}, {2, "Toyota"}, {3, "Frog"}, {4, "Rocket"}, {5, "Hyundai"}, {6, "Stalin"}};
|
||||
toggle = new FrogPilotParamValueToggleControl(param, title, desc, icon, 0, 6, steeringWheelLabels, this, true, "", 1, wheelToggles, wheelToggleNames);
|
||||
|
||||
} else {
|
||||
toggle = new ParamControl(param, title, desc, icon, this);
|
||||
}
|
||||
|
||||
addItem(toggle);
|
||||
toggles[param.toStdString()] = toggle;
|
||||
|
||||
QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamValueControl*>(toggle), &FrogPilotParamValueControl::buttonPressed, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamManageControl*>(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() {
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
std::set<std::string> rebootKeys = {"DriveStats"};
|
||||
for (const std::string &key : rebootKeys) {
|
||||
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
|
||||
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||
Hardware::reboot();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
customOnroadUIKeys = {"AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI", "UseVienna"};
|
||||
customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"};
|
||||
modelUIKeys = {"AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"};
|
||||
qolKeys = {"DriveStats", "HideSpeed", "ShowSLCOffset"};
|
||||
|
||||
QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotVisualsPanel::hideSubToggles);
|
||||
QObject::connect(parent, &OscarSettingsWindow::closeParentToggle, this, &FrogPilotVisualsPanel::hideSubToggles);
|
||||
QObject::connect(parent, &OscarSettingsWindow::updateMetric, this, &FrogPilotVisualsPanel::updateMetric);
|
||||
|
||||
hideSubToggles();
|
||||
updateMetric();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::updateToggles() {
|
||||
std::thread([this]() {
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", true);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", false);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::updateMetric() {
|
||||
bool previousIsMetric = isMetric;
|
||||
isMetric = params.getBool("IsMetric");
|
||||
|
||||
if (isMetric != previousIsMetric) {
|
||||
double distanceConversion = isMetric ? INCH_TO_CM : CM_TO_INCH;
|
||||
double speedConversion = isMetric ? FOOT_TO_METER : METER_TO_FOOT;
|
||||
params.putInt("LaneLinesWidth", std::nearbyint(params.getInt("LaneLinesWidth") * distanceConversion));
|
||||
params.putInt("RoadEdgesWidth", std::nearbyint(params.getInt("RoadEdgesWidth") * distanceConversion));
|
||||
params.putInt("PathWidth", std::nearbyint(params.getInt("PathWidth") * speedConversion));
|
||||
}
|
||||
|
||||
FrogPilotParamValueControl *laneLinesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["LaneLinesWidth"]);
|
||||
FrogPilotParamValueControl *roadEdgesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["RoadEdgesWidth"]);
|
||||
FrogPilotParamValueControl *pathWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["PathWidth"]);
|
||||
|
||||
if (isMetric) {
|
||||
laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the Vienna average of 10 centimeters.");
|
||||
roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the Vienna average lane line width of 10 centimeters.");
|
||||
|
||||
laneLinesWidthToggle->updateControl(0, 60, " centimeters");
|
||||
roadEdgesWidthToggle->updateControl(0, 60, " centimeters");
|
||||
pathWidthToggle->updateControl(0, 30, " meters");
|
||||
} else {
|
||||
laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the MUTCD average of 4 inches.");
|
||||
roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.");
|
||||
|
||||
laneLinesWidthToggle->updateControl(0, 24, " inches");
|
||||
roadEdgesWidthToggle->updateControl(0, 24, " inches");
|
||||
pathWidthToggle->updateControl(0, 100, " feet");
|
||||
}
|
||||
|
||||
laneLinesWidthToggle->refresh();
|
||||
roadEdgesWidthToggle->refresh();
|
||||
|
||||
previousIsMetric = isMetric;
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::parentToggleClicked() {
|
||||
this->openParentToggle();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::hideSubToggles() {
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() ||
|
||||
customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() ||
|
||||
customThemeKeys.find(key.c_str()) != customThemeKeys.end() ||
|
||||
qolKeys.find(key.c_str()) != qolKeys.end();
|
||||
toggle->setVisible(!subToggles);
|
||||
}
|
||||
|
||||
this->closeParentToggle();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::hideEvent(QHideEvent *event) {
|
||||
hideSubToggles();
|
||||
}
|
||||
36
selfdrive/oscarpilot/settings/basic.h
Normal file
36
selfdrive/oscarpilot/settings/basic.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/ui/qt/offroad/settings.h"
|
||||
|
||||
class FrogPilotVisualsPanel : public FrogPilotListWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FrogPilotVisualsPanel(OscarSettingsWindow *parent);
|
||||
|
||||
signals:
|
||||
void closeParentToggle();
|
||||
void openParentToggle();
|
||||
|
||||
private:
|
||||
void hideEvent(QHideEvent *event);
|
||||
void hideSubToggles();
|
||||
void parentToggleClicked();
|
||||
void updateMetric();
|
||||
void updateToggles();
|
||||
|
||||
std::set<QString> customOnroadUIKeys;
|
||||
std::set<QString> customThemeKeys;
|
||||
std::set<QString> modelUIKeys;
|
||||
std::set<QString> qolKeys;
|
||||
|
||||
std::map<std::string, ParamControl*> toggles;
|
||||
|
||||
Params params;
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
|
||||
bool isMetric = params.getBool("IsMetric");
|
||||
};
|
||||
0
selfdrive/oscarpilot/settings/defaults.cc
Normal file
0
selfdrive/oscarpilot/settings/defaults.cc
Normal file
0
selfdrive/oscarpilot/settings/defaults.h
Normal file
0
selfdrive/oscarpilot/settings/defaults.h
Normal file
1
selfdrive/oscarpilot/settings/notes
Normal file
1
selfdrive/oscarpilot/settings/notes
Normal file
@@ -0,0 +1 @@
|
||||
Need a reset to defaults option
|
||||
147
selfdrive/oscarpilot/settings/settings.cc
Normal file
147
selfdrive/oscarpilot/settings/settings.cc
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "selfdrive/ui/qt/offroad/settings.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "selfdrive/ui/qt/network/networking.h"
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/watchdog.h"
|
||||
#include "common/util.h"
|
||||
#include "system/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
#include "selfdrive/ui/qt/widgets/scrollview.h"
|
||||
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
|
||||
#include "selfdrive/ui/qt/widgets/toggle.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
|
||||
#include "selfdrive/frogpilot/navigation/ui/navigation_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/control_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/vehicle_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/visual_settings.h"
|
||||
|
||||
|
||||
void OscarSettingsWindow::showEvent(QShowEvent *event) {
|
||||
setCurrentPanel(0);
|
||||
}
|
||||
|
||||
void OscarSettingsWindow::setCurrentPanel(int index, const QString ¶m) {
|
||||
panel_widget->setCurrentIndex(index);
|
||||
nav_btns->buttons()[index]->setChecked(true);
|
||||
if (!param.isEmpty()) {
|
||||
emit expandToggleDescription(param);
|
||||
}
|
||||
}
|
||||
|
||||
OscarSettingsWindow::OscarSettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
|
||||
// setup two main layouts
|
||||
sidebar_widget = new QWidget;
|
||||
QVBoxLayout *sidebar_layout = new QVBoxLayout(sidebar_widget);
|
||||
sidebar_layout->setMargin(0);
|
||||
panel_widget = new QStackedWidget();
|
||||
|
||||
// close button
|
||||
QPushButton *close_btn = new QPushButton(tr("← Back"));
|
||||
close_btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
font-size: 50px;
|
||||
padding-bottom: 0px;
|
||||
border 1px grey solid;
|
||||
border-radius: 25px;
|
||||
background-color: #292929;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #3B3B3B;
|
||||
}
|
||||
)");
|
||||
close_btn->setFixedSize(300, 125);
|
||||
sidebar_layout->addSpacing(10);
|
||||
sidebar_layout->addWidget(close_btn, 0, Qt::AlignRight);
|
||||
QObject::connect(close_btn, &QPushButton::clicked, [this]() {
|
||||
if (frogPilotTogglesOpen) {
|
||||
frogPilotTogglesOpen = false;
|
||||
this->closeParentToggle();
|
||||
} else {
|
||||
this->closeSettings();
|
||||
}
|
||||
});
|
||||
|
||||
QList<QPair<QString, QWidget *>> panels = {
|
||||
{tr("Basic"), basic},
|
||||
{tr("Advanced"), basic},
|
||||
{tr("Logging"), basic}, // Log / Upload driver cam, Routes
|
||||
{tr("System"), basic}, // Debugging
|
||||
{tr("Status"), basic}, // Report on stuff like connectivity, free space, detected features
|
||||
{tr("Extra"), basic}, // Custom cloud services, QOL automations
|
||||
};
|
||||
|
||||
nav_btns = new QButtonGroup(this);
|
||||
for (auto &[name, panel] : panels) {
|
||||
QPushButton *btn = new QPushButton(name);
|
||||
btn->setCheckable(true);
|
||||
btn->setChecked(nav_btns->buttons().size() == 0);
|
||||
btn->setStyleSheet();
|
||||
btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
nav_btns->addButton(btn);
|
||||
sidebar_layout->addWidget(btn, 0, Qt::AlignRight);
|
||||
|
||||
const int lr_margin = name != tr("Network") ? 50 : 0; // Network panel handles its own margins
|
||||
panel->setContentsMargins(lr_margin, 25, lr_margin, 25);
|
||||
|
||||
ScrollView *panel_frame = new ScrollView(panel, this);
|
||||
panel_widget->addWidget(panel_frame);
|
||||
|
||||
if (name == tr("Controls") || name == tr("Visuals")) {
|
||||
QScrollBar *scrollbar = panel_frame->verticalScrollBar();
|
||||
|
||||
QObject::connect(scrollbar, &QScrollBar::valueChanged, this, [this](int value) {
|
||||
if (!frogPilotTogglesOpen) {
|
||||
previousScrollPosition = value;
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() {
|
||||
panel_frame->restorePosition(previousScrollPosition);
|
||||
});
|
||||
}
|
||||
|
||||
QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() {
|
||||
previousScrollPosition = 0;
|
||||
btn->setChecked(true);
|
||||
panel_widget->setCurrentWidget(w);
|
||||
});
|
||||
}
|
||||
sidebar_layout->setContentsMargins(50, 50, 100, 50);
|
||||
|
||||
// main settings layout, sidebar + main panel
|
||||
QHBoxLayout *main_layout = new QHBoxLayout(this);
|
||||
|
||||
sidebar_widget->setFixedWidth(500);
|
||||
main_layout->addWidget(sidebar_widget);
|
||||
main_layout->addWidget(panel_widget);
|
||||
|
||||
setStyleSheet(R"(
|
||||
* {
|
||||
color: white;
|
||||
font-size: 50px;
|
||||
}
|
||||
OscarSettingsWindow {
|
||||
background-color: black;
|
||||
}
|
||||
QStackedWidget, ScrollView {
|
||||
background-color: #292929;
|
||||
border-radius: 30px;
|
||||
}
|
||||
)");
|
||||
}
|
||||
45
selfdrive/oscarpilot/settings/settings.h
Normal file
45
selfdrive/oscarpilot/settings/settings.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QStackedWidget>
|
||||
#include <QWidget>
|
||||
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
|
||||
// ********** settings window + top-level panels **********
|
||||
class OscarSettingsWindow : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OscarSettingsWindow(QWidget *parent = 0);
|
||||
void setCurrentPanel(int index, const QString ¶m = "");
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void closeSettings();
|
||||
// void showDriverView();
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
// FrogPilot signals
|
||||
void closeParentToggle();
|
||||
void updateMetric();
|
||||
private:
|
||||
QPushButton *sidebar_alert_widget;
|
||||
QWidget *sidebar_widget;
|
||||
QButtonGroup *nav_btns;
|
||||
QStackedWidget *panel_widget;
|
||||
|
||||
// FrogPilot variables
|
||||
bool frogPilotTogglesOpen;
|
||||
int previousScrollPosition;
|
||||
};
|
||||
|
||||
42
selfdrive/oscarpilot/settings/style.cc
Normal file
42
selfdrive/oscarpilot/settings/style.cc
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
bool FrogPilotConfirmationDialog::toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent) {
|
||||
ConfirmationDialog d = ConfirmationDialog(prompt_text, confirm_text, tr("Reboot Later"), false, parent);
|
||||
return d.exec();
|
||||
}
|
||||
|
||||
bool FrogPilotConfirmationDialog::toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent) {
|
||||
ConfirmationDialog d = ConfirmationDialog(prompt_text, button_text, "", false, parent);
|
||||
return d.exec();
|
||||
}
|
||||
|
||||
bool FrogPilotConfirmationDialog::yesorno(const QString &prompt_text, QWidget *parent) {
|
||||
ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Yes"), tr("No"), false, parent);
|
||||
return d.exec();
|
||||
}
|
||||
|
||||
FrogPilotButtonIconControl::FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc, const QString &icon, QWidget *parent) : AbstractControl(title, desc, icon, parent) {
|
||||
btn.setText(text);
|
||||
btn.setStyleSheet(R"(
|
||||
QPushButton {
|
||||
padding: 0;
|
||||
border-radius: 50px;
|
||||
font-size: 35px;
|
||||
font-weight: 500;
|
||||
color: #E4E4E4;
|
||||
background-color: #393939;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
color: #33E4E4E4;
|
||||
}
|
||||
)");
|
||||
btn.setFixedSize(250, 100);
|
||||
QObject::connect(&btn, &QPushButton::clicked, this, &FrogPilotButtonIconControl::clicked);
|
||||
hlayout->addWidget(&btn);
|
||||
}
|
||||
16
selfdrive/oscarpilot/settings/style.h
Normal file
16
selfdrive/oscarpilot/settings/style.h
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
const button_style = R"(
|
||||
QPushButton {
|
||||
color: grey;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 65px;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:checked {
|
||||
color: white;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
color: #ADADAD;
|
||||
}
|
||||
)";
|
||||
0
selfdrive/oscarpilot/settings_sync.py
Normal file
0
selfdrive/oscarpilot/settings_sync.py
Normal file
0
selfdrive/oscarpilot/stocklong.py
Normal file
0
selfdrive/oscarpilot/stocklong.py
Normal file
0
selfdrive/oscarpilot/weather.cc
Normal file
0
selfdrive/oscarpilot/weather.cc
Normal file
0
selfdrive/oscarpilot/weather.h
Normal file
0
selfdrive/oscarpilot/weather.h
Normal file
Reference in New Issue
Block a user