mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-03-04 04:53:57 +08:00
* allow re-regage * bump opendbc * bump panda * apply pause/resume fix for hyundai (should do this in a separate PR) * bump opendbc * fix * rename * Fix? * make sure to disengage for allow always cars * fix * combine * more fix * not needed * check if engagement is from openpilot's state machine * Rename * fix panda safety * fix * no fake lfa button for @devtekve ;) * fix non drive gear re-engage * fix settings * combine * add replace method * use replace * remoev already checks if it exists * fix * group * add todo * reserve events * cleaner * hyundai: only allow for cars with lfa button * sunnyParams * make sure it's car only * Move car-specific changes to opendbc * no need * bump opendbc * more fixes * no more available * more! * final? * always emit user disable * no longer needed * move unit test * add sunnypilot to unit tests * bump opendbc * use new cereal * bump opendbc * static analysis * no unittest * no need available * UI border update * show MADS updates * Add TODO * no longer needed * fix changed events * fix cluster enabled * don't add pre enable if not long * should use enabled * enabled <-> active * better format * bump opendbc * static analysis * static analysis * Rename test as collector was dying * Show our overriding * Revert "show MADS updates" This reverts commitdaf0ad62Revert "fix changed events" This reverts commit31d8c97f* ignoring reserved events * adjusting creation delays * back to stock removing allow_cancel * should be enabled * revert * silent lkas disable * no need * user disable tests * just warning * MUST REMOVE test process replay * fix no entry * fixme * bump opendbc * need this check * cleanup * allow entering paused state if no entry from disabled * brake hold should apply to all * in lists * update unit test * simpler * unused * same thing * fix * only mads in enabled state and long in disabled state * unify silent enable * do this for dlob * bump submodules * fix * bump submodules * bump opendbc * less frequent * more events * fix * allow no entry to paused for non-drive gears * fix * use cereal * Revert "allow no entry to paused for non-drive gears" This reverts commit6d64a4dd9c. * allow in all * Revert "allow in all" This reverts commit6375f14891. * should not be all! * rename for clarity * silent park brake * flipped * bump submodules * Bump to latest mads-new panda * bump panda * more nissan * bump panda * bump msgq * bump panda * bump submodules * bump opendbc * bump opendbc * improving the state * Revert "PlayStation® model (#34133)" This reverts commit5160bee543. * should be none * bump panda * bump opendbc * Apply suggestions from code review * bump panda * bump ref panda * add todo-sp * bump panda ref * bump more panda * changing refs * nuke nuke nuke * use sunny's newer states * bump with new panda * bump panda * Parse more flags from alt exp, more tests, hyundai main cruise allowed * Parse more flags from alt exp, more tests, hyundai main cruise allowed * missed * mutation for controls allowed rising edge * ford mutation * license * remove * unused * bump submodules * use always allowed mads button alt exp * fix * whitelist jason's lastname to codespell * test_processes: update ref logs to82c0278* bump submodules * bump submodules * bump submodules * bump panda * add controls mismatch lateral event * Simplify lateral disengagement logic for MADS configuration Reversed the conditional to align the logic with the `disengage_lateral_on_brake` parameter. This ensures that lateral disengagement behavior is more intuitive and matches the expected configuration. Improves code readability and reduces potential misconfigurations. * remove unified engagement mode in panda * controls allow should be allowed at all times * squash! treat MADS button as user entry * heartbeat for mads * heartbeat mismatch exit control * remove always allow mads button from alt * move to safety_mads * remove main cruise allowed from alt * bump panda * heartbeat engaged mads mismatch mutation test * bump panda * use mads the third panda * ignore pre enable with mads * only force exit if actually actuating * use brake signal instead of pedal events when dlob is active * fix tests * fix panda tests * bump panda * new events to retain long blocks * format * uem: do not engage mads if long is engaged * bump submodules * fix not allowed engaged bug * block uem from engaging * flipped * use different heartbeat check if dlob * hard code to skip heartbeat check * remove toyota lta status for lkas, causes weird behaviors * block tesla * bump panda * bump to merged panda * bump opendbc * bump opendbc * bump opendbc * bump opendbc * Apply suggestions from code review * code ignore spells * needs to be in carstate * Bump opendbc * Update MADS toggle descriptions for clarity. Added notes to clarify behavior of the "MadsMainCruiseAllowed" setting, particularly its impact on vehicles without LFA/LKAS buttons. This ensures users are informed about potential implications when disabling this feature. * Updating translations + Adding spanish * Disengage Lateral on Brake -> Pause Lateral on Brake * test_processes: update ref logs todd41005* Apply suggestions from code review * fix mads button not allowed * bump submodules * bump submodule * test_processes: update ref logs to0a0b998* has multiple lists * Revert "has multiple lists" This reverts commita37c1d26fe. * base * Reapply "has multiple lists" This reverts commitd1cd8dcc81. * migrate mads toggles to sp panel * this is why it keeps crashing * house keeping * more housekeeping * more housekeeping * don't show description by default (yet) * reset to main panel when clicked away * more * some more with interactions * don't stretch cause it looks weird with descriptions * simpler to handle offroad transition * some are toggleable while onroad * remove unused event * slight cleanup * default to true for HKG main cruise toggle * append to list after * add Customize MADS to UI preview * simpler * move to sp list * how tf was this removed * update mads settings button on show event * test_processes: update ref logs toefa9c32--------- Co-authored-by: Jason Wen <haibin.wen3@gmail.com>
215 lines
6.7 KiB
C++
215 lines
6.7 KiB
C++
#include "selfdrive/ui/ui.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
#include <QtConcurrent>
|
|
|
|
#include "common/transformations/orientation.hpp"
|
|
#include "common/swaglog.h"
|
|
#include "common/util.h"
|
|
#include "common/watchdog.h"
|
|
#include "qt/util.h"
|
|
#include "system/hardware/hw.h"
|
|
|
|
#define BACKLIGHT_DT 0.05
|
|
#define BACKLIGHT_TS 10.00
|
|
|
|
void update_sockets(UIState *s) {
|
|
s->sm->update(0);
|
|
}
|
|
|
|
void update_state(UIState *s) {
|
|
SubMaster &sm = *(s->sm);
|
|
UIScene &scene = s->scene;
|
|
|
|
if (sm.updated("liveCalibration")) {
|
|
auto list2rot = [](const capnp::List<float>::Reader &rpy_list) ->Eigen::Matrix3f {
|
|
return euler2rot({rpy_list[0], rpy_list[1], rpy_list[2]}).cast<float>();
|
|
};
|
|
|
|
auto live_calib = sm["liveCalibration"].getLiveCalibration();
|
|
if (live_calib.getCalStatus() == cereal::LiveCalibrationData::Status::CALIBRATED) {
|
|
auto device_from_calib = list2rot(live_calib.getRpyCalib());
|
|
auto wide_from_device = list2rot(live_calib.getWideFromDeviceEuler());
|
|
s->scene.view_from_calib = VIEW_FROM_DEVICE * device_from_calib;
|
|
s->scene.view_from_wide_calib = VIEW_FROM_DEVICE * wide_from_device * device_from_calib;
|
|
} else {
|
|
s->scene.view_from_calib = s->scene.view_from_wide_calib = VIEW_FROM_DEVICE;
|
|
}
|
|
}
|
|
if (sm.updated("pandaStates")) {
|
|
auto pandaStates = sm["pandaStates"].getPandaStates();
|
|
if (pandaStates.size() > 0) {
|
|
scene.pandaType = pandaStates[0].getPandaType();
|
|
|
|
if (scene.pandaType != cereal::PandaState::PandaType::UNKNOWN) {
|
|
scene.ignition = false;
|
|
for (const auto& pandaState : pandaStates) {
|
|
scene.ignition |= pandaState.getIgnitionLine() || pandaState.getIgnitionCan();
|
|
}
|
|
}
|
|
}
|
|
} else if ((s->sm->frame - s->sm->rcv_frame("pandaStates")) > 5*UI_FREQ) {
|
|
scene.pandaType = cereal::PandaState::PandaType::UNKNOWN;
|
|
}
|
|
if (sm.updated("wideRoadCameraState")) {
|
|
auto cam_state = sm["wideRoadCameraState"].getWideRoadCameraState();
|
|
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);
|
|
} else if (!sm.allAliveAndValid({"wideRoadCameraState"})) {
|
|
scene.light_sensor = -1;
|
|
}
|
|
scene.started = sm["deviceState"].getDeviceState().getStarted() && scene.ignition;
|
|
}
|
|
|
|
void ui_update_params(UIState *s) {
|
|
auto params = Params();
|
|
s->scene.is_metric = params.getBool("IsMetric");
|
|
}
|
|
|
|
void UIState::updateStatus() {
|
|
if (scene.started && (sm->updated("selfdriveState") || sm->updated("selfdriveStateSP"))) {
|
|
auto ss = (*sm)["selfdriveState"].getSelfdriveState();
|
|
auto mads = (*sm)["selfdriveStateSP"].getSelfdriveStateSP().getMads();
|
|
auto state = ss.getState();
|
|
auto state_mads = mads.getState();
|
|
if (state == cereal::SelfdriveState::OpenpilotState::PRE_ENABLED || state == cereal::SelfdriveState::OpenpilotState::OVERRIDING ||
|
|
state_mads == cereal::SelfdriveStateSP::ModularAssistiveDrivingSystem::ModularAssistiveDrivingSystemState::PAUSED ||
|
|
state_mads == cereal::SelfdriveStateSP::ModularAssistiveDrivingSystem::ModularAssistiveDrivingSystemState::OVERRIDING) {
|
|
status = STATUS_OVERRIDE;
|
|
} else {
|
|
if (mads.getAvailable()) {
|
|
if (mads.getEnabled()) {
|
|
status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_LAT_ONLY;
|
|
} else {
|
|
status = STATUS_DISENGAGED;
|
|
}
|
|
} else {
|
|
status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle onroad/offroad transition
|
|
if (scene.started != started_prev || sm->frame == 1) {
|
|
if (scene.started) {
|
|
status = STATUS_DISENGAGED;
|
|
scene.started_frame = sm->frame;
|
|
}
|
|
started_prev = scene.started;
|
|
emit offroadTransition(!scene.started);
|
|
}
|
|
}
|
|
|
|
UIState::UIState(QObject *parent) : QObject(parent) {
|
|
sm = std::make_unique<SubMaster>(std::vector<const char*>{
|
|
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
|
|
"pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2",
|
|
"wideRoadCameraState", "managerState", "selfdriveState", "longitudinalPlan",
|
|
});
|
|
prime_state = new PrimeState(this);
|
|
language = QString::fromStdString(Params().get("LanguageSetting"));
|
|
|
|
RETURN_IF_SUNNYPILOT
|
|
// update timer
|
|
timer = new QTimer(this);
|
|
QObject::connect(timer, &QTimer::timeout, this, &UIState::update);
|
|
timer->start(1000 / UI_FREQ);
|
|
}
|
|
|
|
void UIState::update() {
|
|
RETURN_IF_SUNNYPILOT
|
|
update_sockets(this);
|
|
update_state(this);
|
|
updateStatus();
|
|
|
|
if (sm->frame % UI_FREQ == 0) {
|
|
watchdog_kick(nanos_since_boot());
|
|
}
|
|
emit uiUpdate(*this);
|
|
}
|
|
|
|
Device::Device(QObject *parent) : brightness_filter(BACKLIGHT_OFFROAD, BACKLIGHT_TS, BACKLIGHT_DT), QObject(parent) {
|
|
setAwake(true);
|
|
resetInteractiveTimeout();
|
|
#ifndef SUNNYPILOT
|
|
QObject::connect(uiState(), &UIState::uiUpdate, this, &Device::update);
|
|
#endif
|
|
}
|
|
|
|
void Device::update(const UIState &s) {
|
|
updateBrightness(s);
|
|
updateWakefulness(s);
|
|
}
|
|
|
|
void Device::setAwake(bool on) {
|
|
if (on != awake) {
|
|
awake = on;
|
|
Hardware::set_display_power(awake);
|
|
LOGD("setting display power %d", awake);
|
|
emit displayPowerChanged(awake);
|
|
}
|
|
}
|
|
|
|
void Device::resetInteractiveTimeout(int timeout) {
|
|
if (timeout == -1) {
|
|
timeout = (ignition_on ? 10 : 30);
|
|
}
|
|
interactive_timeout = timeout * UI_FREQ;
|
|
}
|
|
|
|
void Device::updateBrightness(const UIState &s) {
|
|
float clipped_brightness = offroad_brightness;
|
|
if (s.scene.started && s.scene.light_sensor >= 0) {
|
|
clipped_brightness = s.scene.light_sensor;
|
|
|
|
// CIE 1931 - https://www.photonstophotos.net/GeneralTopics/Exposure/Psychometric_Lightness_and_Gamma.htm
|
|
if (clipped_brightness <= 8) {
|
|
clipped_brightness = (clipped_brightness / 903.3);
|
|
} else {
|
|
clipped_brightness = std::pow((clipped_brightness + 16.0) / 116.0, 3.0);
|
|
}
|
|
|
|
// Scale back to 10% to 100%
|
|
clipped_brightness = std::clamp(100.0f * clipped_brightness, 10.0f, 100.0f);
|
|
}
|
|
|
|
int brightness = brightness_filter.update(clipped_brightness);
|
|
if (!awake) {
|
|
brightness = 0;
|
|
}
|
|
|
|
if (brightness != last_brightness) {
|
|
if (!brightness_future.isRunning()) {
|
|
brightness_future = QtConcurrent::run(Hardware::set_brightness, brightness);
|
|
last_brightness = brightness;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Device::updateWakefulness(const UIState &s) {
|
|
bool ignition_just_turned_off = !s.scene.ignition && ignition_on;
|
|
ignition_on = s.scene.ignition;
|
|
|
|
if (ignition_just_turned_off) {
|
|
resetInteractiveTimeout();
|
|
} else if (interactive_timeout > 0 && --interactive_timeout == 0) {
|
|
emit interactiveTimeout();
|
|
}
|
|
|
|
setAwake(s.scene.ignition || interactive_timeout > 0);
|
|
}
|
|
|
|
#ifndef SUNNYPILOT
|
|
UIState *uiState() {
|
|
static UIState ui_state;
|
|
return &ui_state;
|
|
}
|
|
|
|
Device *device() {
|
|
static Device _device;
|
|
return &_device;
|
|
}
|
|
#endif
|