2023-01-05 09:35:47 +00:00
|
|
|
/* #define DEBUGTRACE_ENABLED */
|
|
|
|
#include "debugtrace.hpp"
|
2023-06-06 14:05:24 +00:00
|
|
|
#include "lasp_daqdata.h"
|
|
|
|
#include "lasp_daq.h"
|
2023-01-05 09:35:47 +00:00
|
|
|
#include "lasp_rtsignalviewer.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <mutex>
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using Lck = std::scoped_lock<std::mutex>;
|
|
|
|
using rte = std::runtime_error;
|
|
|
|
|
2023-06-07 19:49:07 +00:00
|
|
|
RtSignalViewer::RtSignalViewer(SmgrHandle mgr, const d approx_time_hist,
|
2023-01-05 09:35:47 +00:00
|
|
|
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");
|
|
|
|
}
|
2023-06-06 14:05:24 +00:00
|
|
|
startThread();
|
2023-01-05 09:35:47 +00:00
|
|
|
}
|
|
|
|
|
2023-06-09 08:43:04 +00:00
|
|
|
void RtSignalViewer::inCallback(const DaqData &data) {
|
2023-01-05 09:35:47 +00:00
|
|
|
|
|
|
|
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() {
|
2023-06-06 14:05:24 +00:00
|
|
|
stopThread();
|
2023-01-05 09:35:47 +00:00
|
|
|
}
|
|
|
|
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<us>(static_cast<us>(_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;
|
|
|
|
}
|