From 4045564927198b700f2e947fad10e73d92f7d1ef Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:34:47 -0700 Subject: [PATCH] Force fingerprint function Added function to automatically detect the vehicle's fingerprint if it exists, or an option to force the vehicle's fingerprint if it doesn't. --- common/params.cc | 3 + selfdrive/car/car_helpers.py | 16 ++- selfdrive/frogpilot/ui/vehicle_settings.cc | 128 ++++++++++++++++++++- selfdrive/frogpilot/ui/vehicle_settings.h | 7 ++ 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/common/params.cc b/common/params.cc index 1c972be..07068d8 100644 --- a/common/params.cc +++ b/common/params.cc @@ -222,6 +222,8 @@ std::unordered_map keys = { {"ApiCache_DriveStats", PERSISTENT}, {"BlindSpotPath", PERSISTENT}, {"CameraView", PERSISTENT}, + {"CarMake", PERSISTENT}, + {"CarModel", PERSISTENT}, {"CECurves", PERSISTENT}, {"CECurvesLead", PERSISTENT}, {"CENavigation", PERSISTENT}, @@ -261,6 +263,7 @@ std::unordered_map keys = { {"ExperimentalModeViaScreen", PERSISTENT}, {"FireTheBabysitter", PERSISTENT}, {"ForceAutoTune", PERSISTENT}, + {"ForceFingerprint", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT}, {"FrogsGoMoo", PERSISTENT}, {"GoatScream", PERSISTENT}, diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index de3d870..1247853 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -194,13 +194,23 @@ def fingerprint(logcan, sendcan, num_pandas): def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1): params = Params() + car_brand = params.get("CarMake", encoding='utf-8') + car_model = params.get("CarModel", encoding='utf-8') dongle_id = params.get("DongleId", encoding='utf-8') + force_fingerprint = params.get_bool("ForceFingerprint") + candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas) - if candidate is None: - cloudlog.event("car doesn't match any fingerprints", fingerprints=repr(fingerprints), error=True) - candidate = "mock" + if candidate is None or force_fingerprint: + if car_model is not None: + candidate = car_model + else: + cloudlog.event("car doesn't match any fingerprints", fingerprints=repr(fingerprints), error=True) + candidate = "mock" + elif car_model is None: + params.put("CarMake", candidate.split(' ')[0].title()) + params.put("CarModel", candidate) if get_short_branch() == "FrogPilot-Development" and not Params("/persist/comma/params").get_bool("FrogsGoMoo"): candidate = "mock" diff --git a/selfdrive/frogpilot/ui/vehicle_settings.cc b/selfdrive/frogpilot/ui/vehicle_settings.cc index 3369c24..8143807 100644 --- a/selfdrive/frogpilot/ui/vehicle_settings.cc +++ b/selfdrive/frogpilot/ui/vehicle_settings.cc @@ -1,6 +1,103 @@ +#include +#include +#include + #include "selfdrive/frogpilot/ui/vehicle_settings.h" +QStringList getCarNames(const QString &carMake) { + QMap makeMap; + makeMap["acura"] = "honda"; + makeMap["audi"] = "volkswagen"; + makeMap["buick"] = "gm"; + makeMap["cadillac"] = "gm"; + makeMap["chevrolet"] = "gm"; + makeMap["chrysler"] = "chrysler"; + makeMap["dodge"] = "chrysler"; + makeMap["ford"] = "ford"; + makeMap["gm"] = "gm"; + makeMap["gmc"] = "gm"; + makeMap["genesis"] = "hyundai"; + makeMap["honda"] = "honda"; + makeMap["hyundai"] = "hyundai"; + makeMap["infiniti"] = "nissan"; + makeMap["jeep"] = "chrysler"; + makeMap["kia"] = "hyundai"; + makeMap["lexus"] = "toyota"; + makeMap["lincoln"] = "ford"; + makeMap["man"] = "volkswagen"; + makeMap["mazda"] = "mazda"; + makeMap["nissan"] = "nissan"; + makeMap["ram"] = "chrysler"; + makeMap["seat"] = "volkswagen"; + makeMap["subaru"] = "subaru"; + makeMap["tesla"] = "tesla"; + makeMap["toyota"] = "toyota"; + makeMap["volkswagen"] = "volkswagen"; + makeMap["skoda"] = "volkswagen"; + + QString dirPath = "../../selfdrive/car"; + QDir dir(dirPath); + QString targetFolder = makeMap.value(carMake, carMake); + QStringList names; + + foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + if (folder == targetFolder) { + QFile file(dirPath + "/" + folder + "/values.py"); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QRegularExpression regex("class CAR\\(StrEnum\\):([\\s\\S]*?)(?=^\\w)", QRegularExpression::MultilineOption); + QRegularExpressionMatch match = regex.match(QTextStream(&file).readAll()); + file.close(); + + if (match.hasMatch()) { + QRegularExpression nameRegex("=\\s*\"([^\"]+)\""); + QRegularExpressionMatchIterator it = nameRegex.globalMatch(match.captured(1)); + while (it.hasNext()) { + names << it.next().captured(1); + } + } + } + } + } + + std::sort(names.begin(), names.end()); + return names; +} + FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + selectMakeButton = new ButtonControl(tr("Select Make"), tr("SELECT")); + QObject::connect(selectMakeButton, &ButtonControl::clicked, [this]() { + QStringList makes = { + "Acura", "Audi", "BMW", "Buick", "Cadillac", "Chevrolet", "Chrysler", "Dodge", "Ford", "GM", "GMC", + "Genesis", "Honda", "Hyundai", "Infiniti", "Jeep", "Kia", "Lexus", "Lincoln", "MAN", "Mazda", + "Mercedes", "Nissan", "Ram", "SEAT", "Subaru", "Tesla", "Toyota", "Volkswagen", "Volvo", "Škoda", + }; + + QString newMakeSelection = MultiOptionDialog::getSelection(tr("Select a Make"), makes, "", this); + if (!newMakeSelection.isEmpty()) { + carMake = newMakeSelection; + params.putNonBlocking("CarMake", carMake.toStdString()); + selectMakeButton->setValue(newMakeSelection); + setModels(); + } + }); + addItem(selectMakeButton); + + selectModelButton = new ButtonControl(tr("Select Model"), tr("SELECT")); + QString modelSelection = QString::fromStdString(params.get("CarModel")); + QObject::connect(selectModelButton, &ButtonControl::clicked, [this]() { + QString newModelSelection = MultiOptionDialog::getSelection(tr("Select a Model"), models, "", this); + if (!newModelSelection.isEmpty()) { + params.putNonBlocking("CarModel", newModelSelection.toStdString()); + selectModelButton->setValue(newModelSelection); + } + }); + selectModelButton->setValue(modelSelection); + addItem(selectModelButton); + selectModelButton->setVisible(false); + + ParamControl *forceFingerprint = new ParamControl("ForceFingerprint", "Disable Automatic Fingerprint Detection", "Forces the selected fingerprint and prevents it from ever changing.", "", this); + addItem(forceFingerprint); + ParamControl *disableOpenpilotLong = new ParamControl("DisableOpenpilotLongitudinal", "Disable Openpilot Longitudinal Control", "Disables openpilot longitudinal control to use stock ACC.", "", this); addItem(disableOpenpilotLong); @@ -63,7 +160,24 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(SettingsWindow *parent) : FrogPil }); } + QObject::connect(uiState(), &UIState::offroadTransition, this, [this](bool offroad) { + if (!offroad) { + std::thread([this]() { + while (carMake.isEmpty()) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + carMake = QString::fromStdString(params.get("CarMake")); + } + setModels(); + }).detach(); + } + }); + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVehiclesPanel::updateState); + + carMake = QString::fromStdString(params.get("CarMake")); + if (!carMake.isEmpty()) { + setModels(); + } } void FrogPilotVehiclesPanel::updateState(const UIState &s) { @@ -78,10 +192,18 @@ void FrogPilotVehiclesPanel::updateToggles() { }).detach(); } +void FrogPilotVehiclesPanel::setModels() { + models = getCarNames(carMake.toLower()); + setToggles(); +} + void FrogPilotVehiclesPanel::setToggles() { - bool gm = false; - bool subaru false; - bool toyota = false; + selectMakeButton->setValue(carMake); + selectModelButton->setVisible(!carMake.isEmpty()); + + bool gm = carMake == "Buick" || carMake == "Cadillac" || carMake == "Chevrolet" || carMake == "GM" || carMake == "GMC"; + bool subaru = carMake == "Subaru"; + bool toyota = carMake == "Lexus" || carMake == "Toyota"; for (auto &[key, toggle] : toggles) { if (toggle) { diff --git a/selfdrive/frogpilot/ui/vehicle_settings.h b/selfdrive/frogpilot/ui/vehicle_settings.h index e8bc788..46282f8 100644 --- a/selfdrive/frogpilot/ui/vehicle_settings.h +++ b/selfdrive/frogpilot/ui/vehicle_settings.h @@ -15,10 +15,17 @@ public: explicit FrogPilotVehiclesPanel(SettingsWindow *parent); private: + void setModels(); void setToggles(); void updateState(const UIState &s); void updateToggles(); + ButtonControl *selectMakeButton; + ButtonControl *selectModelButton; + + QString carMake; + QStringList models; + std::map toggles; std::set gmKeys = {};