#include "../src/MainWindow.h" #include "../src/GlobeWidget.h" #include "../src/MapWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { void sendLine(MainWindow &window, const QString &line) { const bool invoked = QMetaObject::invokeMethod( &window, "handleSerialLine", Qt::DirectConnection, Q_ARG(QString, line)); assert(invoked); } void flushUpdates(MainWindow &window) { const bool invoked = QMetaObject::invokeMethod( &window, "flushUiUpdates", Qt::DirectConnection); assert(invoked); } } // namespace int main(int argc, char **argv) { QApplication app(argc, argv); qputenv("LOCATION_PLOTTER_PORT", "/dev/test-usb-uart"); MainWindow window; qunsetenv("LOCATION_PLOTTER_PORT"); { QTemporaryDir uartLogDirectory; assert(uartLogDirectory.isValid()); qputenv("LOCATION_PLOTTER_UART_LOG_DIR", uartLogDirectory.path().toUtf8()); bool loggingStarted = false; assert(QMetaObject::invokeMethod( &window, "startUartLogging", Qt::DirectConnection, Q_RETURN_ARG(bool, loggingStarted), Q_ARG(QString, QStringLiteral("/dev/test-uart")), Q_ARG(int, 460800))); assert(loggingStarted); sendLine(window, QStringLiteral("raw uart test line")); assert(QMetaObject::invokeMethod(&window, "stopUartLogging", Qt::DirectConnection)); qunsetenv("LOCATION_PLOTTER_UART_LOG_DIR"); const QStringList logFiles = QDir(uartLogDirectory.path()).entryList( {QStringLiteral("uart_*.log")}, QDir::Files); assert(logFiles.size() == 1); QFile logFile(QDir(uartLogDirectory.path()).filePath(logFiles.constFirst())); assert(logFile.open(QIODevice::ReadOnly | QIODevice::Text)); const QString contents = QString::fromUtf8(logFile.readAll()); assert(contents.contains(QStringLiteral("[SESSION START] port=/dev/test-uart baud=460800"))); assert(contents.contains(QRegularExpression( QStringLiteral(R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\] raw uart test line)")))); assert(contents.contains(QStringLiteral("[SESSION END]"))); } auto *table = window.findChild(); auto *referenceLatInput = window.findChild(QStringLiteral("referenceLatInput")); auto *referenceLonInput = window.findChild(QStringLiteral("referenceLonInput")); auto *cepValue = window.findChild(QStringLiteral("cepValue")); auto *maxPointsInput = window.findChild(QStringLiteral("maxPointsInput")); auto *elevationMaskSpin = window.findChild(QStringLiteral("elevationMaskSpin")); auto *showTelemetry = window.findChild(QStringLiteral("showTelemetryCheck")); auto *showRecentPoints = window.findChild(QStringLiteral("showRecentPointsCheck")); auto *showAverage = window.findChild(QStringLiteral("showAverageCheck")); auto *portSelector = window.findChild(QStringLiteral("portSelector")); auto *refreshRinexButton = window.findChild(QStringLiteral("refreshRinexButton")); auto *map = window.findChild(); auto *mainViewTabs = window.findChild(QStringLiteral("mainViewTabs")); auto *sideSplitter = window.findChild(QStringLiteral("sideSplitter")); assert(table != nullptr); assert(referenceLatInput != nullptr); assert(referenceLonInput != nullptr); assert(cepValue != nullptr); assert(maxPointsInput != nullptr); assert(elevationMaskSpin != nullptr); assert(elevationMaskSpin->value() == 10); assert(elevationMaskSpin->minimum() == 0); assert(elevationMaskSpin->maximum() == 90.0); elevationMaskSpin->setValue(12.5); assert(elevationMaskSpin->value() == 12.5); assert(showTelemetry != nullptr); assert(showRecentPoints != nullptr); assert(showAverage != nullptr); assert(portSelector != nullptr); assert(refreshRinexButton != nullptr); assert(refreshRinexButton->text() == QStringLiteral("RINEX Guncelle") || refreshRinexButton->text() == QStringLiteral("RINEX indiriliyor...")); assert(portSelector->isEditable()); assert(portSelector->count() >= 1); assert(portSelector->currentText() == QStringLiteral("/dev/test-usb-uart")); for (int i = 0; i < portSelector->count(); ++i) { assert(portSelector->itemText(i).startsWith(QStringLiteral("/dev/"))); assert(!portSelector->itemText(i).trimmed().isEmpty()); } assert(map != nullptr); assert(mainViewTabs != nullptr); assert(mainViewTabs->count() == 2); assert(sideSplitter != nullptr); assert(sideSplitter->orientation() == Qt::Vertical); sendLine(window, QStringLiteral("[TRK] tracked satellites=2 prn_indices=[2,7]")); assert(map != nullptr); auto *globe = window.findChild(); assert(globe != nullptr); assert(globe->observedPrns() == QSet({QStringLiteral("G03"), QStringLiteral("G08")})); sendLine(window, QStringLiteral("[TRK] tracked satellites=1 prn_indices=[13]")); assert(globe->observedPrns() == QSet({QStringLiteral("G14")})); assert(QMetaObject::invokeMethod(map, "referenceLocationSelected", Qt::DirectConnection, Q_ARG(double, 40.25), Q_ARG(double, 29.5))); assert(referenceLatInput->text() == QStringLiteral("40.250000000000000")); assert(referenceLonInput->text() == QStringLiteral("29.500000000000000")); referenceLatInput->clear(); referenceLonInput->clear(); assert(QMetaObject::invokeMethod(&window, "updateReferenceLocation", Qt::DirectConnection)); showTelemetry->setChecked(false); assert(!showRecentPoints->isEnabled()); assert(!showAverage->isEnabled()); showTelemetry->setChecked(true); assert(showRecentPoints->isEnabled()); assert(showAverage->isEnabled()); sendLine(window, QStringLiteral("lattitude : 40.78925034214206846173")); sendLine(window, QStringLiteral("longitude : 29.46277530841727809729")); assert(table->model()->rowCount() == 0); sendLine(window, QStringLiteral("NAV solve done")); flushUpdates(window); assert(table->model()->rowCount() == 1); assert(table->model()->data(table->model()->index(0, 2)).toString() == QStringLiteral("40.78925034214206846173")); assert(table->model()->data(table->model()->index(0, 3)).toString() == QStringLiteral("29.46277530841727809729")); sendLine(window, QStringLiteral( "[LOCATION] source=gps lat=40.1 lon=29.1 height=100 gdop=2 pdop=1.5 " "hdop=1 vdop=1.2 tdop=0.8 tracked=5 used=5")); sendLine(window, QStringLiteral( "[LOCATION] source=imu_corrected lat=40.10001 lon=29.10001 height=100.2 " "gdop=2 pdop=1.5 hdop=1 vdop=1.2 tdop=0.8 tracked=5 used=5")); flushUpdates(window); assert(table->model()->rowCount() == 3); assert(table->model()->data(table->model()->index(1, 1)).toString() == QStringLiteral("GPS")); assert(table->model()->data(table->model()->index(2, 1)).toString() == QStringLiteral("IMU corrected")); sendLine(window, QStringLiteral( "[LOCATION] source=trajectory lat=40.10002 lon=29.10002 height=100 tracked=4 used=4")); flushUpdates(window); assert(table->model()->rowCount() == 4); assert(table->model()->data(table->model()->index(3, 1)).toString() == QStringLiteral("Trajectory (truth)")); QTemporaryFile replayLog; assert(replayLog.open()); replayLog.write( "[LOCATION] source=trajectory lat=40.0 lon=29.0 height=100 tracked=4 used=4\n" "[LOCATION] source=gps lat=40.0001 lon=29.0001 height=104 tracked=4 used=4\n" "[LOCATION] source=imu_corrected lat=40.00002 lon=29.00002 height=101 tracked=4 used=4\n"); replayLog.flush(); assert(window.loadTelemetryLog(replayLog.fileName())); assert(table->model()->rowCount() == 3); assert(table->model()->data(table->model()->index(0, 1)).toString() == QStringLiteral("Trajectory (truth)")); assert(QMetaObject::invokeMethod(&window, "clearPoints", Qt::DirectConnection)); sendLine(window, QStringLiteral( "lat=40.78925034214206846173 long=29.46277530841727809729")); flushUpdates(window); assert(table->model()->rowCount() == 1); referenceLatInput->setText(QStringLiteral("40.78925034214206846173")); referenceLonInput->setText(QStringLiteral("29.46277530841727809729")); const bool referenceUpdated = QMetaObject::invokeMethod( &window, "updateReferenceLocation", Qt::DirectConnection); assert(referenceUpdated); assert(cepValue->text().startsWith(QStringLiteral("0.00 m"))); assert(cepValue->text().contains(QStringLiteral("N=1"))); const bool cleared = QMetaObject::invokeMethod(&window, "clearPoints", Qt::DirectConnection); assert(cleared); assert(table->model()->rowCount() == 0); assert(referenceLatInput->text() == QStringLiteral("40.78925034214206846173")); assert(referenceLonInput->text() == QStringLiteral("29.46277530841727809729")); assert(cepValue->text() == QStringLiteral("-")); referenceLatInput->setText(QStringLiteral("40.0")); referenceLonInput->setText(QStringLiteral("29.0")); assert(QMetaObject::invokeMethod(&window, "updateReferenceLocation", Qt::DirectConnection)); sendLine(window, QStringLiteral("lat=40.000 long=29.000")); sendLine(window, QStringLiteral("lat=40.001 long=29.000")); sendLine(window, QStringLiteral("lat=40.002 long=29.000")); flushUpdates(window); assert(cepValue->text().startsWith(QStringLiteral("111 m"))); assert(cepValue->text().contains(QStringLiteral("N=3"))); assert(QMetaObject::invokeMethod(&window, "clearPoints", Qt::DirectConnection)); referenceLatInput->setText(QStringLiteral("40.78925034214206846173")); referenceLonInput->setText(QStringLiteral("29.46277530841727809729")); assert(QMetaObject::invokeMethod(&window, "updateReferenceLocation", Qt::DirectConnection)); maxPointsInput->setValue(10000); for (int i = 0; i < 10000; ++i) { sendLine(window, QStringLiteral("lat=40.78925 long=29.46277 sats=7")); } flushUpdates(window); assert(table->model()->rowCount() == 10000); assert(cepValue->text().contains(QStringLiteral("N=10000"))); assert(QMetaObject::invokeMethod(&window, "clearPoints", Qt::DirectConnection)); maxPointsInput->setValue(10); { MapWidget followMap; TelemetryPoint corrected; corrected.source = LocationSource::ImuCorrected; corrected.latitude = 40.1; corrected.longitude = 29.1; corrected.receivedAt = QDateTime::currentDateTimeUtc(); TelemetryPoint rawGps; rawGps.source = LocationSource::Gps; rawGps.latitude = 41.0; rawGps.longitude = 30.0; rawGps.receivedAt = corrected.receivedAt.addMSecs(100); followMap.setPoints({corrected, rawGps}); assert(followMap.centerCoordinate() == QPointF(40.1, 29.1)); rawGps.receivedAt = corrected.receivedAt.addMSecs(1100); followMap.setPoints({corrected, rawGps}); assert(followMap.centerCoordinate() == QPointF(41.0, 30.0)); } const QByteArray screenshotPath = qgetenv("LOCATION_PLOTTER_TEST_SCREENSHOT"); if (!screenshotPath.isEmpty()) { sendLine(window, QStringLiteral("NAV solve start sats:5")); sendLine(window, QStringLiteral("tracking PRNs: G03, G08, G14, G21, G27")); sendLine(window, QStringLiteral( "lat=40.78925034214206846173 long=29.46277530841727809729 " "hheight=-89.05779508221894502640 sats=7 PDOP=1.235")); flushUpdates(window); mainViewTabs->setCurrentIndex(1); window.show(); app.processEvents(); window.repaint(); app.processEvents(); assert(window.grab().save(QString::fromLocal8Bit(screenshotPath), "PNG")); } return 0; }