Skip to content
Merged

Dev #179

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
builtin = clear,rare,en-GB_to_en-US,names,informal,code
check-filenames =
check-hidden =
ignore-words-list = weill,sinc,mut,numer,uint,stdio
ignore-words-list = weill,sinc,mut,numer,uint,stdio,ws
skip = */.git,*/build,*/prefix,./scripts/all_plugins,./libs
quiet-level = 2
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include(cmake/prelude.cmake)

project(
"rtxi"
VERSION 3.1.0
VERSION 3.2.0
DESCRIPTION "Real-Time eXperiment Interface"
HOMEPAGE_URL "http://rtxi.org/"
LANGUAGES C CXX
Expand Down
262 changes: 216 additions & 46 deletions plugins/data_recorder/data_recorder.cpp

Large diffs are not rendered by default.

41 changes: 38 additions & 3 deletions plugins/data_recorder/data_recorder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
#include <QTime>
#include <vector>

#include <H5Ipublic.h>
#include <hdf5_hl.h>

#include "fifo.hpp"
#include "io.hpp"
#include "widgets.hpp"
#include "fifo.hpp"

class QComboBox;
class QListWidget;
Expand All @@ -48,12 +49,35 @@ typedef struct data_token_t
double value;
} data_token_t;

enum TIME_TAG_TYPE
{
INDEX = 0,
TIME,
NONE
};

enum PARAMETER
{
INDEXING = 0
};

constexpr size_t DEFAULT_BUFFER_SIZE = 10000 * sizeof(data_token_t);
constexpr std::string_view MODULE_NAME = "Data Recorder";

inline std::vector<Widgets::Variable::Info> get_default_vars()
{
return {};
return {
{PARAMETER::INDEXING,
"Indexing Scheme",
"Used to specify what type of indexing to use when recording. Options "
"are:\n"
"Index(0): add index to each value. resets after recorder is stopped\n"
"Time(1): Attaches current time in nanoseconds since some arbitrary "
"value. useful"
"for knowing the time between each data point.\n"
"None(3): Do not index the values. Just record them.",
Widgets::Variable::UINT_PARAMETER,
uint64_t {DataRecorder::TIME_TAG_TYPE::INDEX}}};
}

inline std::vector<IO::channel_t> get_default_channels()
Expand Down Expand Up @@ -87,6 +111,7 @@ class Component : public Widgets::Component

private:
std::unique_ptr<RT::OS::Fifo> m_fifo;
int64_t index=0;
};

class Panel : public Widgets::Panel
Expand All @@ -101,6 +126,8 @@ class Panel : public Widgets::Panel
Panel(QMainWindow* mwindow, Event::Manager* ev_manager);
~Panel() override = default;

TIME_TAG_TYPE getTimeTagType() const;

signals:
void updateBlockInfo();
void record_signal(bool record);
Expand All @@ -121,11 +148,13 @@ private slots:
void addNewTag();
void processData();
void syncEnableRecordingButtons(const QString& /*unused*/);
void setTimeTagType(int tag_type);

private:
size_t m_buffer_size = DEFAULT_BUFFER_SIZE;
size_t downsample_rate {1};
std::vector<std::string> dataTags;
TIME_TAG_TYPE time_type = TIME_TAG_TYPE::INDEX;

QGroupBox* channelGroup = nullptr;
QGroupBox* stampGroup = nullptr;
Expand All @@ -137,6 +166,7 @@ private slots:
QComboBox* blockList = nullptr;
QComboBox* channelList = nullptr;
QComboBox* typeList = nullptr;
QComboBox* timeTagType = nullptr;
QListWidget* selectionBox = nullptr;
QLabel* recordStatus = nullptr;
QPushButton* addRecorderButton = nullptr;
Expand Down Expand Up @@ -176,6 +206,7 @@ class Plugin : public Widgets::Plugin
void receiveEvent(Event::Object* event) override;
void startRecording();
void stopRecording();
bool changeIndexingType(int tag_type);
void openFile(const std::string& file_name);
void closeFile();
void change_file(const std::string& file_name);
Expand All @@ -200,8 +231,12 @@ class Plugin : public Widgets::Plugin
static void save_data(hid_t data_id,
const std::vector<data_token_t>& data,
size_t packet_count);
static void save_data(hid_t data_id,
const std::vector<double>& data,
size_t packet_count);
hsize_t m_data_chunk_size = static_cast<hsize_t>(1000);
int m_compression_factor = 5;
int tag_count = 0;
struct hdf5_handles
{
hid_t file_handle = H5I_INVALID_HID;
Expand All @@ -210,7 +245,7 @@ class Plugin : public Widgets::Plugin
hid_t sync_group_handle = H5I_INVALID_HID;
hid_t async_group_handle = H5I_INVALID_HID;
hid_t sys_data_group_handle = H5I_INVALID_HID;
hid_t channel_datatype_handle = H5I_INVALID_HID;
hid_t channel_index_datatype_handle = H5I_INVALID_HID;
} hdf5_handles;

struct recorder_t
Expand Down
5 changes: 5 additions & 0 deletions plugins/oscilloscope/oscilloscope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,11 @@ void Oscilloscope::Panel::removeBlockChannels(IO::Block* block)
{
this->scopeWindow->removeBlockChannels(block);
auto* hplugin = dynamic_cast<Oscilloscope::Plugin*>(this->getHostPlugin());
// Sometimes fired events may trigger this function after the plugin has been
// unloaded. in that case just return and don't crash please.
if (hplugin == nullptr) {
return;
}
hplugin->deleteAllProbes(block);
}

