openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

112 lines
3.7 KiB

#include "selfdrive/ui/qt/onroad/hud.h"
#include <cmath>
#include "selfdrive/ui/qt/util.h"
constexpr int SET_SPEED_NA = 255;
HudRenderer::HudRenderer() {}
void HudRenderer::updateState(const UIState &s) {
is_metric = s.scene.is_metric;
status = s.status;
const SubMaster &sm = *(s.sm);
if (sm.rcv_frame("carState") < s.scene.started_frame) {
is_cruise_set = false;
set_speed = SET_SPEED_NA;
speed = 0.0;
return;
}
const auto &controls_state = sm["controlsState"].getControlsState();
const auto &car_state = sm["carState"].getCarState();
// Handle older routes where vCruiseCluster is not set
set_speed = car_state.getVCruiseCluster() == 0.0 ? controls_state.getVCruiseDEPRECATED() : car_state.getVCruiseCluster();
is_cruise_set = set_speed > 0 && set_speed != SET_SPEED_NA;
is_cruise_available = set_speed != -1;
if (is_cruise_set && !is_metric) {
set_speed *= KM_TO_MILE;
}
// Handle older routes where vEgoCluster is not set
v_ego_cluster_seen = v_ego_cluster_seen || car_state.getVEgoCluster() != 0.0;
float v_ego = v_ego_cluster_seen ? car_state.getVEgoCluster() : car_state.getVEgo();
speed = std::max<float>(0.0f, v_ego * (is_metric ? MS_TO_KPH : MS_TO_MPH));
}
void HudRenderer::draw(QPainter &p, const QRect &surface_rect) {
p.save();
// Draw header gradient
QLinearGradient bg(0, UI_HEADER_HEIGHT - (UI_HEADER_HEIGHT / 2.5), 0, UI_HEADER_HEIGHT);
bg.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.45));
bg.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0));
p.fillRect(0, 0, surface_rect.width(), UI_HEADER_HEIGHT, bg);
if (is_cruise_available) {
drawSetSpeed(p, surface_rect);
}
drawCurrentSpeed(p, surface_rect);
p.restore();
}
void HudRenderer::drawSetSpeed(QPainter &p, const QRect &surface_rect) {
// Draw outer box + border to contain set speed
const QSize default_size = {172, 204};
QSize set_speed_size = is_metric ? QSize(200, 204) : default_size;
QRect set_speed_rect(QPoint(60 + (default_size.width() - set_speed_size.width()) / 2, 45), set_speed_size);
// Draw set speed box
p.setPen(QPen(QColor(255, 255, 255, 75), 6));
p.setBrush(QColor(0, 0, 0, 166));
p.drawRoundedRect(set_speed_rect, 32, 32);
// Colors based on status
QColor max_color = QColor(0xa6, 0xa6, 0xa6, 0xff);
QColor set_speed_color = QColor(0x72, 0x72, 0x72, 0xff);
if (is_cruise_set) {
set_speed_color = QColor(255, 255, 255);
if (status == STATUS_DISENGAGED) {
max_color = QColor(255, 255, 255);
} else if (status == STATUS_OVERRIDE) {
max_color = QColor(0x91, 0x9b, 0x95, 0xff);
} else {
max_color = QColor(0x80, 0xd8, 0xa6, 0xff);
}
}
// Draw "MAX" text
p.setFont(InterFont(40, QFont::DemiBold));
p.setPen(max_color);
p.drawText(set_speed_rect.adjusted(0, 27, 0, 0), Qt::AlignTop | Qt::AlignHCenter, tr("MAX"));
// Draw set speed
QString setSpeedStr = is_cruise_set ? QString::number(std::nearbyint(set_speed)) : "";
p.setFont(InterFont(90, QFont::Bold));
p.setPen(set_speed_color);
p.drawText(set_speed_rect.adjusted(0, 77, 0, 0), Qt::AlignTop | Qt::AlignHCenter, setSpeedStr);
}
void HudRenderer::drawCurrentSpeed(QPainter &p, const QRect &surface_rect) {
QString speedStr = QString::number(std::nearbyint(speed));
p.setFont(InterFont(176, QFont::Bold));
drawText(p, surface_rect.center().x(), 210, speedStr);
p.setFont(InterFont(66));
drawText(p, surface_rect.center().x(), 290, is_metric ? tr("km/h") : tr("mph"), 200);
}
void HudRenderer::drawText(QPainter &p, int x, int y, const QString &text, int alpha) {
QRect real_rect = p.fontMetrics().boundingRect(text);
real_rect.moveCenter({x, y - real_rect.height() / 2});
p.setPen(QColor(0xff, 0xff, 0xff, alpha));
p.drawText(real_rect.x(), real_rect.bottom(), text);
}