From 043a309d67da9c4d4671303b370e04aa29cd115d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 3 May 2022 16:51:44 -0700 Subject: [PATCH] ui: new notcar battery design (#24412) * ui: new notcar battery design * if charging * cleanup * remove that * slower * real colors * relative from left * fix that --- selfdrive/ui/qt/body.cc | 50 +++++++++++++++++++++++++++----------- selfdrive/ui/qt/body.h | 4 ++- selfdrive/ui/tests/body.py | 22 +++++++++++++++++ 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100755 selfdrive/ui/tests/body.py diff --git a/selfdrive/ui/qt/body.cc b/selfdrive/ui/qt/body.cc index a83d749577..da87a7485a 100644 --- a/selfdrive/ui/qt/body.cc +++ b/selfdrive/ui/qt/body.cc @@ -1,10 +1,11 @@ #include "selfdrive/ui/qt/body.h" #include +#include #include -BodyWindow::BodyWindow(QWidget *parent) : QLabel(parent) { +BodyWindow::BodyWindow(QWidget *parent) : fuel_filter(1.0, 5., 1. / UI_FREQ), QLabel(parent) { awake = new QMovie("../assets/body/awake.gif"); awake->setCacheMode(QMovie::CacheAll); sleep = new QMovie("../assets/body/sleep.gif"); @@ -26,20 +27,40 @@ void BodyWindow::paintEvent(QPaintEvent *event) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); + + p.translate(width() - 136, 16); + + // battery outline + detail + const QColor gray = QColor("#737373"); + p.setBrush(Qt::NoBrush); + p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + p.drawRoundedRect(2, 2, 78, 36, 8, 8); + p.setPen(Qt::NoPen); + p.setBrush(gray); + p.drawRoundedRect(84, 12, 6, 16, 4, 4); + p.drawRect(84, 12, 3, 16); - // draw battery level - const int offset = 90; - const int radius = 60 / 2; - const int levels = 5; - const float interval = 1. / levels; - for (int i = 0; i < levels; i++) { - float level = 1.0 - (i+1)*interval; - float perc = (fuel >= level) ? 1.0 : 0.35; - - p.setBrush(QColor(255, 255, 255, 255 * perc)); - QPoint pt(width() - (i*offset + offset / 2), offset / 2); - p.drawEllipse(pt, radius, radius); + // battery level + double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f); + const int m = 5; // manual margin since we can't do an inner border + p.setPen(Qt::NoPen); + p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A")); + p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4); + + // charging status + if (charging) { + p.setPen(Qt::NoPen); + p.setBrush(Qt::white); + const QPolygonF charger({ + QPointF(12.31, 0), + QPointF(12.31, 16.92), + QPointF(18.46, 16.92), + QPointF(6.15, 40), + QPointF(6.15, 23.08), + QPointF(0, 23.08), + }); + p.drawPolygon(charger.translated(98, 0)); } } @@ -52,7 +73,8 @@ void BodyWindow::updateState(const UIState &s) { const SubMaster &sm = *(s.sm); auto cs = sm["carState"].getCarState(); - fuel = cs.getFuelGauge(); + charging = cs.getCharging(); + fuel_filter.update(cs.getFuelGauge()); // TODO: use carState.standstill when that's fixed const bool standstill = std::abs(cs.getVEgo()) < 0.01; diff --git a/selfdrive/ui/qt/body.h b/selfdrive/ui/qt/body.h index c1138b8703..cf1ffa191f 100644 --- a/selfdrive/ui/qt/body.h +++ b/selfdrive/ui/qt/body.h @@ -3,6 +3,7 @@ #include #include +#include "selfdrive/common/util.h" #include "selfdrive/ui/ui.h" class BodyWindow : public QLabel { @@ -12,7 +13,8 @@ public: BodyWindow(QWidget* parent = 0); private: - float fuel = 1.0; + bool charging = false; + FirstOrderFilter fuel_filter; QMovie *awake, *sleep; void paintEvent(QPaintEvent*) override; diff --git a/selfdrive/ui/tests/body.py b/selfdrive/ui/tests/body.py new file mode 100755 index 0000000000..c34e717eaf --- /dev/null +++ b/selfdrive/ui/tests/body.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +import time +import cereal.messaging as messaging + +if __name__ == "__main__": + while True: + pm = messaging.PubMaster(['carParams', 'carState']) + batt = 1. + while True: + msg = messaging.new_message('carParams') + msg.carParams.carName = "COMMA BODY" + msg.carParams.notCar = True + pm.send('carParams', msg) + + for b in range(100, 0, -1): + msg = messaging.new_message('carState') + msg.carState.charging = True + msg.carState.fuelGauge = b / 100. + pm.send('carState', msg) + time.sleep(0.1) + + time.sleep(1)