mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-28 01:52:06 +08:00
Vehicle fingerprint selection
This commit is contained in:
@@ -1,5 +1,95 @@
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "frogpilot/ui/qt/offroad/vehicle_settings.h"
|
||||
|
||||
QStringList getCarNames(const QString &carMake, QMap<QString, QString> &carModels) {
|
||||
static const QHash<QString, QString> makeToFolder = {
|
||||
{"acura", "honda"},
|
||||
{"audi", "volkswagen"},
|
||||
{"buick", "gm"},
|
||||
{"cadillac", "gm"},
|
||||
{"chevrolet", "gm"},
|
||||
{"chrysler", "chrysler"},
|
||||
{"cupra", "volkswagen"},
|
||||
{"dodge", "chrysler"},
|
||||
{"ford", "ford"},
|
||||
{"genesis", "hyundai"},
|
||||
{"gmc", "gm"},
|
||||
{"holden", "gm"},
|
||||
{"honda", "honda"},
|
||||
{"hyundai", "hyundai"},
|
||||
{"jeep", "chrysler"},
|
||||
{"kia", "hyundai"},
|
||||
{"lexus", "toyota"},
|
||||
{"lincoln", "ford"},
|
||||
{"man", "volkswagen"},
|
||||
{"mazda", "mazda"},
|
||||
{"nissan", "nissan"},
|
||||
{"peugeot", "psa"},
|
||||
{"ram", "chrysler"},
|
||||
{"rivian", "rivian"},
|
||||
{"seat", "volkswagen"},
|
||||
{"škoda", "volkswagen"},
|
||||
{"subaru", "subaru"},
|
||||
{"tesla", "tesla"},
|
||||
{"toyota", "toyota"},
|
||||
{"volkswagen", "volkswagen"}
|
||||
};
|
||||
|
||||
QStringList carNames;
|
||||
|
||||
const QString folder = makeToFolder.value(carMake.toLower());
|
||||
if (folder.isEmpty()) {
|
||||
return carNames;
|
||||
}
|
||||
|
||||
QFile file(QString("../../opendbc/car/%1/values.py").arg(folder));
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return carNames;
|
||||
}
|
||||
|
||||
QString content = file.readAll();
|
||||
file.close();
|
||||
|
||||
static const QRegularExpression commentRe("#[^\\n]*");
|
||||
static const QRegularExpression footnoteRe("footnotes=\\[[^\\]]*\\],\\s*");
|
||||
content.remove(commentRe).remove(footnoteRe);
|
||||
|
||||
static const QRegularExpression platformRe("(\\w+)\\s*=\\s*\\w+\\s*\\(");
|
||||
QRegularExpressionMatchIterator platformIt = platformRe.globalMatch(content);
|
||||
|
||||
QVector<QPair<int, QString>> platforms;
|
||||
while (platformIt.hasNext()) {
|
||||
QRegularExpressionMatch match = platformIt.next();
|
||||
platforms.append({match.capturedStart(), match.captured(1)});
|
||||
}
|
||||
platforms.append({content.length(), QString()});
|
||||
|
||||
static const QRegularExpression carNameRe("CarDocs\\w*\\s*\\(\\s*\"([^\"]+)\"");
|
||||
const QString lowerMake = carMake.toLower();
|
||||
|
||||
for (int i = 0; i < platforms.size() - 1; ++i) {
|
||||
int start = platforms[i].first;
|
||||
int end = platforms[i + 1].first;
|
||||
const QString &platformName = platforms[i].second;
|
||||
|
||||
QRegularExpressionMatchIterator carIt = carNameRe.globalMatch(
|
||||
content.mid(start, end - start)
|
||||
);
|
||||
|
||||
while (carIt.hasNext()) {
|
||||
QString carName = carIt.next().captured(1);
|
||||
if (carName.startsWith(carMake, Qt::CaseInsensitive)) {
|
||||
carModels[carName] = platformName;
|
||||
carNames.append(carName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
carNames.sort(Qt::CaseInsensitive);
|
||||
return carNames;
|
||||
}
|
||||
|
||||
FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent, bool forceOpen) : FrogPilotListWidget(parent), parent(parent) {
|
||||
forceOpenDescriptions = forceOpen;
|
||||
|
||||
@@ -12,6 +102,37 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent,
|
||||
|
||||
vehiclesLayout->addWidget(vehiclesPanel);
|
||||
|
||||
QStringList makes = {
|
||||
"Acura", "Audi", "Buick", "Cadillac", "Chevrolet", "Chrysler", "CUPRA",
|
||||
"Dodge", "Ford", "Genesis", "GMC", "Holden", "Honda", "Hyundai", "Jeep",
|
||||
"Kia", "Lexus", "Lincoln", "MAN", "Mazda", "Nissan", "Peugeot", "Ram",
|
||||
"Rivian", "SEAT", "Škoda", "Subaru", "Tesla", "Toyota", "Volkswagen"
|
||||
};
|
||||
|
||||
ButtonControl *selectMakeButton = new ButtonControl(tr("Car Make"), tr("SELECT"));
|
||||
QObject::connect(selectMakeButton, &ButtonControl::clicked, [makes, selectMakeButton, this]() {
|
||||
QString makeSelection = MultiOptionDialog::getSelection(tr("Choose your car make"), makes, "", this);
|
||||
if (!makeSelection.isEmpty()) {
|
||||
params.put("CarMake", makeSelection.toStdString());
|
||||
selectMakeButton->setValue(makeSelection);
|
||||
}
|
||||
});
|
||||
settingsList->addItem(selectMakeButton);
|
||||
|
||||
ButtonControl *selectModelButton = new ButtonControl(tr("Car Model"), tr("SELECT"));
|
||||
QObject::connect(selectModelButton, &ButtonControl::clicked, [selectModelButton, this]() {
|
||||
QString modelSelection = MultiOptionDialog::getSelection(tr("Choose your car model"), getCarNames(QString::fromStdString(params.get("CarMake")).toLower(), carModels), "", this);
|
||||
if (!modelSelection.isEmpty()) {
|
||||
params.put("CarModel", carModels.value(modelSelection).toStdString());
|
||||
params.put("CarModelName", modelSelection.toStdString());
|
||||
selectModelButton->setValue(modelSelection);
|
||||
}
|
||||
});
|
||||
settingsList->addItem(selectModelButton);
|
||||
|
||||
forceFingerprint = new ParamControl("ForceFingerprint", tr("Disable Automatic Fingerprint Detection"), tr("<b>Force the selected fingerprint</b> and prevent it from ever changing."), "");
|
||||
settingsList->addItem(forceFingerprint);
|
||||
|
||||
disableOpenpilotLong = new ParamControl("DisableOpenpilotLongitudinal", tr("Disable openpilot Longitudinal Control"), tr("<b>Disable openpilot longitudinal</b> and use the car's stock ACC instead."), "");
|
||||
QObject::connect(disableOpenpilotLong, &ToggleControl::toggleFlipped, [parent, this](bool state) {
|
||||
if (state) {
|
||||
@@ -195,10 +316,18 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent,
|
||||
|
||||
openDescriptions(forceOpenDescriptions, toggles);
|
||||
|
||||
QObject::connect(uiState(), &UIState::offroadTransition, [selectMakeButton, selectModelButton, this]() {
|
||||
std::thread([selectMakeButton, selectModelButton, this]() {
|
||||
selectMakeButton->setValue(QString::fromStdString(params.get("CarMake", true)));
|
||||
selectModelButton->setValue(QString::fromStdString(params.get(params.get("CarModelName").empty() ? "CarModel" : "CarModelName", true)));
|
||||
}).detach();
|
||||
});
|
||||
|
||||
QObject::connect(parent, &FrogPilotSettingsWindow::closeSubPanel, [vehiclesLayout, vehiclesPanel, this] {
|
||||
if (forceOpenDescriptions) {
|
||||
openDescriptions(forceOpenDescriptions, toggles);
|
||||
disableOpenpilotLong->showDescription();
|
||||
forceFingerprint->showDescription();
|
||||
}
|
||||
vehiclesLayout->setCurrentWidget(vehiclesPanel);
|
||||
});
|
||||
@@ -208,6 +337,7 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent,
|
||||
void FrogPilotVehiclesPanel::showEvent(QShowEvent *event) {
|
||||
if (forceOpenDescriptions) {
|
||||
disableOpenpilotLong->showDescription();
|
||||
forceFingerprint->showDescription();
|
||||
}
|
||||
|
||||
QStringList detected;
|
||||
@@ -298,6 +428,7 @@ void FrogPilotVehiclesPanel::updateToggles() {
|
||||
}
|
||||
|
||||
disableOpenpilotLong->setVisible((parent->hasOpenpilotLongitudinal || parent->openpilotLongitudinalControlDisabled) && !parent->hasAlphaLongitudinal && parent->tuningLevel >= parent->frogpilotToggleLevels["DisableOpenpilotLongitudinal"].toBool());
|
||||
forceFingerprint->setVisible(parent->tuningLevel >= parent->frogpilotToggleLevels["ForceFingerprint"].toBool());
|
||||
|
||||
openDescriptions(forceOpenDescriptions, toggles);
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ private:
|
||||
FrogPilotSettingsWindow *parent;
|
||||
|
||||
ParamControl *disableOpenpilotLong;
|
||||
ParamControl *forceFingerprint;
|
||||
|
||||
Params params;
|
||||
|
||||
QMap<QString, QString> carModels;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ from opendbc.car.mock.values import CAR as MOCK
|
||||
from opendbc.car.toyota.values import ToyotaFrogPilotFlags
|
||||
from opendbc.car.values import BRANDS
|
||||
from opendbc.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN
|
||||
from openpilot.common.params import Params
|
||||
|
||||
FRAME_FINGERPRINT = 100 # 1s
|
||||
|
||||
@@ -156,12 +157,18 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu
|
||||
|
||||
|
||||
def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, alpha_long_allowed: bool,
|
||||
is_release: bool, num_pandas: int = 1, cached_params: CarParamsT | None = None, frogpilot_toggles: SimpleNamespace = None):
|
||||
is_release: bool, params: Params, num_pandas: int = 1, cached_params: CarParamsT | None = None, frogpilot_toggles: SimpleNamespace = None):
|
||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params)
|
||||
|
||||
if candidate is None:
|
||||
carlog.error({"event": "car doesn't match any fingerprints", "fingerprints": repr(fingerprints)})
|
||||
candidate = "MOCK"
|
||||
if candidate is None or frogpilot_toggles.force_fingerprint:
|
||||
if frogpilot_toggles.force_fingerprint:
|
||||
candidate = frogpilot_toggles.car_model
|
||||
else:
|
||||
carlog.error({"event": "car doesn't match any fingerprints", "fingerprints": repr(fingerprints)})
|
||||
candidate = "MOCK"
|
||||
else:
|
||||
params.put_nonblocking("CarMake", candidate.split('_')[0].title())
|
||||
params.put_nonblocking("CarModel", str(candidate))
|
||||
|
||||
if frogpilot_toggles.block_user:
|
||||
candidate = "MOCK"
|
||||
|
||||
@@ -106,7 +106,7 @@ class Car:
|
||||
with car.CarParams.from_bytes(cached_params_raw) as _cached_params:
|
||||
cached_params = _cached_params
|
||||
|
||||
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), alpha_long_allowed, is_release, num_pandas, cached_params, get_frogpilot_toggles())
|
||||
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), alpha_long_allowed, is_release, self.params, num_pandas, cached_params, get_frogpilot_toggles())
|
||||
self.RI = interfaces[self.CI.CP.carFingerprint].RadarInterface(self.CI.CP)
|
||||
self.CP = self.CI.CP
|
||||
|
||||
|
||||
Reference in New Issue
Block a user