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.
		
		
		
		
		
			
		
			
				
					
					
						
							182 lines
						
					
					
						
							4.7 KiB
						
					
					
				
			
		
		
	
	
							182 lines
						
					
					
						
							4.7 KiB
						
					
					
				| #pragma once
 | |
| 
 | |
| #include <memory>
 | |
| #include <string>
 | |
| #include <optional>
 | |
| 
 | |
| #include <QObject>
 | |
| #include <QTimer>
 | |
| #include <QColor>
 | |
| #include <QFuture>
 | |
| #include <QTransform>
 | |
| 
 | |
| #include "cereal/messaging/messaging.h"
 | |
| #include "selfdrive/common/modeldata.h"
 | |
| #include "selfdrive/common/params.h"
 | |
| #include "selfdrive/common/timing.h"
 | |
| 
 | |
| const int bdr_s = 30;
 | |
| const int header_h = 420;
 | |
| const int footer_h = 280;
 | |
| 
 | |
| const int UI_FREQ = 20;   // Hz
 | |
| typedef cereal::CarControl::HUDControl::AudibleAlert AudibleAlert;
 | |
| 
 | |
| // TODO: this is also hardcoded in common/transformations/camera.py
 | |
| // TODO: choose based on frame input size
 | |
| const float y_offset = Hardware::EON() ? 0.0 : 150.0;
 | |
| const float ZOOM = Hardware::EON() ? 2138.5 : 2912.8;
 | |
| 
 | |
