diff --git a/common/params.cc b/common/params.cc index 08c728c9ed49ba..60f2baf41e49b6 100644 --- a/common/params.cc +++ b/common/params.cc @@ -214,6 +214,7 @@ std::unordered_map keys = { {"LQR", PERSISTENT}, {"ScreenOffTimer", PERSISTENT}, {"CruiseSpeedRewrite", PERSISTENT}, + {"DriverCamera", PERSISTENT}, }; } // namespace diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 053f3db8ae1349..d5efa66f9e21ba 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -88,6 +88,13 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { "openpilot will set its maximum speed to the vehicle's current speed."), "../assets/offroad/icon_cruise_speed_rewrite.png", }, + // DriverCamera, stolen from FrogPilot + { + "DriverCamera", + tr("Driver Camera On Reverse"), + tr("Displays the driver camera when in reverse."), + "../assets/img_driver_face_static.png", + }, { "IsMetric", tr("Use Metric System"), diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 141bdc82d176cf..dca6178d061e6f 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -189,7 +189,9 @@ void OnroadAlerts::updateAlert(const Alert &a) { } void OnroadAlerts::paintEvent(QPaintEvent *event) { - if (alert.size == cereal::ControlsState::AlertSize::NONE) { + const UIScene &scene = uiState()->scene; + + if (alert.size == cereal::ControlsState::AlertSize::NONE || scene.show_driver_camera) { return; } static std::map alert_heights = { @@ -246,7 +248,7 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) { } // ExperimentalButton -ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent) { +ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent), scene(uiState()->scene) { setFixedSize(btn_size, btn_size); engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size}); @@ -275,7 +277,9 @@ void ExperimentalButton::updateState(const UIState &s) { void ExperimentalButton::paintEvent(QPaintEvent *event) { QPainter p(this); QPixmap img = experimental_mode ? experimental_img : engage_img; - drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0); + if (!scene.show_driver_camera) { + drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0); + } } @@ -351,7 +355,7 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { has_eu_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::VIENNA); is_metric = s.scene.is_metric; speedUnit = s.scene.is_metric ? tr("km/h") : tr("mph"); - hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE); + hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE || showDriverCamera); status = s.status; // update engageability/experimental mode button @@ -363,7 +367,10 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { rightHandDM = dm_state.getIsRHD(); // DM icon transition dm_fade_state = std::clamp(dm_fade_state+0.2*(0.5-dmActive), 0.0, 1.0); - + + // FrogPilot variables + showDriverCamera = scene.show_driver_camera; + // FrogPilot properties setProperty("drivingPersonalitiesUIWheel", s.scene.driving_personalities_ui_wheel); setProperty("personalityProfile", s.scene.personality_profile); @@ -688,7 +695,7 @@ void AnnotatedCameraWidget::paintGL() { // for replay of old routes, never go to widecam wide_cam_requested = wide_cam_requested && s->scene.calibration_wide_valid; } - CameraWidget::setStreamType(wide_cam_requested ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD); + CameraWidget::setStreamType(showDriverCamera ? VISION_STREAM_DRIVER : wide_cam_requested ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD); s->scene.wide_cam = CameraWidget::getStreamType() == VISION_STREAM_WIDE_ROAD; if (s->scene.calibration_valid) { @@ -705,35 +712,37 @@ void AnnotatedCameraWidget::paintGL() { painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::NoPen); - if (s->worldObjectsVisible()) { - if (sm.rcv_frame("modelV2") > s->scene.started_frame) { - update_model(s, model, sm["uiPlan"].getUiPlan()); - if (sm.rcv_frame("radarState") > s->scene.started_frame) { - update_leads(s, radar_state, model.getPosition()); + if (!showDriverCamera) { + if (s->worldObjectsVisible()) { + if (sm.rcv_frame("modelV2") > s->scene.started_frame) { + update_model(s, model, sm["uiPlan"].getUiPlan()); + if (sm.rcv_frame("radarState") > s->scene.started_frame) { + update_leads(s, radar_state, model.getPosition()); + } } - } - - drawLaneLines(painter, s); - if (s->scene.longitudinal_control) { - auto lead_one = radar_state.getLeadOne(); - auto lead_two = radar_state.getLeadTwo(); - if (lead_one.getStatus()) { - drawLead(painter, lead_one, s->scene.lead_vertices[0]); - } - if (lead_two.getStatus() && (std::abs(lead_one.getDRel() - lead_two.getDRel()) > 3.0)) { - drawLead(painter, lead_two, s->scene.lead_vertices[1]); + drawLaneLines(painter, s); + + if (s->scene.longitudinal_control) { + auto lead_one = radar_state.getLeadOne(); + auto lead_two = radar_state.getLeadTwo(); + if (lead_one.getStatus()) { + drawLead(painter, lead_one, s->scene.lead_vertices[0]); + } + if (lead_two.getStatus() && (std::abs(lead_one.getDRel() - lead_two.getDRel()) > 3.0)) { + drawLead(painter, lead_two, s->scene.lead_vertices[1]); + } } } - } - // DMoji - if (!hideBottomIcons && (sm.rcv_frame("driverStateV2") > s->scene.started_frame)) { - update_dmonitoring(s, sm["driverStateV2"].getDriverStateV2(), dm_fade_state, rightHandDM); - drawDriverState(painter, s); - } + // DMoji + if (!hideBottomIcons && (sm.rcv_frame("driverStateV2") > s->scene.started_frame)) { + update_dmonitoring(s, sm["driverStateV2"].getDriverStateV2(), dm_fade_state, rightHandDM); + drawDriverState(painter, s); + } - drawHud(painter); + drawHud(painter); + } double cur_draw_t = millis_since_boot(); double dt = cur_draw_t - prev_draw_t; diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index bf2f562235bb05..dedf6bc8d42e85 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -108,6 +108,7 @@ class AnnotatedCameraWidget : public CameraWidget { // FrogPilot variables bool drivingPersonalitiesUIWheel; int personalityProfile; + bool showDriverCamera; QVector> profile_data; protected: diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index 6a5064e8ca2561..5243849f52b306 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -207,6 +207,7 @@ void CameraWidget::updateFrameMat() { if (active_stream_type == VISION_STREAM_DRIVER) { if (stream_width > 0 && stream_height > 0) { frame_mat = get_driver_view_transform(w, h, stream_width, stream_height); + frame_mat.v[0] *= -1.0; } } else { // Project point at "infinity" to compute x and y offsets diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index ff9097bccf8b4e..36daa414caba21 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -1159,6 +1159,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index be196e46888556..450616b6192363 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -1141,6 +1141,14 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index b2e40bd892d662..5f2e9eda450758 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -1143,6 +1143,14 @@ Cela peut prendre jusqu'à une minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 98150f5fe6153c..f7ef3458310c91 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -1137,6 +1137,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 750d5f3aafc548..b1c1ae88db312b 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -1139,6 +1139,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 1d7c37a7e373db..f7d094ebc1e44f 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -1141,6 +1141,14 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index a1bfcee3051126..43bed04355d496 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -1139,6 +1139,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 899526df803f1f..3b4095d99aecc0 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -1137,6 +1137,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index f5a06724461887..2edb9d26aa6eb3 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -1139,6 +1139,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index fd29f70c04f1b2..3cc71173e04a6e 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -1139,6 +1139,14 @@ This may take up to a minute. 3 bars = Relaxed + + Driver Camera On Reverse + + + + Displays the driver camera when in reverse. + + Updater diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index f23ce6f826880f..e5f996f0bde149 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -201,6 +201,12 @@ static void update_state(UIState *s) { if (sm.updated("carParams")) { scene.longitudinal_control = sm["carParams"].getCarParams().getOpenpilotLongitudinalControl(); } + if (sm.updated("carState")) { + const auto carState = sm["carState"].getCarState(); + if (scene.driver_camera) { + scene.show_driver_camera = carState.getGearShifter() == cereal::CarState::GearShifter::REVERSE; + } + } if (sm.updated("wideRoadCameraState")) { auto cam_state = sm["wideRoadCameraState"].getWideRoadCameraState(); float scale = (cam_state.getSensor() == cereal::FrameData::ImageSensor::AR0231) ? 6.0f : 1.0f; @@ -218,6 +224,7 @@ void ui_update_params(UIState *s) { // FrogPilot variables UIScene &scene = s->scene; scene.driving_personalities_ui_wheel = params.getBool("DrivingPersonalitiesUIWheel"); + scene.driver_camera = params.getBool("DriverCamera"); } void ui_live_update_params(UIState *s) { diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index da23c9b1a9b2a4..49707f713e7ff7 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -155,6 +155,8 @@ typedef struct UIScene { // FrogPilot variables int personality_profile; bool driving_personalities_ui_wheel; + bool driver_camera; + bool show_driver_camera; } UIScene;