From 9b9b452d4bd81fe3b590951398804b11aa572e9e Mon Sep 17 00:00:00 2001 From: Tamir Date: Thu, 8 Feb 2024 10:38:21 +0200 Subject: [PATCH 01/12] drawing empty accel dashboard --- common/output-model.cpp | 44 +++++++++++++++++++++++++++++++++++++++++ common/output-model.h | 31 +++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/common/output-model.cpp b/common/output-model.cpp index 2c471a7700..8b22f3695f 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -123,6 +123,10 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ return std::make_shared(name, &number_of_drops, &total_frames); }; + available_dashboards["Acceleration"] = [&]( std::string name ){ + return std::make_shared< accel_dashboard >( name ); + }; + auto front = available_dashboards.begin(); dashboards.push_back(front->second(front->first)); } @@ -1220,3 +1224,43 @@ void frame_drops_dashboard::clear(bool full) } }); } + +void accel_dashboard::draw(ux_window& win, rect r) { + auto accel_hist = read_shared_data< std::deque< int > >( [&]() { return accel_history; } ); + for( int i = 0; i < accel_hist.size(); i++ ) + { + add_point( (float)i, (float)accel_hist[i] ); + } + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; + draw_dashboard( win, r ); + + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); + ImGui::Text( "%s", "Measurement Metric:" ); + ImGui::SameLine(); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() - 3 ); + + ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); +} + +int accel_dashboard::get_height() const { + return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); +} + +void accel_dashboard::clear( bool full ) { + write_shared_data( + [&]() + { + if( full ) + { + accel_history.clear(); + + for( int i = 0; i < 100; i++ ) // What it do? + accel_history.push_back( 0 ); + } + } ); +} + +void accel_dashboard::process_frame( rs2::frame f ) { + +} \ No newline at end of file diff --git a/common/output-model.h b/common/output-model.h index 9d5ce8dd71..42111fca5c 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -113,6 +113,37 @@ namespace rs2 int method = 0; }; + class accel_dashboard : public stream_dashboard + { + public: + // Constructor + accel_dashboard( std::string name ) + : stream_dashboard( name, 30) + { + x = y = z = accel = 0; + clear( true ); + } + + // Functions + void process_frame( rs2::frame f ) override; + // Draw graph line + void draw( ux_window & window, rect rectangle ) override; + int get_height() const override; + + void clear( bool full ) override; + + private: + float x; + float y; + float z; + float accel; + + std::deque< int > x_history; + std::deque< int > y_history; + std::deque< int > z_history; + std::deque< int > accel_history; + }; + class output_model { public: From ae55299a2b38d6ef0e531fc7e1d1a33de28969bd Mon Sep 17 00:00:00 2001 From: Tamir Date: Thu, 8 Feb 2024 15:17:30 +0200 Subject: [PATCH 02/12] acceleration x shown on a dashboard --- common/output-model.cpp | 58 ++++++++++++++++++++++++++++++++++++----- common/output-model.h | 29 ++++++++++++++------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index 8b22f3695f..0511b8774b 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -1226,7 +1226,7 @@ void frame_drops_dashboard::clear(bool full) } void accel_dashboard::draw(ux_window& win, rect r) { - auto accel_hist = read_shared_data< std::deque< int > >( [&]() { return accel_history; } ); + auto accel_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); for( int i = 0; i < accel_hist.size(); i++ ) { add_point( (float)i, (float)accel_hist[i] ); @@ -1236,13 +1236,19 @@ void accel_dashboard::draw(ux_window& win, rect r) { ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); - ImGui::Text( "%s", "Measurement Metric:" ); - ImGui::SameLine(); - ImGui::SetCursorPosY( ImGui::GetCursorPosY() - 3 ); + //ImGui::Text( "%s", "Measurement Metric:" ); + //ImGui::SameLine(); + //ImGui::SetCursorPosY( ImGui::GetCursorPosY() - 3 ); - ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); + //ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); + + draw_x_line(); + + + // TODO add 3-4 check boxes } +// Done int accel_dashboard::get_height() const { return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); } @@ -1253,14 +1259,52 @@ void accel_dashboard::clear( bool full ) { { if( full ) { - accel_history.clear(); + x_history.clear(); for( int i = 0; i < 100; i++ ) // What it do? - accel_history.push_back( 0 ); + x_history.push_back( 0 ); } } ); } void accel_dashboard::process_frame( rs2::frame f ) { + write_shared_data( + [&]() { + double ts = glfwGetTime(); + auto it = x_to_time.find( f.get_profile().unique_id() ); + + if( f.is< rs2::motion_frame >() ) + { + // X data + if( it != x_to_time.end() ) + { + auto last = x_to_time[f.get_profile().unique_id()]; + + rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); + rs2_vector accel_data = accel_frame.get_motion_data(); + x_value = accel_data.x; + //counter++ Why I need counter? + + + } + + if( ts - last_time > 1.f ) + { + if( x_history.size() > 100 ) + x_history.pop_front(); + + x_history.push_back( x_value ); + last_time = ts; + + } + + x_to_time[f.get_profile().unique_id()] = ts; + } + + } ); +} +bool accel_dashboard::draw_x_line() { + ImGui::Checkbox( "Show X line", &show_x_line ); + return show_x_line; } \ No newline at end of file diff --git a/common/output-model.h b/common/output-model.h index 42111fca5c..e0788cb03c 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -118,30 +118,39 @@ namespace rs2 public: // Constructor accel_dashboard( std::string name ) - : stream_dashboard( name, 30) + : stream_dashboard( name, 30), last_time( glfwGetTime() ) + , x_value( 0 ) { - x = y = z = accel = 0; clear( true ); } // Functions void process_frame( rs2::frame f ) override; - // Draw graph line + + // Draw Accelerate dashboard and choose graph's lines void draw( ux_window & window, rect rectangle ) override; int get_height() const override; + bool draw_x_line(); void clear( bool full ) override; - private: - float x; + float x_value; float y; float z; - float accel; + //float accel_value; + + double last_time; + + bool show_x_line = true; + //bool show_accel_line = true; + + std::deque< float > x_history; + std::map< float, double > x_to_time; + //std::deque< int > y_history; + //std::deque< int > z_history; - std::deque< int > x_history; - std::deque< int > y_history; - std::deque< int > z_history; - std::deque< int > accel_history; + //std::deque< int > accel_history; + //std::map< int, double > accel_to_time; }; class output_model From 302265d86b29a140cb9a262e0bf4374e64764089 Mon Sep 17 00:00:00 2001 From: Tamir Date: Thu, 8 Feb 2024 15:32:43 +0200 Subject: [PATCH 03/12] x checkbox fixed --- common/output-model.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index 0511b8774b..05496b6eee 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -1271,6 +1271,10 @@ void accel_dashboard::process_frame( rs2::frame f ) { write_shared_data( [&]() { double ts = glfwGetTime(); + + if( ! f || ! show_x_line ) + return; + auto it = x_to_time.find( f.get_profile().unique_id() ); if( f.is< rs2::motion_frame >() ) @@ -1281,11 +1285,7 @@ void accel_dashboard::process_frame( rs2::frame f ) { auto last = x_to_time[f.get_profile().unique_id()]; rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); - rs2_vector accel_data = accel_frame.get_motion_data(); - x_value = accel_data.x; - //counter++ Why I need counter? - - + x_value = accel_frame.get_motion_data().x; } if( ts - last_time > 1.f ) @@ -1295,12 +1295,10 @@ void accel_dashboard::process_frame( rs2::frame f ) { x_history.push_back( x_value ); last_time = ts; - } x_to_time[f.get_profile().unique_id()] = ts; } - } ); } From ade7129e4fba84f05ce4359a46fd22e073bfb416 Mon Sep 17 00:00:00 2001 From: Tamir Date: Mon, 12 Feb 2024 14:43:10 +0200 Subject: [PATCH 04/12] accel dashboard completed Check boxes completed The button "add dashboard" appears only when not added dashboard other early. When a user closes a Viewer without closing the dashboard it will start next time with the same dashboard. --- common/device-model.h | 1 + common/output-model.cpp | 139 +++++++++++++++++++++++++++++----------- common/output-model.h | 29 +++++---- common/ux-window.cpp | 1 + 4 files changed, 119 insertions(+), 51 deletions(-) diff --git a/common/device-model.h b/common/device-model.h index 6c637747e0..67bc1ab824 100644 --- a/common/device-model.h +++ b/common/device-model.h @@ -122,6 +122,7 @@ namespace rs2 static const char* is_measuring{ "viewer_model.is_measuring" }; static const char* output_open{ "viewer_model.output_open" }; static const char* dashboard_open{ "viewer_model.dashboard_open" }; + static const char* last_opened_dashboard{ "viewer_model.last_opened_dashboard" }; static const char* search_term{ "viewer_model.search_term" }; static const char* log_to_console{ "viewer_model.log_to_console" }; diff --git a/common/output-model.cpp b/common/output-model.cpp index 05496b6eee..406de29c6d 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -116,6 +116,7 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ configurations::viewer::search_term, std::string("")); is_dashboard_open = config_file::instance().get_or_default( configurations::viewer::dashboard_open, true ); + std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); if (search_line != "") search_open = true; @@ -127,7 +128,10 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ return std::make_shared< accel_dashboard >( name ); }; - auto front = available_dashboards.begin(); + if( last_opened_dashboard.empty() ) + last_opened_dashboard = "Frame Drops per Second"; + + auto front = available_dashboards.find( last_opened_dashboard ); dashboards.push_back(front->second(front->first)); } @@ -707,7 +711,9 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); const auto new_dashboard_name = "new_dashboard"; ImGui::SameLine(); - if (ImGui::Button(u8"\uF0D0 Add Dashboard", ImVec2(-1, 25))) + + std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); + if( last_opened_dashboard.empty() && ImGui::Button( u8"\uF0D0 Add Dashboard", ImVec2( -1, 25 ) ) ) { ImGui::OpenPopup(new_dashboard_name); } @@ -738,6 +744,7 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev bool selected = false; if (ImGui::Selectable(name.c_str(), &selected)) { + config_file::instance().set( configurations::viewer::last_opened_dashboard, kvp.first ); dashboards.push_back(kvp.second(kvp.first)); } } @@ -1056,6 +1063,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) if (ImGui::Button(id.c_str(),ImVec2(22,22))) { close(); + config_file::instance().set( configurations::viewer::last_opened_dashboard, "" ); } if (ImGui::IsItemHovered()) { @@ -1226,29 +1234,51 @@ void frame_drops_dashboard::clear(bool full) } void accel_dashboard::draw(ux_window& win, rect r) { - auto accel_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); - for( int i = 0; i < accel_hist.size(); i++ ) + if( accel_params[curr_accel_param_position] == "X" ) + { + auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); + for( int i = 0; i < x_hist.size(); i++ ) + { + add_point( (float)i, (float)x_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Y" ) + { + auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); + for( int i = 0; i < y_hist.size(); i++ ) + { + add_point( (float)i, (float)y_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Z" ) { - add_point( (float)i, (float)accel_hist[i] ); + auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); + for( int i = 0; i < z_hist.size(); i++ ) + { + add_point( (float)i, (float)z_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "N" ) + { + auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); + for( int i = 0; i < n_hist.size(); i++ ) + { + add_point( (float)i, (float)n_hist[i] ); + } } + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; draw_dashboard( win, r ); ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); - //ImGui::Text( "%s", "Measurement Metric:" ); - //ImGui::SameLine(); - //ImGui::SetCursorPosY( ImGui::GetCursorPosY() - 3 ); - - //ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); - draw_x_line(); - - - // TODO add 3-4 check boxes + show_radiobuttons(); } -// Done int accel_dashboard::get_height() const { return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); } @@ -1259,10 +1289,22 @@ void accel_dashboard::clear( bool full ) { { if( full ) { + const int DEQUE_SIZE = 100; x_history.clear(); - - for( int i = 0; i < 100; i++ ) // What it do? + for( int i = 0; i < DEQUE_SIZE; i++ ) x_history.push_back( 0 ); + + y_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + y_history.push_back( 0 ); + + z_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + z_history.push_back( 0 ); + + n_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + n_history.push_back( 0 ); } } ); } @@ -1270,39 +1312,60 @@ void accel_dashboard::clear( bool full ) { void accel_dashboard::process_frame( rs2::frame f ) { write_shared_data( [&]() { - double ts = glfwGetTime(); - - if( ! f || ! show_x_line ) - return; - - auto it = x_to_time.find( f.get_profile().unique_id() ); - - if( f.is< rs2::motion_frame >() ) + if( f && f.is< rs2::motion_frame >() ) { - // X data - if( it != x_to_time.end() ) - { - auto last = x_to_time[f.get_profile().unique_id()]; + double ts = glfwGetTime(); + auto it = frame_to_time.find( f.get_profile().unique_id() ); + if( ts - last_time > 0.1f && it != frame_to_time.end() ) + { rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); + x_value = accel_frame.get_motion_data().x; - } + y_value = accel_frame.get_motion_data().y; + z_value = accel_frame.get_motion_data().z; + n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - if( ts - last_time > 1.f ) - { - if( x_history.size() > 100 ) + const int MAX_DEQUE_SIZE = 100; + if( x_history.size() > MAX_DEQUE_SIZE ) x_history.pop_front(); + if( y_history.size() > MAX_DEQUE_SIZE ) + y_history.pop_front(); + if( z_history.size() > MAX_DEQUE_SIZE ) + z_history.pop_front(); + if( n_history.size() > MAX_DEQUE_SIZE ) + n_history.pop_front(); x_history.push_back( x_value ); + y_history.push_back( y_value ); + z_history.push_back( z_value ); + n_history.push_back( n_value ); + last_time = ts; } - x_to_time[f.get_profile().unique_id()] = ts; + frame_to_time[f.get_profile().unique_id()] = ts; } } ); } -bool accel_dashboard::draw_x_line() { - ImGui::Checkbox( "Show X line", &show_x_line ); - return show_x_line; -} \ No newline at end of file +void accel_dashboard::show_radiobuttons() { + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); + ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); + ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); + ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); + ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); + ImGui::PopStyleColor(); +} diff --git a/common/output-model.h b/common/output-model.h index e0788cb03c..7a961919a9 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -120,6 +120,9 @@ namespace rs2 accel_dashboard( std::string name ) : stream_dashboard( name, 30), last_time( glfwGetTime() ) , x_value( 0 ) + , y_value( 0 ) + , z_value( 0 ) + , n_value( 0 ) { clear( true ); } @@ -130,27 +133,27 @@ namespace rs2 // Draw Accelerate dashboard and choose graph's lines void draw( ux_window & window, rect rectangle ) override; int get_height() const override; - - bool draw_x_line(); void clear( bool full ) override; + + // Show radio buttons for X, Y, Z and N lines + void show_radiobuttons(); + private: float x_value; - float y; - float z; - //float accel_value; + float y_value; + float z_value; + float n_value; // Norm ||V|| = SQRT(X^2 + Y^2 + Z^2) double last_time; + std::map< float, double > frame_to_time; - bool show_x_line = true; - //bool show_accel_line = true; + std::vector< std::string > accel_params = { "X", "Y", "Z", "N" }; + int curr_accel_param_position = 0; std::deque< float > x_history; - std::map< float, double > x_to_time; - //std::deque< int > y_history; - //std::deque< int > z_history; - - //std::deque< int > accel_history; - //std::map< int, double > accel_to_time; + std::deque< float > y_history; + std::deque< float > z_history; + std::deque< float > n_history; }; class output_model diff --git a/common/ux-window.cpp b/common/ux-window.cpp index 8ae9eacf93..4e210328b5 100644 --- a/common/ux-window.cpp +++ b/common/ux-window.cpp @@ -72,6 +72,7 @@ namespace rs2 config_file::instance().set_default(configurations::viewer::metric_system, true); config_file::instance().set_default(configurations::viewer::ground_truth_r, 2500); config_file::instance().set_default(configurations::viewer::dashboard_open, true); + config_file::instance().set_default(configurations::viewer::last_opened_dashboard, "Frame Drops per Second" ); config_file::instance().set_default(configurations::record::compression_mode, 2); // Let the device decide config_file::instance().set_default(configurations::record::file_save_mode, 0); // Auto-select name From 4e5f0b8c541b172222d0ebcda2e5d2d970060ac2 Mon Sep 17 00:00:00 2001 From: Tamir Date: Tue, 13 Feb 2024 11:51:36 +0200 Subject: [PATCH 05/12] rate slider created --- common/output-model.cpp | 61 +++++++++++++++++++++++++++++++---------- common/output-model.h | 5 ++++ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index 406de29c6d..2e97d81d8c 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -713,15 +713,18 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev ImGui::SameLine(); std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); - if( last_opened_dashboard.empty() && ImGui::Button( u8"\uF0D0 Add Dashboard", ImVec2( -1, 25 ) ) ) + if( last_opened_dashboard.empty() ) { - ImGui::OpenPopup(new_dashboard_name); - } + if( ImGui::Button( u8"\uF0D0 Add Dashboard", ImVec2( -1, 25 ) ) ) + { + ImGui::OpenPopup( new_dashboard_name ); + } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Add one of the available stream dashboards to view"); - win.link_hovered(); + if( ImGui::IsItemHovered() ) + { + ImGui::SetTooltip( "Add one of the available stream dashboards to view" ); + win.link_hovered(); + } } ImGui::PushStyleColor(ImGuiCol_PopupBg, almost_white_bg); @@ -1277,6 +1280,10 @@ void accel_dashboard::draw(ux_window& win, rect r) { ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); show_radiobuttons(); + + ImGui::SameLine(); + + show_data_rate_slider(); } int accel_dashboard::get_height() const { @@ -1289,7 +1296,6 @@ void accel_dashboard::clear( bool full ) { { if( full ) { - const int DEQUE_SIZE = 100; x_history.clear(); for( int i = 0; i < DEQUE_SIZE; i++ ) x_history.push_back( 0 ); @@ -1317,7 +1323,7 @@ void accel_dashboard::process_frame( rs2::frame f ) { double ts = glfwGetTime(); auto it = frame_to_time.find( f.get_profile().unique_id() ); - if( ts - last_time > 0.1f && it != frame_to_time.end() ) + if( ts - last_time > frame_rate && it != frame_to_time.end() ) { rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); @@ -1326,14 +1332,13 @@ void accel_dashboard::process_frame( rs2::frame f ) { z_value = accel_frame.get_motion_data().z; n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - const int MAX_DEQUE_SIZE = 100; - if( x_history.size() > MAX_DEQUE_SIZE ) + if( x_history.size() > DEQUE_SIZE ) x_history.pop_front(); - if( y_history.size() > MAX_DEQUE_SIZE ) + if( y_history.size() > DEQUE_SIZE ) y_history.pop_front(); - if( z_history.size() > MAX_DEQUE_SIZE ) + if( z_history.size() > DEQUE_SIZE ) z_history.pop_front(); - if( n_history.size() > MAX_DEQUE_SIZE ) + if( n_history.size() > DEQUE_SIZE ) n_history.pop_front(); x_history.push_back( x_value ); @@ -1352,20 +1357,48 @@ void accel_dashboard::process_frame( rs2::frame f ) { void accel_dashboard::show_radiobuttons() { ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel X" ); ImGui::PopStyleColor(); ImGui::SameLine(); ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Y" ); ImGui::PopStyleColor(); ImGui::SameLine(); ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Z" ); ImGui::PopStyleColor(); ImGui::SameLine(); ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show Normal" ); ImGui::PopStyleColor(); } + +void accel_dashboard::show_data_rate_slider() +{ + const float min_frame_rate = 0.01f; + const float max_frame_rate = 0.1f; + + ImGui::PushItemWidth( 100 ); + ImGui::SliderFloat( "##rate", &frame_rate, min_frame_rate, max_frame_rate, "%.2f" ); + ImGui::GetWindowWidth(); + + if(ImGui::IsItemHovered()) + { + ImGui::SetTooltip( "%s", + std::string( rsutils::string::from() + << "Update graph every " + << std::to_string( frame_rate ).substr(0, 4) + << " secs" ) + .c_str() ); + } +} \ No newline at end of file diff --git a/common/output-model.h b/common/output-model.h index 7a961919a9..74fe0a0f3b 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -123,6 +123,7 @@ namespace rs2 , y_value( 0 ) , z_value( 0 ) , n_value( 0 ) + , frame_rate( 0.1f ) { clear( true ); } @@ -137,6 +138,8 @@ namespace rs2 // Show radio buttons for X, Y, Z and N lines void show_radiobuttons(); + // Show slider that change pause between acceleration values that we saving. + void show_data_rate_slider(); private: float x_value; @@ -144,12 +147,14 @@ namespace rs2 float z_value; float n_value; // Norm ||V|| = SQRT(X^2 + Y^2 + Z^2) + float frame_rate; double last_time; std::map< float, double > frame_to_time; std::vector< std::string > accel_params = { "X", "Y", "Z", "N" }; int curr_accel_param_position = 0; + const int DEQUE_SIZE = 200; std::deque< float > x_history; std::deque< float > y_history; std::deque< float > z_history; From 222a35708495e285f0833dc597fc066e77c0d05f Mon Sep 17 00:00:00 2001 From: Tamir Date: Tue, 13 Feb 2024 15:45:05 +0200 Subject: [PATCH 06/12] dashboard menu completed --- common/output-model.cpp | 46 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index 2e97d81d8c..f3e49d49f2 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -129,7 +129,10 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ }; if( last_opened_dashboard.empty() ) + { last_opened_dashboard = "Frame Drops per Second"; + config_file::instance().set(configurations::viewer::last_opened_dashboard, last_opened_dashboard); + } auto front = available_dashboards.find( last_opened_dashboard ); dashboards.push_back(front->second(front->first)); @@ -709,31 +712,16 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev if (can_add) { ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); - const auto new_dashboard_name = "new_dashboard"; - ImGui::SameLine(); std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); if( last_opened_dashboard.empty() ) { - if( ImGui::Button( u8"\uF0D0 Add Dashboard", ImVec2( -1, 25 ) ) ) - { - ImGui::OpenPopup( new_dashboard_name ); - } + ImGui::SameLine(); + ImGui::Button( u8"\uF0D0 Dashboards", ImVec2( -1, collapse_dashboard_button_size.y ) ); - if( ImGui::IsItemHovered() ) - { - ImGui::SetTooltip( "Add one of the available stream dashboards to view" ); - win.link_hovered(); - } - } + ImGui::PushStyleColor(ImGuiCol_Text, white); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, light_blue); - ImGui::PushStyleColor(ImGuiCol_PopupBg, almost_white_bg); - ImGui::PushStyleColor(ImGuiCol_Text, black); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, light_blue); - ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5,5)); - if (ImGui::BeginPopup(new_dashboard_name)) - { for (auto&& kvp : available_dashboards) { auto name = kvp.first; @@ -745,22 +733,19 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev { name = name + "##New"; bool selected = false; + + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + collapse_dashboard_button_size.x ); if (ImGui::Selectable(name.c_str(), &selected)) { config_file::instance().set( configurations::viewer::last_opened_dashboard, kvp.first ); dashboards.push_back(kvp.second(kvp.first)); } } - } - - ImGui::EndPopup(); - } - - ImGui::PopStyleColor(4); - ImGui::PopStyleVar(); + } + ImGui::PopStyleColor( 2 ); + } } - ImGui::EndChild(); ImGui::PopStyleColor(); @@ -1396,9 +1381,10 @@ void accel_dashboard::show_data_rate_slider() { ImGui::SetTooltip( "%s", std::string( rsutils::string::from() - << "Update graph every " - << std::to_string( frame_rate ).substr(0, 4) - << " secs" ) + << "Frame rate " + << std::fixed << std::setprecision( 1 ) + << frame_rate * 1000 + << " mSec" ) .c_str() ); } } \ No newline at end of file From 3cc7b496257568e2bf039c496f9bc99726d85984 Mon Sep 17 00:00:00 2001 From: Tamir Date: Thu, 15 Feb 2024 13:31:32 +0200 Subject: [PATCH 07/12] dashboard completed --- common/output-model.cpp | 121 +++++++++++++++++----------------------- common/output-model.h | 2 + common/ux-window.cpp | 2 +- 3 files changed, 54 insertions(+), 71 deletions(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index f3e49d49f2..9e14985f1a 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -116,25 +116,21 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ configurations::viewer::search_term, std::string("")); is_dashboard_open = config_file::instance().get_or_default( configurations::viewer::dashboard_open, true ); - std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); + opened_dashboard_index = config_file::instance().get( configurations::viewer::last_opened_dashboard ); if (search_line != "") search_open = true; - available_dashboards["Frame Drops per Second"] = [&](std::string name){ + available_dashboards[dashboard_names[1]] = [&]( std::string name ) + { return std::make_shared(name, &number_of_drops, &total_frames); }; - available_dashboards["Acceleration"] = [&]( std::string name ){ + available_dashboards[dashboard_names[0]] = [&]( std::string name ) + { return std::make_shared< accel_dashboard >( name ); }; - if( last_opened_dashboard.empty() ) - { - last_opened_dashboard = "Frame Drops per Second"; - config_file::instance().set(configurations::viewer::last_opened_dashboard, last_opened_dashboard); - } - - auto front = available_dashboards.find( last_opened_dashboard ); + auto front = available_dashboards.find( dashboard_names[opened_dashboard_index] ); dashboards.push_back(front->second(front->first)); } @@ -681,23 +677,6 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev default_dashboard_w = min_dashboard_width; } - auto top = 0; - if( is_dashboard_open && dashboard_width == max_dashboard_width ) - { - for( auto && dash : dashboards ) - { - auto h = dash->get_height(); - auto r = rect{ 0.f, (float)top, get_dashboard_width() - 8.f, (float)h }; - dash->draw( win, r ); - top += h; - } - } - - dashboards.erase(std::remove_if(dashboards.begin(), dashboards.end(), - [](std::shared_ptr p){ - return p->closing(); - }), dashboards.end()); - bool can_add = false; for (auto&& kvp : available_dashboards) { @@ -709,41 +688,51 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev if (it == dashboards.end()) can_add = true; } - if (can_add) + if( can_add && is_dashboard_open ) { ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); - std::string last_opened_dashboard = config_file::instance().get( configurations::viewer::last_opened_dashboard ); - if( last_opened_dashboard.empty() ) + ImGui::SameLine(); + ImGui::Button( u8"\uF0D0 Dashboards", ImVec2( -1, collapse_dashboard_button_size.y ) ); + + ImGui::PushStyleColor( ImGuiCol_Text, white ); + ImGui::PushStyleColor( ImGuiCol_HeaderHovered, light_blue ); + + int radio_button_choice = 0; + for( auto && kvp : available_dashboards ) { - ImGui::SameLine(); - ImGui::Button( u8"\uF0D0 Dashboards", ImVec2( -1, collapse_dashboard_button_size.y ) ); + auto name = kvp.first; + auto it = std::find_if( dashboards.begin(), + dashboards.end(), + [name]( std::shared_ptr< stream_dashboard > p ) { return p->get_name() == name; } ); - ImGui::PushStyleColor(ImGuiCol_Text, white); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, light_blue); + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + collapse_dashboard_button_size.x ); - for (auto&& kvp : available_dashboards) + // Show dashboards to user + if( ImGui::RadioButton( name.c_str(), &opened_dashboard_index, radio_button_choice++ ) ) { - auto name = kvp.first; - auto it = std::find_if(dashboards.begin(), dashboards.end(), - [name](std::shared_ptr p){ - return p->get_name() == name; - }); - if (it == dashboards.end()) - { - name = name + "##New"; - bool selected = false; + for( auto & d : dashboards ) + d->close(); + dashboards.clear(); - ImGui::SetCursorPosX( ImGui::GetCursorPosX() + collapse_dashboard_button_size.x ); - if (ImGui::Selectable(name.c_str(), &selected)) - { - config_file::instance().set( configurations::viewer::last_opened_dashboard, kvp.first ); - dashboards.push_back(kvp.second(kvp.first)); - } - } - } - ImGui::PopStyleColor( 2 ); - } + config_file::instance().set( configurations::viewer::last_opened_dashboard, opened_dashboard_index); + dashboards.push_back( kvp.second( kvp.first ) ); + } + } + ImGui::PopStyleColor( 2 ); + + // Draw dashboard background + auto top = 0; + if( dashboard_width == max_dashboard_width ) + { + for( auto && dash : dashboards ) + { + auto h = dash->get_height(); + auto r = rect{ 0.f, (float)top, get_dashboard_width() - 8.f, (float)h }; + dash->draw( win, r ); + top += h; + } + } } ImGui::EndChild(); @@ -1030,6 +1019,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) } auto pos = ImGui::GetCursorScreenPos(); + pos.y += ImGui::GetCursorPosY(); ImGui::PushStyleColor(ImGuiCol_Text, white); @@ -1039,25 +1029,16 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) { pos.x + r.w, pos.y + get_height() }, ImColor(dark_sensor_bg)); auto size = ImGui::CalcTextSize(name.c_str()); - float collapse_buton_h = 28.f + 3.f; // Dashboard button size plus some spacing - ImGui::SetCursorPos(ImVec2( r.w / 2 - size.x / 2, 5 + collapse_buton_h)); + float padding_top = ImGui::GetCursorPosY() + 85.f; // Padding from top for scale digits. Add 85 for background and scale digits synchronizing. + ImGui::SetCursorPos(ImVec2( r.w / 2 - size.x / 2, 5 + padding_top)); ImGui::Text("%s", name.c_str()); ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Text, grey); ImGui::SetCursorPosX(r.w - 25); - ImGui::SetCursorPosY( 3.f + collapse_buton_h ); + ImGui::SetCursorPosY( 3.f + padding_top ); std::string id = rsutils::string::from() << u8"\uF00D##Close_" << name; - if (ImGui::Button(id.c_str(),ImVec2(22,22))) - { - close(); - config_file::instance().set( configurations::viewer::last_opened_dashboard, "" ); - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Remove Dashboard from View"); - win.link_hovered(); - } + ImGui::PopStyleColor(); ImGui::GetWindowDrawList()->AddRectFilled({ pos.x + max_y_label_width + 15, pos.y + ImGui::GetTextLineHeight() + 5 }, @@ -1069,7 +1050,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) auto y = max_y - i * (gap_y / ticks_y); std::string y_label = rsutils::string::from() << std::fixed << std::setprecision(2) << y; auto y_pixel = ImGui::GetTextLineHeight() + i * (height_y / ticks_y); - ImGui::SetCursorPos(ImVec2( 10, y_pixel + collapse_buton_h)); + ImGui::SetCursorPos(ImVec2( 10, y_pixel + padding_top)); ImGui::Text("%s", y_label.c_str()); ImGui::GetWindowDrawList()->AddLine({ pos.x + max_y_label_width + 15.f, pos.y + y_pixel + 5.f }, @@ -1099,7 +1080,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) { auto x = min_x + i * (gap_x / ticks_x); std::string x_label = rsutils::string::from() << std::fixed << std::setprecision(2) << x; - ImGui::SetCursorPos(ImVec2( 15 + max_y_label_width+ i * (graph_width / ticks_x), r.h - ImGui::GetTextLineHeight() + collapse_buton_h)); + ImGui::SetCursorPos(ImVec2( 15 + max_y_label_width+ i * (graph_width / ticks_x), r.h - ImGui::GetTextLineHeight() + padding_top)); ImGui::Text("%s", x_label.c_str()); ImGui::GetWindowDrawList()->AddLine({ pos.x + 15 + max_y_label_width + i * (graph_width / ticks_x), pos.y + ImGui::GetTextLineHeight() + 5 }, @@ -1262,7 +1243,7 @@ void accel_dashboard::draw(ux_window& win, rect r) { draw_dashboard( win, r ); ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); - ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() ); show_radiobuttons(); diff --git a/common/output-model.h b/common/output-model.h index 74fe0a0f3b..f3a8969511 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -242,6 +242,8 @@ namespace rs2 std::vector> dashboards; std::map(std::string)>> available_dashboards; + const std::vector< std::string > dashboard_names = { "Acceleration", "Frame Drops per Second" }; + int opened_dashboard_index; std::atomic to_stop { 0 }; std::thread fw_logger; diff --git a/common/ux-window.cpp b/common/ux-window.cpp index 4e210328b5..4cb40d1b89 100644 --- a/common/ux-window.cpp +++ b/common/ux-window.cpp @@ -72,7 +72,7 @@ namespace rs2 config_file::instance().set_default(configurations::viewer::metric_system, true); config_file::instance().set_default(configurations::viewer::ground_truth_r, 2500); config_file::instance().set_default(configurations::viewer::dashboard_open, true); - config_file::instance().set_default(configurations::viewer::last_opened_dashboard, "Frame Drops per Second" ); + config_file::instance().set_default(configurations::viewer::last_opened_dashboard, 1 ); config_file::instance().set_default(configurations::record::compression_mode, 2); // Let the device decide config_file::instance().set_default(configurations::record::file_save_mode, 0); // Auto-select name From d7281e3ea59e719e76cd7fc1328955436b16f215 Mon Sep 17 00:00:00 2001 From: Tamir Date: Mon, 26 Feb 2024 10:39:53 +0200 Subject: [PATCH 08/12] accel and frame drops dashboards separated to standalone files --- common/CMakeLists.txt | 4 + common/accel-dashboard.cpp | 190 ++++++++++++++++++++++ common/accel-dashboard.h | 52 +++++++ common/frame-drops-dashboard.cpp | 104 +++++++++++++ common/frame-drops-dashboard.h | 41 +++++ common/output-model.cpp | 260 +------------------------------ common/output-model.h | 74 --------- 7 files changed, 394 insertions(+), 331 deletions(-) create mode 100644 common/accel-dashboard.cpp create mode 100644 common/accel-dashboard.h create mode 100644 common/frame-drops-dashboard.cpp create mode 100644 common/frame-drops-dashboard.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6875b2884e..1561acd40d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -52,6 +52,10 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/processing-block-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/stream-model.h" "${CMAKE_CURRENT_LIST_DIR}/stream-model.cpp" + "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/frame_drops_dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/frame_drops_dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.h" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.cpp" ) diff --git a/common/accel-dashboard.cpp b/common/accel-dashboard.cpp new file mode 100644 index 0000000000..a8e7d7966e --- /dev/null +++ b/common/accel-dashboard.cpp @@ -0,0 +1,190 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#include "accel-dashboard.h" + +using namespace rs2; +using namespace rsutils::string; + +accel_dashboard::accel_dashboard( std::string name ) + : stream_dashboard( name, 30 ) + , last_time( glfwGetTime() ) + , x_value( 0 ) + , y_value( 0 ) + , z_value( 0 ) + , n_value( 0 ) + , frame_rate( MAX_FRAME_RATE ) +{ + clear( true ); +} + +void accel_dashboard::draw( ux_window & win, rect r ) +{ + if( accel_params[curr_accel_param_position] == "X" ) + { + auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); + for( int i = 0; i < x_hist.size(); i++ ) + { + add_point( (float)i, (float)x_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Y" ) + { + auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); + for( int i = 0; i < y_hist.size(); i++ ) + { + add_point( (float)i, (float)y_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Z" ) + { + auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); + for( int i = 0; i < z_hist.size(); i++ ) + { + add_point( (float)i, (float)z_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "N" ) + { + auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); + for( int i = 0; i < n_hist.size(); i++ ) + { + add_point( (float)i, (float)n_hist[i] ); + } + } + + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; + draw_dashboard( win, r ); + + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() ); + + show_radiobuttons(); + + ImGui::SameLine(); + + show_data_rate_slider(); +} + +int accel_dashboard::get_height() const +{ + return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); +} + +void accel_dashboard::clear( bool full ) +{ + write_shared_data( + [&]() + { + if( full ) + { + x_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + x_history.push_back( 0 ); + + y_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + y_history.push_back( 0 ); + + z_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + z_history.push_back( 0 ); + + n_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + n_history.push_back( 0 ); + } + } ); +} + +void accel_dashboard::process_frame( rs2::frame f ) +{ + write_shared_data( + [&]() + { + if( f && f.is< rs2::motion_frame >() ) + { + double ts = glfwGetTime(); + auto it = frame_to_time.find( f.get_profile().unique_id() ); + + if( ts - last_time > frame_rate && it != frame_to_time.end() ) + { + rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); + + x_value = accel_frame.get_motion_data().x; + y_value = accel_frame.get_motion_data().y; + z_value = accel_frame.get_motion_data().z; + n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); + + if( x_history.size() > DEQUE_SIZE ) + x_history.pop_front(); + if( y_history.size() > DEQUE_SIZE ) + y_history.pop_front(); + if( z_history.size() > DEQUE_SIZE ) + z_history.pop_front(); + if( n_history.size() > DEQUE_SIZE ) + n_history.pop_front(); + + x_history.push_back( x_value ); + y_history.push_back( y_value ); + z_history.push_back( z_value ); + n_history.push_back( n_value ); + + last_time = ts; + } + + frame_to_time[f.get_profile().unique_id()] = ts; + } + } ); +} + +void accel_dashboard::show_radiobuttons() +{ + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); + ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel X" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); + ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Y" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); + ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Z" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); + ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show Normal" ); + ImGui::PopStyleColor(); +} + +void accel_dashboard::show_data_rate_slider() +{ + ImGui::PushItemWidth( 100 ); + ImGui::SliderFloat( "##rate", &frame_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); + ImGui::GetWindowWidth(); + + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip( "%s", std::string( rsutils::string::from() + << "Frame rate " + << std::fixed + << std::setprecision(1) + << frame_rate * 1000 + << " mSec" + ).c_str() ); + } +} \ No newline at end of file diff --git a/common/accel-dashboard.h b/common/accel-dashboard.h new file mode 100644 index 0000000000..70dc42268f --- /dev/null +++ b/common/accel-dashboard.h @@ -0,0 +1,52 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#pragma once + +#include "output-model.h" +#include "device-model.h" + +namespace rs2 +{ + class accel_dashboard : public stream_dashboard + { + public: + + accel_dashboard( std::string name ); + + // Extract X, Y, Z and calculate N values from a frame + void process_frame( rs2::frame f ) override; + + // Draw Accelerate dashboard and choose graph's lines + void draw( ux_window & window, rect rectangle ) override; + int get_height() const override; + void clear( bool full ) override; + + // Show radio buttons for X, Y, Z and N lines + void show_radiobuttons(); + // Show slider that change pause between acceleration values that we saving. + void show_data_rate_slider(); + + private: + float x_value; + float y_value; + float z_value; + float n_value; // Norm ||V|| = SQRT(X^2 + Y^2 + Z^2) + + float frame_rate; + double last_time; + std::map< float, double > frame_to_time; + + std::vector< std::string > accel_params = { "X", "Y", "Z", "N" }; + int curr_accel_param_position = 0; + + const float MIN_FRAME_RATE = 0.01f; + const float MAX_FRAME_RATE = 0.1f; + + const int DEQUE_SIZE = 200; + std::deque< float > x_history; + std::deque< float > y_history; + std::deque< float > z_history; + std::deque< float > n_history; + }; +} \ No newline at end of file diff --git a/common/frame-drops-dashboard.cpp b/common/frame-drops-dashboard.cpp new file mode 100644 index 0000000000..0a0e6bdc93 --- /dev/null +++ b/common/frame-drops-dashboard.cpp @@ -0,0 +1,104 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#include "frame-drops-dashboard.h" + +using namespace rs2; +using namespace rsutils::string; + +void frame_drops_dashboard::process_frame( rs2::frame f ) +{ + write_shared_data( + [&]() + { + double ts = glfwGetTime(); + if( method == 1 ) + ts = f.get_timestamp() / 1000.f; + auto it = stream_to_time.find( f.get_profile().unique_id() ); + if( it != stream_to_time.end() ) + { + auto last = stream_to_time[f.get_profile().unique_id()]; + + double fps = (double)f.get_profile().fps(); + + if( f.supports_frame_metadata( RS2_FRAME_METADATA_ACTUAL_FPS ) ) + fps = f.get_frame_metadata( RS2_FRAME_METADATA_ACTUAL_FPS ) / 1000.; + + if( 1000. * ( ts - last ) > 1.5 * ( 1000. / fps ) ) + { + drops++; + } + } + + counter++; + + if( ts - last_time > 1.f ) + { + if( drops_history.size() > 100 ) + drops_history.pop_front(); + drops_history.push_back( drops ); + *total = counter; + *frame_drop_count = drops; + drops = 0; + last_time = ts; + counter = 0; + } + + stream_to_time[f.get_profile().unique_id()] = ts; + } ); +} + +void frame_drops_dashboard::draw( ux_window & win, rect r ) +{ + auto hist = read_shared_data< std::deque< int > >( [&]() { return drops_history; } ); + for( int i = 0; i < hist.size(); i++ ) + { + add_point( (float)i, (float)hist[i] ); + } + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; + + if( config_file::instance().get( configurations::viewer::dashboard_open ) ) + draw_dashboard( win, r ); + + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); + ImGui::Text( "%s", "Measurement Metric:" ); + ImGui::SameLine(); + ImGui::SetCursorPosY( ImGui::GetCursorPosY() - 3 ); + + ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); + + std::vector< const char * > methods; + methods.push_back( "Viewer Processing Rate" ); + methods.push_back( "Camera Timestamp Rate" ); + + ImGui::PushItemWidth( -1.f ); + if( ImGui::Combo( "##fps_method", &method, methods.data(), (int)( methods.size() ) ) ) + { + clear( false ); + } + ImGui::PopItemWidth(); +} + +int frame_drops_dashboard::get_height() const +{ + return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); +} + +void frame_drops_dashboard::clear( bool full ) +{ + write_shared_data( + [&]() + { + stream_to_time.clear(); + last_time = 0; + *total = 0; + *frame_drop_count = 0; + if( full ) + { + drops_history.clear(); + for( int i = 0; i < 100; i++ ) + drops_history.push_back( 0 ); + } + } ); +} diff --git a/common/frame-drops-dashboard.h b/common/frame-drops-dashboard.h new file mode 100644 index 0000000000..4d8ce0c536 --- /dev/null +++ b/common/frame-drops-dashboard.h @@ -0,0 +1,41 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#pragma once + +#include "output-model.h" +#include "device-model.h" + +#include +#include "ux-window.h" + +namespace rs2 +{ + class frame_drops_dashboard : public stream_dashboard + { + public: + frame_drops_dashboard( std::string name, int * frame_drop_count, int * total ) + : stream_dashboard( name, 30 ) + , last_time( glfwGetTime() ) + , frame_drop_count( frame_drop_count ) + , total( total ) + { + clear( true ); + } + + void process_frame( rs2::frame f ) override; + void draw( ux_window & win, rect r ) override; + int get_height() const override; + + void clear( bool full ) override; + + private: + std::map< int, double > stream_to_time; + int drops = 0; + double last_time; + std::deque< int > drops_history; + int *frame_drop_count, *total; + int counter = 0; + int method = 0; + }; +} \ No newline at end of file diff --git a/common/output-model.cpp b/common/output-model.cpp index 9e14985f1a..bb14fc7b4a 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -11,6 +11,9 @@ #include #include +#include "accel-dashboard.h" +#include "frame-drops-dashboard.h" + #include #include @@ -1111,261 +1114,4 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) ImGui::PopStyleColor(); xy.clear(); -} - -void frame_drops_dashboard::process_frame(rs2::frame f) -{ - write_shared_data([&](){ - double ts = glfwGetTime(); - if (method == 1) ts = f.get_timestamp() / 1000.f; - auto it = stream_to_time.find(f.get_profile().unique_id()); - if (it != stream_to_time.end()) - { - auto last = stream_to_time[f.get_profile().unique_id()]; - - double fps = (double)f.get_profile().fps(); - - if( f.supports_frame_metadata( RS2_FRAME_METADATA_ACTUAL_FPS ) ) - fps = f.get_frame_metadata( RS2_FRAME_METADATA_ACTUAL_FPS ) / 1000.; - - if (1000. * (ts - last) > 1.5 * (1000. / fps)) { - drops++; - } - } - - counter++; - - if (ts - last_time > 1.f) - { - if (drops_history.size() > 100) drops_history.pop_front(); - drops_history.push_back(drops); - *total = counter; - *frame_drop_count = drops; - drops = 0; - last_time = ts; - counter = 0; - } - - stream_to_time[f.get_profile().unique_id()] = ts; - }); -} - -void frame_drops_dashboard::draw(ux_window& win, rect r) -{ - auto hist = read_shared_data>([&](){ return drops_history; }); - for (int i = 0; i < hist.size(); i++) - { - add_point((float)i, (float)hist[i]); - } - r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; - - if( config_file::instance().get( configurations::viewer::dashboard_open) ) - draw_dashboard(win, r); - - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 40); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 3); - ImGui::Text("%s", "Measurement Metric:"); ImGui::SameLine(); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 3); - - ImGui::SetCursorPosX( 11.5f * win.get_font_size() ); - - std::vector methods; - methods.push_back("Viewer Processing Rate"); - methods.push_back("Camera Timestamp Rate"); - - ImGui::PushItemWidth(-1.f); - if (ImGui::Combo("##fps_method", &method, methods.data(), (int)(methods.size()))) - { - clear(false); - } - ImGui::PopItemWidth(); -} - -int frame_drops_dashboard::get_height() const -{ - return (int)(160 + ImGui::GetTextLineHeightWithSpacing()); -} - -void frame_drops_dashboard::clear(bool full) -{ - write_shared_data([&](){ - stream_to_time.clear(); - last_time = 0; - *total = 0; - *frame_drop_count = 0; - if (full) - { - drops_history.clear(); - for (int i = 0; i < 100; i++) - drops_history.push_back(0); - } - }); -} - -void accel_dashboard::draw(ux_window& win, rect r) { - if( accel_params[curr_accel_param_position] == "X" ) - { - auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); - for( int i = 0; i < x_hist.size(); i++ ) - { - add_point( (float)i, (float)x_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "Y" ) - { - auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); - for( int i = 0; i < y_hist.size(); i++ ) - { - add_point( (float)i, (float)y_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "Z" ) - { - auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); - for( int i = 0; i < z_hist.size(); i++ ) - { - add_point( (float)i, (float)z_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "N" ) - { - auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); - for( int i = 0; i < n_hist.size(); i++ ) - { - add_point( (float)i, (float)n_hist[i] ); - } - } - - r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; - draw_dashboard( win, r ); - - ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); - ImGui::SetCursorPosY( ImGui::GetCursorPosY() ); - - show_radiobuttons(); - - ImGui::SameLine(); - - show_data_rate_slider(); -} - -int accel_dashboard::get_height() const { - return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); -} - -void accel_dashboard::clear( bool full ) { - write_shared_data( - [&]() - { - if( full ) - { - x_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - x_history.push_back( 0 ); - - y_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - y_history.push_back( 0 ); - - z_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - z_history.push_back( 0 ); - - n_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - n_history.push_back( 0 ); - } - } ); -} - -void accel_dashboard::process_frame( rs2::frame f ) { - write_shared_data( - [&]() { - if( f && f.is< rs2::motion_frame >() ) - { - double ts = glfwGetTime(); - auto it = frame_to_time.find( f.get_profile().unique_id() ); - - if( ts - last_time > frame_rate && it != frame_to_time.end() ) - { - rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); - - x_value = accel_frame.get_motion_data().x; - y_value = accel_frame.get_motion_data().y; - z_value = accel_frame.get_motion_data().z; - n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - - if( x_history.size() > DEQUE_SIZE ) - x_history.pop_front(); - if( y_history.size() > DEQUE_SIZE ) - y_history.pop_front(); - if( z_history.size() > DEQUE_SIZE ) - z_history.pop_front(); - if( n_history.size() > DEQUE_SIZE ) - n_history.pop_front(); - - x_history.push_back( x_value ); - y_history.push_back( y_value ); - z_history.push_back( z_value ); - n_history.push_back( n_value ); - - last_time = ts; - } - - frame_to_time[f.get_profile().unique_id()] = ts; - } - } ); -} - -void accel_dashboard::show_radiobuttons() { - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); - ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel X" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); - ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Y" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); - ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Z" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); - ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show Normal" ); - ImGui::PopStyleColor(); -} - -void accel_dashboard::show_data_rate_slider() -{ - const float min_frame_rate = 0.01f; - const float max_frame_rate = 0.1f; - - ImGui::PushItemWidth( 100 ); - ImGui::SliderFloat( "##rate", &frame_rate, min_frame_rate, max_frame_rate, "%.2f" ); - ImGui::GetWindowWidth(); - - if(ImGui::IsItemHovered()) - { - ImGui::SetTooltip( "%s", - std::string( rsutils::string::from() - << "Frame rate " - << std::fixed << std::setprecision( 1 ) - << frame_rate * 1000 - << " mSec" ) - .c_str() ); - } } \ No newline at end of file diff --git a/common/output-model.h b/common/output-model.h index f3a8969511..f200c4e8a0 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -87,80 +87,6 @@ namespace rs2 bool to_close = false; }; - class frame_drops_dashboard : public stream_dashboard - { - public: - frame_drops_dashboard(std::string name, int* frame_drop_count, int* total) - : stream_dashboard(name, 30), - last_time(glfwGetTime()), frame_drop_count(frame_drop_count), total(total) - { - clear(true); - } - - void process_frame(rs2::frame f) override; - void draw(ux_window& win, rect r) override; - int get_height() const override; - - void clear(bool full) override; - - private: - std::map stream_to_time; - int drops = 0; - double last_time; - std::deque drops_history; - int *frame_drop_count, *total; - int counter = 0; - int method = 0; - }; - - class accel_dashboard : public stream_dashboard - { - public: - // Constructor - accel_dashboard( std::string name ) - : stream_dashboard( name, 30), last_time( glfwGetTime() ) - , x_value( 0 ) - , y_value( 0 ) - , z_value( 0 ) - , n_value( 0 ) - , frame_rate( 0.1f ) - { - clear( true ); - } - - // Functions - void process_frame( rs2::frame f ) override; - - // Draw Accelerate dashboard and choose graph's lines - void draw( ux_window & window, rect rectangle ) override; - int get_height() const override; - void clear( bool full ) override; - - // Show radio buttons for X, Y, Z and N lines - void show_radiobuttons(); - // Show slider that change pause between acceleration values that we saving. - void show_data_rate_slider(); - - private: - float x_value; - float y_value; - float z_value; - float n_value; // Norm ||V|| = SQRT(X^2 + Y^2 + Z^2) - - float frame_rate; - double last_time; - std::map< float, double > frame_to_time; - - std::vector< std::string > accel_params = { "X", "Y", "Z", "N" }; - int curr_accel_param_position = 0; - - const int DEQUE_SIZE = 200; - std::deque< float > x_history; - std::deque< float > y_history; - std::deque< float > z_history; - std::deque< float > n_history; - }; - class output_model { public: From 360e02b4012a4b35d45777933abe3cd359f10fe2 Mon Sep 17 00:00:00 2001 From: Tamir Date: Mon, 26 Feb 2024 14:54:22 +0200 Subject: [PATCH 09/12] gyro added --- common/CMakeLists.txt | 8 +- common/accel-dashboard.cpp | 152 +------------- common/gyro-dashboard.cpp | 54 +++++ common/motion-dashboard.cpp | 190 ++++++++++++++++++ .../{accel-dashboard.h => motion-dashboard.h} | 26 ++- common/output-model.cpp | 11 +- common/output-model.h | 2 +- 7 files changed, 288 insertions(+), 155 deletions(-) create mode 100644 common/gyro-dashboard.cpp create mode 100644 common/motion-dashboard.cpp rename common/{accel-dashboard.h => motion-dashboard.h} (72%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 1561acd40d..4f004612d2 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -52,10 +52,12 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/processing-block-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/stream-model.h" "${CMAKE_CURRENT_LIST_DIR}/stream-model.cpp" - "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/frame_drops_dashboard.h" - "${CMAKE_CURRENT_LIST_DIR}/frame_drops_dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/gyro-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.h" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.cpp" ) diff --git a/common/accel-dashboard.cpp b/common/accel-dashboard.cpp index a8e7d7966e..e2e67ad345 100644 --- a/common/accel-dashboard.cpp +++ b/common/accel-dashboard.cpp @@ -1,103 +1,14 @@ // License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2024 Intel Corporation. All Rights Reserved. -#include "accel-dashboard.h" +#include "motion-dashboard.h" using namespace rs2; using namespace rsutils::string; accel_dashboard::accel_dashboard( std::string name ) - : stream_dashboard( name, 30 ) - , last_time( glfwGetTime() ) - , x_value( 0 ) - , y_value( 0 ) - , z_value( 0 ) - , n_value( 0 ) - , frame_rate( MAX_FRAME_RATE ) + : motion_dashboard( name ) { - clear( true ); -} - -void accel_dashboard::draw( ux_window & win, rect r ) -{ - if( accel_params[curr_accel_param_position] == "X" ) - { - auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); - for( int i = 0; i < x_hist.size(); i++ ) - { - add_point( (float)i, (float)x_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "Y" ) - { - auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); - for( int i = 0; i < y_hist.size(); i++ ) - { - add_point( (float)i, (float)y_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "Z" ) - { - auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); - for( int i = 0; i < z_hist.size(); i++ ) - { - add_point( (float)i, (float)z_hist[i] ); - } - } - - if( accel_params[curr_accel_param_position] == "N" ) - { - auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); - for( int i = 0; i < n_hist.size(); i++ ) - { - add_point( (float)i, (float)n_hist[i] ); - } - } - - r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; - draw_dashboard( win, r ); - - ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); - ImGui::SetCursorPosY( ImGui::GetCursorPosY() ); - - show_radiobuttons(); - - ImGui::SameLine(); - - show_data_rate_slider(); -} - -int accel_dashboard::get_height() const -{ - return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); -} - -void accel_dashboard::clear( bool full ) -{ - write_shared_data( - [&]() - { - if( full ) - { - x_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - x_history.push_back( 0 ); - - y_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - y_history.push_back( 0 ); - - z_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - z_history.push_back( 0 ); - - n_history.clear(); - for( int i = 0; i < DEQUE_SIZE; i++ ) - n_history.push_back( 0 ); - } - } ); } void accel_dashboard::process_frame( rs2::frame f ) @@ -105,18 +16,19 @@ void accel_dashboard::process_frame( rs2::frame f ) write_shared_data( [&]() { - if( f && f.is< rs2::motion_frame >() ) + if( f && f.is< rs2::motion_frame >() + && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == RS2_STREAM_ACCEL ) { double ts = glfwGetTime(); auto it = frame_to_time.find( f.get_profile().unique_id() ); if( ts - last_time > frame_rate && it != frame_to_time.end() ) { - rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); + rs2::motion_frame frame = f.as< rs2::motion_frame >(); - x_value = accel_frame.get_motion_data().x; - y_value = accel_frame.get_motion_data().y; - z_value = accel_frame.get_motion_data().z; + x_value = frame.get_motion_data().x; + y_value = frame.get_motion_data().y; + z_value = frame.get_motion_data().z; n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); if( x_history.size() > DEQUE_SIZE ) @@ -139,52 +51,4 @@ void accel_dashboard::process_frame( rs2::frame f ) frame_to_time[f.get_profile().unique_id()] = ts; } } ); -} - -void accel_dashboard::show_radiobuttons() -{ - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); - ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel X" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); - ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Y" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); - ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Z" ); - ImGui::PopStyleColor(); - ImGui::SameLine(); - - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); - ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); - if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show Normal" ); - ImGui::PopStyleColor(); -} - -void accel_dashboard::show_data_rate_slider() -{ - ImGui::PushItemWidth( 100 ); - ImGui::SliderFloat( "##rate", &frame_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); - ImGui::GetWindowWidth(); - - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip( "%s", std::string( rsutils::string::from() - << "Frame rate " - << std::fixed - << std::setprecision(1) - << frame_rate * 1000 - << " mSec" - ).c_str() ); - } } \ No newline at end of file diff --git a/common/gyro-dashboard.cpp b/common/gyro-dashboard.cpp new file mode 100644 index 0000000000..317468c7a1 --- /dev/null +++ b/common/gyro-dashboard.cpp @@ -0,0 +1,54 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#include "motion-dashboard.h" + +using namespace rs2; +using namespace rsutils::string; + +gyro_dashboard::gyro_dashboard( std::string name ) + : motion_dashboard( name ) +{ +} + +void gyro_dashboard::process_frame( rs2::frame f ) +{ + write_shared_data( + [&]() + { + if( f && f.is< rs2::motion_frame >() + && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == RS2_STREAM_GYRO ) + { + double ts = glfwGetTime(); + auto it = frame_to_time.find( f.get_profile().unique_id() ); + + if( ts - last_time > frame_rate && it != frame_to_time.end() ) + { + rs2::motion_frame frame = f.as< rs2::motion_frame >(); + + x_value = frame.get_motion_data().x; + y_value = frame.get_motion_data().y; + z_value = frame.get_motion_data().z; + n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); + + if( x_history.size() > DEQUE_SIZE ) + x_history.pop_front(); + if( y_history.size() > DEQUE_SIZE ) + y_history.pop_front(); + if( z_history.size() > DEQUE_SIZE ) + z_history.pop_front(); + if( n_history.size() > DEQUE_SIZE ) + n_history.pop_front(); + + x_history.push_back( x_value ); + y_history.push_back( y_value ); + z_history.push_back( z_value ); + n_history.push_back( n_value ); + + last_time = ts; + } + + frame_to_time[f.get_profile().unique_id()] = ts; + } + } ); +} \ No newline at end of file diff --git a/common/motion-dashboard.cpp b/common/motion-dashboard.cpp new file mode 100644 index 0000000000..a95e6a090e --- /dev/null +++ b/common/motion-dashboard.cpp @@ -0,0 +1,190 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +#include "motion-dashboard.h" + +using namespace rs2; +using namespace rsutils::string; + +motion_dashboard::motion_dashboard( std::string name ) + : stream_dashboard( name, 30 ) + , last_time( glfwGetTime() ) + , x_value( 0 ) + , y_value( 0 ) + , z_value( 0 ) + , n_value( 0 ) +{ + frame_rate = MAX_FRAME_RATE; + clear( true ); +} + +void motion_dashboard::draw( ux_window & win, rect r ) +{ + if( accel_params[curr_accel_param_position] == "X" ) + { + auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); + for( int i = 0; i < x_hist.size(); i++ ) + { + add_point( (float)i, (float)x_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Y" ) + { + auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); + for( int i = 0; i < y_hist.size(); i++ ) + { + add_point( (float)i, (float)y_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "Z" ) + { + auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); + for( int i = 0; i < z_hist.size(); i++ ) + { + add_point( (float)i, (float)z_hist[i] ); + } + } + + if( accel_params[curr_accel_param_position] == "N" ) + { + auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); + for( int i = 0; i < n_hist.size(); i++ ) + { + add_point( (float)i, (float)n_hist[i] ); + } + } + + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; + draw_dashboard( win, r ); + + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + show_radiobuttons(); + + ImGui::SameLine(); + + show_data_rate_slider(); +} + +int motion_dashboard::get_height() const +{ + return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); +} + +void motion_dashboard::clear( bool full ) +{ + write_shared_data( + [&]() + { + if( full ) + { + x_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + x_history.push_back( 0 ); + + y_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + y_history.push_back( 0 ); + + z_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + z_history.push_back( 0 ); + + n_history.clear(); + for( int i = 0; i < DEQUE_SIZE; i++ ) + n_history.push_back( 0 ); + } + } ); +} + +/* +void accel_dashboard::process_frame( rs2::frame f ) +{ + write_shared_data( + [&]() + { + if( f && f.is< rs2::motion_frame >() ) + { + double ts = glfwGetTime(); + auto it = frame_to_time.find( f.get_profile().unique_id() ); + + if( ts - last_time > frame_rate && it != frame_to_time.end() ) + { + rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); + + x_value = accel_frame.get_motion_data().x; + y_value = accel_frame.get_motion_data().y; + z_value = accel_frame.get_motion_data().z; + n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); + + if( x_history.size() > DEQUE_SIZE ) + x_history.pop_front(); + if( y_history.size() > DEQUE_SIZE ) + y_history.pop_front(); + if( z_history.size() > DEQUE_SIZE ) + z_history.pop_front(); + if( n_history.size() > DEQUE_SIZE ) + n_history.pop_front(); + + x_history.push_back( x_value ); + y_history.push_back( y_value ); + z_history.push_back( z_value ); + n_history.push_back( n_value ); + + last_time = ts; + } + + frame_to_time[f.get_profile().unique_id()] = ts; + } + } ); +} +*/ + +void motion_dashboard::show_radiobuttons() +{ + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); + ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel X" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); + ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Y" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); + ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show accel Z" ); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); + ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); + if( ImGui::IsItemHovered() ) + ImGui::SetTooltip( "%s", "Show Normal" ); + ImGui::PopStyleColor(); +} + +void motion_dashboard::show_data_rate_slider() +{ + ImGui::PushItemWidth( 100 ); + ImGui::SliderFloat( "##rate", &frame_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); + ImGui::GetWindowWidth(); + + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip( "%s", std::string( rsutils::string::from() + << "Frame rate " + << std::fixed + << std::setprecision(1) + << frame_rate * 1000 + << " mSec" + ).c_str() ); + } +} \ No newline at end of file diff --git a/common/accel-dashboard.h b/common/motion-dashboard.h similarity index 72% rename from common/accel-dashboard.h rename to common/motion-dashboard.h index 70dc42268f..b5d839eeab 100644 --- a/common/accel-dashboard.h +++ b/common/motion-dashboard.h @@ -8,14 +8,14 @@ namespace rs2 { - class accel_dashboard : public stream_dashboard + class motion_dashboard : public stream_dashboard { public: - accel_dashboard( std::string name ); + motion_dashboard( std::string name ); // Extract X, Y, Z and calculate N values from a frame - void process_frame( rs2::frame f ) override; + //void process_frame( rs2::frame f ) override; // Draw Accelerate dashboard and choose graph's lines void draw( ux_window & window, rect rectangle ) override; @@ -27,7 +27,7 @@ namespace rs2 // Show slider that change pause between acceleration values that we saving. void show_data_rate_slider(); - private: + protected: float x_value; float y_value; float z_value; @@ -49,4 +49,22 @@ namespace rs2 std::deque< float > z_history; std::deque< float > n_history; }; + + class accel_dashboard : public motion_dashboard + { + public: + accel_dashboard( std::string name ); + + // Extract X, Y, Z and calculate N values from a frame + void process_frame( rs2::frame f ) override; + }; + + class gyro_dashboard : public motion_dashboard + { + public: + gyro_dashboard( std::string name ); + + // Extract X, Y, Z and calculate N values from a frame + void process_frame( rs2::frame f ) override; + }; } \ No newline at end of file diff --git a/common/output-model.cpp b/common/output-model.cpp index bb14fc7b4a..44f48950bc 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -11,7 +11,7 @@ #include #include -#include "accel-dashboard.h" +#include "motion-dashboard.h" #include "frame-drops-dashboard.h" #include @@ -133,6 +133,11 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ return std::make_shared< accel_dashboard >( name ); }; + available_dashboards[dashboard_names[2]] = [&]( std::string name ) + { + return std::make_shared< gyro_dashboard >( name ); + }; + auto front = available_dashboards.find( dashboard_names[opened_dashboard_index] ); dashboards.push_back(front->second(front->first)); } @@ -1022,7 +1027,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) } auto pos = ImGui::GetCursorScreenPos(); - pos.y += ImGui::GetCursorPosY(); + pos.y += 5; ImGui::PushStyleColor(ImGuiCol_Text, white); @@ -1032,7 +1037,7 @@ void stream_dashboard::draw_dashboard(ux_window& win, rect& r) { pos.x + r.w, pos.y + get_height() }, ImColor(dark_sensor_bg)); auto size = ImGui::CalcTextSize(name.c_str()); - float padding_top = ImGui::GetCursorPosY() + 85.f; // Padding from top for scale digits. Add 85 for background and scale digits synchronizing. + float padding_top = ImGui::GetCursorPosY(); // Padding from top for scale digits. ImGui::SetCursorPos(ImVec2( r.w / 2 - size.x / 2, 5 + padding_top)); ImGui::Text("%s", name.c_str()); ImGui::SameLine(); diff --git a/common/output-model.h b/common/output-model.h index f200c4e8a0..b7f687ac97 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -168,7 +168,7 @@ namespace rs2 std::vector> dashboards; std::map(std::string)>> available_dashboards; - const std::vector< std::string > dashboard_names = { "Acceleration", "Frame Drops per Second" }; + const std::vector< std::string > dashboard_names = { "Acceleration", "Frame Drops per Second", "Gyro" }; int opened_dashboard_index; std::atomic to_stop { 0 }; From a7eeea1b460e877581b1c70453ca2b53fa5d40aa Mon Sep 17 00:00:00 2001 From: Tamir Date: Wed, 28 Feb 2024 11:04:38 +0200 Subject: [PATCH 10/12] small fixes Tabs removed from CmakeList Font scalability improved Int/float warning fixed --- common/CMakeLists.txt | 12 ++++---- common/frame-drops-dashboard.cpp | 7 ++--- common/gyro-dashboard.cpp | 4 +-- common/motion-dashboard.cpp | 48 ++------------------------------ common/motion-dashboard.h | 5 +--- 5 files changed, 14 insertions(+), 62 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 4f004612d2..d4c303b3c0 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -52,12 +52,12 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/processing-block-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/stream-model.h" "${CMAKE_CURRENT_LIST_DIR}/stream-model.cpp" - "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.h" - "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/gyro-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.h" - "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/gyro-dashboard.cpp" + "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.h" + "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.h" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.cpp" ) diff --git a/common/frame-drops-dashboard.cpp b/common/frame-drops-dashboard.cpp index 0a0e6bdc93..3d949561ac 100644 --- a/common/frame-drops-dashboard.cpp +++ b/common/frame-drops-dashboard.cpp @@ -57,10 +57,9 @@ void frame_drops_dashboard::draw( ux_window & win, rect r ) } r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; - if( config_file::instance().get( configurations::viewer::dashboard_open ) ) - draw_dashboard( win, r ); + draw_dashboard( win, r ); - ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + ImGui::GetTextLineHeightWithSpacing() * 2 ); ImGui::SetCursorPosY( ImGui::GetCursorPosY() + 3 ); ImGui::Text( "%s", "Measurement Metric:" ); ImGui::SameLine(); @@ -82,7 +81,7 @@ void frame_drops_dashboard::draw( ux_window & win, rect r ) int frame_drops_dashboard::get_height() const { - return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); + return (int)( 10 * ImGui::GetTextLineHeight() + ImGui::GetTextLineHeightWithSpacing() ); } void frame_drops_dashboard::clear( bool full ) diff --git a/common/gyro-dashboard.cpp b/common/gyro-dashboard.cpp index 317468c7a1..9ab54c1004 100644 --- a/common/gyro-dashboard.cpp +++ b/common/gyro-dashboard.cpp @@ -20,7 +20,7 @@ void gyro_dashboard::process_frame( rs2::frame f ) && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == RS2_STREAM_GYRO ) { double ts = glfwGetTime(); - auto it = frame_to_time.find( f.get_profile().unique_id() ); + auto it = frame_to_time.find( static_cast( f.get_profile().unique_id() ) ); if( ts - last_time > frame_rate && it != frame_to_time.end() ) { @@ -48,7 +48,7 @@ void gyro_dashboard::process_frame( rs2::frame f ) last_time = ts; } - frame_to_time[f.get_profile().unique_id()] = ts; + frame_to_time[static_cast( f.get_profile().unique_id() )] = ts; } } ); } \ No newline at end of file diff --git a/common/motion-dashboard.cpp b/common/motion-dashboard.cpp index a95e6a090e..1944ade16c 100644 --- a/common/motion-dashboard.cpp +++ b/common/motion-dashboard.cpp @@ -55,11 +55,10 @@ void motion_dashboard::draw( ux_window & win, rect r ) add_point( (float)i, (float)n_hist[i] ); } } - r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; draw_dashboard( win, r ); - ImGui::SetCursorPosX( ImGui::GetCursorPosX() + 40 ); + ImGui::SetCursorPosX( ImGui::GetCursorPosX() + ImGui::GetTextLineHeightWithSpacing() * 2 ); show_radiobuttons(); ImGui::SameLine(); @@ -69,7 +68,7 @@ void motion_dashboard::draw( ux_window & win, rect r ) int motion_dashboard::get_height() const { - return (int)( 160 + ImGui::GetTextLineHeightWithSpacing() ); + return (int)( 10 * ImGui::GetTextLineHeight() + ImGui::GetTextLineHeightWithSpacing() ); } void motion_dashboard::clear( bool full ) @@ -98,49 +97,6 @@ void motion_dashboard::clear( bool full ) } ); } -/* -void accel_dashboard::process_frame( rs2::frame f ) -{ - write_shared_data( - [&]() - { - if( f && f.is< rs2::motion_frame >() ) - { - double ts = glfwGetTime(); - auto it = frame_to_time.find( f.get_profile().unique_id() ); - - if( ts - last_time > frame_rate && it != frame_to_time.end() ) - { - rs2::motion_frame accel_frame = f.as< rs2::motion_frame >(); - - x_value = accel_frame.get_motion_data().x; - y_value = accel_frame.get_motion_data().y; - z_value = accel_frame.get_motion_data().z; - n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - - if( x_history.size() > DEQUE_SIZE ) - x_history.pop_front(); - if( y_history.size() > DEQUE_SIZE ) - y_history.pop_front(); - if( z_history.size() > DEQUE_SIZE ) - z_history.pop_front(); - if( n_history.size() > DEQUE_SIZE ) - n_history.pop_front(); - - x_history.push_back( x_value ); - y_history.push_back( y_value ); - z_history.push_back( z_value ); - n_history.push_back( n_value ); - - last_time = ts; - } - - frame_to_time[f.get_profile().unique_id()] = ts; - } - } ); -} -*/ - void motion_dashboard::show_radiobuttons() { ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); diff --git a/common/motion-dashboard.h b/common/motion-dashboard.h index b5d839eeab..2342f393ab 100644 --- a/common/motion-dashboard.h +++ b/common/motion-dashboard.h @@ -14,10 +14,7 @@ namespace rs2 motion_dashboard( std::string name ); - // Extract X, Y, Z and calculate N values from a frame - //void process_frame( rs2::frame f ) override; - - // Draw Accelerate dashboard and choose graph's lines + // Draw Accelerate dashboard and graph's lines void draw( ux_window & window, rect rectangle ) override; int get_height() const override; void clear( bool full ) override; From 8a9591589ceaebf97871f9d0819cf1d58c8018fc Mon Sep 17 00:00:00 2001 From: Tamir Date: Mon, 4 Mar 2024 12:09:29 +0200 Subject: [PATCH 11/12] small fixes Variables names, Function separating --- common/CMakeLists.txt | 2 - common/accel-dashboard.cpp | 54 --------------------- common/gyro-dashboard.cpp | 54 --------------------- common/motion-dashboard.cpp | 94 +++++++++++++++++++++++++++---------- common/motion-dashboard.h | 43 +++++++---------- common/output-model.cpp | 36 +++++++------- common/output-model.h | 9 ++-- 7 files changed, 108 insertions(+), 184 deletions(-) delete mode 100644 common/accel-dashboard.cpp delete mode 100644 common/gyro-dashboard.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d4c303b3c0..62ab4990f4 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -54,8 +54,6 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/stream-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.h" "${CMAKE_CURRENT_LIST_DIR}/motion-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/accel-dashboard.cpp" - "${CMAKE_CURRENT_LIST_DIR}/gyro-dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.h" "${CMAKE_CURRENT_LIST_DIR}/frame-drops-dashboard.cpp" "${CMAKE_CURRENT_LIST_DIR}/post-processing-filters.h" diff --git a/common/accel-dashboard.cpp b/common/accel-dashboard.cpp deleted file mode 100644 index e2e67ad345..0000000000 --- a/common/accel-dashboard.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2024 Intel Corporation. All Rights Reserved. - -#include "motion-dashboard.h" - -using namespace rs2; -using namespace rsutils::string; - -accel_dashboard::accel_dashboard( std::string name ) - : motion_dashboard( name ) -{ -} - -void accel_dashboard::process_frame( rs2::frame f ) -{ - write_shared_data( - [&]() - { - if( f && f.is< rs2::motion_frame >() - && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == RS2_STREAM_ACCEL ) - { - double ts = glfwGetTime(); - auto it = frame_to_time.find( f.get_profile().unique_id() ); - - if( ts - last_time > frame_rate && it != frame_to_time.end() ) - { - rs2::motion_frame frame = f.as< rs2::motion_frame >(); - - x_value = frame.get_motion_data().x; - y_value = frame.get_motion_data().y; - z_value = frame.get_motion_data().z; - n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - - if( x_history.size() > DEQUE_SIZE ) - x_history.pop_front(); - if( y_history.size() > DEQUE_SIZE ) - y_history.pop_front(); - if( z_history.size() > DEQUE_SIZE ) - z_history.pop_front(); - if( n_history.size() > DEQUE_SIZE ) - n_history.pop_front(); - - x_history.push_back( x_value ); - y_history.push_back( y_value ); - z_history.push_back( z_value ); - n_history.push_back( n_value ); - - last_time = ts; - } - - frame_to_time[f.get_profile().unique_id()] = ts; - } - } ); -} \ No newline at end of file diff --git a/common/gyro-dashboard.cpp b/common/gyro-dashboard.cpp deleted file mode 100644 index 9ab54c1004..0000000000 --- a/common/gyro-dashboard.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2024 Intel Corporation. All Rights Reserved. - -#include "motion-dashboard.h" - -using namespace rs2; -using namespace rsutils::string; - -gyro_dashboard::gyro_dashboard( std::string name ) - : motion_dashboard( name ) -{ -} - -void gyro_dashboard::process_frame( rs2::frame f ) -{ - write_shared_data( - [&]() - { - if( f && f.is< rs2::motion_frame >() - && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == RS2_STREAM_GYRO ) - { - double ts = glfwGetTime(); - auto it = frame_to_time.find( static_cast( f.get_profile().unique_id() ) ); - - if( ts - last_time > frame_rate && it != frame_to_time.end() ) - { - rs2::motion_frame frame = f.as< rs2::motion_frame >(); - - x_value = frame.get_motion_data().x; - y_value = frame.get_motion_data().y; - z_value = frame.get_motion_data().z; - n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); - - if( x_history.size() > DEQUE_SIZE ) - x_history.pop_front(); - if( y_history.size() > DEQUE_SIZE ) - y_history.pop_front(); - if( z_history.size() > DEQUE_SIZE ) - z_history.pop_front(); - if( n_history.size() > DEQUE_SIZE ) - n_history.pop_front(); - - x_history.push_back( x_value ); - y_history.push_back( y_value ); - z_history.push_back( z_value ); - n_history.push_back( n_value ); - - last_time = ts; - } - - frame_to_time[static_cast( f.get_profile().unique_id() )] = ts; - } - } ); -} \ No newline at end of file diff --git a/common/motion-dashboard.cpp b/common/motion-dashboard.cpp index 1944ade16c..22948a65dd 100644 --- a/common/motion-dashboard.cpp +++ b/common/motion-dashboard.cpp @@ -1,12 +1,13 @@ // License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2024 Intel Corporation. All Rights Reserved. +#include "output-model.h" #include "motion-dashboard.h" using namespace rs2; using namespace rsutils::string; -motion_dashboard::motion_dashboard( std::string name ) +motion_dashboard::motion_dashboard( std::string name, enum rs2_stream stream) : stream_dashboard( name, 30 ) , last_time( glfwGetTime() ) , x_value( 0 ) @@ -14,45 +15,88 @@ motion_dashboard::motion_dashboard( std::string name ) , z_value( 0 ) , n_value( 0 ) { - frame_rate = MAX_FRAME_RATE; + dashboard_update_rate = MAX_FRAME_RATE; + stream_type = stream; clear( true ); } +void motion_dashboard::process_frame( rs2::frame f ) +{ + write_shared_data( + [&]() + { + if( f && f.is< rs2::motion_frame >() + && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == stream_type ) + { + double ts = glfwGetTime(); + auto it = frame_to_time.find( f.get_profile().unique_id() ); + + if( ts - last_time > dashboard_update_rate && it != frame_to_time.end() ) + { + rs2::motion_frame frame = f.as< rs2::motion_frame >(); + + x_value = frame.get_motion_data().x; + y_value = frame.get_motion_data().y; + z_value = frame.get_motion_data().z; + n_value = std::sqrt( ( x_value * x_value ) + ( y_value * y_value ) + ( z_value * z_value ) ); + + if( x_history.size() > DEQUE_SIZE ) + x_history.pop_front(); + if( y_history.size() > DEQUE_SIZE ) + y_history.pop_front(); + if( z_history.size() > DEQUE_SIZE ) + z_history.pop_front(); + if( n_history.size() > DEQUE_SIZE ) + n_history.pop_front(); + + x_history.push_back( x_value ); + y_history.push_back( y_value ); + z_history.push_back( z_value ); + n_history.push_back( n_value ); + + last_time = ts; + } + + frame_to_time[f.get_profile().unique_id()] = ts; + } + } ); +} + void motion_dashboard::draw( ux_window & win, rect r ) { - if( accel_params[curr_accel_param_position] == "X" ) + if( plots[plot_index] == x_axes_name ) { auto x_hist = read_shared_data< std::deque< float > >( [&]() { return x_history; } ); for( int i = 0; i < x_hist.size(); i++ ) { - add_point( (float)i, (float)x_hist[i] ); + add_point( (float)i, x_hist[i] ); } } - if( accel_params[curr_accel_param_position] == "Y" ) + if( plots[plot_index] == y_axes_name ) { auto y_hist = read_shared_data< std::deque< float > >( [&]() { return y_history; } ); for( int i = 0; i < y_hist.size(); i++ ) { - add_point( (float)i, (float)y_hist[i] ); + add_point( (float)i, y_hist[i] ); } } - if( accel_params[curr_accel_param_position] == "Z" ) + if( plots[plot_index] == z_axes_name ) { auto z_hist = read_shared_data< std::deque< float > >( [&]() { return z_history; } ); for( int i = 0; i < z_hist.size(); i++ ) { - add_point( (float)i, (float)z_hist[i] ); + add_point( (float)i, z_hist[i] ); } } - if( accel_params[curr_accel_param_position] == "N" ) + if( plots[plot_index] == n_axes_name ) { auto n_hist = read_shared_data< std::deque< float > >( [&]() { return n_history; } ); for( int i = 0; i < n_hist.size(); i++ ) { - add_point( (float)i, (float)n_hist[i] ); + add_point( (float)i, n_hist[i] ); } } r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; @@ -99,47 +143,47 @@ void motion_dashboard::clear( bool full ) void motion_dashboard::show_radiobuttons() { - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 233, 0, 0, 255, true ) ); - ImGui::RadioButton( "X", &curr_accel_param_position, 0 ); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 1.0f, 0.0f, 0.0f, 1.0f ) ); // -> Red + ImGui::RadioButton( "X", &plot_index, 0 ); if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel X" ); + ImGui::SetTooltip( "%s", std::string( rsutils::string::from() << "Show " << x_axes_name ).c_str() ); ImGui::PopStyleColor(); ImGui::SameLine(); - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 0, 255, 0, 255, true ) ); - ImGui::RadioButton( "Y", &curr_accel_param_position, 1 ); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 0.00f, 1.00f, 0.00f, 1.00f ) ); // -> Green + ImGui::RadioButton( "Y", &plot_index, 1 ); if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Y" ); + ImGui::SetTooltip( "%s", std::string( rsutils::string::from() << "Show " << y_axes_name ).c_str() ); ImGui::PopStyleColor(); ImGui::SameLine(); - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 85, 89, 245, 255, true ) ); - ImGui::RadioButton( "Z", &curr_accel_param_position, 2 ); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 0.00f, 0.00f, 1.00f, 1.00f ) ); // -> Blue + ImGui::RadioButton( "Z", &plot_index, 2 ); if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show accel Z" ); + ImGui::SetTooltip( "%s", std::string( rsutils::string::from() << "Show " << z_axes_name ).c_str() ); ImGui::PopStyleColor(); ImGui::SameLine(); - ImGui::PushStyleColor( ImGuiCol_Text, from_rgba( 255, 255, 255, 255, true ) ); - ImGui::RadioButton( "N", &curr_accel_param_position, 3 ); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 1.00f, 1.00f, 1.00f, 1.00f ) ); // -> White + ImGui::RadioButton( "N", &plot_index, 3 ); if( ImGui::IsItemHovered() ) - ImGui::SetTooltip( "%s", "Show Normal" ); + ImGui::SetTooltip( "%s", "Show Normal - sqrt(x^2 + y^2 + z^2)" ); ImGui::PopStyleColor(); } void motion_dashboard::show_data_rate_slider() { ImGui::PushItemWidth( 100 ); - ImGui::SliderFloat( "##rate", &frame_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); + ImGui::SliderFloat( "##rate", &dashboard_update_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); ImGui::GetWindowWidth(); if (ImGui::IsItemHovered()) { ImGui::SetTooltip( "%s", std::string( rsutils::string::from() - << "Frame rate " + << "Dashboard update every " << std::fixed << std::setprecision(1) - << frame_rate * 1000 + << dashboard_update_rate * 1000 << " mSec" ).c_str() ); } diff --git a/common/motion-dashboard.h b/common/motion-dashboard.h index 2342f393ab..f6818f4a15 100644 --- a/common/motion-dashboard.h +++ b/common/motion-dashboard.h @@ -1,18 +1,16 @@ // License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2024 Intel Corporation. All Rights Reserved. -#pragma once - -#include "output-model.h" -#include "device-model.h" namespace rs2 { + class stream_dashboard; + class motion_dashboard : public stream_dashboard { public: - motion_dashboard( std::string name ); + motion_dashboard( std::string name, enum rs2_stream stream); // Draw Accelerate dashboard and graph's lines void draw( ux_window & window, rect rectangle ) override; @@ -24,19 +22,28 @@ namespace rs2 // Show slider that change pause between acceleration values that we saving. void show_data_rate_slider(); + // Extract X, Y, Z and calculate N values from a frame + void process_frame( rs2::frame f ) override; + protected: float x_value; float y_value; float z_value; float n_value; // Norm ||V|| = SQRT(X^2 + Y^2 + Z^2) - float frame_rate; + float dashboard_update_rate; double last_time; - std::map< float, double > frame_to_time; + std::map< int, double > frame_to_time; - std::vector< std::string > accel_params = { "X", "Y", "Z", "N" }; - int curr_accel_param_position = 0; + const char * x_axes_name = "X"; + const char * y_axes_name = "Y"; + const char * z_axes_name = "Z"; + const char * n_axes_name = "N"; + std::vector< std::string > plots = { x_axes_name, y_axes_name, z_axes_name, n_axes_name }; + int plot_index = 0; + + enum rs2_stream stream_type; const float MIN_FRAME_RATE = 0.01f; const float MAX_FRAME_RATE = 0.1f; @@ -46,22 +53,4 @@ namespace rs2 std::deque< float > z_history; std::deque< float > n_history; }; - - class accel_dashboard : public motion_dashboard - { - public: - accel_dashboard( std::string name ); - - // Extract X, Y, Z and calculate N values from a frame - void process_frame( rs2::frame f ) override; - }; - - class gyro_dashboard : public motion_dashboard - { - public: - gyro_dashboard( std::string name ); - - // Extract X, Y, Z and calculate N values from a frame - void process_frame( rs2::frame f ) override; - }; } \ No newline at end of file diff --git a/common/output-model.cpp b/common/output-model.cpp index 44f48950bc..fdbf7a8f2b 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -119,27 +119,27 @@ output_model::output_model() : fw_logger([this](){ thread_loop(); }) , incoming_ configurations::viewer::search_term, std::string("")); is_dashboard_open = config_file::instance().get_or_default( configurations::viewer::dashboard_open, true ); - opened_dashboard_index = config_file::instance().get( configurations::viewer::last_opened_dashboard ); + current_dashboard_index = config_file::instance().get( configurations::viewer::last_opened_dashboard ); if (search_line != "") search_open = true; - available_dashboards[dashboard_names[1]] = [&]( std::string name ) - { - return std::make_shared(name, &number_of_drops, &total_frames); - }; + available_dashboards.push_back( std::make_pair( dashboard_names[0], + [&]( std::string name ) + { return std::make_shared< frame_drops_dashboard >( name, &number_of_drops, &total_frames ); } ) ); - available_dashboards[dashboard_names[0]] = [&]( std::string name ) - { - return std::make_shared< accel_dashboard >( name ); - }; + available_dashboards.push_back( std::make_pair( dashboard_names[1], + [&]( std::string name ) + { return std::make_shared< motion_dashboard >( name, RS2_STREAM_ACCEL ); } ) ); - available_dashboards[dashboard_names[2]] = [&]( std::string name ) - { - return std::make_shared< gyro_dashboard >( name ); - }; + available_dashboards.push_back( std::make_pair( dashboard_names[2], + [&]( std::string name ) + { return std::make_shared< motion_dashboard >( name, RS2_STREAM_GYRO ); } ) ); - auto front = available_dashboards.find( dashboard_names[opened_dashboard_index] ); - dashboards.push_back(front->second(front->first)); + for(const auto& dashboard: available_dashboards) + { + if( dashboard.first == dashboard_names[current_dashboard_index] ) + dashboards.push_back( dashboard.second( dashboard.first ) ); + } } bool output_model::round_indicator(ux_window& win, std::string icon, @@ -716,14 +716,14 @@ void output_model::draw(ux_window& win, rect view_rect, device_models_list & dev ImGui::SetCursorPosX( ImGui::GetCursorPosX() + collapse_dashboard_button_size.x ); - // Show dashboards to user - if( ImGui::RadioButton( name.c_str(), &opened_dashboard_index, radio_button_choice++ ) ) + // Show dashboard radio button to user + if( ImGui::RadioButton( name.c_str(), ¤t_dashboard_index, radio_button_choice++ ) ) { for( auto & d : dashboards ) d->close(); dashboards.clear(); - config_file::instance().set( configurations::viewer::last_opened_dashboard, opened_dashboard_index); + config_file::instance().set( configurations::viewer::last_opened_dashboard, current_dashboard_index); dashboards.push_back( kvp.second( kvp.first ) ); } } diff --git a/common/output-model.h b/common/output-model.h index b7f687ac97..4345efce55 100644 --- a/common/output-model.h +++ b/common/output-model.h @@ -83,7 +83,7 @@ namespace rs2 std::mutex m; std::atomic stop { false }; std::thread t; - std::vector> xy; + std::deque> xy; bool to_close = false; }; @@ -167,9 +167,10 @@ namespace rs2 bool command_focus = true; std::vector> dashboards; - std::map(std::string)>> available_dashboards; - const std::vector< std::string > dashboard_names = { "Acceleration", "Frame Drops per Second", "Gyro" }; - int opened_dashboard_index; + std::vector(std::string)>>> available_dashboards; + const std::vector< std::string > dashboard_names = { "Frame Drops per Second", "Acceleration", "Gyro" }; + + int current_dashboard_index; std::atomic to_stop { 0 }; std::thread fw_logger; From 8b16100bad14127bb18d7729385ef7df08cf39c7 Mon Sep 17 00:00:00 2001 From: Tamir Date: Tue, 5 Mar 2024 10:27:17 +0200 Subject: [PATCH 12/12] default dashboard fixed A slider size is fixed for a small viewer size. --- common/motion-dashboard.cpp | 11 ++++++----- common/motion-dashboard.h | 1 - common/ux-window.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/motion-dashboard.cpp b/common/motion-dashboard.cpp index 22948a65dd..3d3d0ad305 100644 --- a/common/motion-dashboard.cpp +++ b/common/motion-dashboard.cpp @@ -29,9 +29,8 @@ void motion_dashboard::process_frame( rs2::frame f ) && ( f.as< rs2::motion_frame >() ).get_profile().stream_type() == stream_type ) { double ts = glfwGetTime(); - auto it = frame_to_time.find( f.get_profile().unique_id() ); - if( ts - last_time > dashboard_update_rate && it != frame_to_time.end() ) + if( ts - last_time > dashboard_update_rate ) { rs2::motion_frame frame = f.as< rs2::motion_frame >(); @@ -56,8 +55,6 @@ void motion_dashboard::process_frame( rs2::frame f ) last_time = ts; } - - frame_to_time[f.get_profile().unique_id()] = ts; } } ); } @@ -173,7 +170,11 @@ void motion_dashboard::show_radiobuttons() void motion_dashboard::show_data_rate_slider() { - ImGui::PushItemWidth( 100 ); + if( ( ImGui::GetContentRegionMax().x - ImGui::GetCursorPosX() - 10.f ) < 100 ) + ImGui::PushItemWidth( ImGui::GetContentRegionMax().x - ImGui::GetCursorPosX() - 10.f ); + else + ImGui::PushItemWidth( 100 ); + ImGui::SliderFloat( "##rate", &dashboard_update_rate, MIN_FRAME_RATE, MAX_FRAME_RATE, "%.2f" ); ImGui::GetWindowWidth(); diff --git a/common/motion-dashboard.h b/common/motion-dashboard.h index f6818f4a15..08656328b2 100644 --- a/common/motion-dashboard.h +++ b/common/motion-dashboard.h @@ -33,7 +33,6 @@ namespace rs2 float dashboard_update_rate; double last_time; - std::map< int, double > frame_to_time; const char * x_axes_name = "X"; const char * y_axes_name = "Y"; diff --git a/common/ux-window.cpp b/common/ux-window.cpp index 4cb40d1b89..760581015d 100644 --- a/common/ux-window.cpp +++ b/common/ux-window.cpp @@ -72,7 +72,7 @@ namespace rs2 config_file::instance().set_default(configurations::viewer::metric_system, true); config_file::instance().set_default(configurations::viewer::ground_truth_r, 2500); config_file::instance().set_default(configurations::viewer::dashboard_open, true); - config_file::instance().set_default(configurations::viewer::last_opened_dashboard, 1 ); + config_file::instance().set_default(configurations::viewer::last_opened_dashboard, 0 ); config_file::instance().set_default(configurations::record::compression_mode, 2); // Let the device decide config_file::instance().set_default(configurations::record::file_save_mode, 0); // Auto-select name