ui.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #pragma once
  2. #include <memory>
  3. #include <string>
  4. #include <optional>
  5. #include <QObject>
  6. #include <QTimer>
  7. #include <QColor>
  8. #include <QFuture>
  9. #include <QPolygonF>
  10. #include <QTransform>
  11. #include "cereal/messaging/messaging.h"
  12. #include "common/modeldata.h"
  13. #include "common/params.h"
  14. #include "common/timing.h"
  15. const int bdr_s = 30;
  16. const int header_h = 420;
  17. const int footer_h = 280;
  18. const int UI_FREQ = 20; // Hz
  19. typedef cereal::CarControl::HUDControl::AudibleAlert AudibleAlert;
  20. const mat3 DEFAULT_CALIBRATION = {{ 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0 }};
  21. struct Alert {
  22. QString text1;
  23. QString text2;
  24. QString type;
  25. cereal::ControlsState::AlertSize size;
  26. AudibleAlert sound;
  27. bool equal(const Alert &a2) {
  28. return text1 == a2.text1 && text2 == a2.text2 && type == a2.type && sound == a2.sound;
  29. }
  30. static Alert get(const SubMaster &sm, uint64_t started_frame) {
  31. const cereal::ControlsState::Reader &cs = sm["controlsState"].getControlsState();
  32. if (sm.updated("controlsState")) {
  33. return {cs.getAlertText1().cStr(), cs.getAlertText2().cStr(),
  34. cs.getAlertType().cStr(), cs.getAlertSize(),
  35. cs.getAlertSound()};
  36. } else if ((sm.frame - started_frame) > 5 * UI_FREQ) {
  37. const int CONTROLS_TIMEOUT = 5;
  38. const int controls_missing = (nanos_since_boot() - sm.rcv_time("controlsState")) / 1e9;
  39. // Handle controls timeout
  40. if (sm.rcv_frame("controlsState") < started_frame) {
  41. // car is started, but controlsState hasn't been seen at all
  42. return {"openpilot Unavailable", "Waiting for controls to start",
  43. "controlsWaiting", cereal::ControlsState::AlertSize::MID,
  44. AudibleAlert::NONE};
  45. } else if (controls_missing > CONTROLS_TIMEOUT && !Hardware::PC()) {
  46. // car is started, but controls is lagging or died
  47. if (cs.getEnabled() && (controls_missing - CONTROLS_TIMEOUT) < 10) {
  48. return {"TAKE CONTROL IMMEDIATELY", "Controls Unresponsive",
  49. "controlsUnresponsive", cereal::ControlsState::AlertSize::FULL,
  50. AudibleAlert::WARNING_IMMEDIATE};
  51. } else {
  52. return {"Controls Unresponsive", "Reboot Device",
  53. "controlsUnresponsivePermanent", cereal::ControlsState::AlertSize::MID,
  54. AudibleAlert::NONE};
  55. }
  56. }
  57. }
  58. return {};
  59. }
  60. };
  61. typedef enum UIStatus {
  62. STATUS_DISENGAGED,
  63. STATUS_OVERRIDE,
  64. STATUS_ENGAGED,
  65. STATUS_WARNING,
  66. STATUS_ALERT,
  67. } UIStatus;
  68. const QColor bg_colors [] = {
  69. [STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
  70. [STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
  71. [STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
  72. [STATUS_WARNING] = QColor(0xDA, 0x6F, 0x25, 0xf1),
  73. [STATUS_ALERT] = QColor(0xC9, 0x22, 0x31, 0xf1),
  74. };
  75. typedef struct UIScene {
  76. bool calibration_valid = false;
  77. bool calibration_wide_valid = false;
  78. bool wide_cam = true;
  79. mat3 view_from_calib = DEFAULT_CALIBRATION;
  80. mat3 view_from_wide_calib = DEFAULT_CALIBRATION;
  81. cereal::PandaState::PandaType pandaType;
  82. // modelV2
  83. float lane_line_probs[4];
  84. float road_edge_stds[2];
  85. QPolygonF track_vertices;
  86. QPolygonF lane_line_vertices[4];
  87. QPolygonF road_edge_vertices[2];
  88. // lead
  89. QPointF lead_vertices[2];
  90. float light_sensor;
  91. bool started, ignition, is_metric, map_on_left, longitudinal_control;
  92. uint64_t started_frame;
  93. } UIScene;
  94. class UIState : public QObject {
  95. Q_OBJECT
  96. public:
  97. UIState(QObject* parent = 0);
  98. void updateStatus();
  99. inline bool worldObjectsVisible() const {
  100. return sm->rcv_frame("liveCalibration") > scene.started_frame;
  101. };
  102. inline bool engaged() const {
  103. return scene.started && (*sm)["controlsState"].getControlsState().getEnabled();
  104. };
  105. int fb_w = 0, fb_h = 0;
  106. std::unique_ptr<SubMaster> sm;
  107. UIStatus status;
  108. UIScene scene = {};
  109. bool awake;
  110. int prime_type;
  111. QString language;
  112. QTransform car_space_transform;
  113. bool wide_cam_only;
  114. signals:
  115. void uiUpdate(const UIState &s);
  116. void offroadTransition(bool offroad);
  117. void primeTypeChanged(int prime_type);
  118. private slots:
  119. void update();
  120. private:
  121. QTimer *timer;
  122. bool started_prev = false;
  123. int prime_type_prev = -1;
  124. };
  125. UIState *uiState();
  126. // device management class
  127. class Device : public QObject {
  128. Q_OBJECT
  129. public:
  130. Device(QObject *parent = 0);
  131. private:
  132. bool awake = false;
  133. int interactive_timeout = 0;
  134. bool ignition_on = false;
  135. int last_brightness = 0;
  136. FirstOrderFilter brightness_filter;
  137. QFuture<void> brightness_future;
  138. void updateBrightness(const UIState &s);
  139. void updateWakefulness(const UIState &s);
  140. bool motionTriggered(const UIState &s);
  141. void setAwake(bool on);
  142. signals:
  143. void displayPowerChanged(bool on);
  144. void interactiveTimout();
  145. public slots:
  146. void resetInteractiveTimout();
  147. void update(const UIState &s);
  148. };
  149. void ui_update_params(UIState *s);
  150. int get_path_length_idx(const cereal::ModelDataV2::XYZTData::Reader &line, const float path_height);
  151. void update_model(UIState *s, const cereal::ModelDataV2::Reader &model);
  152. void update_leads(UIState *s, const cereal::RadarState::Reader &radar_state, const cereal::ModelDataV2::XYZTData::Reader &line);
  153. void update_line_data(const UIState *s, const cereal::ModelDataV2::XYZTData::Reader &line,
  154. float y_off, float z_off, QPolygonF *pvd, int max_idx, bool allow_invert);