RTXI  3.0.0
The Real-Time eXperiment Interface Reference Manual
scope.hpp
Go to the documentation of this file.
1 /*
2  The Real-Time eXperiment Interface (RTXI)
3  Copyright (C) 2011 Georgia Institute of Technology, University of Utah,
4  Weill Cornell Medical College
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 /*
22  This class instantiates a single scope instance.
23  This includes the painting director, the canvass,
24  and the functions necessary for modifying those
25  scopes. Multiple scope objects can be instantiated,
26  and each instance will have it's own set of settings
27  that can be edited with the Panel class.
28  */
29 
30 #ifndef SCOPE_H
31 #define SCOPE_H
32 
33 #include <cstddef>
34 #include <shared_mutex>
35 #include <vector>
36 
37 #include <qwt.h>
38 #include <qwt_curve_fitter.h>
39 #include <qwt_interval.h>
40 #include <qwt_painter.h>
41 #include <qwt_plot.h>
42 #include <qwt_plot_canvas.h>
43 #include <qwt_plot_curve.h>
44 #include <qwt_plot_directpainter.h>
45 #include <qwt_plot_grid.h>
46 #include <qwt_plot_layout.h>
47 #include <qwt_plot_legenditem.h>
48 #include <qwt_plot_marker.h>
49 #include <qwt_scale_engine.h>
50 #include <qwt_system_clock.h>
51 
52 #include "fifo.hpp"
53 #include "io.hpp"
54 
55 namespace Oscilloscope
56 {
57 
58 namespace Trigger
59 {
60 enum trig_t : int
61 {
62  NONE = 0,
63  POS,
64  NEG,
65 };
66 
67 typedef struct Info
68 {
71  double threshold = 0.0;
72 } Info;
73 } // namespace Trigger
74 
75 // values meant to be used with qt timer for redrawing the screen
76 // values are in milliseconds
77 namespace FrameRates
78 {
79 constexpr size_t HZ60 = 17;
80 constexpr size_t HZ120 = 8;
81 constexpr size_t HZ240 = 4;
82 } // namespace FrameRates
83 
84 constexpr size_t DEFAULT_BUFFER_SIZE = 100000;
85 typedef struct sample
86 {
87  int64_t time;
88  double value;
90 
91 typedef struct scope_channel
92 {
93  QString label;
95  RT::OS::Fifo* fifo = nullptr;
96  double scale = 1.0;
97  double offset = 0.0;
98  std::vector<int64_t> timebuffer;
99  std::vector<double> xbuffer;
100  std::vector<double> ybuffer;
101  std::vector<double> xtransformed;
102  std::vector<double> ytransformed;
103  size_t data_indx = 0;
104  QwtPlotCurve* curve = nullptr;
106 
107 namespace ColorID
108 {
109 enum color_id : size_t
110 {
111  Red = 0,
117  Black
118 };
119 } // namespace ColorID
120 
121 const std::array<QColor, 7> penColors = {QColor(255, 0, 16, 255),
122  QColor(255, 164, 5, 255),
123  QColor(43, 206, 72, 255),
124  QColor(0, 117, 220, 255),
125  QColor(178, 102, 255, 255),
126  QColor(0, 153, 143, 255),
127  QColor(83, 81, 84, 255)};
128 
129 constexpr std::array<std::string_view, 7> color2string {
130  "Red", "Orange", "Green", "Blue", "Purple", "Teal", "Black"};
131 
132 constexpr std::array<Qt::PenStyle, 5> penStyles = {Qt::SolidLine,
133  Qt::DashLine,
134  Qt::DotLine,
137 
138 constexpr std::array<std::string_view, 5> penstyles2string {
139  "Solid", "Dash", "Dot", "Dash Dot", "Dash Dot Dot"};
140 
141 namespace PenStyleID
142 {
143 enum penstyle_id : size_t
144 {
150 };
151 } // namespace PenStyleID
152 
153 class LegendItem : public QwtPlotLegendItem
154 {
155 public:
156  LegendItem();
157 }; // LegendItem
158 
159 class Canvas : public QwtPlotCanvas
160 {
161 public:
162  explicit Canvas(QwtPlot* plot);
163 
164 private:
165  void setupPalette();
166 }; // Canvas
167 
168 class Scope : public QwtPlot
169 {
170  Q_OBJECT
171 
172 public:
173  Scope(const Scope&) = delete;
174  Scope(Scope&&) = delete;
175  Scope& operator=(const Scope&) = delete;
176  Scope& operator=(Scope&&) = delete;
177  explicit Scope(QWidget* parent);
178  ~Scope() override;
179 
180  bool paused() const;
181  void setPause(bool value);
182  void createChannel(IO::endpoint probeInfo, RT::OS::Fifo* fifo);
183  bool channelRegistered(IO::endpoint probeInfo);
184  void removeChannel(IO::endpoint probeInfo);
185  void removeBlockChannels(IO::Block* block);
186  size_t getChannelCount();
187 
188  void clearData();
189  size_t getDataSize() const;
190  void setDataSize(size_t size);
191 
192  int64_t getDivT();
193  void setDivT(int64_t value);
194 
195  size_t getDivX() const;
196  size_t getDivY() const;
197 
198  size_t getRefresh() const;
199  void setRefresh(size_t r);
200 
201  void setChannelScale(IO::endpoint endpoint, double scale);
203  void setChannelOffset(IO::endpoint endpoint, double offset);
205  void setChannelLabel(IO::endpoint endpoint, const QString& label);
207  Qt::PenStyle getChannelStyle(IO::endpoint endpoint);
208  void setChannelPen(IO::endpoint endpoint, const QPen& pen);
210  double getTriggerThreshold() const;
211  void setTriggerThreshold(double threshold);
214 
215  void drawCurves();
217  {
218  return this->m_trigger_info.endpoint;
219  }
220 public slots:
221  void process_data();
222 
223 protected:
224  void resizeEvent(QResizeEvent* event) override;
225 
226 private:
227  Oscilloscope::Trigger::Info m_trigger_info;
228  std::atomic<size_t> buffer_size = DEFAULT_BUFFER_SIZE;
229 
230  std::atomic<bool> isPaused = false;
231  int64_t divX = 10;
232  int64_t divY = 10;
233  size_t refresh = Oscilloscope::FrameRates::HZ60;
234  int64_t horizontal_scale_ns = 1000000; // horizontal scale for time (ns)
235  bool triggering = false;
236  std::vector<sample> sample_buffer;
237 
238  // Scope primary paint element
239  QwtPlotDirectPainter* d_directPainter = nullptr;
240 
241  // Scope painter elements
242  QwtPlotGrid* grid;
243  QwtPlotMarker* origin;
244 
245  // Scaling engine
246  QwtScaleMap* scaleMapY;
247  QwtScaleMap* scaleMapX;
248 
249  // Legend
250  LegendItem* legendItem;
251 
252  QTimer* timer;
253  QString dtLabel;
254  std::vector<scope_channel> channels;
255 
256  // synchronization
257  std::shared_mutex m_channel_mutex;
258 }; // Scope
259 
260 } // namespace Oscilloscope
261 
262 #endif // SCOPE_H
Definition: io.hpp:79
Canvas(QwtPlot *plot)
Definition: scope.cpp:42
void setDataSize(size_t size)
Definition: scope.cpp:265
double getChannelScale(IO::endpoint endpoint)
Definition: scope.cpp:341
void removeChannel(IO::endpoint probeInfo)
Definition: scope.cpp:208
void setTriggerThreshold(double threshold)
Definition: scope.cpp:445
void setChannelLabel(IO::endpoint endpoint, const QString &label)
Definition: scope.cpp:380
void setChannelPen(IO::endpoint endpoint, const QPen &pen)
Definition: scope.cpp:433
int getChannelWidth(IO::endpoint endpoint)
Definition: scope.cpp:420
int64_t getDivT()
Definition: scope.cpp:285
Scope & operator=(const Scope &)=delete
double getChannelOffset(IO::endpoint endpoint)
Definition: scope.cpp:367
QColor getChannelColor(IO::endpoint endpoint)
Definition: scope.cpp:394
bool paused() const
Definition: scope.cpp:157
Scope(Scope &&)=delete
~Scope() override
Definition: scope.cpp:149
void setChannelOffset(IO::endpoint endpoint, double offset)
Definition: scope.cpp:354
void process_data()
Definition: scope.cpp:505
double getTriggerThreshold() const
Definition: scope.cpp:450
size_t getDataSize() const
Definition: scope.cpp:280
size_t getChannelCount()
Definition: scope.cpp:246
Scope(const Scope &)=delete
void setRefresh(size_t r)
Definition: scope.cpp:321
void createChannel(IO::endpoint probeInfo, RT::OS::Fifo *fifo)
Definition: scope.cpp:167
IO::endpoint getTriggerEndpoint() const
Definition: scope.hpp:216
Qt::PenStyle getChannelStyle(IO::endpoint endpoint)
Definition: scope.cpp:407
size_t getRefresh() const
Definition: scope.cpp:316
size_t getDivX() const
Definition: scope.cpp:306
void setTriggerDirection(Trigger::trig_t direction)
Trigger::trig_t getTriggerDirection()
void resizeEvent(QResizeEvent *event) override
Definition: scope.cpp:240
void setDivT(int64_t value)
Definition: scope.cpp:291
void removeBlockChannels(IO::Block *block)
Definition: scope.cpp:225
void setPause(bool value)
Definition: scope.cpp:162
bool channelRegistered(IO::endpoint probeInfo)
Definition: scope.cpp:198
Scope & operator=(Scope &&)=delete
size_t getDivY() const
Definition: scope.cpp:311
void setChannelScale(IO::endpoint endpoint, double scale)
Definition: scope.cpp:328
struct IO::endpoint endpoint
constexpr size_t HZ240
Definition: scope.hpp:81
constexpr size_t HZ120
Definition: scope.hpp:80
constexpr size_t HZ60
Definition: scope.hpp:79
struct Oscilloscope::Trigger::Info Info
constexpr std::array< std::string_view, 7 > color2string
Definition: scope.hpp:129
struct Oscilloscope::sample sample
constexpr std::array< Qt::PenStyle, 5 > penStyles
Definition: scope.hpp:132
constexpr std::array< std::string_view, 5 > penstyles2string
Definition: scope.hpp:138
const std::array< QColor, 7 > penColors
Definition: scope.hpp:121
constexpr size_t DEFAULT_BUFFER_SIZE
Definition: scope.hpp:84
struct Oscilloscope::scope_channel scope_channel
Trigger::trig_t trigger_direction
Definition: scope.hpp:70
IO::endpoint endpoint
Definition: scope.hpp:69
QwtPlotCurve * curve
Definition: scope.hpp:104
std::vector< double > ytransformed
Definition: scope.hpp:102
std::vector< double > ybuffer
Definition: scope.hpp:100
std::vector< int64_t > timebuffer
Definition: scope.hpp:98
std::vector< double > xtransformed
Definition: scope.hpp:101
std::vector< double > xbuffer
Definition: scope.hpp:99
RT::OS::Fifo * fifo
Definition: scope.hpp:95
IO::endpoint endpoint
Definition: scope.hpp:94