Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Hanna Rathje, SLTE, 2022-03-29
|
||||
#
|
||||
|
||||
SET(SRCS
|
||||
main.cpp
|
||||
mainwindow.h
|
||||
mainwindow.cpp
|
||||
position_helper.h
|
||||
position_helper.cpp
|
||||
settings.h
|
||||
settings.cpp
|
||||
simulated_player.h
|
||||
simulated_player.cpp
|
||||
worker.h
|
||||
worker.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(SRCS mainwindow.ui )
|
||||
|
||||
NGL_ADD_EXECUTABLE(TOOLSSV wlsRandomPositions ${SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(wlsRandomPositions
|
||||
Qt5::Widgets
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
LtsCommandLineParser
|
||||
LtsWidgets
|
||||
ltsCoordWidget
|
||||
LtsCoordTrans
|
||||
LtsUtilsCore
|
||||
SfmConverter
|
||||
nglapplication
|
||||
nglsettings
|
||||
ngltools
|
||||
NGLLogger
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(wlsRandomPositions)
|
||||
NGL_INSTALL(TOOLSSV FILES log4cxx_wrp.props wrp_data.ini DESTINATION bin)
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# DbAdministration
|
||||
###########################################################
|
||||
|
||||
log4j.logger.MainWindow=DEBUG
|
||||
log4j.logger.Worker=DEBUG
|
||||
log4j.logger.PositionHelper=DEBUG
|
||||
log4j.logger.SimulatedPlayer=DEBUG
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
log4j.appender.file=Lts::RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#include "mainwindow.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <nglapplication/nglapplication.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
NGLApplication app(argc, argv);
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options(LtsCommandLineParser::LtsCommandLineParser::ProvideCommandLineParameterOptions::CustomConfigFile);
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
app.createLogger("WRP", "log4cxx_wrp.props");
|
||||
NGL::INGLLogger &logger = app.logger("main");
|
||||
QCoreApplication::setApplicationName(QLatin1String("WLS Random Position Generator"));
|
||||
QCoreApplication::setOrganizationName(QLatin1String("RME"));
|
||||
|
||||
QString iniFile = options.iniFileSet() ? options.iniFile() : QStringLiteral("wrp_training_areas.ini");
|
||||
|
||||
WlsRandomPositions::Settings::setIniFile(iniFile);
|
||||
|
||||
WlsRandomPositions::MainWindow w;
|
||||
w.show();
|
||||
STARTUP_LOG(logger);
|
||||
int iRet = app.exec();
|
||||
SHUTDOWN_LOG(logger);
|
||||
return iRet;
|
||||
}
|
||||
Executable
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* MainWindow
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "position_helper.h"
|
||||
#include "settings.h"
|
||||
#include "worker.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <LtsCoordTrans/lts_coord_widget.h>
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, m_ui(new Ui::MainWindow)
|
||||
, m_worker(new Worker(this))
|
||||
, m_posHelper(nullptr)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("MainWindow"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
const QMap<int, Settings::TrainingArea> trainingAreas = Settings::trainingAreas();
|
||||
|
||||
ERROR_LOG(m_logger) << "trainingArea size: " << trainingAreas.size();
|
||||
for (const auto &item : trainingAreas)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ta name: " << item.name << ", id: " << item.id;
|
||||
m_ui->cbTrainingArea->addItem(item.name, QVariant::fromValue(item));
|
||||
}
|
||||
|
||||
connect(m_worker, &Worker::connectionStateChanged, this, &MainWindow::onConnectionStateChanged);
|
||||
connect(m_worker, &Worker::telegramsIncremented, this, &MainWindow::onTelegramsIncremented);
|
||||
|
||||
m_ui->sbAmountPlayers->setValue(Settings::amountPlayers());
|
||||
m_ui->sbEquipNo->setValue(Settings::firstEquipNo());
|
||||
|
||||
m_ui->sbMsecs->setValue(Settings::msecs());
|
||||
m_ui->sbJitter->setValue(Settings::jitter());
|
||||
|
||||
m_ui->leMacAddress->setInputMask(QStringLiteral("HH:HH:HH:HH:HH:HH"));
|
||||
m_ui->leMacAddress->setText(Settings::firstMacAddress());
|
||||
|
||||
m_ui->leServerName->setText(Settings::serverName());
|
||||
m_ui->sbServerPort->setValue(Settings::serverPort());
|
||||
|
||||
m_ui->sbHeightMin->setValue(Settings::heightMin());
|
||||
m_ui->sbHeightMax->setValue(Settings::heightMax());
|
||||
|
||||
m_ui->sbMaxdistance->setValue(Settings::maxDistance());
|
||||
|
||||
m_statusLabelConnected = new QLabel(this);
|
||||
m_statusLabelConnected->setText(tr("Disconnected"));
|
||||
m_statusLabelSentTelegrams = new QLabel(this);
|
||||
m_statusLabelSentTelegrams->setText(tr("0 telegrams"));
|
||||
m_ui->statusbar->addWidget(m_statusLabelConnected, 50);
|
||||
m_ui->statusbar->addWidget(m_statusLabelSentTelegrams, 100);
|
||||
|
||||
connect(m_ui->actionExit, &QAction::triggered, this, &MainWindow::close);
|
||||
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Start"));
|
||||
m_ui->buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &MainWindow::onStartClicked);
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setText(tr("Stop"));
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &MainWindow::onStopClicked);
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close)->hide();
|
||||
m_ui->sbMaxdistance->setEnabled(false);
|
||||
connect(m_ui->cbMaxDistance, &QCheckBox::toggled, m_ui->sbMaxdistance, &LtsWidgets::LtsDoubleSpinBox::setEnabled);
|
||||
|
||||
|
||||
connect(m_ui->cbTrainingArea, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::onTrainingAreaChanged);
|
||||
onTrainingAreaChanged(m_ui->cbTrainingArea->currentIndex());
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete m_ui;
|
||||
delete m_posHelper;
|
||||
}
|
||||
|
||||
void MainWindow::onTrainingAreaChanged(int index)
|
||||
{
|
||||
Settings::TrainingArea ta = m_ui->cbTrainingArea->itemData(index).value<Settings::TrainingArea>();
|
||||
|
||||
LtsCoordTrans::UtmCoordinate bottomLeft = LtsCoordTrans::UtmCoordinate::fromMgrs(ta.bottomLeft);
|
||||
LtsCoordTrans::getMgrsSquares(QRectF(bottomLeft.geographic(0, 0), bottomLeft.geographic(ta.width, ta.height)), true, true);
|
||||
|
||||
delete m_ui->peTopLeft;
|
||||
m_ui->peTopLeft = new LtsCoordWidget::LtsCoordWidget(m_ui->centralwidget);
|
||||
m_ui->peTopLeft->setObjectName(QString::fromUtf8("peTopLeft"));
|
||||
m_ui->gridLayout->addWidget(m_ui->peTopLeft, 8, 1, 1, 3);
|
||||
m_ui->peTopLeft->setCoordinate(bottomLeft.geographic(0, ta.height), true);
|
||||
|
||||
delete m_ui->peBottomRight;
|
||||
m_ui->peBottomRight = new LtsCoordWidget::LtsCoordWidget(m_ui->centralwidget);
|
||||
m_ui->peBottomRight->setObjectName(QString::fromUtf8("peButtomRight"));
|
||||
m_ui->gridLayout->addWidget(m_ui->peBottomRight, 9, 1, 1, 3);
|
||||
m_ui->peBottomRight->setCoordinate(bottomLeft.geographic(ta.width, 0), true);
|
||||
}
|
||||
|
||||
void MainWindow::onStartClicked()
|
||||
{
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Load)->setDisabled(true);
|
||||
|
||||
if (!m_posHelper)
|
||||
m_posHelper = new PositionHelper(m_ui->peTopLeft->coordinate(), m_ui->peBottomRight->coordinate(), m_ui->sbHeightMin->value(), m_ui->sbHeightMax->value());
|
||||
else
|
||||
m_posHelper->set(m_ui->peTopLeft->coordinate(), m_ui->peBottomRight->coordinate(), m_ui->sbHeightMin->value(), m_ui->sbHeightMax->value());
|
||||
|
||||
m_worker->connectToServer(m_ui->leServerName->text(), m_ui->sbServerPort->value());
|
||||
}
|
||||
|
||||
void MainWindow::onConnectionStateChanged(bool connected, const QString &status)
|
||||
{
|
||||
m_statusLabelConnected->setText(status);
|
||||
if (!connected)
|
||||
{
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Load)->setDisabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QString macAddressStr = m_ui->leMacAddress->text();
|
||||
macAddressStr.remove(QLatin1Char(':'));
|
||||
bool ok;
|
||||
qint64 macAddress = macAddressStr.toLongLong(&ok, 16);
|
||||
DEBUG_LOG(m_logger) << "MacAdress: " << macAddressStr << ", numeric: " << macAddress << ", Okay? " << ok;
|
||||
double maxDistance = 0;
|
||||
if (m_ui->cbMaxDistance->isChecked())
|
||||
maxDistance = m_ui->sbMaxdistance->value();
|
||||
|
||||
m_worker->start(m_ui->sbAmountPlayers->value(), m_ui->sbEquipNo->value(), macAddress, m_ui->sbMsecs->value(), m_ui->sbJitter->value(), maxDistance);
|
||||
}
|
||||
|
||||
void MainWindow::onStopClicked()
|
||||
{
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Load)->setDisabled(false);
|
||||
m_worker->stop();
|
||||
}
|
||||
|
||||
void MainWindow::onTelegramsIncremented(int sentTelegrams)
|
||||
{
|
||||
m_statusLabelSentTelegrams->setText(tr("%1 telegrams sent.").arg(sentTelegrams));
|
||||
}
|
||||
|
||||
} // Namespace WlsRandomPositions}
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* MainWindow
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
class PositionHelper;
|
||||
class Worker;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void onStartClicked();
|
||||
void onStopClicked();
|
||||
void onConnectionStateChanged(bool connected, const QString &status);
|
||||
void onTelegramsIncremented(int sentTelegrams);
|
||||
void onTrainingAreaChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *m_ui;
|
||||
QLabel *m_statusLabelConnected;
|
||||
QLabel *m_statusLabelSentTelegrams;
|
||||
Worker *m_worker;
|
||||
PositionHelper *m_posHelper;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
|
||||
Executable
+311
@@ -0,0 +1,311 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>570</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>WLS Random Positions</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../../TetraIF/LogView/LogViewResources.qrc">
|
||||
<normaloff>:/image/P2C.png</normaloff>:/image/P2C.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="lbxHeightMax">
|
||||
<property name="text">
|
||||
<string>Altitude Max:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="lbxServerPort">
|
||||
<property name="text">
|
||||
<string>Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="lbxBottomRight">
|
||||
<property name="text">
|
||||
<string>Bottom Right Coordinate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxAmountPlayers">
|
||||
<property name="text">
|
||||
<string>Amount Players:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="lbxTcpServer">
|
||||
<property name="text">
|
||||
<string>TCP Server:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbHeightMax">
|
||||
<property name="minimum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbEquipNo">
|
||||
<property name="minimum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="lbxHeightMin">
|
||||
<property name="text">
|
||||
<string>Altitude Min:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1" colspan="3">
|
||||
<widget class="LtsCoordWidget::LtsCoordWidget" name="peBottomRight"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="4">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="3">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbServerPort">
|
||||
<property name="minimum">
|
||||
<number>1025</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="lbxJitter">
|
||||
<property name="text">
|
||||
<string>Jitter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="cbTrainingArea"/>
|
||||
</item>
|
||||
<item row="15" column="3">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxFirstMacAddress">
|
||||
<property name="text">
|
||||
<string>First Mac Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="leServerName"/>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="leMacAddress"/>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="3">
|
||||
<widget class="LtsCoordWidget::LtsCoordWidget" name="peTopLeft"/>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="4">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbJitter">
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxFirstEquipNo">
|
||||
<property name="text">
|
||||
<string>First EquipNo:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbHeightMin">
|
||||
<property name="minimum">
|
||||
<number>-10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lbxTrainingArea">
|
||||
<property name="text">
|
||||
<string>Training Area:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbAmountPlayers">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0" colspan="4">
|
||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="lbxTopLeft">
|
||||
<property name="text">
|
||||
<string>Top Left Coordinate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lbxMsecs">
|
||||
<property name="text">
|
||||
<string>MSecs:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="LtsWidgets::LtsSpinBox" name="sbMsecs">
|
||||
<property name="minimum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="4">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="LtsWidgets::LtsDoubleSpinBox" name="sbMaxdistance">
|
||||
<property name="maximum">
|
||||
<double>50.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QCheckBox" name="cbMaxDistance">
|
||||
<property name="text">
|
||||
<string>Max. Distance to old position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+D</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsCoordWidget::LtsCoordWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsCoordTrans/lts_coord_widget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>LtsWidgets/lts_spinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>LtsWidgets/lts_spinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>sbAmountPlayers</tabstop>
|
||||
<tabstop>sbEquipNo</tabstop>
|
||||
<tabstop>leMacAddress</tabstop>
|
||||
<tabstop>sbMsecs</tabstop>
|
||||
<tabstop>sbJitter</tabstop>
|
||||
<tabstop>cbTrainingArea</tabstop>
|
||||
<tabstop>peTopLeft</tabstop>
|
||||
<tabstop>peBottomRight</tabstop>
|
||||
<tabstop>sbHeightMin</tabstop>
|
||||
<tabstop>sbHeightMax</tabstop>
|
||||
<tabstop>leServerName</tabstop>
|
||||
<tabstop>sbServerPort</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../TetraIF/LogView/LogViewResources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Generates a postion for a player
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
|
||||
#include "position_helper.h"
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QLineF>
|
||||
|
||||
static QRectF s_area;
|
||||
static double s_heightMin;
|
||||
static double s_heightMax;
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
PositionHelper::PositionHelper(const QPointF &topLeft, const QPointF &bottomRight, double heightMin, double heightMax)
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("PositionHelper"))
|
||||
{
|
||||
s_area = QRectF(topLeft, bottomRight).normalized();
|
||||
s_heightMin = heightMin;
|
||||
s_heightMax = heightMax;
|
||||
INFO_LOG(m_logger) << "Area initialized: " << LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.topLeft()).mgrs() << "//"
|
||||
<< LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.bottomRight()).mgrs();
|
||||
}
|
||||
|
||||
void PositionHelper::set(const QPointF &topLeft, const QPointF &bottomRight, double heightMin, double heightMax)
|
||||
{
|
||||
s_area = QRectF(topLeft, bottomRight).normalized();
|
||||
s_heightMin = heightMin;
|
||||
s_heightMax = heightMax;
|
||||
|
||||
INFO_LOG(m_logger) << "New Area initialized: " << LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.topLeft()).mgrs() << "//"
|
||||
<< LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.bottomRight()).mgrs();
|
||||
}
|
||||
|
||||
QPair<QPointF,double> PositionHelper::randPos()
|
||||
{
|
||||
LtsCoordTrans::UtmCoordinate bl = LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.bottomLeft());
|
||||
LtsCoordTrans::UtmCoordinate tr = LtsCoordTrans::UtmCoordinate::fromGeographic(s_area.topRight());
|
||||
|
||||
QPointF distance = bl.relativeTo(tr);
|
||||
|
||||
// Multiplying with -1 works for all Degree Squares (northern/southern hemisphere, west/east of Greenwich)
|
||||
distance.setX((rand() % 100) / 100.0 * distance.x() * -1.0);
|
||||
distance.setY((rand() % 100) / 100.0 * distance.y() * -1.0);
|
||||
double z = (rand() % 100) / 100.0 * (s_heightMax - s_heightMin) + s_heightMin;
|
||||
return {bl.geographic(distance),z};
|
||||
}
|
||||
|
||||
QPair<QPointF,double> PositionHelper::randPos(const QPointF &oldPos, double maxDistance)
|
||||
{
|
||||
double z = (rand() % 100) / 100.0 * (s_heightMax - s_heightMin) + s_heightMin;
|
||||
|
||||
LtsCoordTrans::UtmCoordinate utm = LtsCoordTrans::UtmCoordinate::fromGeographic(oldPos);
|
||||
QLineF line;
|
||||
line.setP1({0,0});
|
||||
line.setP2({1,0});
|
||||
do
|
||||
{
|
||||
line.setAngle((rand() % 36000) / 100.0);
|
||||
line.setLength(((rand() % 100) / 100.0) * maxDistance);
|
||||
} while (!s_area.contains(utm.geographic(line.p2())));
|
||||
|
||||
return {utm.geographic(line.p2()),z};
|
||||
}
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Generates a postion for a player
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
#pragma once
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#include <QRectF>
|
||||
#include <QPair>
|
||||
/*
|
||||
* Class only works with Relative Positions!!!!
|
||||
*/
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
class PositionHelper
|
||||
{
|
||||
public:
|
||||
PositionHelper(const QPointF &topLeft, const QPointF &bottomRight, double heightMin, double heightMax);
|
||||
|
||||
static QPair<QPointF, double> randPos(); // lon/lat, height
|
||||
static QPair<QPointF, double> randPos(const QPointF &oldPos, double maxDistance); // lon/lat, height
|
||||
|
||||
void set(const QPointF &topLeft, const QPointF &bottomRight, double heightMin, double heightMax);
|
||||
|
||||
private:
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Settings for WlsRandomPositions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* * Created by Hanna E. Rathje, SLTE, 2022-04-01
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
class NGLSettingsClass : public NGL::Settings
|
||||
{
|
||||
public:
|
||||
NGLSettingsClass()
|
||||
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
|
||||
{}
|
||||
static void setIniFile(const QString &fn)
|
||||
{
|
||||
s_iniFile = fn;
|
||||
}
|
||||
static QString s_iniFile;
|
||||
};
|
||||
QString NGLSettingsClass::s_iniFile;
|
||||
Q_GLOBAL_STATIC(NGLSettingsClass, s)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NGL::Settings *Settings::settings()
|
||||
{
|
||||
return s();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::setIniFile(const QString &ini)
|
||||
{
|
||||
NGLSettingsClass::setIniFile(ini);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QMap<int,Settings::TrainingArea> Settings::trainingAreas()
|
||||
{
|
||||
QSettings *settings = s()->settings();
|
||||
QMap<int, TrainingArea> map;
|
||||
|
||||
settings->beginGroup(QStringLiteral("TrainingAreas"));
|
||||
{
|
||||
int size_ta = settings->beginReadArray(QStringLiteral("TrainingArea"));
|
||||
for (int i = 0; i < size_ta; ++i)
|
||||
{
|
||||
settings->setArrayIndex(i);
|
||||
TrainingArea ta;
|
||||
ta.id = settings->value(QStringLiteral("id")).toInt();
|
||||
ta.name = settings->value(QStringLiteral("name")).toString();
|
||||
ta.bottomLeft = settings->value(QStringLiteral("bottomLeftMgrs")).toString();
|
||||
ta.width = settings->value(QStringLiteral("width"), 1000).toInt();
|
||||
ta.height = settings->value(QStringLiteral("height"), 1000).toInt();
|
||||
map.insert(ta.id, ta);
|
||||
}
|
||||
settings->endArray();
|
||||
}
|
||||
settings->endGroup();
|
||||
return map;
|
||||
}
|
||||
|
||||
int Settings::amountPlayers()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/amountPlayers"), 100).toInt();
|
||||
}
|
||||
|
||||
int Settings::firstEquipNo()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/firstEquipNo"), 1000).toInt();
|
||||
}
|
||||
|
||||
QString Settings::firstMacAddress()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/firstMacAddress"), QStringLiteral("01:12:23:34:45:5")).toString();
|
||||
}
|
||||
|
||||
int Settings::msecs()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/msecs"), 100).toInt();
|
||||
}
|
||||
|
||||
int Settings::jitter()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/jitter"), 00).toInt();
|
||||
}
|
||||
|
||||
int Settings::heightMin()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/altitudeMin"), 0).toInt();
|
||||
}
|
||||
|
||||
int Settings::heightMax()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/altitudeMax"), 10).toInt();
|
||||
}
|
||||
|
||||
double Settings::maxDistance()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/naxDistance"), 10).toDouble();
|
||||
}
|
||||
|
||||
QString Settings::serverName()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/serverName"), QStringLiteral("EXCTDS01")).toString();
|
||||
}
|
||||
|
||||
int Settings::serverPort()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("Global/serverPort"), 12002).toInt();
|
||||
}
|
||||
|
||||
} // namespace WlsRandomPositions
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Settings for WlsRandomPositions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* * Created by Hanna E. Rathje, SLTE, 2022-04-01
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
|
||||
struct TrainingArea
|
||||
{
|
||||
int id;
|
||||
QString name;
|
||||
QString bottomLeft;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
QMap<int, TrainingArea> trainingAreas();
|
||||
|
||||
int amountPlayers();
|
||||
int firstEquipNo();
|
||||
QString firstMacAddress();
|
||||
int msecs();
|
||||
int jitter();
|
||||
int heightMin();
|
||||
int heightMax();
|
||||
double maxDistance();
|
||||
QString serverName();
|
||||
int serverPort();
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace WlsRandomPositions
|
||||
|
||||
// needed for QVariant
|
||||
Q_DECLARE_METATYPE(WlsRandomPositions::Settings::TrainingArea)
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Simulate players
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
|
||||
#include "simulated_player.h"
|
||||
#include "position_helper.h"
|
||||
|
||||
#include <WirelessLocationSystem/wls_sfm_message_converter.h>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <LtsUtils/LtsUtilsCore/sfm_bytemessage_converter.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include "math.h"
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
SimulatedPlayer::SimulatedPlayer(int equipNo, qint64 mac, int msecs, int jitter, double maxDistance, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_equipNo(equipNo)
|
||||
, m_macAddress(toMacString(mac))
|
||||
, m_msecs(msecs)
|
||||
, m_jitter(jitter)
|
||||
, m_maxDistance(maxDistance)
|
||||
, m_pos({{},0.0})
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(QString::fromLatin1("SimulatedPlayer.%1").arg(QString::number(m_equipNo)).toStdString()))
|
||||
{
|
||||
}
|
||||
|
||||
void SimulatedPlayer::start()
|
||||
{
|
||||
QString eqNoString = QString::number(m_equipNo);
|
||||
QString initialTelegram = QString::fromLatin1("%1;%2;%3").arg(4).arg(m_macAddress).arg(eqNoString);
|
||||
|
||||
INFO_LOG(m_logger) << "initTelegram: " << initialTelegram;
|
||||
|
||||
WirelessLocationSystem::SfmMsgEquipmentId msg;
|
||||
msg.setEquipmentNumber(m_equipNo);
|
||||
QByteArray ba = WirelessLocationSystem::SfmMessageConverter::generateTxMessage(msg);
|
||||
|
||||
emit sendInitTelegram(m_macAddress, ba);
|
||||
|
||||
QTimer::singleShot(m_msecs + (((rand() % 200) - 100) / 100) * m_jitter, this, &SimulatedPlayer::onTimerTimeout);
|
||||
}
|
||||
|
||||
void SimulatedPlayer::onTimerTimeout()
|
||||
{
|
||||
QPair<QPointF,double> pos;
|
||||
if (qFuzzyIsNull(m_maxDistance) || m_pos.first.isNull())
|
||||
pos = PositionHelper::randPos();
|
||||
else
|
||||
pos = PositionHelper::randPos(m_pos.first, m_maxDistance);
|
||||
|
||||
DEBUG_LOG(m_logger) << "posTelegram: x: " << pos.first.x() << ", y: " << pos.first.y() << ", z: " << pos.second;
|
||||
DEBUG_LOG(m_logger) << "MGRS: " << LtsCoordTrans::UtmCoordinate::fromGeographic(pos.first).mgrs(5, true);
|
||||
|
||||
emit sendPositionTelegram(m_macAddress, pos.first, pos.second);
|
||||
|
||||
m_pos = pos;
|
||||
QTimer::singleShot(m_msecs + (((rand() % 200) - 100) / 100) * m_jitter, this, &SimulatedPlayer::onTimerTimeout);
|
||||
}
|
||||
|
||||
QString SimulatedPlayer::toMacString(qint64 mac)
|
||||
{
|
||||
QString macString = QString::number(mac, 16);
|
||||
macString = macString.prepend(QString(12 - macString.length(), QLatin1Char('0')));
|
||||
macString.insert(10, QLatin1Char(':'));
|
||||
macString.insert( 8, QLatin1Char(':'));
|
||||
macString.insert( 6, QLatin1Char(':'));
|
||||
macString.insert( 4, QLatin1Char(':'));
|
||||
macString.insert( 2, QLatin1Char(':'));
|
||||
return macString;
|
||||
}
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Simulate players
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <QObject>
|
||||
#include <QPointF>
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
class SimulatedPlayer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SimulatedPlayer(int equipNo, qint64 mac, int msecs, int jitter = 0, double maxDistance = 0.0, QObject *parent = nullptr);
|
||||
void start();
|
||||
|
||||
signals:
|
||||
void sendInitTelegram(const QString &macAddress, const QByteArray &msg);
|
||||
void sendPositionTelegram(const QString &macAddress, QPointF pos, double height);
|
||||
|
||||
private slots:
|
||||
void onTimerTimeout();
|
||||
|
||||
private:
|
||||
static QString toMacString(qint64 mac);
|
||||
|
||||
int m_equipNo;
|
||||
QString m_macAddress;
|
||||
int m_msecs;
|
||||
int m_jitter;
|
||||
double m_maxDistance;
|
||||
QPair<QPointF,double> m_pos;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
Executable
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Sending of telegrams to websocket
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
|
||||
#include "worker.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QPointF>
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
static inline QByteArray escapeData(const QByteArray &bufferData)
|
||||
{
|
||||
QByteArray ret;
|
||||
ret.reserve(bufferData.size() * 6 / 5);
|
||||
for (const unsigned char c : bufferData)
|
||||
{
|
||||
if (c >= 0x20 && c < 0x7f)
|
||||
ret += c;
|
||||
else
|
||||
ret += "\\x" + QByteArray::number(static_cast<unsigned char>(c), 16);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Worker::Worker(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("Worker"))
|
||||
{
|
||||
m_tcpClient = new QTcpSocket(this);
|
||||
|
||||
connect(m_tcpClient, &QTcpSocket::connected, this, &Worker::onTcpConnected);
|
||||
connect(m_tcpClient, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &Worker::error);
|
||||
connect(m_tcpClient, &QTcpSocket::disconnected, this, &Worker::onTcpDisconnected);
|
||||
}
|
||||
|
||||
Worker::~Worker()
|
||||
{
|
||||
delete m_tcpClient;
|
||||
}
|
||||
|
||||
void Worker::connectToServer(const QString &serverName, int serverPort)
|
||||
{
|
||||
m_server = serverName;
|
||||
m_serverPort = serverPort;
|
||||
|
||||
m_tcpClient->connectToHost(m_server, m_serverPort);
|
||||
}
|
||||
|
||||
void Worker::onTcpConnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Connected to " << m_server << ", Port: " << m_serverPort;
|
||||
QString status = tr("Connected to %1, Port: %2").arg(m_server).arg(m_serverPort);
|
||||
emit connectionStateChanged(true, status);
|
||||
}
|
||||
|
||||
void Worker::onTcpDisconnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Disconnected";
|
||||
QString status = tr("Disconnected");
|
||||
emit connectionStateChanged(false, status);
|
||||
}
|
||||
|
||||
void Worker::error()
|
||||
{
|
||||
ERROR_LOG(m_logger) << "SocketError " << m_tcpClient->errorString();
|
||||
emit connectionStateChanged(false, m_tcpClient->errorString());
|
||||
}
|
||||
|
||||
void Worker::start(int numberParticipants, int firstEquipNo, qint64 firstMacAddress, int mSecs, int jitter, double maxDistance)
|
||||
{
|
||||
m_sentTelegrams = 0;
|
||||
int equipNo = firstEquipNo;
|
||||
qint64 mac = firstMacAddress;
|
||||
|
||||
for (int i=0; i<numberParticipants; ++i)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "SimulatedPlayer: equipNo: " << equipNo << ", macAddress: " << mac;
|
||||
SimulatedPlayer *sp = new SimulatedPlayer(equipNo++, mac++, mSecs, jitter, maxDistance, this);
|
||||
connect(sp, &SimulatedPlayer::sendInitTelegram, this, &Worker::onInit);
|
||||
connect(sp, &SimulatedPlayer::sendPositionTelegram, this, &Worker::onPosition);
|
||||
m_players << sp;
|
||||
sp->start();
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << numberParticipants << " Players started";
|
||||
}
|
||||
|
||||
void Worker::onInit(const QString &macAddress, const QByteArray &content)
|
||||
{
|
||||
QDateTime dt = QDateTime::currentDateTime();
|
||||
QByteArray data;
|
||||
|
||||
data.clear();
|
||||
|
||||
data.append(0x7F); // Startkennung
|
||||
data.append(QByteArray::number(3)); //
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss.zzz")).toLatin1()); // Aktuelle Zeit
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(macAddress.toUtf8()); // Tag-ID
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(content); // ba < 80 Zeichen!
|
||||
data.append(0x8F); // Endekennung
|
||||
|
||||
qint64 ret = m_tcpClient->write(data);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not send init data for macAddress " << macAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Sending telegram to wls: " << escapeData(data);
|
||||
m_tcpClient->flush();
|
||||
emit telegramsIncremented(++m_sentTelegrams);
|
||||
}
|
||||
}
|
||||
|
||||
void Worker::onPosition(const QString &macAddress, QPointF pos, double height)
|
||||
{
|
||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(pos.x(), pos.y(), 7, false);
|
||||
QString value = mgrs.right(14);
|
||||
QString x = value.left(7);
|
||||
QString y = value.right(7);
|
||||
QString z = QString::number(height);
|
||||
|
||||
QDateTime dt = QDateTime::currentDateTime();
|
||||
QByteArray data;
|
||||
|
||||
data.clear();
|
||||
|
||||
data.append(0x7F); // Startkennung
|
||||
data.append(QByteArray::number(1)); //
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(dt.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss.zzz")).toLatin1()); // Aktuelle Zeit
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(macAddress.toUtf8()); // Tag-ID
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(x.toUtf8());
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(y.toUtf8());
|
||||
data.append(';'); // Trennzeichen
|
||||
data.append(z.toUtf8());
|
||||
data.append(";1;0;0;-1;-1");
|
||||
data.append(0x8F); // Endekennung
|
||||
|
||||
qint64 ret = m_tcpClient->write(data);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not send pos data for macAddress " << macAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Sending telegram to wls: " << escapeData(data);
|
||||
m_tcpClient->flush();
|
||||
emit telegramsIncremented(++m_sentTelegrams);
|
||||
}
|
||||
}
|
||||
|
||||
void Worker::stop()
|
||||
{
|
||||
INFO_LOG(m_logger) << "stop worker";
|
||||
|
||||
for (SimulatedPlayer* sp : m_players)
|
||||
sp->deleteLater();
|
||||
m_players.clear();
|
||||
|
||||
m_tcpClient->close();
|
||||
}
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @RDE_HEADER@
|
||||
* Sending of telegrams to websocket
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLTE, 2022-03-29
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "simulated_player.h"
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
namespace WlsRandomPositions
|
||||
{
|
||||
|
||||
class Worker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Worker(QObject *parent = nullptr);
|
||||
~Worker();
|
||||
|
||||
void connectToServer(const QString &serverName, int serverPort);
|
||||
void start(int numberParticipants, int firstEquipNo, qint64 firstMacAddress, int mSecs, int jitter, double maxDistance);
|
||||
void stop();
|
||||
void error();
|
||||
|
||||
signals:
|
||||
void telegramsIncremented(int sentTelegrams);
|
||||
void connectionStateChanged(bool connected, QString status);
|
||||
|
||||
private slots:
|
||||
void onInit(const QString &macAddress, const QByteArray &content);
|
||||
void onPosition(const QString &macAddress, QPointF pos, double height);
|
||||
void onTcpConnected();
|
||||
void onTcpDisconnected();
|
||||
|
||||
private:
|
||||
QVector<SimulatedPlayer*> m_players;
|
||||
QTcpSocket *m_tcpClient;
|
||||
QString m_server;
|
||||
int m_serverPort;
|
||||
int m_sentTelegrams;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // Namespace WlsRandomPositions
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
|
||||
[Global]
|
||||
amountPlayers=10
|
||||
firstEquipNo=500
|
||||
firstMacAddress=01:12:23:34:45:56
|
||||
msecs=100
|
||||
jitter=10
|
||||
altitudeMin=0
|
||||
altitudeMax=10
|
||||
maxDistance=10.0
|
||||
serverName=EXCTDS01
|
||||
serverPort=12002
|
||||
|
||||
|
||||
[TrainingAreas]
|
||||
TrainingArea/1/id=1
|
||||
TrainingArea/1/name=Alhamra
|
||||
TrainingArea/1/bottomLeftMgrs=39QXG1000000000
|
||||
TrainingArea/1/width=80000
|
||||
TrainingArea/1/height=70000
|
||||
|
||||
TrainingArea/2/id=6
|
||||
TrainingArea/2/name=Bremen
|
||||
TrainingArea/2/bottomLeftMgrs=32UMD0000000000
|
||||
TrainingArea/2/width=12800
|
||||
TrainingArea/2/height=12800
|
||||
|
||||
TrainingArea/3/id=3
|
||||
TrainingArea/3/name=Bremen 2
|
||||
TrainingArea/3/bottomLeftMgrs=32UMD8000080000
|
||||
TrainingArea/3/width=100
|
||||
TrainingArea/3/height=100
|
||||
|
||||
TrainingArea/4/id=4
|
||||
TrainingArea/4/name=Rio
|
||||
TrainingArea/4/bottomLeftMgrs=23KPP5000060000
|
||||
TrainingArea/4/width=100
|
||||
TrainingArea/4/height=100
|
||||
TrainingArea/size=4
|
||||
|
||||
Reference in new issue
Block a user