Skip to content

Commit

Permalink
PR #7452 from Nir: Add time utility classes + UT
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel authored Oct 14, 2020
2 parents 296d104 + aaa6a6a commit 405772c
Show file tree
Hide file tree
Showing 21 changed files with 363 additions and 120 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ set_target_properties(${LRS_TARGET} PROPERTIES VERSION ${REALSENSE_VERSION_STRIN
include(include/CMakeLists.txt)
include(src/CMakeLists.txt)
include(third-party/CMakeLists.txt)
include(common/utilities/CMakeLists.txt)

# configure the project according to OS specific requirments
# macro definition located at "CMake/<OS>_config.cmake"
Expand Down
4 changes: 2 additions & 2 deletions common/cah-model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cah_model::cah_model(device_model & dev_model, viewer_model& viewer) :
_viewer(viewer),
_state(model_state_type::TRIGGER_MODAL),
_process_started(false),
_process_timeout()
_process_timeout(std::chrono::seconds(30))
{
global_calib_status = RS2_CALIBRATION_NOT_NEEDED;

Expand Down Expand Up @@ -106,7 +106,7 @@ bool cah_model::prompt_trigger_popup(ux_window& window, std::string& error_messa
_state = model_state_type::PROCESS_MODAL;
// We switch to process state without a guarantee that the process really started,
// Set a timeout to make sure if it is not started we will allow closing the window.
_process_timeout.start( std::chrono::seconds( 30 ) );
_process_timeout.start();

}
}
Expand Down
34 changes: 2 additions & 32 deletions common/cah-model.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#pragma once

#include <utilities/time/timer.h>
#include <string>
#include <chrono>
#include <atomic>

namespace rs2
Expand All @@ -13,36 +13,6 @@ namespace rs2
class viewer_model;
class device_model;

// Helper class for setting , starting and checking a timeout.
// Inner units are [ms] , API units are seconds.
// This class is not thread safe and should not be passed between threads.
class timeout
{
public:
timeout() : timeout_delay_ms(0), start_time_ms(0) {};

// Start timer from current time
// Can be called with std::chrono::hours/minutes/seconds/milliseconds/microseconds/nanoseconds type
void start(std::chrono::seconds timeout)
{
using namespace std::chrono;
start_time_ms = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
timeout_delay_ms = duration_cast<milliseconds>(timeout).count();
}

// Check if timeout expired
bool has_expired() const
{
using namespace std::chrono;
auto curr_time = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
return curr_time - start_time_ms >= timeout_delay_ms;
}

private:
long long timeout_delay_ms;
long long start_time_ms;
};

class cah_model // CAH = Camera Accuracy Health
{
public:
Expand All @@ -57,6 +27,6 @@ namespace rs2
enum class model_state_type { TRIGGER_MODAL, PROCESS_MODAL };
std::atomic<model_state_type> _state; // will be set from a different thread callback function
bool _process_started;
timeout _process_timeout;
utilities::time::timer _process_timeout;
};
}
4 changes: 2 additions & 2 deletions common/model-views.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6053,7 +6053,7 @@ namespace rs2
{
viewer.synchronization_enable = false;
}
_update_readonly_options_timer.signal();
_update_readonly_options_timer.set_expired();
sub->play(profiles, viewer, dev_syncer);
}
catch (const error& e)
Expand Down Expand Up @@ -6094,7 +6094,7 @@ namespace rs2
}))
{
stop_recording = true;
_update_readonly_options_timer.signal();
_update_readonly_options_timer.set_expired();
}
}
if (ImGui::IsItemHovered())
Expand Down
3 changes: 2 additions & 1 deletion common/model-views.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "updates-model.h"
#include "calibration-model.h"
#include "cah-model.h"
#include "../common/utilities/time/periodic_timer.h"

ImVec4 from_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a, bool consistent_color = false);
ImVec4 operator+(const ImVec4& c, float v);
Expand Down Expand Up @@ -847,7 +848,7 @@ namespace rs2

std::shared_ptr<recorder> _recorder;
std::vector<std::shared_ptr<subdevice_model>> live_subdevices;
periodic_timer _update_readonly_options_timer;
utilities::time::periodic_timer _update_readonly_options_timer;
bool pause_required = false;
std::shared_ptr< atomic_objects_in_frame > _detected_objects;
std::shared_ptr<updates_model> _updates;
Expand Down
70 changes: 6 additions & 64 deletions common/rendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <librealsense2/rs.hpp>
#include <librealsense2-gl/rs_processing_gl.hpp>
#include <utilities/time/timer.h>


#include <vector>
#include <algorithm>
Expand Down Expand Up @@ -791,68 +793,6 @@ namespace rs2
size_t _size; float3* _data;
};

using clock = std::chrono::steady_clock;

// Helper class to keep track of time
class timer
{
public:
timer()
{
_start = std::chrono::steady_clock::now();
}

void reset() { _start = std::chrono::steady_clock::now(); }

// Get elapsed milliseconds since timer creation
double elapsed_ms() const
{
return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed()).count();
}

