mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-27 11:42:10 +08:00
Merge branch 'SP-64-ui-force-offroad' into master-dev-c3-new
# Conflicts: # CHANGELOGS.md
This commit is contained in:
@@ -24,6 +24,9 @@ sunnypilot - 0.9.7.0 (2024-05-xx)
|
||||
* comma Prime support
|
||||
* Personal Mapbox/Amap/Google Maps token support
|
||||
* Instructions on how to set up your iOS Siri Shortcuts: https://routinehub.co/shortcut/17677/
|
||||
* NEW❗: Forced Offroad mode
|
||||
* Force sunnypilot in the offroad state even when the car is on
|
||||
* When Forced Offroad mode is on, allows changing offroad-only settings even when the car is turned on
|
||||
* NEW❗: Ford CAN-FD longitudinal
|
||||
* NEW❗: Parse speed limit sign recognition from camera for certain supported platforms
|
||||
* UPDATED: Hyundai CAN-FD Radar-based SCC
|
||||
|
||||
@@ -256,6 +256,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"EnhancedScc", PERSISTENT | BACKUP},
|
||||
{"FeatureStatus", PERSISTENT | BACKUP},
|
||||
{"FleetManagerPin", PERSISTENT},
|
||||
{"ForceOffroad", CLEAR_ON_MANAGER_START},
|
||||
{"GmapKey", PERSISTENT | BACKUP},
|
||||
{"HandsOnWheelMonitoring", PERSISTENT | BACKUP},
|
||||
{"HideVEgoUi", PERSISTENT | BACKUP},
|
||||
@@ -325,6 +326,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"VisionCurveLaneless", PERSISTENT | BACKUP},
|
||||
{"VwAccType", PERSISTENT | BACKUP},
|
||||
{"VwCCOnly", PERSISTENT | BACKUP},
|
||||
{"Offroad_ForceStatus", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_SupersededUpdate", PERSISTENT},
|
||||
|
||||
{"SunnylinkCache_Users", PERSISTENT},
|
||||
|
||||
@@ -229,7 +229,7 @@ void can_recv_thread(std::vector<Panda *> pandas) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *> &pandas, bool spoofing_started) {
|
||||
std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *> &pandas, bool spoofing_started, Params ¶ms) {
|
||||
bool ignition_local = false;
|
||||
const uint32_t pandas_cnt = pandas.size();
|
||||
|
||||
@@ -277,7 +277,7 @@ std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *>
|
||||
health.ignition_line_pkt = 0;
|
||||
}
|
||||
|
||||
ignition_local |= ((health.ignition_line_pkt != 0) || (health.ignition_can_pkt != 0));
|
||||
ignition_local |= ((health.ignition_line_pkt != 0) || (health.ignition_can_pkt != 0)) && !params.getBool("ForceOffroad");
|
||||
|
||||
pandaStates.push_back(health);
|
||||
}
|
||||
@@ -432,7 +432,7 @@ void panda_state_thread(std::vector<Panda *> pandas, bool spoofing_started) {
|
||||
send_peripheral_state(&pm, peripheral_panda);
|
||||
}
|
||||
|
||||
auto ignition_opt = send_panda_states(&pm, pandas, spoofing_started);
|
||||
auto ignition_opt = send_panda_states(&pm, pandas, spoofing_started, params);
|
||||
|
||||
if (!ignition_opt) {
|
||||
LOGE("Failed to get ignition_opt");
|
||||
|
||||
@@ -52,5 +52,9 @@
|
||||
"Offroad_OSMUpdateRequired": {
|
||||
"text": "OpenStreetMap database is out of date. New maps must be downloaded if you wish to continue using OpenStreetMap data for Enhanced Speed Control and road name display.\n\n%1",
|
||||
"severity": 0
|
||||
},
|
||||
"Offroad_ForceStatus": {
|
||||
"text": "sunnypilot is now in Forced Offroad mode. sunnypilot won't start until Forced Offroad mode is disabled. Go to \"Settings\" -> \"Device\" -> \"Unforce Offroad\" to exit Force Offroad mode.",
|
||||
"severity": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +311,12 @@ def thermald_thread(end_event, hw_queue) -> None:
|
||||
# ensure device is fully booted
|
||||
startup_conditions["device_booted"] = startup_conditions.get("device_booted", False) or HARDWARE.booted()
|
||||
|
||||
# user-forced status
|
||||
force_offroad = params.get_bool("ForceOffroad")
|
||||
startup_conditions["not_force_offroad"] = not force_offroad
|
||||
onroad_conditions["not_force_offroad"] = not force_offroad
|
||||
set_offroad_alert("Offroad_ForceStatus", force_offroad)
|
||||
|
||||
# if the temperature enters the danger zone, go offroad to cool down
|
||||
onroad_conditions["device_temp_good"] = thermal_status < ThermalStatus.danger
|
||||
extra_text = f"{offroad_comp_temp:.1f}C"
|
||||
|
||||
@@ -442,13 +442,24 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
connect(uiState(), &UIState::offroadTransition, poweroff_btn, &QPushButton::setVisible);
|
||||
}
|
||||
|
||||
offroad_btn = new QPushButton(tr("Toggle Onroad/Offroad"));
|
||||
offroad_btn->setObjectName("offroad_btn");
|
||||
QObject::connect(offroad_btn, &QPushButton::clicked, this, &DevicePanel::forceoffroad);
|
||||
|
||||
QVBoxLayout *buttons_layout = new QVBoxLayout();
|
||||
buttons_layout->setSpacing(24);
|
||||
buttons_layout->addLayout(power_layout);
|
||||
buttons_layout->addWidget(offroad_btn);
|
||||
|
||||
setStyleSheet(R"(
|
||||
#reboot_btn { height: 120px; border-radius: 15px; background-color: #393939; }
|
||||
#reboot_btn:pressed { background-color: #4a4a4a; }
|
||||
#poweroff_btn { height: 120px; border-radius: 15px; background-color: #E22C2C; }
|
||||
#poweroff_btn:pressed { background-color: #FF2424; }
|
||||
)");
|
||||
addItem(power_layout);
|
||||
addItem(buttons_layout);
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void DevicePanel::onPinFileChanged(const QString &file_path) {
|
||||
@@ -523,9 +534,51 @@ void DevicePanel::poweroff() {
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePanel::forceoffroad() {
|
||||
if (!uiState()->engaged()) {
|
||||
if (params.getBool("ForceOffroad")) {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to unforce offroad?"), tr("Unforce"), this)) {
|
||||
// Check engaged again in case it changed while the dialog was open
|
||||
if (!uiState()->engaged()) {
|
||||
params.remove("ForceOffroad");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to force offroad?"), tr("Force"), this)) {
|
||||
// Check engaged again in case it changed while the dialog was open
|
||||
if (!uiState()->engaged()) {
|
||||
params.putBool("ForceOffroad", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ConfirmationDialog::alert(tr("Disengage to Force Offroad"), this);
|
||||
}
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void DevicePanel::showEvent(QShowEvent *event) {
|
||||
pair_device->setVisible(uiState()->primeType() == PrimeType::UNPAIRED);
|
||||
ListWidget::showEvent(event);
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void DevicePanel::updateLabels() {
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool force_offroad_param = params.getBool("ForceOffroad");
|
||||
QString offroad_btn_style = force_offroad_param ? "#393939" : "#E22C2C";
|
||||
QString offroad_btn_pressed_style = force_offroad_param ? "#4a4a4a" : "#FF2424";
|
||||
QString btn_common_style = QString("QPushButton { height: 120px; border-radius: 15px; background-color: %1; }"
|
||||
"QPushButton:pressed { background-color: %2; }")
|
||||
.arg(offroad_btn_style,
|
||||
offroad_btn_pressed_style);
|
||||
|
||||
offroad_btn->setText(force_offroad_param ? tr("Unforce Offroad") : tr("Force Offroad"));
|
||||
offroad_btn->setStyleSheet(btn_common_style + offroad_btn_style + offroad_btn_pressed_style);
|
||||
}
|
||||
|
||||
void SettingsWindow::showEvent(QShowEvent *event) {
|
||||
|
||||
@@ -63,6 +63,9 @@ private slots:
|
||||
void updateCalibDescription();
|
||||
void onPinFileChanged(const QString &file_path);
|
||||
void refreshPin();
|
||||
void forceoffroad();
|
||||
|
||||
void updateLabels();
|
||||
|
||||
private:
|
||||
Params params;
|
||||
@@ -72,6 +75,8 @@ private:
|
||||
QString pin_title = tr("Fleet Manager PIN:") + " ";
|
||||
QString pin = "OFF";
|
||||
QFileSystemWatcher *fs_watch;
|
||||
|
||||
QPushButton *offroad_btn;
|
||||
};
|
||||
|
||||
class TogglesPanel : public ListWidget {
|
||||
|
||||
+2
-1
@@ -165,6 +165,7 @@ static void update_sockets(UIState *s) {
|
||||
static void update_state(UIState *s) {
|
||||
SubMaster &sm = *(s->sm);
|
||||
UIScene &scene = s->scene;
|
||||
auto params = Params();
|
||||
|
||||
if (sm.updated("liveCalibration")) {
|
||||
auto live_calib = sm["liveCalibration"].getLiveCalibration();
|
||||
@@ -214,7 +215,7 @@ static void update_state(UIState *s) {
|
||||
float scale = (cam_state.getSensor() == cereal::FrameData::ImageSensor::AR0231) ? 6.0f : 1.0f;
|
||||
scene.light_sensor = std::max(100.0f - scale * cam_state.getExposureValPercent(), 0.0f);
|
||||
}
|
||||
scene.started = sm["deviceState"].getDeviceState().getStarted() && scene.ignition;
|
||||
scene.started = sm["deviceState"].getDeviceState().getStarted() && scene.ignition && !params.getBool("ForceOffroad");
|
||||
|
||||
scene.world_objects_visible = scene.world_objects_visible ||
|
||||
(scene.started &&
|
||||
|
||||
Reference in New Issue
Block a user