ui: refactor hud updating and rendering into HudRenderer class  (#33458)
	
		
	
				
					
				
			refactor hud updating and rendering into DriverMonitorRenderer classfix-notebooks
							parent
							
								
									900c2c83bd
								
							
						
					
					
						commit
						caa33c3193
					
				
				 16 changed files with 302 additions and 269 deletions
			
			
		| @ -0,0 +1,109 @@ | |||||||
|  | #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.alive("carState")) { | ||||||
|  |     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; | ||||||
|  | 
 | ||||||
|  |   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); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   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) { | ||||||
|  |     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); | ||||||
|  |       set_speed_color = QColor(255, 255, 255); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 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); | ||||||
|  | } | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <QPainter> | ||||||
|  | #include "selfdrive/ui/ui.h" | ||||||
|  | 
 | ||||||
|  | class HudRenderer : public QObject { | ||||||
|  | public: | ||||||
|  |   HudRenderer(); | ||||||
|  |   void updateState(const UIState &s); | ||||||
|  |   void draw(QPainter &p, const QRect &surface_rect); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |   void drawSetSpeed(QPainter &p, const QRect &surface_rect); | ||||||
|  |   void drawCurrentSpeed(QPainter &p, const QRect &surface_rect); | ||||||
|  |   void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255); | ||||||
|  | 
 | ||||||
|  |   float speed = 0; | ||||||
|  |   float set_speed = 0; | ||||||
|  |   bool is_cruise_set = false; | ||||||
|  |   bool is_metric = false; | ||||||
|  |   bool v_ego_cluster_seen = false; | ||||||
|  |   int status = STATUS_DISENGAGED; | ||||||
|  | }; | ||||||
					Loading…
					
					
				
		Reference in new issue