YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
qtyarpscope.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: GPL-3.0-or-later
4 */
5
6#include "qtyarpscope.h"
8#include "simpleloader.h"
9#include "xmlloader.h"
10#include <yarp/os/Time.h>
11
12#define PADDING 25
13#define GRIDSPACING 25
14#define SCALEWIDTH 25
15
16QtYARPScope::QtYARPScope(QQuickItem *parent):
17 QQuickPaintedItem(parent),
18 i(0),
19 yarp(yarp::os::YARP_CLOCK_SYSTEM),
20 loader(nullptr),
21 plotManager(PlotManager::instance()),
22 topLevel(nullptr),
23 bPressed(false),
24 currentSelectedPlotter(nullptr)
25{
26 setFlag(ItemHasContents, true);
27
28 setAcceptedMouseButtons(Qt::AllButtons);
29 setRenderTarget(QQuickPaintedItem::FramebufferObject);
30
31 connect(this, SIGNAL(widthChanged()), this, SLOT(updateCustomPlotSize()) );
32 connect(this, SIGNAL(heightChanged()), this, SLOT(updateCustomPlotSize()));
33
34}
35
37{
38 playPressed(false);
39 if (plotManager)
40 {
41 for (auto pltr : *(plotManager->getPlotters()))
42 {
43 if (pltr)
44 {
45 for (auto graph : static_cast<Plotter*> (pltr)->graphList)
46 {
47 if (graph)
48 {
49 static_cast<Graph*> (graph)->getConnection()->freeResources();
50 }
51 }
52 }
53 }
54 }
55
56 if(loader){
57 delete loader;
58 }
59}
63bool QtYARPScope::parseParameters(QStringList params)
64{
65 //YARP network initialization
66 if (!yarp.checkNetwork()) {
67 qCritical("Cannot connect to yarp network");
68 return false;
69 }
70 else
71 {
72 connect(plotManager,SIGNAL(requestRepaint()),this,SLOT(onRepaint()),Qt::QueuedConnection);
73 }
74 // Setup resource finder
76 // TODO Read default values from yarpscope.ini
77 rf.setDefaultConfigFile("yarpscope.ini");
78 rf.setDefaultContext("yarpscope");
79
80 // Transform Qt Params array in standard argc & argv
81 int c = params.count();
82 char **v;
83 v = (char**)malloc(sizeof(char*) * c);
84 for(int i=0;i<params.count();i++){
85 v[i] = strdup(params.at(i).toLatin1().data());
86 }
87
88 if(!rf.configure(c, v)){
89 usage();
90 for(int i=0;i<params.count();i++) {
91 free(v[i]);
92 }
93 free(v);
94 return false;
95 }
96
97 qDebug("%s",rf.toString().data());
98
99 if (rf.check("help")) {
100 usage();
101 for(int i=0;i<params.count();i++) {
102 free(v[i]);
103 }
104 free(v);
105 return false;
106 }
107
108 for(int i=0;i<params.count();i++) {
109 free(v[i]);
110 }
111 free(v);
112
113//********************** Deprecated options
114 // local
115 if (rf.check("local")) {
116 qWarning() << "--local option is deprecated. YARPScope now uses \"${YARP_PORT_PREFIX}/YARPScope/${REMOTE_PORT_NAME}\"";
117 }
118
119 // rows
120 if (rf.check("rows")) {
121 qWarning() << "--rows option is deprecated. Use XML mode if you need more than one plot in a single window\"";
122 }
123
124 // cols
125 if (rf.check("cols")) {
126 qWarning() << "--cols option is deprecated. Use XML mode if you need more than one plot in a single window\"";
127 }
128//********************************************
129//************************* Generic options
130 int interval;
131 // title
132 if (rf.find("title").isString()) {
133 emit setWindowTitle(QString("%1").arg(rf.find("title").asString().data()));
134 }
135 // position
136 if (rf.find("x").isInt32() && rf.find("y").isInt32()) {
137 emit setWindowPosition(rf.find("x").asInt32(), rf.find("y").asInt32());
138 }
139 // size
140 if (rf.find("dx").isInt32() && rf.find("dy").isInt32()) {
141 emit setWindowSize(rf.find("dx").asInt32(), rf.find("dy").asInt32());
142 }
143 // interval
144 if (rf.find("interval").isInt32()) {
145 interval = rf.find("interval").asInt32();
146 }else{
147 interval = 50;
148 }
149//*******************************************
150
151 bool ok;
152 if (rf.check("xml")) {
153// XML Mode Options
154 const std::string &filename = rf.findFile("xml");
155 QString f = QString("%1").arg(filename.data());
156 loader = new XmlLoader(f,plotManager,this);
157 qDebug("Loading file %s",filename.c_str());
158 } else {
159// Command Line Mode Options
160 qDebug("Loading from command line");
161 loader = new SimpleLoader(&rf,plotManager, &ok,this);
162 if (!ok) {
163 usage();
164 exit(1);
165 }
166 }
167 plotManager->setInterval(interval);
168 emit intervalLoaded(interval);
169
170
171 updateCustomPlotSize();
172
173 return true;
174}
175
180{
181 plotManager->playPressed(check);
182}
183
186{
187 plotManager->clear();
188}
189
194{
195 plotManager->setInterval(interval);
196}
197
202{
203 plotManager->rescale();
204}
205
208 qDebug("Usage: yarpscope [OPTIONS]\n");
209
210 qDebug("OPTIONS:");
211 qDebug(" --help Print this help and exit.\n");
212
213 qDebug(" --title [string] Title of the window (default \"YARP Port Scope\")");
214 qDebug(" --x [uint] Initial X position of the window.");
215 qDebug(" --y [uint] Initial Y position of the window.");
216 qDebug(" --dx [uint] Initial width of the window.");
217 qDebug(" --dy [uint] Initial height of the window.\n");
218
219 qDebug(" --interval [int] Initial refresh interval in milliseconds. (default = 50ms)\n");
220
221 qDebug("XML MODE:");
222 qDebug(" --xml [path] Path to the xml with the description of the scene (all the");
223 qDebug(" \"simple mode\" options are discarded).\n");
224
225 qDebug("SIMPLE MODE (single remote):");
226 qDebug(" --remote [string] Remote port to connect to.");
227 qDebug(" --carrier [string] YARP Carrier used for connections (default \"mcast\")");
228 qDebug(" --persistent, Make normal or persistent connections (default persistent)");
229 qDebug(" --no-persistent");
230 qDebug(" --index [...] Index(es) of the vector to plot.");
231 qDebug(" It can be an [uint] or an array of [uint]s");
232 qDebug(" --plot_title [string] Plot title (default = remote)");
233 qDebug(" --min [float] Minimum value for the X axis (default -100)");
234 qDebug(" --max [float] Maximum value for the X axis (default 100)");
235 qDebug(" --size [uint] Plot size (Number of samples to plot) (default 201)");
236 qDebug(" --bgcolor [string] Background color.");
237// qDebug(" --autorescale Rescale plot automatically.");
238// qDebug(" --realtime Use real time mode.");
239// qDebug(" --triggermode Use trigger mode.");
240// qDebug(" --graph_title [...] Graph title(s) (used in legend).");
241// qDebug(" Depending on index it must be a [string] or an array of [string]s.");
242 qDebug(" --color [...] Graph color(s).");
243 qDebug(" Depending on index it must be a [string] or an array of [string]s.");
244 qDebug(R"( --type [...] Graph type(s). Accepted values are "points", "lines" and "bars" (default = "lines"))");
245 qDebug(" Depending on index it must be a [string] or an array of [string]s.");
246 qDebug(" --graph_size [...] Graph size(s) (thickness of the points) (default = 1)");
247 qDebug(" Depending on index it must be a [uint] or an array of [uint]s.\n");
248
249
250// These options are here to give a hint to the user about how these
251// options from the old qt3 portscope are supposed to be replaced.
252 qDebug("LEGACY OPTIONS (deprecated and unused):");
253 qDebug(" --local [string] Use YARP_PORT_PREFIX environment variable to modify default value.");
254 qDebug(" --rows [uint] Only one plot is supported from command line. Use XML mode instead.");
255 qDebug(" --cols [uint] Only one plot is supported from command line. Use XML mode instead.");
256}
257
259void QtYARPScope::onRepaint()
260{
261 update();
262}
263
268void QtYARPScope::paint(QPainter *painter)
269{
270 if(!loader) {
271 return;
272 }
273 int rows = loader->portscope_rows;
274 int cols = loader->portscope_columns;
275 int w = painter->device()->width();
276 int h = painter->device()->height();
277
278 for (int i=0; i<plotManager->getPlotters()->count();i++)
279 {
280 painter->beginNativePainting(); // Workaround to flush the painter
281 auto* plotter = (Plotter*)plotManager->getPlotters()->at(i);
282
283 int hSpan = plotter->hspan;
284 int vSpan = plotter->vspan;
285 int plotterWidth = (w/cols) * hSpan;
286 int plotterHeight = (h/rows) * vSpan;
287
288 QPixmap picture(QSize(plotter->customPlot.width() * plotter->customPlot.devicePixelRatio(),
289 plotter->customPlot.height() * plotter->customPlot.devicePixelRatio()));
290
291 QCPPainter qcpPainter( &picture );
292 plotter->customPlot.toPainter( &qcpPainter );
293 QRectF r = QRectF(plotter->gridx * plotterWidth/hSpan,
294 plotter->gridy * plotterHeight/vSpan,
295 picture.rect().width(),picture.rect().height());
296 plotter->setPaintGeometry(r);
297 painter->drawPixmap(r,picture,QRectF(0,0,plotterWidth,plotterHeight) );
298
299 painter->endNativePainting();
300 }
301
302}
303
304
305
306
310void QtYARPScope::wheelEvent(QWheelEvent* event)
311{
312 routeMouseEvents( event );
313}
314
318void QtYARPScope::mousePressEvent( QMouseEvent* event )
319{
320 routeMouseEvents( event );
321}
322
326void QtYARPScope::mouseReleaseEvent( QMouseEvent* event )
327{
328 routeMouseEvents( event );
329}
330
334void QtYARPScope::mouseMoveEvent( QMouseEvent* event )
335{
336 routeMouseEvents( event );
337}
338
342void QtYARPScope::mouseDoubleClickEvent( QMouseEvent* event )
343{
344 routeMouseEvents( event );
345}
346
347void QtYARPScope::graphClicked( QCPAbstractPlottable* plottable )
348{
349 //qDebug() << Q_FUNC_INFO << QString( "Clicked on graph '%1 " ).arg( plottable->name() );
350}
351
357void QtYARPScope::routeMouseEvents( QMouseEvent* event )
358{
359 int x = event->x();
360 int y = event->y();
361
362 for (int i=0; i<plotManager->getPlotters()->count();i++)
363 {
364 auto* plotter = (Plotter*)plotManager->getPlotters()->at(i);
365 QRectF r = plotter->paintRectGeometry;
366
367 if(r.contains(x,y)){
368 QPoint pos = QPoint(x - r.x(), y - r.y());
369 QMouseEvent* newEvent = new QMouseEvent( event->type(), pos, event->button(), event->buttons(), event->modifiers() );
370 QCoreApplication::postEvent( &plotter->customPlot, newEvent,Qt::HighEventPriority );
371 update();
372 break;
373 }
374 }
375}
376
381void QtYARPScope::routeMouseEvents( QWheelEvent* event )
382{
383#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
384 int x = event->position().x();
385 int y = event->position().y();
386#else
387 int x = event->x();
388 int y = event->y();
389#endif
390
391 for (int i=0; i<plotManager->getPlotters()->count();i++)
392 {
393 auto* plotter = (Plotter*)plotManager->getPlotters()->at(i);
394 QRectF r = plotter->paintRectGeometry;
395
396 if(r.contains(x,y)){
397 QPoint pos = QPoint(x - r.x(), y - r.y());
398#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
399 QWheelEvent* newEvent = new QWheelEvent(pos,
400 event->globalPosition(),
401 event->pixelDelta(),
402 event->angleDelta(),
403 event->buttons(),
404 event->modifiers(),
405 event->phase(),
406 event->inverted(),
407 event->source());
408#else
409 QWheelEvent* newEvent = new QWheelEvent(pos, event->angleDelta().y(), event->buttons(), event->modifiers() );
410#endif
411 QCoreApplication::postEvent( &plotter->customPlot, newEvent );
412 update();
413 break;
414 }
415 }
416}
417
421void QtYARPScope::updateCustomPlotSize()
422{
423
424 if(loader == nullptr){
425 return;
426 }
427 int w = width();
428 int h = height();
429 int rows = loader->portscope_rows;
430 int cols = loader->portscope_columns;
431
432 int plottersCount = plotManager->getPlotters()->count();
433 for(int i=0; i<plottersCount; i++){
434 auto* plotter = (Plotter*)plotManager->getPlotters()->at(i);
435
436 int hSpan = plotter->hspan;
437 int vSpan = plotter->vspan;
438 int plotterWidth = (w/cols) * hSpan;
439 int plotterHeight = (h/rows) * vSpan;
440
441 plotter->customPlot.setGeometry(0,0,plotterWidth,plotterHeight);
442 }
443}
int SIGNAL(int pid, int signum)
Class representing a Graph.
Definition plotter.h:26
The Manager of the plotters.
Definition plotmanager.h:19
void playPressed(bool check)
Sets the play or pause state.
void setInterval(int interval)
Sets the refresh interval.
void clear()
Clear all plotters datas.
QList< QObject * > * getPlotters()
Returns a list of all plotters.
void rescale()
Rescale all plotters.
Class representing a Plotter.
Definition plotter.h:115
void mouseMoveEvent(QMouseEvent *event) override
the mouse move event
void intervalLoaded(int interval)
void mouseDoubleClickEvent(QMouseEvent *event) override
the mouse double click event
void usage()
Prints the help menu.
Q_INVOKABLE bool parseParameters(QStringList params)
parse the parameters received from the main container in QstringList form
void paint(QPainter *painter) override
paint method.
Q_INVOKABLE void rescale()
rescales the graphs in order to contains the maximum and minimum value visible in the window
Q_INVOKABLE void changeInterval(int interval)
changes the refresh interval
void routeMouseEvents(QMouseEvent *event)
this function is used to route the mouse events on the core plugin to the relative QCustomPlot.
Q_INVOKABLE void clear()
clears the data in the current window
QtYARPScope(QQuickItem *parent=0)
void setWindowSize(int w, int h)
void setWindowTitle(QString title)
void mouseReleaseEvent(QMouseEvent *event) override
the mouse release event
void setWindowPosition(int x, int y)
void mousePressEvent(QMouseEvent *event) override
the mouse press event
Q_INVOKABLE void playPressed(int check)
plays or pauses the data flow
void wheelEvent(QWheelEvent *event) override
the wheel mouse event
Reads a configuration from a xml file.
Reads a configuration from a xml file.
Definition xmlloader.h:15
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
std::string toString() const override
Return a standard text representation of the content of the object.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string findFile(const std::string &name)
Find the full path to a file.
bool setDefaultConfigFile(const std::string &fname)
Provide a default value for the configuration file (can be overridden from command line with the –fro...
virtual bool isString() const
Checks if value is a string.
Definition Value.cpp:156
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition Value.cpp:204
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition Value.cpp:132
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
The main, catch-all namespace for YARP.
Definition dirs.h:16