/* #define DEBUGTRACE_ENABLED */ #include "debugtrace.hpp" #include "lasp_daqdata.h" #include "lasp_daq.h" #include "lasp_rtsignalviewer.h" #include #include using std::cerr; using std::endl; using Lck = std::scoped_lock; using rte = std::runtime_error; RtSignalViewer::RtSignalViewer(SmgrHandle mgr, const d approx_time_hist, const us resolution, const us channel) : ThreadedInDataHandler(mgr), _approx_time_hist(approx_time_hist), _resolution(resolution), _channel(channel) { DEBUGTRACE_ENTER; if (approx_time_hist <= 0) { throw rte("Invalid time history. Should be > 0"); } if (resolution <= 1) { throw rte("Invalid resolution. Should be > 1"); } startThread(); } void RtSignalViewer::inCallback(const DaqData &data) { DEBUGTRACE_ENTER; Lck lck(_sv_mtx); /// Push new data in time buffer, scaled by sensitivity _tb.push(data.toFloat(_channel) / _sens(_channel)); _dat.col(0) += _nsamples_per_point / _fs; /// Required number of samples for a new 'point' while (_tb.size() > _nsamples_per_point) { // Roll forward time column _dat.col(0) += _nsamples_per_point / _fs; vd newvals = _tb.pop(_nsamples_per_point); d newmax = newvals.max(); d newmin = newvals.min(); vd mincol = _dat.col(1); vd maxcol = _dat.col(2); _dat(arma::span(0, _resolution-2),1) = mincol(arma::span(1, _resolution-1)); _dat(arma::span(0, _resolution-2),2) = maxcol(arma::span(1, _resolution-1)); _dat(_resolution-1, 1) = newmin; _dat(_resolution-1, 2) = newmax; } } RtSignalViewer::~RtSignalViewer() { stopThread(); } void RtSignalViewer::reset(const Daq *daq) { DEBUGTRACE_ENTER; Lck lck(_sv_mtx); // Reset time buffer _tb.reset(); if (daq) { _fs = daq->samplerate(); /// Update sensitivity values _sens.resize(daq->neninchannels()); us i = 0; for (const auto &ch : daq->enabledInChannels()) { _sens[i] = ch.sensitivity; i++; } /// The number of samples per point, based on which minmax are computed _nsamples_per_point = std::max(static_cast(_approx_time_hist / _resolution * _fs), 1); const d dt_points = _nsamples_per_point / _fs; const d tend = dt_points * _resolution; // Initialize data array _dat.resize(_resolution, 3); _dat.col(0) = arma::linspace(0, tend, _resolution); _dat.col(1).zeros(); _dat.col(2).zeros(); } else { _sens.zeros(); _fs = 0; _dat.reset(); } } dmat RtSignalViewer::getCurrentValue() const { DEBUGTRACE_ENTER; Lck lck(_sv_mtx); return _dat; }