clock::duration elapsed() const
{
return clock::now() - _start;
}

clock::time_point now() const
{
return clock::now();
}
private:
clock::time_point _start;
};

class periodic_timer
{
public:
periodic_timer(clock::duration delta)
: _delta(delta)
{
_last = _time.now();
}

operator bool() const
{
if (_time.now() - _last > _delta)
{
_last = _time.now();
return true;
}
return false;
}

void signal() const
{
_last = _time.now() - _delta;
}

private:
timer _time;
mutable clock::time_point _last;
clock::duration _delta;
};

// Temporal event is a very simple time filter
// that allows a concensus based on a set of measurements in time
// You set the window, and add measurements, and the class offers
Expand All @@ -861,6 +801,8 @@ namespace rs2
class temporal_event
{
public:
using clock = std::chrono::steady_clock;

temporal_event(clock::duration window) : _window(window) {}
temporal_event() : _window(std::chrono::milliseconds(1000)) {}

Expand All @@ -879,7 +821,7 @@ namespace rs2
{
std::lock_guard<std::mutex> lock(_m);

if (_t.elapsed() < _window) return false; // Ensure no false alarms in the warm-up time
if (_t.get_elapsed() < _window) return false; // Ensure no false alarms in the warm-up time

_measurements.erase(std::remove_if(_measurements.begin(), _measurements.end(),
[this](std::pair<clock::time_point, bool> pair) {
Expand All @@ -904,7 +846,7 @@ namespace rs2
std::mutex _m;
clock::duration _window;
std::vector<std::pair<clock::time_point, bool>> _measurements;
timer _t;
utilities::time::stopwatch _t;
};

class texture_buffer
Expand Down
10 changes: 10 additions & 0 deletions common/utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# License: Apache 2.0. See LICENSE file in root directory.
# Copyright(c) 2019 Intel Corporation. All Rights Reserved.

target_sources(${LRS_TARGET}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/time/common.h"
"${CMAKE_CURRENT_LIST_DIR}/time/stopwatch.h"
"${CMAKE_CURRENT_LIST_DIR}/time/timer.h"
"${CMAKE_CURRENT_LIST_DIR}/time/periodic_timer.h"
)
14 changes: 14 additions & 0 deletions common/utilities/time/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#pragma once

#include <chrono>

namespace utilities
{
namespace time
{
using clock = std::chrono::steady_clock;
}
}
48 changes: 48 additions & 0 deletions common/utilities/time/periodic_timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

// Helper classes to keep track of time
#pragma once

#include "timer.h"

namespace utilities
{
namespace time
{
// A timer class that wakes up every <delta> seconds/minutes/etc. on its bool operator:
// Usage example:
// periodic_timer timer( chrono::seconds( 5 ));
// while(1) {
// if( timer ) { /* do something every 5 seconds */ }
// }
class periodic_timer
{
public:

periodic_timer(clock::duration delta)
: _delta(delta)
{
}

// Allow use of bool operator for checking time expiration and re trigger when time expired
operator bool() const
{
if (_delta.has_expired())
{
_delta.start();
return true;
}
return false;
}

// Force time expiration
void set_expired()
{
_delta.set_expired();
}
protected:
timer _delta;
};
}
}
51 changes: 51 additions & 0 deletions common/utilities/time/stopwatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#pragma once

#include "common.h"

namespace utilities
{
namespace time
{
// Timer that counts forward in time (vs backwards in the 'timer' class)
// It supply a basic stopwatch API, reset, get elapsed time..
class stopwatch
{
public:

stopwatch()
{
_start = clock::now();
}

// Reset the stopwatch time
void reset(clock::time_point start_time = clock::now()) const
{
_start = start_time;
}

// Get elapsed in milliseconds since timer creation
double get_elapsed_ms() const
{
return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(get_elapsed()).count();
}

// Get elapsed since timer creation
clock::duration get_elapsed() const
{
return clock::now() - _start;
}

// Get stopwatch start time
clock::time_point get_start() const
{
return _start;
}

protected:
mutable clock::time_point _start;
};
}
}
45 changes: 45 additions & 0 deletions common/utilities/time/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

// Helper classes to keep track of time
#pragma once

#include "stopwatch.h"

namespace utilities
{
namespace time
{
// A timer counting backwards in time (vs forwards in the `stopwatch` class)
// It supply basic timer API, start, has_expired..
class timer
{
public:

timer(clock::duration timeout) : _delta(timeout), sw()
{
}

// Start timer
void start() const
{
sw.reset();
}

// Check if timer time expired
bool has_expired() const
{
return sw.get_start() + _delta <= clock::now();
}

// Force time expiration
void set_expired()
{
sw.reset(clock::now() - (_delta + std::chrono::nanoseconds(100)));
}
protected:
clock::duration _delta;
stopwatch sw;
};
}
}
Loading

0 comments on commit 405772c

Please sign in to comment.