UI: border is always engagement state (#27416)

* border is for engagement state

* round shading too

* alerts =/= status

* no debug print

* Full still full

* more cleanup

* more radius

* Update mui too

* normal black

* cleanup

---------

Co-authored-by: Bruce Wayne <harald.the.engineer@gmail.com>
pull/28652/head
Adeeb Shihadeh 2 years ago committed by GitHub
parent 7d6c22949a
commit 07a68ca032
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      selfdrive/ui/mui.cc
  2. 42
      selfdrive/ui/qt/onroad.cc
  3. 2
      selfdrive/ui/qt/onroad.h
  4. 7
      selfdrive/ui/ui.cc
  5. 15
      selfdrive/ui/ui.h

@ -110,14 +110,8 @@ int main(int argc, char *argv[]) {
if (onroad) {
auto cs = sm["controlsState"].getControlsState();
UIStatus status = cs.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
if (cs.getAlertStatus() == cereal::ControlsState::AlertStatus::USER_PROMPT) {
status = STATUS_WARNING;
} else if (cs.getAlertStatus() == cereal::ControlsState::AlertStatus::CRITICAL) {
status = STATUS_ALERT;
}
auto lp = sm["lateralPlan"].getLateralPlan();
if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::PRE_LANE_CHANGE || status == STATUS_ALERT) {
if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::PRE_LANE_CHANGE) {
status_bar->blinkingColor(bg_colors[status]);
} else if (lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::LANE_CHANGE_STARTING ||
lp.getLaneChangeState() == cereal::LateralPlan::LaneChangeState::LANE_CHANGE_FINISHING) {

@ -54,14 +54,7 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
void OnroadWindow::updateState(const UIState &s) {
QColor bgColor = bg_colors[s.status];
Alert alert = Alert::get(*(s.sm), s.scene.started_frame);
if (s.sm->updated("controlsState") || !alert.equal({})) {
if (alert.type == "controlsUnresponsive") {
bgColor = bg_colors[STATUS_ALERT];
} else if (alert.type == "controlsUnresponsivePermanent") {
bgColor = bg_colors[STATUS_DISENGAGED];
}
alerts->updateAlert(alert, bgColor);
}
alerts->updateAlert(alert);
if (s.scene.map_on_left) {
split->setDirection(QBoxLayout::LeftToRight);
@ -108,7 +101,7 @@ void OnroadWindow::offroadTransition(bool offroad) {
}
#endif
alerts->updateAlert({}, bg);
alerts->updateAlert({});
}
void OnroadWindow::paintEvent(QPaintEvent *event) {
@ -119,10 +112,9 @@ void OnroadWindow::paintEvent(QPaintEvent *event) {
// ***** onroad widgets *****
// OnroadAlerts
void OnroadAlerts::updateAlert(const Alert &a, const QColor &color) {
if (!alert.equal(a) || color != bg) {
void OnroadAlerts::updateAlert(const Alert &a) {
if (!alert.equal(a)) {
alert = a;
bg = color;
update();
}
}
@ -131,31 +123,29 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
if (alert.size == cereal::ControlsState::AlertSize::NONE) {
return;
}
static std::map<cereal::ControlsState::AlertSize, const int> alert_sizes = {
static std::map<cereal::ControlsState::AlertSize, const int> alert_heights = {
{cereal::ControlsState::AlertSize::SMALL, 271},
{cereal::ControlsState::AlertSize::MID, 420},
{cereal::ControlsState::AlertSize::FULL, height()},
};
int h = alert_sizes[alert.size];
QRect r = QRect(0, height() - h, width(), h);
int h = alert_heights[alert.size];
int margin = 40;
int radius = 30;
if (alert.size == cereal::ControlsState::AlertSize::FULL) {
margin = 0;
radius = 0;
}
QRect r = QRect(0 + margin, height() - h + margin, width() - margin*2, h - margin*2);
QPainter p(this);
// draw background + gradient
p.setPen(Qt::NoPen);
p.setBrush(QBrush(alert_colors[alert.status]));
p.drawRoundedRect(r, radius, radius);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setBrush(QBrush(bg));
p.drawRect(r);
QLinearGradient g(0, r.y(), 0, r.bottom());
g.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.05));
g.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.35));
p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
p.setBrush(QBrush(g));
p.fillRect(r, g);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
// text
const QPoint c = r.center();

@ -19,7 +19,7 @@ class OnroadAlerts : public QWidget {
public:
OnroadAlerts(QWidget *parent = 0) : QWidget(parent) {};
void updateAlert(const Alert &a, const QColor &color);
void updateAlert(const Alert &a);
protected:
void paintEvent(QPaintEvent*) override;

@ -216,13 +216,8 @@ void ui_update_params(UIState *s) {
void UIState::updateStatus() {
if (scene.started && sm->updated("controlsState")) {
auto controls_state = (*sm)["controlsState"].getControlsState();
auto alert_status = controls_state.getAlertStatus();
auto state = controls_state.getState();
if (alert_status == cereal::ControlsState::AlertStatus::USER_PROMPT) {
status = STATUS_WARNING;
} else if (alert_status == cereal::ControlsState::AlertStatus::CRITICAL) {
status = STATUS_ALERT;
} else if (state == cereal::ControlsState::OpenpilotState::PRE_ENABLED || state == cereal::ControlsState::OpenpilotState::OVERRIDING) {
if (state == cereal::ControlsState::OpenpilotState::PRE_ENABLED || state == cereal::ControlsState::OpenpilotState::OVERRIDING) {
status = STATUS_OVERRIDE;
} else {
status = controls_state.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;

@ -40,6 +40,7 @@ struct Alert {
QString text2;
QString type;
cereal::ControlsState::AlertSize size;
cereal::ControlsState::AlertStatus status;
AudibleAlert sound;
bool equal(const Alert &a2) {
@ -51,6 +52,7 @@ struct Alert {
if (sm.updated("controlsState")) {
return {cs.getAlertText1().cStr(), cs.getAlertText2().cStr(),
cs.getAlertType().cStr(), cs.getAlertSize(),
cs.getAlertStatus(),
cs.getAlertSound()};
} else if ((sm.frame - started_frame) > 5 * UI_FREQ) {
const int CONTROLS_TIMEOUT = 5;
@ -61,16 +63,19 @@ struct Alert {
// car is started, but controlsState hasn't been seen at all
return {"openpilot Unavailable", "Waiting for controls to start",
"controlsWaiting", cereal::ControlsState::AlertSize::MID,
cereal::ControlsState::AlertStatus::NORMAL,
AudibleAlert::NONE};
} else if (controls_missing > CONTROLS_TIMEOUT && !Hardware::PC()) {
// car is started, but controls is lagging or died
if (cs.getEnabled() && (controls_missing - CONTROLS_TIMEOUT) < 10) {
return {"TAKE CONTROL IMMEDIATELY", "Controls Unresponsive",
"controlsUnresponsive", cereal::ControlsState::AlertSize::FULL,
cereal::ControlsState::AlertStatus::CRITICAL,
AudibleAlert::WARNING_IMMEDIATE};
} else {
return {"Controls Unresponsive", "Reboot Device",
"controlsUnresponsivePermanent", cereal::ControlsState::AlertSize::MID,
cereal::ControlsState::AlertStatus::NORMAL,
AudibleAlert::NONE};
}
}
@ -83,16 +88,18 @@ typedef enum UIStatus {
STATUS_DISENGAGED,
STATUS_OVERRIDE,
STATUS_ENGAGED,
STATUS_WARNING,
STATUS_ALERT,
} UIStatus;
const QColor bg_colors [] = {
[STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
[STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
[STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
[STATUS_WARNING] = QColor(0xDA, 0x6F, 0x25, 0xf1),
[STATUS_ALERT] = QColor(0xC9, 0x22, 0x31, 0xf1),
};
static std::map<cereal::ControlsState::AlertStatus, QColor> alert_colors = {
{cereal::ControlsState::AlertStatus::NORMAL, QColor(0x00, 0x00, 0x00, 0xa6)},
{cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
{cereal::ControlsState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)},
};
typedef struct UIScene {

Loading…
Cancel
Save