| struct Alert {
 | |
|   QString text1;
 | |
|   QString text2;
 | |
|   QString type;
 | |
|   cereal::ControlsState::AlertSize size;
 | |
|   AudibleAlert sound;
 | |
| 
 | |
|   bool equal(const Alert &a2) {
 | |
|     return text1 == a2.text1 && text2 == a2.text2 && type == a2.type && sound == a2.sound;
 | |
|   }
 | |
| 
 | |
|   static Alert get(const SubMaster &sm, uint64_t started_frame) {
 | |
|     const cereal::ControlsState::Reader &cs = sm["controlsState"].getControlsState();
 | |
|     if (sm.updated("controlsState")) {
 | |
|       return {cs.getAlertText1().cStr(), cs.getAlertText2().cStr(),
 | |
|               cs.getAlertType().cStr(), cs.getAlertSize(),
 | |
|               cs.getAlertSound()};
 | |
|     } else if ((sm.frame - started_frame) > 5 * UI_FREQ) {
 | |
|       const int CONTROLS_TIMEOUT = 5;
 | |
|       const int controls_missing = (nanos_since_boot() - sm.rcv_time("controlsState")) / 1e9;
 | |
| 
 | |
|       // Handle controls timeout
 | |
|       if (sm.rcv_frame("controlsState") < started_frame) {
 | |
|         // car is started, but controlsState hasn't been seen at all
 | |
|         return {"openpilot Unavailable", "Waiting for controls to start",
 | |
|                 "controlsWaiting", cereal::ControlsState::AlertSize::MID,
 | |
|                 AudibleAlert::NONE};
 | |
|       } else if (controls_missing > CONTROLS_TIMEOUT) {
 | |
|         // 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,
 | |
|                   AudibleAlert::WARNING_IMMEDIATE};
 | |
|         } else {
 | |
|           return {"Controls Unresponsive", "Reboot Device",
 | |
|                   "controlsUnresponsivePermanent", cereal::ControlsState::AlertSize::MID,
 | |
|                   AudibleAlert::NONE};
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return {};
 | |
|   }
 | |
| };
 | |
| 
 | |
| typedef enum UIStatus {
 | |
|   STATUS_DISENGAGED,
 | |
|   STATUS_ENGAGED,
 | |
|   STATUS_WARNING,
 | |
|   STATUS_ALERT,
 | |
| } UIStatus;
 | |
| 
 | |
| const QColor bg_colors [] = {
 | |
|   [STATUS_DISENGAGED] =  QColor(0x17, 0x33, 0x49, 0xc8),
 | |
|   [STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
 | |
|   [STATUS_WARNING] = QColor(0xDA, 0x6F, 0x25, 0xf1),
 | |
|   [STATUS_ALERT] = QColor(0xC9, 0x22, 0x31, 0xf1),
 | |
| };
 | |
| 
 | |
| typedef struct {
 | |
|   QPointF v[TRAJECTORY_SIZE * 2];
 | |
|   int cnt;
 | |
| } line_vertices_data;
 | |
| 
 | |
| typedef struct UIScene {
 | |
|   mat3 view_from_calib;
 | |
|   cereal::PandaState::PandaType pandaType;
 | |
| 
 | |
|   // modelV2
 | |
|   float lane_line_probs[4];
 | |
|   float road_edge_stds[2];
 | |
|   line_vertices_data track_vertices;
 | |
|   line_vertices_data lane_line_vertices[4];
 | |
|   line_vertices_data road_edge_vertices[2];
 | |
| 
 | |
|   // lead
 | |
|   QPointF lead_vertices[2];
 | |
| 
 | |
|   float light_sensor, accel_sensor, gyro_sensor;
 | |
|   bool started, ignition, is_metric, longitudinal_control, end_to_end;
 | |
|   uint64_t started_frame;
 | |
| } UIScene;
 | |
| 
 | |
| class UIState : public QObject {
 | |
|   Q_OBJECT
 | |
| 
 | |
| public:
 | |
|   UIState(QObject* parent = 0);
 | |
|   void updateStatus();
 | |
|   inline bool worldObjectsVisible() const { 
 | |
|     return sm->rcv_frame("liveCalibration") > scene.started_frame;
 | |
|   };
 | |
| 
 | |
|   int fb_w = 0, fb_h = 0;
 | |
| 
 | |
|   std::unique_ptr<SubMaster> sm;
 | |
| 
 | |
|   UIStatus status;
 | |
|   UIScene scene = {};
 | |
| 
 | |
|   bool awake;
 | |
|   bool has_prime = false;
 | |
| 
 | |
|   QTransform car_space_transform;
 | |
|   bool wide_camera;
 | |
| 
 | |
| signals:
 | |
|   void uiUpdate(const UIState &s);
 | |
|   void offroadTransition(bool offroad);
 | |
| 
 | |
| private slots:
 | |
|   void update();
 | |
| 
 | |
| private:
 | |
|   QTimer *timer;
 | |
|   bool started_prev = true;
 | |
| };
 | |
| 
 | |
| UIState *uiState();
 | |
| 
 | |
| // device management class
 | |
| 
 | |
| class Device : public QObject {
 | |
|   Q_OBJECT
 | |
| 
 | |
| public:
 | |
|   Device(QObject *parent = 0);
 | |
| 
 | |
| private:
 | |
|   // auto brightness
 | |
|   const float accel_samples = 5*UI_FREQ;
 | |
| 
 | |
|   bool awake = false;
 | |
|   int interactive_timeout = 0;
 | |
|   bool ignition_on = false;
 | |
|   int last_brightness = 0;
 | |
|   FirstOrderFilter brightness_filter;
 | |
|   QFuture<void> brightness_future;
 | |
| 
 | |
|   void updateBrightness(const UIState &s);
 | |
|   void updateWakefulness(const UIState &s);
 | |
|   bool motionTriggered(const UIState &s);
 | |
|   void setAwake(bool on);
 | |
| 
 | |
| signals:
 | |
|   void displayPowerChanged(bool on);
 | |
|   void interactiveTimout();
 | |
| 
 | |
| public slots:
 | |
|   void resetInteractiveTimout();
 | |
|   void update(const UIState &s);
 | |
| };
 | |
| 
 | |
| void ui_update_params(UIState *s);
 | |
| 
 |