Merge branch 'master-new' of https://github.com/sunnypilot/sunnypilot into master-new

This commit is contained in:
infiniteCable2
2025-07-21 23:07:40 +02:00
12 changed files with 174 additions and 64 deletions
+10 -8
View File
@@ -5,8 +5,8 @@
inline static std::unordered_map<std::string, uint32_t> keys = {
{"AccessToken", CLEAR_ON_MANAGER_START | DONT_LOG},
{"AdbEnabled", PERSISTENT},
{"AlwaysOnDM", PERSISTENT},
{"AdbEnabled", PERSISTENT | BACKUP},
{"AlwaysOnDM", PERSISTENT | BACKUP},
{"ApiCache_Device", PERSISTENT},
{"ApiCache_FirehoseStats", PERSISTENT},
{"AssistNowToken", PERSISTENT},
@@ -86,7 +86,7 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
{"LocationFilterInitialState", PERSISTENT},
{"LongitudinalManeuverMode", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"LongitudinalPersonality", PERSISTENT | BACKUP},
{"NetworkMetered", PERSISTENT},
{"NetworkMetered", PERSISTENT | BACKUP},
{"ObdMultiplexingChanged", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"ObdMultiplexingEnabled", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"Offroad_BadNvme", CLEAR_ON_MANAGER_START},
@@ -132,15 +132,15 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
// --- sunnypilot params --- //
{"ApiCache_DriveStats", PERSISTENT},
{"AutoLaneChangeBsmDelay", PERSISTENT},
{"AutoLaneChangeTimer", PERSISTENT},
{"AutoLaneChangeBsmDelay", PERSISTENT | BACKUP},
{"AutoLaneChangeTimer", PERSISTENT | BACKUP},
{"BlinkerMinLateralControlSpeed", PERSISTENT | BACKUP},
{"BlinkerPauseLateralControl", PERSISTENT | BACKUP},
{"Brightness", PERSISTENT | BACKUP},
{"CarParamsSP", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"CarParamsSPCache", CLEAR_ON_MANAGER_START},
{"CarParamsSPPersistent", PERSISTENT},
{"CarPlatformBundle", PERSISTENT},
{"CarPlatformBundle", PERSISTENT | BACKUP},
{"ChevronInfo", PERSISTENT | BACKUP},
{"CustomAccIncrementsEnabled", PERSISTENT | BACKUP},
{"CustomAccLongPressIncrement", PERSISTENT | BACKUP},
@@ -154,6 +154,7 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
{"OffroadMode", CLEAR_ON_MANAGER_START},
{"QuickBootToggle", PERSISTENT | BACKUP},
{"QuietMode", PERSISTENT | BACKUP},
{"ShowAdvancedControls", PERSISTENT | BACKUP},
// MADS params
{"Mads", PERSISTENT | BACKUP},
@@ -163,6 +164,7 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
// Model Manager params
{"ModelManager_ActiveBundle", PERSISTENT},
{"ModelManager_ClearCache", CLEAR_ON_MANAGER_START},
{"ModelManager_DownloadIndex", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"ModelManager_LastSyncTime", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"ModelManager_ModelsCache", PERSISTENT | BACKUP},
@@ -184,9 +186,9 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
{"BackupManager_RestoreVersion", PERSISTENT},
// sunnypilot car specific params
{"HyundaiLongitudinalTuning", PERSISTENT},
{"HyundaiLongitudinalTuning", PERSISTENT | BACKUP},
{"DynamicExperimentalControl", PERSISTENT},
{"DynamicExperimentalControl", PERSISTENT | BACKUP},
{"BlindSpot", PERSISTENT | BACKUP},
// model panel params
@@ -7,12 +7,23 @@
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/developer_panel.h"
DeveloperPanelSP::DeveloperPanelSP(SettingsWindow *parent) : DeveloperPanel(parent) {
// Advanced Controls Toggle
showAdvancedControls = new ParamControlSP("ShowAdvancedControls", tr("Show Advanced Controls"), tr("Toggle visibility of advanced sunnypilot controls.\nThis only toggles the visibility of the controls; it does not toggle the actual control enabled/disabled state."), "");
addItem(showAdvancedControls);
QObject::connect(showAdvancedControls, &ParamControlSP::toggleFlipped, this, [=](bool) {
AbstractControlSP::UpdateAllAdvancedControls();
updateToggles(!uiState()->scene.started);
});
showAdvancedControls->showDescription();
// Github Runner Toggle
enableGithubRunner = new ParamControlSP("EnableGithubRunner", tr("Enable GitHub runner service"), tr("Enables or disables the github runner service."), "");
enableGithubRunner = new ParamControlSP("EnableGithubRunner", tr("Enable GitHub runner service"), tr("Enables or disables the github runner service."), "", this, true);
addItem(enableGithubRunner);
// Quickboot Mode Toggle
prebuiltToggle = new ParamControlSP("QuickBootToggle", tr("Enable Quickboot Mode"), tr(""), "");
prebuiltToggle = new ParamControlSP("QuickBootToggle", tr("Enable Quickboot Mode"), tr(""), "", this, true);
addItem(prebuiltToggle);
QObject::connect(prebuiltToggle, &ParamControl::toggleFlipped, [=](bool state) {
@@ -57,11 +68,13 @@ void DeveloperPanelSP::updateToggles(bool offroad) {
: tr("Quickboot mode requires updates to be disabled.<br>Enable 'Disable Updates' in the Software panel first."));
enableGithubRunner->setVisible(!is_release);
errorLogBtn->setVisible(!is_release && !is_tested);
errorLogBtn->setVisible(!is_release);
showAdvancedControls->setEnabled(true);
}
void DeveloperPanelSP::showEvent(QShowEvent *event) {
DeveloperPanel::showEvent(event);
updateToggles(!uiState()->scene.started);
AbstractControlSP::UpdateAllAdvancedControls();
prebuiltToggle->showDescription();
}
@@ -20,6 +20,7 @@ private:
ButtonControlSP *errorLogBtn;
ParamControlSP *prebuiltToggle;
Params params;
ParamControlSP *showAdvancedControls;
private slots:
void updateToggles(bool offroad);
@@ -8,6 +8,8 @@
#include <algorithm>
#include <QJsonDocument>
#include <QStyle>
#include <QtConcurrent/QtConcurrent>
#include <QDir>
#include "common/model.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h"
@@ -66,6 +68,11 @@ ModelsPanel::ModelsPanel(QWidget *parent) : QWidget(parent) {
connect(uiStateSP(), &UIStateSP::uiUpdate, this, &ModelsPanel::updateLabels);
list->addItem(currentModelLblBtn);
clearModelCacheBtn = new ButtonControlSP(tr("Clear Model Cache"), tr("CLEAR"), "", this);
connect(clearModelCacheBtn, &ButtonControlSP::clicked, this, &ModelsPanel::clearModelCache);
list->addItem(clearModelCacheBtn);
// Create progress bars for downloads
supercomboProgressBar = createProgressBar(this);
QString supercomboType = tr("Driving Model");
@@ -98,7 +105,7 @@ ModelsPanel::ModelsPanel(QWidget *parent) : QWidget(parent) {
delay_control = new OptionControlSP("LagdToggledelay", tr("Adjust Software Delay"),
tr("Adjust the software delay when Live Learning Steer Delay is toggled off."
"\nThe default software delay value is 0.2"),
"", {5, 30}, 1, false, nullptr, true);
"", {5, 30}, 1, false, nullptr, true, true);
connect(delay_control, &OptionControlSP::updateLabels, [=]() {
float value = QString::fromStdString(params.get("LagdToggledelay")).toFloat();
@@ -367,6 +374,8 @@ void ModelsPanel::updateLabels() {
delay_control->setLabel(QString::number(value, 'f', 2) + "s");
delay_control->showDescription();
}
clearModelCacheBtn->setValue(QString::number(calculateCacheSize(), 'f', 2) + " MB");
}
/**
@@ -387,3 +396,32 @@ void ModelsPanel::showResetParamsDialog() {
params.remove("LiveTorqueParameters");
}
}
void ModelsPanel::clearModelCache() {
QString confirmMsg = tr("This will delete ALL downloaded models from the cache"
"<br/><u>except the currently active model</u>."
"<br/><br/>Are you sure you want to continue?");
QString content("<body><h2 style=\"text-align: center;\">" + tr("Driving Model Selector") + "</h2><br>"
"<p style=\"text-align: center; margin: 0 128px; font-size: 50px;\">" + confirmMsg + "</p></body>");
if (showConfirmationDialog(
content,
tr("Clear Cache"))) {
params.putBool("ModelManager_ClearCache", true);
}
}
double ModelsPanel::calculateCacheSize() {
QFuture<qint64> future_ModelCacheSize = QtConcurrent::run([=]() {
QDir model_dir(QString::fromStdString(Path::model_root()));
QFileInfoList model_files = model_dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
qint64 totalSize = 0;
for (const QFileInfo &model_file : model_files) {
if (model_file.isFile()) {
totalSize += model_file.size();
}
}
return totalSize;
});
return static_cast<double>(future_ModelCacheSize) / (1024.0 * 1024.0);
}
@@ -41,6 +41,8 @@ private:
cereal::ModelManagerSP::Reader model_manager;
cereal::ModelManagerSP::DownloadStatus download_status{};
cereal::ModelManagerSP::DownloadStatus prev_download_status{};
void clearModelCache();
double calculateCacheSize();
bool canContinueOnMeteredDialog() {
if (!is_metered) return true;
@@ -75,5 +77,6 @@ private:
QProgressBar *policyProgressBar;
QFrame *policyFrame;
Params params;
ButtonControlSP *clearModelCacheBtn;
};
@@ -24,7 +24,7 @@ SoftwarePanelSP::SoftwarePanelSP(QWidget *parent) : SoftwarePanel(parent) {
tr("Disable Updates"),
tr("When enabled, software updates will be disabled. <b>This requires a reboot to take effect.</b>"),
"../assets/icons/icon_warning.png",
this);
this, true);
disableUpdatesToggle->showDescription();
addItem(disableUpdatesToggle);
connect(disableUpdatesToggle, &ParamControl::toggleFlipped, this, &SoftwarePanelSP::handleDisableUpdatesToggled);
+23 -8
View File
@@ -30,9 +30,24 @@ QFrame *vertical_space(int height, QWidget *parent) {
}
// AbstractControlSP
std::vector<AbstractControlSP*> AbstractControlSP::advanced_controls_;
AbstractControlSP::~AbstractControlSP() { UnregisterAdvancedControl(this); }
AbstractControlSP::AbstractControlSP(const QString &title, const QString &desc, const QString &icon, QWidget *parent)
: AbstractControl(title, desc, icon, parent) {
void AbstractControlSP::RegisterAdvancedControl(AbstractControlSP *ctrl) { advanced_controls_.push_back(ctrl); }
void AbstractControlSP::UnregisterAdvancedControl(AbstractControlSP *ctrl) {
advanced_controls_.erase(std::remove(advanced_controls_.begin(), advanced_controls_.end(), ctrl), advanced_controls_.end());
}
void AbstractControlSP::UpdateAllAdvancedControls() {
bool visibility = Params().getBool("ShowAdvancedControls");
advanced_controls_.erase(std::remove(advanced_controls_.begin(), advanced_controls_.end(), nullptr), advanced_controls_.end());
for (auto *ctrl : advanced_controls_) ctrl->setVisible(visibility);
}
AbstractControlSP::AbstractControlSP(const QString &title, const QString &desc, const QString &icon, QWidget *parent, bool advancedControl)
: AbstractControl(title, desc, icon, parent), isAdvancedControl(advancedControl) {
if (isAdvancedControl) RegisterAdvancedControl(this);
main_layout = new QVBoxLayout(this);
main_layout->setMargin(0);
@@ -82,8 +97,8 @@ void AbstractControlSP::hideEvent(QHideEvent *e) {
}
}
AbstractControlSP_SELECTOR::AbstractControlSP_SELECTOR(const QString &title, const QString &desc, const QString &icon, QWidget *parent)
: AbstractControlSP(title, desc, icon, parent) {
AbstractControlSP_SELECTOR::AbstractControlSP_SELECTOR(const QString &title, const QString &desc, const QString &icon, QWidget *parent, bool advancedControl)
: AbstractControlSP(title, desc, icon, parent, advancedControl) {
if (title_label != nullptr) {
delete title_label;
@@ -169,8 +184,8 @@ void AbstractControlSP_SELECTOR::hideEvent(QHideEvent *e) {
// controls
ButtonControlSP::ButtonControlSP(const QString &title, const QString &text, const QString &desc, QWidget *parent)
: AbstractControlSP(title, desc, "", parent) {
ButtonControlSP::ButtonControlSP(const QString &title, const QString &text, const QString &desc, QWidget *parent, bool advancedControl)
: AbstractControlSP(title, desc, "", parent, advancedControl) {
btn.setText(text);
btn.setStyleSheet(R"(
@@ -225,8 +240,8 @@ void ElidedLabelSP::paintEvent(QPaintEvent *event) {
// ParamControlSP
ParamControlSP::ParamControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent)
: ToggleControlSP(title, desc, icon, false, parent) {
ParamControlSP::ParamControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent, bool advancedControl)
: ToggleControlSP(title, desc, icon, false, parent, advancedControl){
key = param.toStdString();
QObject::connect(this, &ParamControlSP::toggleFlipped, this, &ParamControlSP::toggleClicked);
+27 -9
View File
@@ -57,6 +57,7 @@ class AbstractControlSP : public AbstractControl {
Q_OBJECT
public:
~AbstractControlSP();
void setDescription(const QString &desc) override {
if (description) description->setText(desc);
}
@@ -81,13 +82,30 @@ public slots:
description->setVisible(true);
}
void setVisible(bool visible) override {
bool _visible = visible;
if (isAdvancedControl && !params.getBool("ShowAdvancedControls")) {
_visible = false;
}
AbstractControl::setVisible(_visible);
}
static void RegisterAdvancedControl(AbstractControlSP *ctrl);
static void UnregisterAdvancedControl(AbstractControlSP *ctrl);
static void UpdateAllAdvancedControls();
protected:
AbstractControlSP(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr);
AbstractControlSP(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr, bool advancedControl = false);
void hideEvent(QHideEvent *e) override;
QVBoxLayout *main_layout;
ElidedLabelSP *value;
QLabel *description = nullptr;
bool isAdvancedControl;
private:
Params params;
static std::vector<AbstractControlSP*> advanced_controls_;
};
// AbstractControlSP_SELECTOR
@@ -97,7 +115,7 @@ class AbstractControlSP_SELECTOR : public AbstractControlSP {
protected:
QSpacerItem *spacingItem = new QSpacerItem(44, 44, QSizePolicy::Minimum, QSizePolicy::Fixed);
AbstractControlSP_SELECTOR(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr);
AbstractControlSP_SELECTOR(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr, bool advancedControl = false);
void hideEvent(QHideEvent *e) override;
};
@@ -123,7 +141,7 @@ class ButtonControlSP : public AbstractControlSP {
Q_OBJECT
public:
ButtonControlSP(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr);
ButtonControlSP(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr, bool advancedControl = false);
inline void setText(const QString &text) { btn.setText(text); }
inline QString text() const { return btn.text(); }
inline void click() { btn.click(); }
@@ -142,7 +160,7 @@ class ToggleControlSP : public AbstractControlSP {
Q_OBJECT
public:
ToggleControlSP(const QString &title, const QString &desc = "", const QString &icon = "", const bool state = false, QWidget *parent = nullptr) : AbstractControlSP(title, desc, icon, parent) {
ToggleControlSP(const QString &title, const QString &desc = "", const QString &icon = "", const bool state = false, QWidget *parent = nullptr, bool advancedControl = false) : AbstractControlSP(title, desc, icon, parent, advancedControl) {
// space between toggle and title
icon_label = new QLabel(this);
hlayout->addWidget(icon_label);
@@ -173,7 +191,7 @@ class ParamControlSP : public ToggleControlSP {
Q_OBJECT
public:
ParamControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr);
ParamControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr, bool advancedControl = false);
void setConfirmation(bool _confirm, bool _store_confirm) {
confirm = _confirm;
store_confirm = _store_confirm;
@@ -219,7 +237,7 @@ class MultiButtonControlSP : public AbstractControlSP_SELECTOR {
public:
MultiButtonControlSP(const QString &title, const QString &desc, const QString &icon,
const std::vector<QString> &button_texts, const int minimum_button_width = 225, const bool inline_layout = false) : AbstractControlSP_SELECTOR(title, desc, icon), button_texts(button_texts), is_inline_layout(inline_layout) {
const std::vector<QString> &button_texts, const int minimum_button_width = 225, const bool inline_layout = false, bool advancedControl = false) : AbstractControlSP_SELECTOR(title, desc, icon, nullptr, advancedControl), button_texts(button_texts), is_inline_layout(inline_layout) {
const QString style = R"(
QPushButton {
border-radius: 20px;
@@ -371,8 +389,8 @@ class ButtonParamControlSP : public MultiButtonControlSP {
Q_OBJECT
public:
ButtonParamControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon,
const std::vector<QString> &button_texts, const int minimum_button_width = 225, const bool inline_layout = false) : MultiButtonControlSP(title, desc, icon,
button_texts, minimum_button_width, inline_layout) {
const std::vector<QString> &button_texts, const int minimum_button_width = 225, const bool inline_layout = false, bool advancedControl = false) : MultiButtonControlSP(title, desc, icon,
button_texts, minimum_button_width, inline_layout, advancedControl) {
key = param.toStdString();
int value = atoi(params.get(key).c_str());
@@ -499,7 +517,7 @@ private:
public:
OptionControlSP(const QString &param, const QString &title, const QString &desc, const QString &icon,
const MinMaxValue &range, const int per_value_change = 1, const bool inline_layout = false,
const QMap<QString, QString> *valMap = nullptr, bool scale_float = false) : AbstractControlSP_SELECTOR(title, desc, icon, nullptr), _title(title), valueMap(valMap), is_inline_layout(inline_layout), use_float_scaling(scale_float) {
const QMap<QString, QString> *valMap = nullptr, bool scale_float = false, bool advancedControl = false) : AbstractControlSP_SELECTOR(title, desc, icon, nullptr, advancedControl), _title(title), valueMap(valMap), is_inline_layout(inline_layout), use_float_scaling(scale_float) {
const QString style = R"(
QPushButton {
border-radius: 20px;
@@ -91,42 +91,28 @@ class Parser:
outs[name] = pred_mu_final.reshape(final_shape)
outs[name + '_stds'] = pred_std_final.reshape(final_shape)
def _parse_mhp_output(self, name, output, shape_threshold, in_n_mhp, out_n_mhp, out_shape) -> None:
if name not in output:
return
shape = output[name].shape[1]
shape_is_expected_size = None
if name == 'lead':
shape_is_expected_size = shape == 2 * shape_threshold
elif name == 'plan':
shape_is_expected_size = shape <= 2 * shape_threshold
use_default_format = self.generation >= 12 and shape_is_expected_size
in_n = 0 if use_default_format else in_n_mhp
out_n = 0 if use_default_format else out_n_mhp
self.parse_mdn(name, output, in_n, out_n, out_shape)
def _parse_plan_mhp(self, outs):
self.parse_mdn('plan', outs, in_N=SplitModelConstants.PLAN_MHP_N, out_N=SplitModelConstants.PLAN_MHP_SELECTION,
out_shape=(SplitModelConstants.IDX_N,SplitModelConstants.PLAN_WIDTH))
def parse_dynamic_outputs(self, outs: dict[str, np.ndarray]) -> None:
self._parse_mhp_output(
name='lead',
output=outs,
shape_threshold=SplitModelConstants.LEAD_MHP_SELECTION * SplitModelConstants.LEAD_TRAJ_LEN * SplitModelConstants.LEAD_WIDTH,
in_n_mhp=SplitModelConstants.LEAD_MHP_N,
out_n_mhp=SplitModelConstants.LEAD_MHP_SELECTION,
out_shape=(SplitModelConstants.LEAD_TRAJ_LEN, SplitModelConstants.LEAD_WIDTH),
)
self._parse_mhp_output(
name='plan',
output=outs,
shape_threshold=SplitModelConstants.PLAN_WIDTH * SplitModelConstants.IDX_N,
in_n_mhp=SplitModelConstants.PLAN_MHP_N,
out_n_mhp=SplitModelConstants.PLAN_MHP_SELECTION,
out_shape=(SplitModelConstants.IDX_N, SplitModelConstants.PLAN_WIDTH),
)
if 'lead' in outs:
if self.generation >= 12 and \
outs['lead'].shape[1] == 2 * SplitModelConstants.LEAD_MHP_SELECTION * SplitModelConstants.LEAD_TRAJ_LEN * SplitModelConstants.LEAD_WIDTH:
self.parse_mdn('lead', outs, in_N=0, out_N=0,
out_shape=(SplitModelConstants.LEAD_MHP_SELECTION, SplitModelConstants.LEAD_TRAJ_LEN, SplitModelConstants.LEAD_WIDTH))
else:
self.parse_mdn('lead', outs, in_N=SplitModelConstants.LEAD_MHP_N, out_N=SplitModelConstants.LEAD_MHP_SELECTION,
out_shape=(SplitModelConstants.LEAD_TRAJ_LEN, SplitModelConstants.LEAD_WIDTH))
if 'plan' in outs:
if self.generation >= 12 and \
outs['plan'].shape[1] > 2 * SplitModelConstants.PLAN_WIDTH * SplitModelConstants.IDX_N:
self._parse_plan_mhp(outs)
elif self.generation >= 12:
self.parse_mdn('plan', outs, in_N=0, out_N=0,
out_shape=(SplitModelConstants.IDX_N, SplitModelConstants.PLAN_WIDTH))
else:
self._parse_plan_mhp(outs)
def split_outputs(self, outs: dict[str, np.ndarray]) -> None:
if 'desired_curvature' in outs:
+29
View File
@@ -178,6 +178,10 @@ class ModelManagerSP:
finally:
self.params.put("ModelManager_DownloadIndex", "")
if self.params.get("ModelManager_ClearCache", block=False, encoding="utf-8"):
self.clear_model_cache()
self.params.remove("ModelManager_ClearCache")
self._report_status()
rk.keep_time()
@@ -185,6 +189,31 @@ class ModelManagerSP:
cloudlog.exception(f"Error in main thread: {str(e)}")
rk.keep_time()
def clear_model_cache(self) -> None:
"""
Clears the model cache directory of all files except those in the active model bundle.
"""
# Get list of files used by active model bundle
active_files = []
if self.active_bundle is not None: # When the default model is active
for model in self.active_bundle.models:
if hasattr(model, 'artifact') and model.artifact.fileName:
active_files.append(model.artifact.fileName)
if hasattr(model, 'metadata') and model.metadata.fileName:
active_files.append(model.metadata.fileName)
# Remove all files except active ones
model_dir = Paths.model_root()
try:
for filename in os.listdir(model_dir):
if filename not in active_files:
file_path = os.path.join(model_dir, filename)
if os.path.isfile(file_path):
os.remove(file_path)
cloudlog.info("Model cache cleared, keeping active model files")
except Exception as e:
cloudlog.exception(f"Error clearing model cache: {str(e)}")
def main():
ModelManagerSP().main_thread()
+4
View File
@@ -55,4 +55,8 @@ namespace Path {
return "/dev/shm";
#endif
}
inline std::string model_root() {
return Hardware::PC() ? Path::comma_home() + "/media/0/models" : "/data/media/0/models";
}
} // namespace Path
+1
View File
@@ -73,6 +73,7 @@ def manager_init() -> None:
("NeuralNetworkLateralControl", "0"),
("QuickBootToggle", "0"),
("QuietMode", "0"),
("ShowAdvancedControls", "0" if build_metadata.tested_channel else "1"),
]
# device boot mode