Expand Down
9 changes: 8 additions & 1 deletion plugins/performance_measurement/performance_measurement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ PerformanceMeasurement::Panel::Panel(const std::string& mod_name,
PerformanceMeasurement::Component::Component(Widgets::Plugin* hplugin)
: Widgets::Component(hplugin,
std::string(MODULE_NAME),
std::vector<IO::channel_t>(),
PerformanceMeasurement::get_default_channels(),
PerformanceMeasurement::get_default_vars())
{
if (RT::OS::getFifo(this->fifo,
Expand Down Expand Up @@ -137,6 +137,13 @@ void PerformanceMeasurement::Component::execute()

switch (this->getState()) {
case RT::State::EXEC:
writeoutput(0, stats.duration);
writeoutput(1, stats.timestep);
writeoutput(2, stats.latency);
writeoutput(3, stats.max_timestep);
writeoutput(4, stats.max_duration);
writeoutput(5, stats.max_latency);
writeoutput(6, stats.jitter);
this->fifo->writeRT(&this->stats,
sizeof(PerformanceMeasurement::performance_stats_t));
break;
Expand Down
80 changes: 51 additions & 29 deletions plugins/performance_measurement/performance_measurement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
#include "math/runningstat.h"
#include "widgets.hpp"

namespace RT::OS{
namespace RT::OS
{
class Fifo;
} // namespace RT::OS
} // namespace RT::OS

class QLineEdit;

Expand All @@ -36,51 +37,69 @@ namespace PerformanceMeasurement
constexpr std::string_view MODULE_NAME = "RT Benchmarks";

inline std::vector<Widgets::Variable::Info> get_default_vars()
{
return
{
{
}
};
{
return {{}};
}

inline std::vector<IO::channel_t> get_default_channels()
{
return {
{"Duration",
"Real-Time measurement of time elapsed time (ns) for calculations each period",
IO::OUTPUT},
{"Time Step", "Real-Time measurement of system period", IO::OUTPUT},
{"Latency", "Time between intended wake-up and real wake-up", IO::OUTPUT},
{"Max Duration",
"Maximum computation time measured since last reset",
IO::OUTPUT},
{"Max Time Step",
"Maximum realtime period measured since last reset",
IO::OUTPUT},
{"Max Latency", "Maximum latency measured since last reset", IO::OUTPUT},
{"Jitter",
"Standard Deviation of the real-time period measured since last reset",
IO::OUTPUT}};
}

struct performance_stats_t{
double duration=0.0;
double timestep=0.0;
double latency=0.0;
double max_duration=0.0;
double max_timestep=0.0;
double max_latency=0.0;
double jitter=0.0;
struct performance_stats_t
{
double duration = 0.0;
double timestep = 0.0;
double latency = 0.0;
double max_duration = 0.0;
double max_timestep = 0.0;
double max_latency = 0.0;
double jitter = 0.0;
};

class Plugin : public Widgets::Plugin
{
public:
explicit Plugin(Event::Manager* ev_manager);
performance_stats_t getSampleStat();

private:
RT::OS::Fifo* component_fifo;
}; // class Plugin

class Component : public Widgets::Component
{
public:
explicit Component(Widgets::Plugin* hplugin);
public:
explicit Component(Widgets::Plugin* hplugin);

void setTickPointers(int64_t* s_ticks, int64_t* e_ticks);
void execute() override;
RT::OS::Fifo* getFIfoPtr(){ return this->fifo.get(); }
RT::OS::Fifo* getFIfoPtr() { return this->fifo.get(); }

private:
performance_stats_t stats;

//RunningStat timestepStat;
// RunningStat timestepStat;
RunningStat latencyStat;

int64_t *start_ticks=nullptr; // only accessed in rt
int64_t *end_ticks=nullptr; // only accessed in rt
int64_t last_start_ticks=0;
int64_t* start_ticks = nullptr; // only accessed in rt
int64_t* end_ticks = nullptr; // only accessed in rt
int64_t last_start_ticks = 0;
std::unique_ptr<RT::OS::Fifo> fifo;
};

Expand All @@ -89,20 +108,21 @@ class Panel : public Widgets::Panel
Q_OBJECT

public:
Panel(const std::string& mod_name, QMainWindow* mwindow, Event::Manager* ev_manager);
Panel(const std::string& mod_name,
QMainWindow* mwindow,
Event::Manager* ev_manager);

public slots:
/*!
* Starts the statistics over
*/
void reset();
//void resetMaxTimeStep();
// void resetMaxTimeStep();
/*!
* Updates the GUI with the latest values
*/
void refresh() override;


private:
QLineEdit* durationEdit;
QLineEdit* timestepEdit;
Expand All @@ -114,10 +134,12 @@ public slots:

std::unique_ptr<Widgets::Plugin> createRTXIPlugin(Event::Manager* ev_manager);

Widgets::Panel* createRTXIPanel(QMainWindow* main_window, Event::Manager* ev_manager);
Widgets::Panel* createRTXIPanel(QMainWindow* main_window,
Event::Manager* ev_manager);

std::unique_ptr<Widgets::Component> createRTXIComponent(Widgets::Plugin* host_plugin);
std::unique_ptr<Widgets::Component> createRTXIComponent(
Widgets::Plugin* host_plugin);

Widgets::FactoryMethods getFactories();
} // namespace PerformanceMeasurement
} // namespace PerformanceMeasurement
#endif /* PERFORMANCE_MEASUREMENT_H */
Loading