Merge branch 'SP-64-ui-force-offroad' into master-dev-c3-new

# Conflicts:
#	CHANGELOGS.md
This commit is contained in:
Jason Wen
2024-05-16 11:03:00 -04:00
8 changed files with 79 additions and 5 deletions
+3
View File
@@ -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
+2
View File
@@ -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},
+3 -3
View File
@@ -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 &params) {
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
}
}
+6
View File
@@ -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"
+54 -1
View File
@@ -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) {
+5
View File
@@ -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
View File
@@ -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 &&