YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
portloggerdialog.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 <fstream>
7#include <QDir>
8#include <QFileDialog>
9#include <QProgressDialog>
10
11#include <yarp/os/LogStream.h>
12#include <yarp/os/Time.h>
13#include "portloggerdialog.h"
14#include "ui_portloggerdialog.h"
16#include <QMessageBox>
17
18using namespace yarp::os;
19using namespace yarp::profiler;
20using namespace yarp::profiler::graph;
21
22PortLoggerDialog::PortLoggerDialog(Graph *graph, QWidget *parent) :
23 QDialog(parent),
24 ui(new Ui::PortLoggerDialog), isStarted(false), timer(nullptr)
25{
26 yAssert(graph);
27 ui->setupUi(this);
28
29
30 connect(ui->pushButtonAdd, SIGNAL(clicked()), this, SLOT(addConnections()));
31 connect(ui->pushButtonRemove, SIGNAL(clicked()), this, SLOT(removeConnections()));
32 connect(ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(startStopLoggers()));
33 connect(ui->toolButtonLogPath, SIGNAL(clicked()), this, SLOT(setLogPath()));
34 connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(openCons()));
35
36 ui->pushButtonStart->setEnabled(false);
37 ui->checkBoxCollect->setChecked(true);
38
39 PortLoggerDialog::graph = graph;
40 // adding all process nodes and subgraphs
42 const pvertex_set& vertices = graph->vertices();
43 for(itr = vertices.begin(); itr!=vertices.end(); itr++) {
44 const Vertex &v1 = (**itr);
45 for(const auto& i : v1.outEdges()) {
46 Edge& edge = (Edge&) i;
47 const Vertex &v2 = edge.second();
48 if(!v1.property.check("hidden") && !v2.property.check("hidden")) {
49 if(edge.property.find("type").asString() == "connection") {
50 //yInfo()<<v1.property.find("name").asString()<<"->"<<v2.property.find("name").asString()<<label;
51 std::string source = v1.property.find("name").asString();
52 std::string destination = v2.property.find("name").asString();
53 std::string carrier = edge.property.find("carrier").asString();
54
55 QTreeWidgetItem* item;
56 QStringList prop;
57 prop.clear();
58 prop.append(source.c_str());
59 prop.append(destination.c_str());
60 prop.append(carrier.c_str());
61 item = new QTreeWidgetItem( ui->treeWidgetCons, prop);
63 }
64 }
65 }
66 }
67 ui->pushButtonAdd->setEnabled(ui->treeWidgetCons->topLevelItemCount() > 0);
68 ui->pushButtonRemove->setEnabled(ui->treeWidgetSelectedCons->topLevelItemCount() > 0);
69 ui->lineEditLogPath->setText(QDir::homePath());
70}
71
75
76
77void PortLoggerDialog::openCons()
78{
79 QString filters("Text files (*.txt);;All files (*.*)");
80 QString defaultFilter("Connections list file (*.txt)");
81 QString filename = QFileDialog::getOpenFileName(nullptr, "Load connections list",
82 QDir::homePath(),
84 if (filename.size() == 0) {
85 return;
86 }
87
88 std::fstream file;
89 file.open(filename.toStdString().c_str());
90 if (!file.is_open()) {
91 QMessageBox::critical(nullptr, QObject::tr("Error"), QObject::tr("Cannot open the file for loading"));
92 return;
93 }
94
95 ui->treeWidgetCons->clear();
96 std::string line;
97 unsigned int count = 0;
98 while(getline(file, line)) {
99 count++;
100 Bottle sample(line);
101 if(sample.size() == 3) {
102 //data.addList() = sample;
103 //yInfo()<<sample.toString();
104 QTreeWidgetItem* item;
105 QStringList prop;
106 prop.clear();
107 prop.append(sample.get(0).asString().c_str());
108 prop.append(sample.get(1).asString().c_str());
109 prop.append(sample.get(2).asString().c_str());
110 item = new QTreeWidgetItem( ui->treeWidgetCons, prop);
112 } else {
113 yWarning() << "Wrong connection data at line" << count;
114 }
115 }
116 file.close();
117}
118
119void PortLoggerDialog::addConnections() {
121 itemList = ui->treeWidgetCons->selectedItems();
122 foreach(QTreeWidgetItem *item, itemList) {
123 QTreeWidgetItem* newitem;
124 QStringList prop;
125 prop.clear();
126 prop.append(item->text(0));
127 prop.append(item->text(1));
128 prop.append(item->text(2));
129 newitem = new QTreeWidgetItem( ui->treeWidgetSelectedCons, prop);
130 delete item;
132 }
133 ui->pushButtonStart->setEnabled(ui->treeWidgetSelectedCons->topLevelItemCount() > 0);
134 ui->pushButtonAdd->setEnabled(ui->treeWidgetCons->topLevelItemCount() > 0);
135 ui->pushButtonRemove->setEnabled(ui->treeWidgetSelectedCons->topLevelItemCount() > 0);
136}
137
138void PortLoggerDialog::removeConnections() {
140 itemList = ui->treeWidgetSelectedCons->selectedItems();
141 foreach(QTreeWidgetItem *item, itemList) {
142 QTreeWidgetItem* newitem;
143 QStringList prop;
144 prop.clear();
145 prop.append(item->text(0));
146 prop.append(item->text(1));
147 prop.append(item->text(2));
148 newitem = new QTreeWidgetItem( ui->treeWidgetCons, prop);
149 delete item;
151 }
152 ui->pushButtonStart->setEnabled(ui->treeWidgetSelectedCons->topLevelItemCount() > 0);
153 ui->pushButtonAdd->setEnabled(ui->treeWidgetCons->topLevelItemCount() > 0);
154 ui->pushButtonRemove->setEnabled(ui->treeWidgetSelectedCons->topLevelItemCount() > 0);
155}
156
157void PortLoggerDialog::startStopLoggers() {
158 if(!isStarted) {
160 prop.put("context", "yarpviz");
161 prop.put("file", "portrate");
162
163 isStarted = true;
164 for( int i=0; i < ui->treeWidgetSelectedCons->topLevelItemCount(); ++i ){
165 QTreeWidgetItem *item = ui->treeWidgetSelectedCons->topLevelItem(i);
166 //yInfo()<<item->text(1).toUtf8().constData();
167 isStarted = isStarted && NetworkProfiler::attachPortmonitorPlugin(item->text(1).toUtf8().constData(), prop);
168 //yarp::os::Property param;
169 //param.put("log_raw", 1);
170 //isStarted = isStarted && NetworkProfiler::setPortmonitorParams(item->text(1).toUtf8().constData(), param);
171 }
172
173 if(isStarted) {
174 timer = new QTimer(this);
175 // setup signal and slot
176 connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot()));
177 logTime.start();
178 logTime.restart();
179 timer->start(1000);
180 ui->pushButtonStart->setText("Sto&p");
181 }
182 else
183 {
184 // something went wrong
186 messageBox.critical(nullptr,"Error","An error has occurred while starting the portrate plugin for some ports ! \n Please check if the LUA portmonitor carrier is enabled in YARP and portrate plugin can be found by the portmonitor.");
187 messageBox.setFixedSize(500,200);
188 }
189 }
190 else { // stop it
191 QProgressDialog* progressDlg = new QProgressDialog("...", "Cancel", 0,
192 ui->treeWidgetSelectedCons->topLevelItemCount(), this);
193 progressDlg->setLabelText("Collecting the results...");
194 progressDlg->reset();
195 progressDlg->setValue(0);
196 progressDlg->setWindowModality(Qt::WindowModal);
197 progressDlg->show();
198 for( int i=0; i < ui->treeWidgetSelectedCons->topLevelItemCount(); ++i ){
199 progressDlg->setValue(i);
200 progressDlg->update();
201 progressDlg->repaint();
202 QTreeWidgetItem *item = ui->treeWidgetSelectedCons->topLevelItem(i);
203 if(ui->checkBoxCollect->checkState() == Qt::Checked) { //collect the results
204 yarp::os::Bottle param;
205 std::string portname = item->text(1).toUtf8().constData();
206 if(NetworkProfiler::getPortmonitorParams(portname, param)) {
207 Bottle* bt = param.get(0).asList();
208 if(!bt) {
209 yError()<<"Got wrong result format from portrate plugin at "<<portname;
210 continue;
211 }
212 //yInfo()<<bt->toString();
213 Bottle& data = bt->findGroup("data");
214 if(data.isNull() || data.size()<2) {
215 yError()<<"Got wrong result format from portrate plugin at "<<portname;
216 continue;
217 }
218 Bottle* samples = data.get(1).asList();
219 QString filename = portname.c_str();
220 filename.replace("/", "_");
221 filename = ui->lineEditLogPath->text() + "/port." +filename + ".log";
222 if (!saveLog(filename.toStdString(), samples)) {
223 yError() << "could not save the result into " << filename.toStdString();
224 }
225 }
226 }
227 else {
228 yarp::os::Property param;
229 param.put("log_save", 1);
230 NetworkProfiler::setPortmonitorParams(item->text(1).toUtf8().constData(), param);
231 }
232
233 NetworkProfiler::detachPortmonitorPlugin(item->text(1).toUtf8().constData());
234 }
235 delete progressDlg;
236 if(timer) {
237 timer->stop();
238 delete timer;
239 timer = nullptr;
240 }
241 isStarted = false;
242 ui->pushButtonStart->setText("&Start");
243 }
244 ui->treeWidgetCons->setEnabled(!isStarted);
245 ui->treeWidgetSelectedCons->setEnabled(!isStarted);
246 ui->pushButtonClose->setEnabled(!isStarted);
247 ui->pushButtonAdd->setEnabled(!isStarted);
248 ui->pushButtonRemove->setEnabled(!isStarted);
249 ui->checkBoxCollect->setEnabled(!isStarted);
250}
251
252void PortLoggerDialog::MyTimerSlot() {
253 ui->lcdNumberLogTime->display(logTime.elapsed()/1000.0);
254}
255
256bool PortLoggerDialog::saveLog(std::string filename, yarp::os::Bottle* samples) {
257 std::ofstream file;
258 file.open(filename.c_str());
259 if(!file.is_open()) {
260 return false;
261 }
262
263 for(size_t k=0; k<samples->size(); k++) {
264 Bottle* smp = samples->get(k).asList();
265 file<<smp->toString().c_str()<<'\n';
266 }
267
268 file.close();
269 return true;
270}
271
272void PortLoggerDialog::setLogPath() {
273 //QString filters("Log files (*.log);;Text files (*.txt);;All files (*.*)");
274 //QString defaultFilter("Log file (*.log)");
275 QString filename = QFileDialog::getExistingDirectory(nullptr, "Set the log files path",
276 QDir::homePath(),QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
277 if (filename.size() == 0) {
278 return;
279 }
280 ui->lineEditLogPath->setText(filename);
281}
pvertex_set::const_iterator pvertex_const_iterator
Definition Graph.h:35
std::vector< yarp::profiler::graph::Vertex * > pvertex_set
Definition Graph.h:33
#define yError(...)
Definition Log.h:361
#define yAssert(x)
Definition Log.h:388
#define yWarning(...)
Definition Log.h:340
int SIGNAL(int pid, int signum)
PortLoggerDialog(yarp::profiler::graph::Graph *graph, QWidget *parent=0)
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
Definition Bottle.cpp:293
bool isNull() const override
Checks if the object is invalid.
Definition Bottle.cpp:343
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
A class for storing options and configuration information.
Definition Property.h:33
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition Property.cpp:987
virtual Bottle * asList() const
Get list value.
Definition Value.cpp:240
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
static bool getPortmonitorParams(std::string portName, yarp::os::Bottle &param)
static bool attachPortmonitorPlugin(std::string portName, yarp::os::Property pluginProp)
static bool setPortmonitorParams(std::string portName, yarp::os::Property &param)
static bool detachPortmonitorPlugin(std::string portName)
The yarp::profiler::graph::Edge class.
Definition Graph.h:45
const yarp::profiler::graph::Vertex & second() const
Definition Graph.cpp:44
yarp::os::Property property
Definition Graph.h:61
The yarp::profiler::graph::Graph class.
Definition Graph.h:104
const pvertex_set & vertices()
Definition Graph.h:126
The yarp::profiler::graph::Vertex class.
Definition Graph.h:72
Definition aboutdlg.h:11
An interface to the operating system, including Port based communication.
#define YARP_UNUSED(var)
Definition api.h:162