diff --git a/common/fw-update-helper.cpp b/common/fw-update-helper.cpp index c1048efc2b..d5d50f0b54 100644 --- a/common/fw-update-helper.cpp +++ b/common/fw-update-helper.cpp @@ -15,15 +15,18 @@ #ifdef INTERNAL_FW #include "common/fw/D4XX_FW_Image.h" +#include "common/fw/D4XX_RC_Image.h" #include "common/fw/SR3XX_FW_Image.h" #else #define FW_D4XX_FW_IMAGE_VERSION "" +#define FW_D4XX_RC_IMAGE_VERSION "" #define FW_SR3XX_FW_IMAGE_VERSION "" const char* fw_get_D4XX_FW_Image(int) { return NULL; } +const char* fw_get_D4XX_RC_Image(int) { return NULL; } const char* fw_get_SR3XX_FW_Image(int) { return NULL; } #endif // INTERNAL_FW -constexpr const char* recommended_fw_url = "https://downloadcenter.intel.com/download/27522/Latest-Firmware-for-Intel-RealSense-D400-Product-Family?v=t"; +constexpr const char* recommended_fw_url = "https://dev.intelrealsense.com/docs/firmware-releases"; namespace rs2 { @@ -40,12 +43,6 @@ namespace rs2 return !(strcmp("", FW_D4XX_FW_IMAGE_VERSION) == 0); } - static std::map product_line_to_fw = - { - {RS2_PRODUCT_LINE_D400, FW_D4XX_FW_IMAGE_VERSION}, - {RS2_PRODUCT_LINE_SR300, FW_SR3XX_FW_IMAGE_VERSION}, - }; - int parse_product_line(std::string id) { if (id == "D400") return RS2_PRODUCT_LINE_D400; @@ -55,17 +52,21 @@ namespace rs2 std::string get_available_firmware_version(int product_line) { - auto it = product_line_to_fw.find(product_line); - if (it != product_line_to_fw.end()) - return it->second; - return ""; + bool allow_rc_firmware = config_file::instance().get_or_default(configurations::update::allow_rc_firmware, false); + + if (product_line == RS2_PRODUCT_LINE_D400 && allow_rc_firmware) return FW_D4XX_RC_IMAGE_VERSION; + else if (product_line == RS2_PRODUCT_LINE_D400) return FW_D4XX_FW_IMAGE_VERSION; + else if (product_line == RS2_PRODUCT_LINE_SR300) return FW_SR3XX_FW_IMAGE_VERSION; + else return ""; } std::map> create_default_fw_table() { + bool allow_rc_firmware = config_file::instance().get_or_default(configurations::update::allow_rc_firmware, false); + std::map> rv; - if ("" != FW_D4XX_FW_IMAGE_VERSION) + if ("" != FW_D4XX_FW_IMAGE_VERSION && !allow_rc_firmware) { int size = 0; auto hex = fw_get_D4XX_FW_Image(size); @@ -73,6 +74,14 @@ namespace rs2 rv[RS2_PRODUCT_LINE_D400] = vec; } + if ("" != FW_D4XX_RC_IMAGE_VERSION && allow_rc_firmware) + { + int size = 0; + auto hex = fw_get_D4XX_RC_Image(size); + auto vec = std::vector(hex, hex + size); + rv[RS2_PRODUCT_LINE_D400] = vec; + } + if ("" != FW_SR3XX_FW_IMAGE_VERSION) { int size = 0; diff --git a/common/fw/CMakeLists.txt b/common/fw/CMakeLists.txt index 1cfc204a29..440d0f3af3 100644 --- a/common/fw/CMakeLists.txt +++ b/common/fw/CMakeLists.txt @@ -8,12 +8,19 @@ file(READ "firmware-version.h" ver) message(STATUS "Fetching recommended firmwares:") +string(REGEX MATCH "D4XX_RC_FIRMWARE_VERSION \"([0-9]+.[0-9]+.[0-9]+.[0-9]+)\"" _ ${ver}) +set(D4XX_RC_VERSION ${CMAKE_MATCH_1}) +message(STATUS "D4XX_RC_VERSION: ${D4XX_RC_VERSION}") +set(D4XX_RC_SHA1 7ae298ff3c7bb1a6afc6fe70b3ec6527adcecd73) +set(D4XX_RC_URL "http://realsense-hw-public.s3-eu-west-1.amazonaws.com/Releases/RS4xx/FW") + string(REGEX MATCH "D4XX_RECOMMENDED_FIRMWARE_VERSION \"([0-9]+.[0-9]+.[0-9]+.[0-9]+)\"" _ ${ver}) set(D4XX_FW_VERSION ${CMAKE_MATCH_1}) message(STATUS "D4XX_FW_VERSION: ${D4XX_FW_VERSION}") -set(D4XX_FW_SHA1 7ae298ff3c7bb1a6afc6fe70b3ec6527adcecd73) +set(D4XX_FW_SHA1 2fb8830cd86c0871e59ec17bd674d98df229442b) set(D4XX_FW_URL "http://realsense-hw-public.s3-eu-west-1.amazonaws.com/Releases/RS4xx/FW") + string(REGEX MATCH "SR3XX_RECOMMENDED_FIRMWARE_VERSION \"([0-9]+.[0-9]+.[0-9]+.[0-9]+)\"" _ ${ver}) set(SR3XX_FW_VERSION ${CMAKE_MATCH_1}) message(STATUS "SR3XX_FW_VERSION: ${SR3XX_FW_VERSION}") @@ -61,6 +68,7 @@ function(target_binary url version sha1 symbol ext) endfunction() target_binary( "${D4XX_FW_URL}" "${D4XX_FW_VERSION}" "${D4XX_FW_SHA1}" D4XX_FW_Image .bin) +target_binary( "${D4XX_RC_URL}" "${D4XX_RC_VERSION}" "${D4XX_RC_SHA1}" D4XX_RC_Image .bin) target_binary( "${SR3XX_FW_URL}" "${SR3XX_FW_VERSION}" "${SR3XX_FW_SHA1}" SR3XX_FW_Image .bin) install(TARGETS ${PROJECT_NAME} EXPORT realsense2Targets diff --git a/common/fw/firmware-version.h b/common/fw/firmware-version.h index 08f1b8fcfe..c92d4d046c 100644 --- a/common/fw/firmware-version.h +++ b/common/fw/firmware-version.h @@ -3,5 +3,6 @@ #pragma once -#define D4XX_RECOMMENDED_FIRMWARE_VERSION "5.11.14.0" +#define D4XX_RECOMMENDED_FIRMWARE_VERSION "5.11.11.100" #define SR3XX_RECOMMENDED_FIRMWARE_VERSION "3.26.1.0" +#define D4XX_RC_FIRMWARE_VERSION "5.11.14.0" \ No newline at end of file diff --git a/common/fw/uvc_fw.rc b/common/fw/uvc_fw.rc index 301cfc9570..2de1f53c73 100644 --- a/common/fw/uvc_fw.rc +++ b/common/fw/uvc_fw.rc @@ -1,2 +1,3 @@ #include "D4XX_FW_Image.rc" +#include "D4XX_RC_Image.rc" #include "SR3XX_FW_Image.rc" diff --git a/common/model-views.cpp b/common/model-views.cpp index 2f8841b34b..7208596714 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -2935,84 +2935,111 @@ namespace rs2 for (auto&& n : related_notifications) n->dismiss(false); } - device_model::device_model(device& dev, std::string& error_message, viewer_model& viewer) - : dev(dev), - syncer(viewer.syncer), - _update_readonly_options_timer(std::chrono::seconds(6)) - { + void device_model::refresh_notifications(viewer_model& viewer) + { + for (auto&& n : related_notifications) n->dismiss(false); + auto name = get_device_name(dev); - id = to_string() << name.first << ", " << name.second; - bool fw_update_required = false; - for (auto&& sub : dev.query_sensors()) + if ((bool)config_file::instance().get(configurations::update::recommend_updates)) { - if (sub.supports(RS2_CAMERA_INFO_FIRMWARE_VERSION) && - sub.supports(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION) && - sub.supports(RS2_CAMERA_INFO_PRODUCT_LINE)) + bool fw_update_required = false; + for (auto&& sub : dev.query_sensors()) { - std::string fw = sub.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION); - std::string recommended = sub.get_info(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION); + if (sub.supports(RS2_CAMERA_INFO_FIRMWARE_VERSION) && + sub.supports(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION) && + sub.supports(RS2_CAMERA_INFO_PRODUCT_LINE)) + { + std::string fw = sub.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION); + std::string recommended = sub.get_info(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION); - int product_line = parse_product_line(sub.get_info(RS2_CAMERA_INFO_PRODUCT_LINE)); + int product_line = parse_product_line(sub.get_info(RS2_CAMERA_INFO_PRODUCT_LINE)); - std::string available = get_available_firmware_version(product_line); + bool allow_rc_firmware = config_file::instance().get_or_default(configurations::update::allow_rc_firmware, false); + bool is_rc = (product_line == RS2_PRODUCT_LINE_D400) && allow_rc_firmware; + std::string available = get_available_firmware_version(product_line); - std::shared_ptr manager = nullptr; + std::shared_ptr manager = nullptr; - if (is_upgradeable(fw, available)) - { - recommended = available; + if (is_upgradeable(fw, available)) + { + recommended = available; - static auto table = create_default_fw_table(); + static auto table = create_default_fw_table(); - manager = std::make_shared(*this, dev, viewer.ctx, table[product_line], true); - } + manager = std::make_shared(*this, dev, viewer.ctx, table[product_line], true); + } - if (is_upgradeable(fw, recommended)) - { - std::string msg = to_string() - << name.first << " (S/N " << name.second << ")\n" - << "Current Version: " + fw + "\nRecommended Version: " + recommended; - if (!fw_update_required) + if (is_upgradeable(fw, recommended)) { - auto n = std::make_shared( - msg, manager, false); - viewer.not_model.add_notification(n); + std::stringstream msg; + msg << name.first << " (S/N " << name.second << ")\n" + << "Current Version: " << fw << "\n"; - fw_update_required = true; + if (is_rc) + msg << "Release Candidate: " << recommended << " Pre-Release"; + else + msg << "Recommended Version: " << recommended; + + if (!fw_update_required) + { + auto n = std::make_shared( + msg.str(), manager, false); + viewer.not_model.add_notification(n); - related_notifications.push_back(n); + fw_update_required = true; + + related_notifications.push_back(n); + } } - } + } } + } - auto model = std::make_shared(dev, std::make_shared(sub), error_message, viewer); - subdevices.push_back(model); - - if (model->supports_on_chip_calib()) + if ((bool)config_file::instance().get(configurations::update::recommend_calibration)) + { + for (auto&& model : subdevices) { - // Make sure we don't spam calibration remainders too often: - time_t rawtime; - time(&rawtime); - std::string id = to_string() << configurations::viewer::last_calib_notice << "." << name.second; - long long last_time = config_file::instance().get_or_default(id.c_str(), (long long)0); - - std::string msg = to_string() - << name.first << " (S/N " << name.second << ")"; - auto manager = std::make_shared(viewer, model, *this, dev); - auto n = std::make_shared( - msg, manager, false); - - // Recommend calibration once a week per device - if (rawtime - last_time < 60) + if (model->supports_on_chip_calib()) { - n->snoozed = true; + // Make sure we don't spam calibration remainders too often: + time_t rawtime; + time(&rawtime); + std::string id = to_string() << configurations::viewer::last_calib_notice << "." << name.second; + long long last_time = config_file::instance().get_or_default(id.c_str(), (long long)0); + + std::string msg = to_string() + << name.first << " (S/N " << name.second << ")"; + auto manager = std::make_shared(viewer, model, *this, dev); + auto n = std::make_shared( + msg, manager, false); + + // Recommend calibration once a week per device + if (rawtime - last_time < 60) + { + n->snoozed = true; + } + + viewer.not_model.add_notification(n); + related_notifications.push_back(n); } - - viewer.not_model.add_notification(n); - related_notifications.push_back(n); } } + } + + device_model::device_model(device& dev, std::string& error_message, viewer_model& viewer) + : dev(dev), + syncer(viewer.syncer), + _update_readonly_options_timer(std::chrono::seconds(6)) + { + auto name = get_device_name(dev); + id = to_string() << name.first << ", " << name.second; + + for (auto&& sub : dev.query_sensors()) + { + auto model = std::make_shared(dev, std::make_shared(sub), error_message, viewer); + subdevices.push_back(model); + } // Initialize static camera info: for (auto i = 0; i < RS2_CAMERA_INFO_COUNT; i++) @@ -3046,6 +3073,8 @@ namespace rs2 } play_defaults(viewer); } + + refresh_notifications(viewer); } void device_model::play_defaults(viewer_model& viewer) { @@ -4302,7 +4331,7 @@ namespace rs2 product_line_str = sensors.front().get_info(RS2_CAMERA_INFO_PRODUCT_LINE); int product_line = parse_product_line(product_line_str); - static auto table = create_default_fw_table(); + auto table = create_default_fw_table(); begin_update(table[product_line], viewer, error_message); } diff --git a/common/model-views.h b/common/model-views.h index 720a93ef89..8d32bf902b 100644 --- a/common/model-views.h +++ b/common/model-views.h @@ -146,6 +146,12 @@ namespace rs2 static const char* default_path { "record.default_path" }; static const char* compression_mode { "record.compression" }; } + namespace update + { + static const char* allow_rc_firmware { "update.allow_rc_firmware" }; + static const char* recommend_updates { "update.recommend_updates" }; + static const char* recommend_calibration { "update.recommend_calibration" }; + } namespace viewer { static const char* is_3d_view { "viewer_model.is_3d_view" }; @@ -765,6 +771,9 @@ namespace rs2 void stop_recording(viewer_model& viewer); void pause_record(); void resume_record(); + + void refresh_notifications(viewer_model& viewer); + int draw_playback_panel(ux_window& window, ImFont* font, viewer_model& view); bool draw_advanced_controls(viewer_model& view, ux_window& window, std::string& error_message); void draw_controls(float panel_width, float panel_height, diff --git a/common/ux-window.cpp b/common/ux-window.cpp index 2ebb4aa9ff..6840c16d53 100644 --- a/common/ux-window.cpp +++ b/common/ux-window.cpp @@ -25,6 +25,10 @@ namespace rs2 { void prepare_config_file() { + config_file::instance().set_default(configurations::update::allow_rc_firmware, false); + config_file::instance().set_default(configurations::update::recommend_calibration, true); + config_file::instance().set_default(configurations::update::recommend_updates, true); + config_file::instance().set_default(configurations::window::is_fullscreen, false); config_file::instance().set_default(configurations::window::saved_pos, false); config_file::instance().set_default(configurations::window::saved_size, false); diff --git a/common/viewer.cpp b/common/viewer.cpp index 2ca1de2304..ec6834a995 100644 --- a/common/viewer.cpp +++ b/common/viewer.cpp @@ -1806,6 +1806,7 @@ namespace rs2 static config_file temp_cfg; static bool reload_required = false; static bool refresh_required = false; + static bool refresh_updates = false; static int tab = 0; @@ -1838,7 +1839,7 @@ namespace rs2 if (ImGui::BeginPopupModal(settings, nullptr, flags)) { - ImGui::SetCursorScreenPos({ (float)(x0 + w / 2 - 220), (float)(y0 + 27) }); + ImGui::SetCursorScreenPos({ (float)(x0 + w / 2 - 280), (float)(y0 + 27) }); ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, sensor_bg); ImGui::PushFont(window.get_large_font()); @@ -1874,7 +1875,17 @@ namespace rs2 temp_cfg.set(configurations::viewer::settings_tab, tab); } ImGui::PopStyleColor(2); - //ImGui::SameLine(); + + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, tab != 3 ? light_grey : light_blue); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, tab != 3 ? light_grey : light_blue); + if (ImGui::Button("Updates", { 120, 30 })) + { + tab = 3; + config_file::instance().set(configurations::viewer::settings_tab, tab); + temp_cfg.set(configurations::viewer::settings_tab, tab); + } + ImGui::PopStyleColor(2); ImGui::PopFont(); ImGui::PopStyleColor(2); // button color @@ -2126,6 +2137,43 @@ namespace rs2 } } + if (tab == 3) + { + bool recommend_calibration = temp_cfg.get(configurations::update::recommend_calibration); + if (ImGui::Checkbox("Recommend Camera Calibration", &recommend_calibration)) + { + temp_cfg.set(configurations::update::recommend_calibration, recommend_calibration); + refresh_updates = true; + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "When checked, the Viewer / DQT will post weekly remainders for on-chip calibration"); + } + + bool recommend_fw_updates = temp_cfg.get(configurations::update::recommend_updates); + if (ImGui::Checkbox("Recommend Firmware Updates", &recommend_fw_updates)) + { + temp_cfg.set(configurations::update::recommend_updates, recommend_fw_updates); + refresh_updates = true; + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "When firmware of the device is below the version bundled with this software release\nsuggest firmware update"); + } + + bool allow_rc_firmware = temp_cfg.get(configurations::update::allow_rc_firmware); + if (ImGui::Checkbox("Access Pre-Release Firmware Updates", &allow_rc_firmware)) + { + temp_cfg.set(configurations::update::allow_rc_firmware, allow_rc_firmware); + refresh_updates = true; + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "Firmware Releases recommended for production-use are published at dev.intelrealsense.com/docs/firmware-releases\n" + "After firmware version passes basic regression tests and until it is published on the site, it is available as a Pre-Release\n"); + } + } + ImGui::Separator(); ImGui::GetWindowDrawList()->AddRectFilled({ (float)x0, (float)(y0 + h - 60) }, @@ -2144,6 +2192,10 @@ namespace rs2 if (reload_required) window.reload(); else if (refresh_required) window.refresh(); update_configuration(); + + if (refresh_updates) + for (auto&& dev : devices) + dev->refresh_notifications(*this); }; ImGui::SetCursorScreenPos({ (float)(x0 + w / 2 - 190), (float)(y0 + h - 30) });