Major Changes:
- Merged latest Qt5 devel content from dlbo (292 files changed, 7 new dirs)
- Consolidated forward-declarations and include folders
- Removed unneeded modules per Niklas' repo check list
Build System Fixes:
- Fixed CMake VERSION_GREATER syntax in ParticipantManagement/CMakeLists.txt
- Added VLC packages (libvlc-dev, vlc-plugin-base) to docker_build.sh
- Added PostgreSQL dev packages (libpq-dev, postgresql-server-dev-all) to Dockerfile
- Fixed locale warnings (ANSI_X3.4-1968 → C.UTF-8)
- Fixed ArcGIS SDK path warnings when BUILD_ARCGIS=OFF
Code Generation Fixes:
- Fixed IDL enum collisions (PortType→CorePortType/DdsutPortType, PdmEventType)
- Fixed Grantlee template svc_translation.cpp.grantlee:
- Changed {{ idl_enum.name }}_def:: to {{ idl_enum.name }}::
- Fixed .underlying() calls for C++11 scoped enums (enum class)
- Removed generated files from repo (moc_*, *_dtc.h, *_ftc.h)
Validation:
- BUILD_RTI=ON: SUCCESS
- BUILD_RTI=OFF: SUCCESS
- C++17 standard maintained for RTI 7.7 compatibility
- Ubuntu 26.04 Docker environment verified
Remaining Warnings (expected):
- BgViewer, KDChart, KDReports, Poppler-Qt6 not found (optional features)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
207 lines
6.0 KiB
C++
207 lines
6.0 KiB
C++
/**
|
|
* A single Participant
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, SLSE, 2017-01-10
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <QByteArray>
|
|
#include <QObject>
|
|
#include <QQueue>
|
|
#include <QStringBuilder>
|
|
#include <QTimer>
|
|
//#include <QDebug>
|
|
|
|
#include <math.h>
|
|
|
|
#include <TrainingAreaBase/training_area_telegrams.h>
|
|
|
|
#include "logger.h"
|
|
#include "settings.h"
|
|
|
|
inline Q_CONSTEXPR double pi() { return M_PI; }
|
|
inline Q_CONSTEXPR double deg2rad() { return pi() / 180.; }
|
|
|
|
namespace WirelessLocationSystem
|
|
{
|
|
class Acknowledge_rx;
|
|
class SfmMsgTetra_rx;
|
|
class SfmMsgTetra_tx;
|
|
|
|
class WlsParticipant : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
static int calcWlsZone(int wlsAreaId, int wlsBuildingId, int wlsRoomNumber)
|
|
{
|
|
if (wlsAreaId == 0 && wlsBuildingId == 0 && wlsRoomNumber == 0)
|
|
return 3;
|
|
if (wlsAreaId != 0 && wlsBuildingId == 1002 && wlsRoomNumber == 1001)
|
|
return 4;
|
|
if (wlsAreaId != 0 && wlsBuildingId == 0 && wlsRoomNumber == 0)
|
|
return 5;
|
|
|
|
return 6;
|
|
}
|
|
static bool mustSendGpsOn(int wlsZoneOld, int wlsZoneNew)
|
|
{
|
|
// restart of service
|
|
if (wlsZoneOld == -1)
|
|
return wlsZoneNew <= 4;
|
|
// normal operation
|
|
return (wlsZoneOld >= 4 && wlsZoneNew <= 3);
|
|
}
|
|
static bool mustSendGpsOff(int wlsZoneOld, int wlsZoneNew)
|
|
{
|
|
// restart of service
|
|
if (wlsZoneOld == -1)
|
|
return wlsZoneNew >= 5;
|
|
// normal operation
|
|
return (wlsZoneOld <= 4 && wlsZoneNew >= 5);
|
|
}
|
|
|
|
enum class GpsMode : char
|
|
{
|
|
Off,
|
|
On
|
|
};
|
|
enum class DataCommunication : char
|
|
{
|
|
Unknown,
|
|
Off,
|
|
On
|
|
};
|
|
|
|
struct RelativePosition
|
|
{
|
|
double x = 0;
|
|
double y = 0;
|
|
double z = 0;
|
|
int wlsAreaId = 0;
|
|
int wlsBuildingId = 0; // = externalWlsId
|
|
int wlsRoomNumber = 0;
|
|
int playerOrientation = 0;
|
|
int weaponOrientation = 0;
|
|
bool isValid = false;
|
|
|
|
} ;
|
|
|
|
static bool comparePos (const RelativePosition &rhs, const RelativePosition &lhs )
|
|
{
|
|
double dx = ((lhs.x/deg2rad())-(rhs.x/deg2rad()));
|
|
double dy = ((lhs.y/deg2rad())-rhs.y/deg2rad());
|
|
double dz = (lhs.z-rhs.z);
|
|
double dist = dx*dx + dy*dy + dz*dz;
|
|
//qWarning() << "Compare two pos: square distance= " << QString::number(dist,'g',10);
|
|
|
|
bool ret = dist < Settings::wlsSquareDistanceMax()
|
|
&& lhs.wlsAreaId == rhs.wlsAreaId
|
|
&& lhs.wlsBuildingId == rhs.wlsBuildingId
|
|
&& lhs.wlsRoomNumber == rhs.wlsRoomNumber;
|
|
// && lhs.isValid == rhs.isValid;
|
|
//qWarning() << "Return Value= " << ret;
|
|
|
|
return ret;
|
|
}
|
|
protected:
|
|
explicit WlsParticipant(QObject *parent = nullptr);
|
|
public:
|
|
void setPosition(const RelativePosition &newPosition, qint64 tsCurrentPos);
|
|
bool positionIsValid() const { return m_relativePosition.isValid; }
|
|
qint64 positionTimestamp() const { return m_lastValidPosition; }
|
|
RelativePosition position() const { return m_relativePosition; }
|
|
bool isGpsMode() const { return m_gpsMode == WlsParticipant::GpsMode::On; }
|
|
// returns true when timeout is reached
|
|
void checkGpsOnOffTimeoutTimer(qint64 tNow);
|
|
void setLastSeenWlsTelegramTime(qint64 ts);
|
|
qint64 lastSeenWlsTelegramTime() const { return m_lastSeenDataCommunication; }
|
|
|
|
void setWlsZone(int newWlsZone);
|
|
int wlsZone() const { return m_wlsZone; }
|
|
|
|
QByteArray getPlayerIdStr() const;
|
|
|
|
const QByteArray &tagId() const { return m_tagId; }
|
|
void setEquipmentNumber(int newEquipmentNumber);
|
|
int equipmentNumber() const { return m_equipmentNumber; }
|
|
int exerciseId() const { return m_exerciseId; }
|
|
void setExerciseId(int exerciseId) { m_exerciseId = exerciseId; }
|
|
bool isDataCommunicationPossible() const { return m_dataCommunication == DataCommunication::On; }
|
|
DataCommunication dataCommunication() const { return m_dataCommunication; }
|
|
GpsMode gpsMode() const { return m_gpsMode; }
|
|
|
|
bool handleSfmRxData(const SfmMsgTetra_rx *sfmTele);
|
|
bool isSfmRxDataAvailable() const { return m_bSfmPayloadReady; }
|
|
uint8_t nextSfmRxDataFragmentCounter() const { return m_sfmRxPayloadFragmentNumber; }
|
|
const QByteArray &sfmRxData() const { return m_sfmRxPayloadData; }
|
|
|
|
static bool calcChunkCountAndLen(const QByteArray &data, int &chunkCount, int &chunkLen);
|
|
void sendBinarySfmData(const std::vector<unsigned char> &data);
|
|
void handleWlsAck(const Acknowledge_rx *ack);
|
|
|
|
TrainingAreaBase::TetraIcd::WlsParticipantState wlsParticipantState() const;
|
|
|
|
// TODO
|
|
double voltage = 0;
|
|
qint64 lastEquipmentNumberRequest = 0;
|
|
|
|
Q_SIGNALS:
|
|
void positionChanged(WlsParticipant *p);
|
|
void gpsOnOffChanged(WlsParticipant *p);
|
|
void wlsBinarySfmDataComplete(WlsParticipant *p);
|
|
void dataCommunicationStateChanged(WlsParticipant *p);
|
|
void dataForWls(WlsParticipant *p, const SfmMsgTetra_tx &data);
|
|
private Q_SLOTS:
|
|
void checkSendTele();
|
|
void sendNextWlsTelegram(bool bIsResend);
|
|
void onWlsTeleTimeout();
|
|
private:
|
|
uint8_t getNextSendCounter(bool bIsResend);
|
|
bool isRecvCounterCorrect(uint8_t recvCounter);
|
|
private:
|
|
struct WlsPayloadData
|
|
{
|
|
QByteArray payload;
|
|
uint8_t retryCount = 0;
|
|
uint8_t fragmentCount = 0;
|
|
uint8_t fragmentNumber = 0;
|
|
};
|
|
|
|
friend class WlsParticipantHandler;
|
|
QByteArray m_tagId;
|
|
QByteArray m_sfmRxPayloadData;
|
|
QQueue<WlsPayloadData> m_currentFragmentedTeleQueue;
|
|
QQueue<WlsPayloadData> m_wlsQueue;
|
|
|
|
uint8_t m_sfmRxPayloadFragmentNumber = 0;
|
|
bool m_bSfmPayloadReady = false;
|
|
|
|
int m_equipmentNumber = 0;
|
|
int m_exerciseId = 0;
|
|
// zone 1 and 2 will never be met here - far outside wls area
|
|
int m_wlsZone = -1; // 1 .. 6
|
|
|
|
RelativePosition m_relativePosition;
|
|
GpsMode m_gpsMode = GpsMode::On;
|
|
DataCommunication m_dataCommunication = DataCommunication::Unknown;
|
|
qint64 m_lastSeenDataCommunication = 0;
|
|
qint64 m_lastValidPosition = 0;
|
|
qint64 m_lastSeenPosition = 0;
|
|
|
|
QTimer *m_wlsTeleTimeoutTimer = nullptr;
|
|
int m_wlsTeleTimeoutCounter = 0;
|
|
uint8_t m_nextSendCounter = 0;
|
|
uint8_t m_lastRecvCounter = 0;
|
|
|
|
NGL::INGLLogger &m_logger;
|
|
};
|
|
|
|
std::ostream &operator<<(std::ostream &stream, WlsParticipant::GpsMode gm);
|
|
std::ostream &operator<<(std::ostream &stream, WlsParticipant::DataCommunication dc);
|
|
|
|
} // namespace WirelessLocationSystem
|
|
|