Stylistic map UIs and MapBox styles
Fancied up the map in the onroad UI and added toggles to use a custom MapBox style when using "Navigate on openpilot", Co-Authored-By: mike8643 <98910897+mike8643@users.noreply.github.com> Co-Authored-By: pencilpusher <83676301+jakethesnake420@users.noreply.github.com> Co-Authored-By: multikyd <72329880+multikyd@users.noreply.github.com>
This commit is contained in:
@@ -313,6 +313,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"MapsSelected", PERSISTENT},
|
||||
{"MapSpeedLimit", PERSISTENT},
|
||||
{"MapSpeedLimitControl", PERSISTENT},
|
||||
{"MapStyle", PERSISTENT},
|
||||
{"MapTargetLatA", PERSISTENT},
|
||||
{"MapTargetVelocities", PERSISTENT},
|
||||
{"Model", PERSISTENT},
|
||||
|
||||
@@ -53,6 +53,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
|
||||
{"DriveStats", "Drive Stats In Home Screen", "Display your device's drive stats in the home screen.", ""},
|
||||
{"FullMap", "Full Sized Map", "Maximize the size of the map in the onroad UI.", ""},
|
||||
{"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'.", ""},
|
||||
|
||||
{"ScreenManagement", "Screen Management", "Manage your screen's brightness, timeout settings, and hide specific onroad UI elements.", "../frogpilot/assets/toggle_icons/icon_light.png"},
|
||||
{"HideUIElements", "Hide UI Elements", "Hide the selected UI elements from the onroad screen.", ""},
|
||||
@@ -172,12 +173,46 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end());
|
||||
}
|
||||
mapStyleButton->setVisible(true);
|
||||
});
|
||||
toggle = qolToggle;
|
||||
} else if (param == "HideSpeed") {
|
||||
std::vector<QString> hideSpeedToggles{"HideSpeedUI"};
|
||||
std::vector<QString> hideSpeedToggleNames{tr("Control Via UI")};
|
||||
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, hideSpeedToggles, hideSpeedToggleNames);
|
||||
} else if (param == "MapStyle") {
|
||||
QMap<int, QString> styleMap = {
|
||||
{0, tr("Stock openpilot")},
|
||||
{1, tr("Mapbox Streets")},
|
||||
{2, tr("Mapbox Outdoors")},
|
||||
{3, tr("Mapbox Light")},
|
||||
{4, tr("Mapbox Dark")},
|
||||
{5, tr("Mapbox Satellite")},
|
||||
{6, tr("Mapbox Satellite Streets")},
|
||||
{7, tr("Mapbox Navigation Day")},
|
||||
{8, tr("Mapbox Navigation Night")},
|
||||
{9, tr("Mapbox Traffic Night")},
|
||||
{10, tr("mike854's (Satellite hybrid)")},
|
||||
};
|
||||
|
||||
QStringList styles = styleMap.values();
|
||||
|
||||
mapStyleButton = new ButtonControl(title, tr("SELECT"), desc);
|
||||
QObject::connect(mapStyleButton, &ButtonControl::clicked, this, [this, styleMap]() {
|
||||
QStringList styles = styleMap.values();
|
||||
QString selection = MultiOptionDialog::getSelection(tr("Select a map style"), styles, "", this);
|
||||
if (!selection.isEmpty()) {
|
||||
int selectedStyle = styleMap.key(selection);
|
||||
params.putInt("MapStyle", selectedStyle);
|
||||
mapStyleButton->setValue(selection);
|
||||
updateToggles();
|
||||
}
|
||||
});
|
||||
|
||||
int currentStyle = params.getInt("MapStyle");
|
||||
mapStyleButton->setValue(styleMap[currentStyle]);
|
||||
|
||||
addItem(mapStyleButton);
|
||||
|
||||
} else if (param == "ScreenManagement") {
|
||||
FrogPilotParamManageControl *screenToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
||||
@@ -307,14 +342,20 @@ void FrogPilotVisualsPanel::updateMetric() {
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::parentToggleClicked() {
|
||||
mapStyleButton->setVisible(false);
|
||||
|
||||
openParentToggle();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::subParentToggleClicked() {
|
||||
mapStyleButton->setVisible(false);
|
||||
|
||||
openSubParentToggle();
|
||||
}
|
||||
|
||||
void FrogPilotVisualsPanel::hideSubToggles() {
|
||||
mapStyleButton->setVisible(false);
|
||||
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
bool subToggles = alertVolumeControlKeys.find(key.c_str()) != alertVolumeControlKeys.end() ||
|
||||
customAlertsKeys.find(key.c_str()) != customAlertsKeys.end() ||
|
||||
|
||||
@@ -28,12 +28,14 @@ private:
|
||||
void updateState(const UIState &s);
|
||||
void updateToggles();
|
||||
|
||||
ButtonControl *mapStyleButton;
|
||||
|
||||
std::set<QString> alertVolumeControlKeys = {"EngageVolume", "DisengageVolume", "RefuseVolume", "PromptVolume", "PromptDistractedVolume", "WarningSoftVolume", "WarningImmediateVolume"};
|
||||
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"};
|
||||
std::set<QString> qolKeys = {"DriveStats", "FullMap", "HideSpeed"};
|
||||
std::set<QString> qolKeys = {"DriveStats", "FullMap", "HideSpeed", "MapStyle"};
|
||||
std::set<QString> screenKeys = {"HideUIElements", "ScreenBrightness", "ScreenBrightnessOnroad", "ScreenRecorder", "ScreenTimeout", "ScreenTimeoutOnroad", "StandbyMode"};
|
||||
|
||||
std::map<std::string, ParamControl*> toggles;
|
||||
|
||||
0
selfdrive/manager/manager.py
Executable file → Normal file
0
selfdrive/manager/manager.py
Executable file → Normal file
@@ -54,17 +54,6 @@ MapWindow::~MapWindow() {
|
||||
|
||||
void MapWindow::initLayers() {
|
||||
// This doesn't work from initializeGL
|
||||
if (!m_map->layerExists("modelPathLayer")) {
|
||||
qDebug() << "Initializing modelPathLayer";
|
||||
QVariantMap modelPath;
|
||||
//modelPath["id"] = "modelPathLayer";
|
||||
modelPath["type"] = "line";
|
||||
modelPath["source"] = "modelPathSource";
|
||||
m_map->addLayer("modelPathLayer", modelPath);
|
||||
m_map->setPaintProperty("modelPathLayer", "line-color", QColor("red"));
|
||||
m_map->setPaintProperty("modelPathLayer", "line-width", 5.0);
|
||||
m_map->setLayoutProperty("modelPathLayer", "line-cap", "round");
|
||||
}
|
||||
if (!m_map->layerExists("navLayer")) {
|
||||
qDebug() << "Initializing navLayer";
|
||||
QVariantMap nav;
|
||||
@@ -79,6 +68,17 @@ void MapWindow::initLayers() {
|
||||
m_map->setPaintProperty("navLayer", "line-width", 7.5);
|
||||
m_map->setLayoutProperty("navLayer", "line-cap", "round");
|
||||
}
|
||||
if (!m_map->layerExists("modelPathLayer")) {
|
||||
qDebug() << "Initializing modelPathLayer";
|
||||
QVariantMap modelPath;
|
||||
//modelPath["id"] = "modelPathLayer";
|
||||
modelPath["type"] = "line";
|
||||
modelPath["source"] = "modelPathSource";
|
||||
m_map->addLayer("modelPathLayer", modelPath);
|
||||
m_map->setPaintProperty("modelPathLayer", "line-color", QColor("red"));
|
||||
m_map->setPaintProperty("modelPathLayer", "line-width", 5.0);
|
||||
m_map->setLayoutProperty("modelPathLayer", "line-cap", "round");
|
||||
}
|
||||
if (!m_map->layerExists("pinLayer")) {
|
||||
qDebug() << "Initializing pinLayer";
|
||||
m_map->addImage("default_marker", QImage("../assets/navigation/default_marker.svg"));
|
||||
@@ -109,6 +109,50 @@ void MapWindow::initLayers() {
|
||||
// TODO: remove, symbol-sort-key does not seem to matter outside of each layer
|
||||
m_map->setLayoutProperty("carPosLayer", "symbol-sort-key", 0);
|
||||
}
|
||||
|
||||
if (!m_map->layerExists("buildingsLayer")) {
|
||||
qDebug() << "Initializing buildingsLayer";
|
||||
QVariantMap buildings;
|
||||
buildings["id"] = "buildingsLayer";
|
||||
buildings["source"] = "composite";
|
||||
buildings["source-layer"] = "building";
|
||||
buildings["type"] = "fill-extrusion";
|
||||
buildings["minzoom"] = 15;
|
||||
m_map->addLayer("buildingsLayer", buildings);
|
||||
m_map->setFilter("buildingsLayer", QVariantList({"==", "extrude", "true"}));
|
||||
|
||||
QVariantList fillExtrusionHight = {
|
||||
"interpolate",
|
||||
QVariantList{"linear"},
|
||||
QVariantList{"zoom"},
|
||||
15, 0,
|
||||
15.05, QVariantList{"get", "height"}
|
||||
};
|
||||
|
||||
QVariantList fillExtrusionBase = {
|
||||
"interpolate",
|
||||
QVariantList{"linear"},
|
||||
QVariantList{"zoom"},
|
||||
15, 0,
|
||||
15.05, QVariantList{"get", "min_height"}
|
||||
};
|
||||
|
||||
QVariantList fillExtrusionOpacity = {
|
||||
"interpolate",
|
||||
QVariantList{"linear"},
|
||||
QVariantList{"zoom"},
|
||||
15, 0,
|
||||
15.5, .6,
|
||||
17, .6,
|
||||
20, 0
|
||||
};
|
||||
|
||||
m_map->setPaintProperty("buildingsLayer", "fill-extrusion-color", QColor("grey"));
|
||||
m_map->setPaintProperty("buildingsLayer", "fill-extrusion-opacity", fillExtrusionOpacity);
|
||||
m_map->setPaintProperty("buildingsLayer", "fill-extrusion-height", fillExtrusionHight);
|
||||
m_map->setPaintProperty("buildingsLayer", "fill-extrusion-base", fillExtrusionBase);
|
||||
m_map->setLayoutProperty("buildingsLayer", "visibility", "visible");
|
||||
}
|
||||
}
|
||||
|
||||
void MapWindow::updateState(const UIState &s) {
|
||||
@@ -151,6 +195,17 @@ void MapWindow::updateState(const UIState &s) {
|
||||
velocity_filter.update(std::max(10.0, locationd_velocity.getValue()[0]));
|
||||
}
|
||||
}
|
||||
// Credit to jakethesnake420
|
||||
if (loaded_once && (sm.rcv_frame("uiPlan") != model_rcv_frame)) {
|
||||
auto locationd_location = sm["liveLocationKalman"].getLiveLocationKalman();
|
||||
auto model_path = model_to_collection(locationd_location.getCalibratedOrientationECEF(), locationd_location.getPositionECEF(), sm["uiPlan"].getUiPlan().getPosition());
|
||||
QMapLibre::Feature model_path_feature(QMapLibre::Feature::LineStringType, model_path, {}, {});
|
||||
QVariantMap modelV2Path;
|
||||
modelV2Path["type"] = "geojson";
|
||||
modelV2Path["data"] = QVariant::fromValue<QMapLibre::Feature>(model_path_feature);
|
||||
m_map->updateSource("modelPathSource", modelV2Path);
|
||||
model_rcv_frame = sm.rcv_frame("uiPlan");
|
||||
}
|
||||
|
||||
if (sm.updated("navRoute") && sm["navRoute"].getNavRoute().getCoordinates().size()) {
|
||||
auto nav_dest = coordinate_from_param("NavDestination");
|
||||
@@ -237,6 +292,30 @@ void MapWindow::updateState(const UIState &s) {
|
||||
route_rcv_frame = sm.rcv_frame("navRoute");
|
||||
updateDestinationMarker();
|
||||
}
|
||||
|
||||
// Map Styling - Credit goes to OPKR!
|
||||
int map_style = uiState()->scene.map_style;
|
||||
|
||||
if (map_style != previous_map_style) {
|
||||
std::unordered_map<int, std::string> styleUrls = {
|
||||
{0, "mapbox://styles/commaai/clkqztk0f00ou01qyhsa5bzpj"}, // Stock openpilot
|
||||
{1, "mapbox://styles/mapbox/streets-v11"}, // Mapbox Streets
|
||||
{2, "mapbox://styles/mapbox/outdoors-v11"}, // Mapbox Outdoors
|
||||
{3, "mapbox://styles/mapbox/light-v10"}, // Mapbox Light
|
||||
{4, "mapbox://styles/mapbox/dark-v10"}, // Mapbox Dark
|
||||
{5, "mapbox://styles/mapbox/satellite-v9"}, // Mapbox Satellite
|
||||
{6, "mapbox://styles/mapbox/satellite-streets-v11"}, // Mapbox Satellite Streets
|
||||
{7, "mapbox://styles/mapbox/navigation-day-v1"}, // Mapbox Navigation Day
|
||||
{8, "mapbox://styles/mapbox/navigation-night-v1"}, // Mapbox Navigation Night
|
||||
{9, "mapbox://styles/mapbox/traffic-night-v2"}, // Mapbox Traffic Night
|
||||
{10, "mapbox://styles/mike854/clt0hm8mw01ok01p4blkr27jp"}, // mike854's (Satellite hybrid)
|
||||
};
|
||||
|
||||
std::unordered_map<int, std::string>::iterator it = styleUrls.find(map_style);
|
||||
m_map->setStyleUrl(QString::fromStdString(it->second));
|
||||
}
|
||||
|
||||
previous_map_style = map_style;
|
||||
}
|
||||
|
||||
void MapWindow::setError(const QString &err_str) {
|
||||
|
||||
@@ -77,10 +77,13 @@ private:
|
||||
void clearRoute();
|
||||
void updateDestinationMarker();
|
||||
uint64_t route_rcv_frame = 0;
|
||||
uint64_t model_rcv_frame = 0;
|
||||
|
||||
// FrogPilot variables
|
||||
Params params;
|
||||
|
||||
int previous_map_style;
|
||||
|
||||
private slots:
|
||||
void updateState(const UIState &s);
|
||||
|
||||
|
||||
@@ -368,6 +368,7 @@ void ui_update_frogpilot_params(UIState *s) {
|
||||
scene.full_map = quality_of_life_visuals && params.getBool("FullMap");
|
||||
scene.hide_speed = quality_of_life_visuals && params.getBool("HideSpeed");
|
||||
scene.hide_speed_ui = scene.hide_speed && params.getBool("HideSpeedUI");
|
||||
scene.map_style = quality_of_life_visuals ? params.getInt("MapStyle") : 0;
|
||||
|
||||
scene.rotating_wheel = params.getBool("RotatingWheel");
|
||||
|
||||
|
||||
@@ -255,6 +255,7 @@ typedef struct UIScene {
|
||||
int custom_icons;
|
||||
int custom_signals;
|
||||
int desired_follow;
|
||||
int map_style;
|
||||
int obstacle_distance;
|
||||
int obstacle_distance_stock;
|
||||
int screen_brightness;
|
||||
|
||||
Reference in New Issue
Block a user