This repository has been archived by the owner on Oct 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mainwindow.cpp
362 lines (292 loc) · 11.5 KB
/
mainwindow.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDesktopServices>
#include <QProcess>
#include <stdio.h>
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include "simulation.h"
#include "tp4.h"
QGraphicsView* TP4view;
Simulation simulation = Simulation(); // The global simulation object, use `extern Simulation simulation;` in other files?
int currentEditingBaseStation_index = 0; // The base station that is currently selected for user edit
QList<qreal> resolutions = {0.5, 0.25, 0.125, 0.0625};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
// MainWindow constructor, is ran on program's UI launch
this->setWindowIcon(QIcon(":/assets/icon.png"));
initFirstBaseStation();
ui->setupUi(this);
showFirstBaseStation();
toggleCoverageParametersLayout(true);
toggleCellParametersLayout(false);
for (qreal resolution : resolutions) {
ui->resolutionComboBox->addItem(QString("%1 m").arg(resolution));
}
ui->resolutionComboBox->setCurrentIndex(0);
this->setWindowIcon(QIcon(":/assets/icon.png"));
}
MainWindow::~MainWindow()
{
// MainWindow destructor
delete ui;
}
void MainWindow::on_runSimulationButton_clicked()
{
// User clicked on the "Run Simulation" button
if (simulation.is_running) {
return;
}
qInfo("\n### Starting simulation ###");
QProgressBar* progress_bar = ui->simulationProgressBar;
progress_bar->setValue(100);
ui->runSimulationButton->setEnabled(false);
ui->runSimulationButton->setStyleSheet("font-size: 14px;");
ui->runSimulationButton->setText("[Menu->Reset App] or (Ctrl+R) to reset");
bool res = runSimulation(progress_bar);
progress_bar->setValue(100);
// Turn the text green if simulation ran successfully, red otherwise
ui->runSuccessOrFailText->setStyleSheet(res ? "color: green;" : "color: red;");
ui->runSuccessOrFailText->setText(res ? QString("Success, took %1ms").arg(simulation.getSimulationTime()): "Failed");
simulation.is_running = false;
}
bool MainWindow::runSimulation(QProgressBar* progress_bar)
{
// Run the simulation and returns true if no errors ocurred
simulation.ran = true;
simulation.is_running = true;
try {
simulation.run(progress_bar);
qInfo("### Simulation ended successfully ###\n");
return true;
} catch (...) {
qInfo("#!#!#!# Simulation failed #!#!#!#\n");
return false;
}
}
void MainWindow::changeBaseStationPower(qreal value)
{
// Modify the current editing base station with the new user chosen power
qDebug() << "dBm value:" << value;
//Transmitter* base_station = simulation.getBaseStation(currentEditingBaseStation_index);
Transmitter* base_station = simulation.baseStations[currentEditingBaseStation_index];
qreal power = pow(10.0, value / 10.0);
base_station->power=power;
simulation.baseStations[currentEditingBaseStation_index]->power_dBm=value;
//base_station->setPower_dBm(value);
showBaseStationPower(value);
}
void MainWindow::on_sliderBaseStationPower_valueChanged(int value)
{
// User changed the current editing base station power (with slider)
changeBaseStationPower(value);
}
void MainWindow::on_spinBoxBaseStationPower_valueChanged(int value)
{
// User changed the current editing base station power (with spin box)
changeBaseStationPower(value);
}
void MainWindow::changeBaseStationCoordinates(QPointF point)
{
// Modify the current editing base station with the new user chosen coordinates
Transmitter* base_station = simulation.baseStations.at(currentEditingBaseStation_index);
base_station->changeCoordinates(point);
showBaseStationCoordinates(point);
}
void MainWindow::on_baseStationXspinBox_valueChanged(double x)
{
// User changed the current editing base station X coordinate
Transmitter* base_station = simulation.baseStations.at(currentEditingBaseStation_index);
QPointF coordinates = base_station->toPointF();
coordinates.setX(x);
changeBaseStationCoordinates(coordinates);
}
void MainWindow::on_baseStationYspinBox_valueChanged(double y)
{
// User changed the current editing base station Y coordinate
Transmitter* base_station = simulation.baseStations.at(currentEditingBaseStation_index);
QPointF coordinates = base_station->toPointF();
coordinates.setY(y);
changeBaseStationCoordinates(coordinates);
}
void MainWindow::on_actionExit_triggered()
{
// User clicked on the menu's "Exit" button, or presse "CTRL+W"
printf("Closing app...\n");
qApp->quit();
}
void MainWindow::on_actionReset_triggered()
{
// User clicked on the menu's "Reset" button, or presse "CTRL+R"
qInfo("Resetting app...");
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
}
void MainWindow::on_actionSee_Github_triggered()
{
// User clicked on the menu's "See Github" button
QDesktopServices::openUrl(QUrl("https://github.com/LucasPlacentino/802_11ay-Raytracing-Simulator", QUrl::TolerantMode));
}
void MainWindow::on_actionAbout_triggered()
{
// User clicked on the menu's "About" button
QMessageBox::about(this, tr("About this application"),
tr("This <b>802.11ay Raytracing Simulator</b> was made as a "
"project for the course <b>ELEC-H304</b> Telecommunications Physics "
"at <b>École polytechnique de Bruxelles - ULB</b>."
"<br>By Lucas Placentino & Salman Houdaibi"));
}
void MainWindow::saveImage(QGraphicsView* view = simulation.view, bool isTP4 = false)
{
QSize size = view->scene()->sceneRect().size().toSize()*10; // get the Scene size
//QImage img(size, QImage::Format_ARGB32); // scene's size, Format_RGBA64 ?
QImage img(size, QImage::Format_RGBA64);
QPainter painter(&img);
painter.setRenderHint(QPainter::Antialiasing);
// renderscene() //&painter //? scene->render(&painter);
view->render(&painter);
QString img_filename= QFileDialog::getSaveFileName(
this,
tr("Save Image"),
QDir::currentPath(),
"PNG (*.png);;BMP Files (*.bmp);;JPEG (*.JPEG)"
);
bool success = img.save(img_filename);
success? qInfo("Image saved") : qInfo("Cancelled");
}
void MainWindow::on_actionSave_image_triggered()
{
// User clicked on the menu's "Save Image" button, captures an image of the simulation view.
if (simulation.scene == nullptr || !simulation.ran) { // checks if a simulation has run
qInfo("Cannot save simulation that has not already run.");
//throw std::runtime_error("Cannot save simulation that has not already run.");
return;
}
saveImage(simulation.view);
}
void MainWindow::initFirstBaseStation()
{
// Creates the first (non-deletable) Base Station
simulation.baseStations.append(new Transmitter(9.4,7, 0, "Base Station 1"));
}
void MainWindow::showFirstBaseStation()
{
// Makes sure the first (non-deletable) Base Station is shown on the base station user edit box
QString new_item = QString("Base Station 1");
ui->transmitterSelector->addItem(new_item);
ui->transmitterSelector->setCurrentIndex(0);
on_transmitterSelector_activated(0);
}
void MainWindow::showBaseStationPower(int value_dBm)
{
// Updates the UI to show this base station power
ui->spinBoxBaseStationPower->setValue(value_dBm);
ui->sliderBaseStationPower->setValue(value_dBm);
}
void MainWindow::showBaseStationCoordinates(QPointF point)
{
// Updates the UI to show these base station coordinates
ui->baseStationXspinBox->setValue(point.x());
ui->baseStationYspinBox->setValue(point.y());
}
void MainWindow::toggleCellParametersLayout(bool enabled)
{
//ui->cellParametersLayout->setEnabled(enabled);
ui->cellCoordinatesLabel->setEnabled(enabled);
ui->cellCoordinatesXLabel->setEnabled(enabled);
ui->cellCoordinatesYLabel->setEnabled(enabled);
ui->cellXspinBox->setEnabled(enabled);
ui->cellYspinBox->setEnabled(enabled);
}
void MainWindow::toggleCoverageParametersLayout(bool enabled)
{
ui->showCellOutlineCheckBox->setEnabled(enabled);
}
void MainWindow::on_transmitterSelector_activated(int index)
{
// User selected a base station in the dropdown
qDebug() << "Selected base station: " << index+1;
// set current editing transmitter to this one
currentEditingBaseStation_index = index;
showBaseStationPower(simulation.getBaseStation(currentEditingBaseStation_index)->getPower_dBm());
showBaseStationCoordinates(simulation.baseStations.at(currentEditingBaseStation_index)->toPointF());
}
void MainWindow::on_addTransmitterButton_clicked()
{
// User clicked "Add Base Station" button
if (ui->transmitterSelector->count() < ui->transmitterSelector->maxCount()) //check if has not reached the max number of transmitters
{
qDebug("Added base station");
QString new_item_name = QString("Base Station %1").arg(ui->transmitterSelector->count()+1);
ui->transmitterSelector->addItem(new_item_name);
int new_item_index = ui->transmitterSelector->findText(new_item_name);
simulation.baseStations.append(new Transmitter(5,5, new_item_index, new_item_name));
on_transmitterSelector_activated(new_item_index);
ui->transmitterSelector->setCurrentIndex(new_item_index);
} else {
qInfo("There is already the maximum number of base stations");
}
}
void MainWindow::on_deleteBaseStationPushButton_clicked()
{
// User clicked on the "Delete Base Station" button
//currentEditingBaseStation_index
if (ui->transmitterSelector->count()>1 && currentEditingBaseStation_index != 0)
{
ui->transmitterSelector->removeItem(currentEditingBaseStation_index);
simulation.deleteBaseStation(currentEditingBaseStation_index);
int previous_item_index = currentEditingBaseStation_index-1;
on_transmitterSelector_activated(previous_item_index);
ui->transmitterSelector->setCurrentIndex(previous_item_index);
} else {
qDebug("Cannot delete Base Station 1");
}
}
void MainWindow::on_coverageHeatmapRadioButton_clicked(bool checked)
{
simulation.showRaySingleCell = !checked;
toggleCoverageParametersLayout(checked);
toggleCellParametersLayout(!checked);
qDebug() << "Coverage parameters" << (checked? "enabled," : "disabled,") << "Cell parameters" << (!checked? "enabled" : "disabled");
}
void MainWindow::on_singleCellRadioButton_clicked(bool checked)
{
simulation.showRaySingleCell = checked;
toggleCellParametersLayout(checked);
toggleCoverageParametersLayout(!checked);
qDebug() << "Coverage parameters" << (!checked? "enabled," : "disabled,") << "Cell parameters" << (checked? "enabled" : "disabled");
}
void MainWindow::on_liftOnFloorCheckBox_clicked(bool checked)
{
qDebug() << "Set lift:" << checked;
simulation.lift_is_on_floor = checked;
}
void MainWindow::on_showCellOutlineCheckBox_toggled(bool checked)
{
simulation.show_cell_outline = checked;
qDebug() << "Show cell outline:" << checked;
}
void MainWindow::on_resolutionComboBox_currentIndexChanged(int index)
{
simulation.resolution = resolutions[index];
qInfo() << "Changed resolution to" << resolutions[index] << "m";
}
void MainWindow::on_actionRun_TP4_Simulation_triggered()
{
TP4view = runTP4();
}
void MainWindow::on_actionSave_TP4_image_triggered()
{
saveImage(TP4view);
}
void MainWindow::on_cellXspinBox_valueChanged(double x)
{
simulation.singleCellX = x;
}
void MainWindow::on_cellYspinBox_valueChanged(double y)
{
simulation.singleCellY = y;
}