Model switcher
Added model selector to swap between several different models on the fly.
This commit is contained in:
@@ -263,6 +263,8 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"LongPitch", PERSISTENT},
|
{"LongPitch", PERSISTENT},
|
||||||
{"LowerVolt", PERSISTENT},
|
{"LowerVolt", PERSISTENT},
|
||||||
{"MapTargetVelocities", PERSISTENT},
|
{"MapTargetVelocities", PERSISTENT},
|
||||||
|
{"Model", PERSISTENT},
|
||||||
|
{"ModelList", PERSISTENT},
|
||||||
{"ModelUI", PERSISTENT},
|
{"ModelUI", PERSISTENT},
|
||||||
{"MTSCAggressiveness", PERSISTENT},
|
{"MTSCAggressiveness", PERSISTENT},
|
||||||
{"MTSCEnabled", PERSISTENT},
|
{"MTSCEnabled", PERSISTENT},
|
||||||
|
|||||||
@@ -560,3 +560,4 @@ tinygrad_repo/tinygrad/*.py
|
|||||||
selfdrive/frogpilot/functions/conditional_experimental_mode.py
|
selfdrive/frogpilot/functions/conditional_experimental_mode.py
|
||||||
selfdrive/frogpilot/functions/frogpilot_planner.py
|
selfdrive/frogpilot/functions/frogpilot_planner.py
|
||||||
selfdrive/frogpilot/functions/map_turn_speed_controller.py
|
selfdrive/frogpilot/functions/map_turn_speed_controller.py
|
||||||
|
selfdrive/frogpilot/functions/model_switcher.py
|
||||||
|
|||||||
63
selfdrive/frogpilot/functions/model_switcher.py
Normal file
63
selfdrive/frogpilot/functions/model_switcher.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from openpilot.common.params import Params
|
||||||
|
from openpilot.system.hardware import HARDWARE
|
||||||
|
|
||||||
|
OPENPILOT_PATH = "/data/openpilot"
|
||||||
|
DESTINATION_PATH = os.path.join(OPENPILOT_PATH, "selfdrive/modeld/models")
|
||||||
|
MODELS_SOURCE = os.path.join(DESTINATION_PATH, "models")
|
||||||
|
THNEED_FILE = os.path.join(DESTINATION_PATH, "supercombo.thneed")
|
||||||
|
|
||||||
|
MODEL_NAME = {
|
||||||
|
0: "new-delhi",
|
||||||
|
1: "blue-diamond-v1",
|
||||||
|
2: "blue-diamond-v2",
|
||||||
|
3: "farmville",
|
||||||
|
4: "new-lemon-pie",
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_model_list_parameter(params):
|
||||||
|
"""Create a string of all the model names for future comparisons."""
|
||||||
|
# Retrieve the previous model list
|
||||||
|
previous_model_list = params.get("ModelList", encoding='utf-8')
|
||||||
|
|
||||||
|
# Create a new model list
|
||||||
|
model_list = "".join(MODEL_NAME.values())
|
||||||
|
|
||||||
|
if previous_model_list != model_list:
|
||||||
|
# Reset the selected model if the model list changed
|
||||||
|
params.put_int("Model", 0)
|
||||||
|
params.put("ModelList", model_list)
|
||||||
|
params.remove("CalibrationParams");
|
||||||
|
params.remove("LiveTorqueParameters");
|
||||||
|
|
||||||
|
def onnx_already_set(path1, path2):
|
||||||
|
"""Check if the two files are identical by comparing their SHA-256 hashes."""
|
||||||
|
with open(path1, 'rb') as f1, open(path2, 'rb') as f2:
|
||||||
|
return hashlib.sha256(f1.read()).hexdigest() == hashlib.sha256(f2.read()).hexdigest()
|
||||||
|
|
||||||
|
def copy_model_variant(params):
|
||||||
|
# Get the corresponding supercombo variant name
|
||||||
|
variant = MODEL_NAME.get(params.get_int("Model"), MODEL_NAME[0])
|
||||||
|
|
||||||
|
# Copy the variant .onnx file to supercombo.onnx in the destination models folder
|
||||||
|
onnx_path = os.path.join(MODELS_SOURCE, f"{variant}.onnx")
|
||||||
|
destination = os.path.join(DESTINATION_PATH, "supercombo.onnx")
|
||||||
|
|
||||||
|
if not onnx_already_set(onnx_path, destination):
|
||||||
|
# Delete the thneed file
|
||||||
|
if os.path.exists(THNEED_FILE):
|
||||||
|
os.remove(THNEED_FILE)
|
||||||
|
|
||||||
|
# Copy over the onnx file
|
||||||
|
shutil.copy(onnx_path, destination)
|
||||||
|
|
||||||
|
# Reboot
|
||||||
|
HARDWARE.reboot()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
params = Params()
|
||||||
|
|
||||||
|
set_model_list_parameter(params)
|
||||||
|
copy_model_variant(params)
|
||||||
@@ -31,6 +31,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
|||||||
{"AggressiveAcceleration", "Aggressive Acceleration With Lead", "Increase acceleration aggressiveness when following a lead vehicle from a stop.", ""},
|
{"AggressiveAcceleration", "Aggressive Acceleration With Lead", "Increase acceleration aggressiveness when following a lead vehicle from a stop.", ""},
|
||||||
{"StoppingDistance", "Increased Stopping Distance", "Increase the stopping distance for a more comfortable stop.", ""},
|
{"StoppingDistance", "Increased Stopping Distance", "Increase the stopping distance for a more comfortable stop.", ""},
|
||||||
|
|
||||||
|
{"Model", "Model Selector", "Choose your preferred openpilot model.", "../assets/offroad/icon_calibration.png"},
|
||||||
{"MTSCEnabled", "Map Turn Speed Control", "Slow down for anticipated curves detected by your downloaded maps.", "../frogpilot/assets/toggle_icons/icon_speed_map.png"},
|
{"MTSCEnabled", "Map Turn Speed Control", "Slow down for anticipated curves detected by your downloaded maps.", "../frogpilot/assets/toggle_icons/icon_speed_map.png"},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,6 +177,28 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
|
|||||||
} else if (param == "StoppingDistance") {
|
} else if (param == "StoppingDistance") {
|
||||||
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, std::map<int, QString>(), this, false, " feet");
|
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, std::map<int, QString>(), this, false, " feet");
|
||||||
|
|
||||||
|
} else if (param == "Model") {
|
||||||
|
modelSelectorButton = new FrogPilotButtonIconControl(title, tr("SELECT"), desc, icon);
|
||||||
|
QStringList models = {"New Delhi (Default)", "Blue Diamond V1", "Blue Diamond V2", "Farmville", "New Lemon Pie"};
|
||||||
|
QObject::connect(modelSelectorButton, &FrogPilotButtonIconControl::clicked, this, [this, models]() {
|
||||||
|
int currentModel = params.getInt("Model");
|
||||||
|
QString currentModelLabel = models[currentModel];
|
||||||
|
|
||||||
|
QString selection = MultiOptionDialog::getSelection(tr("Select a driving model"), models, currentModelLabel, this);
|
||||||
|
if (!selection.isEmpty()) {
|
||||||
|
int selectedModel = models.indexOf(selection);
|
||||||
|
params.putInt("Model", selectedModel);
|
||||||
|
params.remove("CalibrationParams");
|
||||||
|
params.remove("LiveTorqueParameters");
|
||||||
|
modelSelectorButton->setValue(selection);
|
||||||
|
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||||
|
Hardware::reboot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
modelSelectorButton->setValue(models[params.getInt("Model")]);
|
||||||
|
addItem(modelSelectorButton);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
toggle = new ParamControl(param, title, desc, icon, this);
|
toggle = new ParamControl(param, title, desc, icon, this);
|
||||||
}
|
}
|
||||||
@@ -262,6 +285,7 @@ void FrogPilotControlsPanel::parentToggleClicked() {
|
|||||||
aggressiveProfile->setVisible(false);
|
aggressiveProfile->setVisible(false);
|
||||||
conditionalSpeedsImperial->setVisible(false);
|
conditionalSpeedsImperial->setVisible(false);
|
||||||
conditionalSpeedsMetric->setVisible(false);
|
conditionalSpeedsMetric->setVisible(false);
|
||||||
|
modelSelectorButton->setVisible(false);
|
||||||
standardProfile->setVisible(false);
|
standardProfile->setVisible(false);
|
||||||
relaxedProfile->setVisible(false);
|
relaxedProfile->setVisible(false);
|
||||||
|
|
||||||
@@ -272,6 +296,7 @@ void FrogPilotControlsPanel::hideSubToggles() {
|
|||||||
aggressiveProfile->setVisible(false);
|
aggressiveProfile->setVisible(false);
|
||||||
conditionalSpeedsImperial->setVisible(false);
|
conditionalSpeedsImperial->setVisible(false);
|
||||||
conditionalSpeedsMetric->setVisible(false);
|
conditionalSpeedsMetric->setVisible(false);
|
||||||
|
modelSelectorButton->setVisible(true);
|
||||||
standardProfile->setVisible(false);
|
standardProfile->setVisible(false);
|
||||||
relaxedProfile->setVisible(false);
|
relaxedProfile->setVisible(false);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ private:
|
|||||||
void updateMetric();
|
void updateMetric();
|
||||||
void updateToggles();
|
void updateToggles();
|
||||||
|
|
||||||
|
FrogPilotButtonIconControl *modelSelectorButton;
|
||||||
|
|
||||||
FrogPilotDualParamControl *aggressiveProfile;
|
FrogPilotDualParamControl *aggressiveProfile;
|
||||||
FrogPilotDualParamControl *conditionalSpeedsImperial;
|
FrogPilotDualParamControl *conditionalSpeedsImperial;
|
||||||
FrogPilotDualParamControl *conditionalSpeedsMetric;
|
FrogPilotDualParamControl *conditionalSpeedsMetric;
|
||||||
|
|||||||
@@ -199,6 +199,9 @@ def main() -> None:
|
|||||||
if os.path.exists("/data/openpilot/prebuilt"):
|
if os.path.exists("/data/openpilot/prebuilt"):
|
||||||
os.remove("/data/openpilot/prebuilt")
|
os.remove("/data/openpilot/prebuilt")
|
||||||
|
|
||||||
|
# Set the desired model on boot
|
||||||
|
subprocess.run(["python3", "/data/openpilot/selfdrive/frogpilot/functions/model_switcher.py"])
|
||||||
|
|
||||||
# Start UI early so prepare can happen in the background
|
# Start UI early so prepare can happen in the background
|
||||||
if not prepare_only:
|
if not prepare_only:
|
||||||
managed_processes['ui'].start()
|
managed_processes['ui'].start()
|
||||||
|
|||||||
BIN
selfdrive/modeld/models/models/blue-diamond-v1.onnx
Normal file
BIN
selfdrive/modeld/models/models/blue-diamond-v1.onnx
Normal file
Binary file not shown.
BIN
selfdrive/modeld/models/models/blue-diamond-v2.onnx
Normal file
BIN
selfdrive/modeld/models/models/blue-diamond-v2.onnx
Normal file
Binary file not shown.
BIN
selfdrive/modeld/models/models/farmville.onnx
Normal file
BIN
selfdrive/modeld/models/models/farmville.onnx
Normal file
Binary file not shown.
BIN
selfdrive/modeld/models/models/new-delhi.onnx
Normal file
BIN
selfdrive/modeld/models/models/new-delhi.onnx
Normal file
Binary file not shown.
BIN
selfdrive/modeld/models/models/new-lemon-pie.onnx
Normal file
BIN
selfdrive/modeld/models/models/new-lemon-pie.onnx
Normal file
Binary file not shown.
@@ -463,7 +463,8 @@ def thermald_thread(end_event, hw_queue) -> None:
|
|||||||
|
|
||||||
# Create the prebuilt file if it doesn't exist
|
# Create the prebuilt file if it doesn't exist
|
||||||
if not os.path.isfile('/data/openpilot/prebuilt'):
|
if not os.path.isfile('/data/openpilot/prebuilt'):
|
||||||
os.system(f"touch {'/data/openpilot/prebuilt'}")
|
if os.path.exists("/data/openpilot/selfdrive/modeld/models/supercombo.thneed"):
|
||||||
|
os.system(f"touch {'/data/openpilot/prebuilt'}")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
hw_queue = queue.Queue(maxsize=1)
|
hw_queue = queue.Queue(maxsize=1)
|
||||||
|
|||||||
@@ -217,6 +217,17 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
|
|||||||
font-size: 55px;
|
font-size: 55px;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
|
// Set the model name
|
||||||
|
std::map<int, QString> MODEL_NAME {
|
||||||
|
{0, "New Delhi"},
|
||||||
|
{1, "Blue Diamond V1"},
|
||||||
|
{2, "Blue Diamond V2"},
|
||||||
|
{3, "Farmville"},
|
||||||
|
{4, "New Lemon Pie"},
|
||||||
|
};
|
||||||
|
|
||||||
|
modelName = MODEL_NAME[params.getInt("Model")];
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffroadHome::showEvent(QShowEvent *event) {
|
void OffroadHome::showEvent(QShowEvent *event) {
|
||||||
@@ -230,7 +241,7 @@ void OffroadHome::hideEvent(QHideEvent *event) {
|
|||||||
|
|
||||||
void OffroadHome::refresh() {
|
void OffroadHome::refresh() {
|
||||||
date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d"));
|
date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d"));
|
||||||
version->setText(getBrand() + " v" + getVersion().left(14).trimmed());
|
version->setText(getBrand() + " v" + getVersion().left(14).trimmed() + " - " + modelName);
|
||||||
|
|
||||||
bool updateAvailable = update_widget->refresh();
|
bool updateAvailable = update_widget->refresh();
|
||||||
int alerts = alerts_widget->refresh();
|
int alerts = alerts_widget->refresh();
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ private:
|
|||||||
QPushButton* update_notif;
|
QPushButton* update_notif;
|
||||||
|
|
||||||
// FrogPilot variables
|
// FrogPilot variables
|
||||||
|
QString modelName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HomeWindow : public QWidget {
|
class HomeWindow : public QWidget {
|
||||||
|
|||||||
Reference in New Issue
Block a user