Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+313
@@ -0,0 +1,313 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* ObjectMap for EffectCluster
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "aes_db.h"
|
||||
#include "object_base.h"
|
||||
#include <CentralEffectSimulation/ces_ftc.h>
|
||||
#include <TrainingAreaBase/tab_ftc.h>
|
||||
#include <Trajectory/trajectory_generator.h>
|
||||
#include <LtsUtilsCore/qpoint3d.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <Utils/firing_timer.h>
|
||||
#include <Utils/polygons.h>
|
||||
#include <Utils/aes_helper.h>
|
||||
|
||||
#include <AreaEffectSimulation/Utils/fire_automaton.h>
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
using DetonationLocationRequest = CentralEffectSimulation::DetonationLocationRequest;
|
||||
using DetonationLocationReply = CentralEffectSimulation::DetonationLocationReply;
|
||||
|
||||
const static int DEFAULT_EFFECT_DURATION = 777777;
|
||||
|
||||
namespace AreaEffectSimulation
|
||||
{
|
||||
|
||||
//inline bool chargeTypeIdIsVulcano(int chargeTypeId) { return (chargeTypeId == 376) || (chargeTypeId == 393) ; }
|
||||
|
||||
class ObjectEffectCluster final
|
||||
: public ObjectBaseTmpl<Database::AesEffectCluster>
|
||||
, protected CentralEffectSimulation::Interface::Ftc::DetonationLocationReplyHandler
|
||||
, protected TrainingAreaBase::Interface::Ftc::AdlerCalculateTrajectoryReplyHandler
|
||||
, protected TrainingAreaBase::Interface::Ftc::SendExFireReadinessReplyHandler
|
||||
, protected TrainingAreaBase::Interface::Ftc::SendExFiredReportReplyHandler
|
||||
, protected TrainingAreaBase::Interface::Ftc::SendExConfirmationReportReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = ObjectBaseTmpl<Database::AesEffectCluster>;
|
||||
|
||||
public:
|
||||
|
||||
constexpr static double s_defaultZ_Value = 100; // default Elevation for GUEZ / Altmark. Hopefully fine for other areas..
|
||||
constexpr static double s_invalid_rotation_angle = -1000;
|
||||
|
||||
explicit ObjectEffectCluster(MainHandler *mainHandler,
|
||||
QObject *parent = nullptr);
|
||||
~ObjectEffectCluster();
|
||||
|
||||
bool isActivationTimeReached() const override
|
||||
{
|
||||
|
||||
if (noTracjectoryRequired())
|
||||
return BaseClass::isActivationTimeReached();
|
||||
|
||||
return BaseClass::isActivationTimeReached();
|
||||
}
|
||||
bool isFiringTimeReached() const override
|
||||
{
|
||||
return m_firingTimeReached;
|
||||
}
|
||||
|
||||
|
||||
qint32 flightDurationMsec() const override { return m_data.flightDuration; }
|
||||
QString name() const { return m_data.name; }
|
||||
bool isOnlyObjectNameModifiable() const override;
|
||||
bool isObjectModifiable() const override; // is at least one parameter in the object modifyable
|
||||
|
||||
Core::FunctionReplyObject createObject(const Database::AesEffectCluster &data, const QVector<Database::AesEffectorData> &effectorDatas);
|
||||
Core::FunctionReplyObject updateObject(const Database::AesEffectCluster &data, const QVector<Database::AesEffectorData> &effectorDatas) ;
|
||||
Core::FunctionReplyObject removeObject() override;
|
||||
|
||||
Core::FunctionReplyObject checkObjectData(const Database::AesEffectCluster &data) const;
|
||||
|
||||
/*!
|
||||
* \brief removeObjectFromDb
|
||||
* \details Removes the object from db, Used if the object is created but there are to much objects (amount border)
|
||||
* \author Niklas Schmidt
|
||||
* \return bool if the deletion was working
|
||||
*/
|
||||
bool removeObjectFromDb();
|
||||
|
||||
Core::FunctionReplyObject resumePause(const EffectClusterPauseResumeRequest &req);
|
||||
Core::FunctionReplyObject targetPositionsModify(const TargetPositionsModifyRequest &req);
|
||||
Core::FunctionReplyObject trajectoryAdlerModify(const TrajectoryAdlerModifyRequest &req);
|
||||
Core::FunctionReplyObject effectClusterModifyActor(const EffectClusterModifyActorRequest &req);
|
||||
|
||||
Core::FunctionReplyObject checkPreConditionsComplete();
|
||||
Core::FunctionReplyObject checkPreConditions();
|
||||
bool initialCalculations(QString *reasonOut = nullptr);
|
||||
void abortPreStartTimer();
|
||||
|
||||
std::vector<Core::GeoPosition> form() const override { return m_aiv.form(); }
|
||||
QPolygonF generateForm() override;
|
||||
AesType aesType() const override { return AesType::AtExplosionArea; }
|
||||
bool isCentral() const override { return m_data.isCentral; }
|
||||
bool isEffectClusterMarkedValid() const { return m_temporaryData.annotationString.empty(); }
|
||||
|
||||
bool intersectWithCircle(double lonRad, double latRad, int radius);
|
||||
void markAsExpired(bool fireLoadedRound);
|
||||
void removeTopics();
|
||||
void setCookie(const rti::core::SampleIdentity &cookie) {m_cookie = cookie;}
|
||||
// Vulcano
|
||||
bool isVulcano() const { return chargeTypeIdIsVulcano(m_data.chargeTypeId); }
|
||||
|
||||
// From HLA, no participantId -> -1;
|
||||
// 0 is default. For EffectClusterDialog, a value of zero is an error!
|
||||
// to skip trajectory, provied -1.
|
||||
bool isOriginatorParticipantIdProvided() const { return m_data.participantId >= 0; } // !! >= !! For EffectClusterDialog, a value of zero is an error!
|
||||
|
||||
void setAirSupportSource(bool isAirSupportSource) { m_isAirSupportSource = isAirSupportSource; }
|
||||
|
||||
bool setEffectors(const QVector<Database::AesEffectorData> &effectors);
|
||||
bool isMhpRotationProvided() const { return m_data.mhpRotationRequest > s_invalid_rotation_angle; }
|
||||
|
||||
bool noTracjectoryRequired() const { return (m_data.externalId > 0) || (m_data.participantId <= 0); }
|
||||
void setAesProperty(QJsonObject property, bool pubish = true);
|
||||
//EffectorControl
|
||||
bool sendFireCommand(const QString &identifier);
|
||||
bool sendFireCommand(int participantId);
|
||||
bool overrideEffectorStates(const AesEffectorState &newState);
|
||||
|
||||
void onSendReadinessToTab();
|
||||
|
||||
protected:
|
||||
void setEffectState(AesEffectState newState) override;
|
||||
void publishAiv();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onPublishData() override;
|
||||
void onDetonationLocationReply(const DetonationLocationReply &reply) override;
|
||||
void onAdlerCalculateTrajectoryReply(const Core::FunctionReplyObject &reply) override;
|
||||
void onSendExFireReadinessReply(const Core::FunctionReplyObject &reply) override;
|
||||
void onSendExFiredReportReply(const Core::FunctionReplyObject &reply) override;
|
||||
void onSendExConfirmationReportReply(const Core::FunctionReplyObject &reply) override;
|
||||
|
||||
void checkNextFire();
|
||||
void checkAutomaton();
|
||||
void onAutomatonFinished();
|
||||
// void checkNextSingleExplosion();
|
||||
|
||||
//slots triggered by effectors
|
||||
void onEffectorNotReadyToFire(int participantId, int aesItemId);
|
||||
void onEffectorReadyToFire(int participantId, int aesItemId);
|
||||
void onEffectorReceivedOrder(int participantId, int aesItemId);
|
||||
void onEffectorReportedFired(int participantId, int aesItemId);
|
||||
void onEffectorFired(int participantId, int aesItemId, const QVector<int> &chargeEffectIds);
|
||||
|
||||
|
||||
protected:
|
||||
bool generateTrajectory(int explosionNumber, bool startDetonationLocationRequest = true, QString *reasonOut = nullptr);
|
||||
bool generateTrajectoryVulcanoSpecific(int explosionNumber, const TrajectoryGeneratorVulcano::Options options, QString *reasonOut = nullptr);
|
||||
double getElevationFor(const QPointF &originGeoRadiant, const QString &context) const;
|
||||
|
||||
void adjustTrajectoryToDetonationLocation(int explosionIndex, const Core::GeoPosition &intersectionLocation, const int buildingId);
|
||||
// void setTrajectoryStartTime(int explosionIndex);
|
||||
|
||||
Core::FunctionReplyObject setupFiringOrigin();
|
||||
bool getFiringUnitOrigin(const int firingParticipantId, LtsUtils::QPoint3D &firingOriginOut, QString *reasonOut = nullptr);
|
||||
bool firingOriginIsValid(const LtsUtils::QPoint3D &firingOrigin, QString *reasonOut) const;
|
||||
LtsUtils::QPoint3D getFiringCannonGeoPosition(int explosionIndex) const;
|
||||
LtsUtils::QPoint3D getFiringCannonUtmPosition(int explosionIndex, int zoneToUse) const;
|
||||
|
||||
void sendCalculateTrajectoryAdlerRequest(const QVector<Database::AesEffectorData> &effectorData);
|
||||
std::vector<Core::GeoPosition> generateGunToTargetForm(const std::vector<Core::RelativePositionRelativeTime> &trajectoryRelativeToOriginator,
|
||||
int participantId);
|
||||
std::vector<Core::GeoPosition> generateGunToTargetForm(QString *reasonOut = nullptr);
|
||||
static std::vector<Core::RelativePositionRelativeTime> reduceSMArtTrajectoryToSingle(const std::vector<Core::RelativePositionRelativeTime> &trajectory); // E01562-294: Falsche Darstellung Flugkurve SMArt
|
||||
void publishTrajectory(int explosionIndex);
|
||||
ParticipantManagement::Participant getParticipantFromInternalName(const QString &name);
|
||||
bool assignEffector(int participantId);
|
||||
bool updateEffector(int participantId, const Database::AesEffectorData &data);
|
||||
|
||||
void freeEffectors();
|
||||
|
||||
//
|
||||
QVector<Database::AesEffectorData> generateMHPs(const QVector<Database::AesEffectorData> &effectorData, const AreaEffectSimulation::AesExplosionGeometry &geometry);
|
||||
// QVector<Database::AesEffectorData> generateTrajectoryInternal(const QVector<Database::AesEffectorData> &effectorData);
|
||||
|
||||
// to TAB Stuff
|
||||
void onSendConfirmationReportToTab(int participantId);
|
||||
//Internal stuff
|
||||
void onChargeEffectChanged(int chargeEffectId);
|
||||
// void publishDetonationAiv();
|
||||
|
||||
private:
|
||||
AreaEffectSimulation::EffectorData fromDatabase(const Database::AesEffectorData &data);
|
||||
void dump(const char *file = nullptr, int lineNo = 0) const;
|
||||
// void startSingleExplosionHandling();
|
||||
// void stopSingleExplosionHandling(AesEffectState newState);
|
||||
// qint64 impactDeltaMSec() const;
|
||||
// int currentExplosionNumber() const;
|
||||
|
||||
DetonationLocationRequest detonationLocationRequest(int explosionIndex) const;
|
||||
|
||||
private:
|
||||
QTimer *m_singleExplosionTriggerTimer{nullptr};
|
||||
QTimer *m_preStartTimer{nullptr};
|
||||
QTimer *m_fireHoldWaitforLateFire{nullptr};
|
||||
QTimer *m_automatonTimer{nullptr};
|
||||
int m_lastSentTriggeredExplosionNumber;
|
||||
int m_chargeCountUntilLastStart;
|
||||
|
||||
EffectCluster m_EffectCluster;
|
||||
AesItemView m_aiv; // AtEffectCluster
|
||||
AesItemView m_aiv2; // AtEffectClusterSingleExplosions - SingleExplosions
|
||||
bool m_aiv2HasChanged{true};
|
||||
|
||||
// Effects
|
||||
Effects m_effects; // replacement for m_aiv2 & TriggeredImpacts
|
||||
|
||||
bool m_aivGunToTargetTrajectoryDirty{false};
|
||||
|
||||
bool m_isAirSupportSource{false};
|
||||
|
||||
FireAutomaton *m_fireAutomaton {nullptr};
|
||||
QMap<int, QString> m_publisedTrajectoriesForDebug;
|
||||
|
||||
struct temporaryData
|
||||
{
|
||||
std::string annotationString;
|
||||
std::vector<Core::GeoPosition2D> mhPoints;
|
||||
double mhpWidth {0.0};
|
||||
double mhpLength {0.0};
|
||||
double mhpRotation {0.0};
|
||||
|
||||
long estimatedMaxFlightDurationMSec{0};
|
||||
double calculatedFiringAngle {0}; // degree
|
||||
double calculatedFiringSpeed {0}; // m/sec
|
||||
double calculatedPeakHeightAbs {0};
|
||||
long calculatedFlightDurationMsec {0};
|
||||
double calculatedMhpRotationNorthDeg {0};
|
||||
|
||||
// center
|
||||
LtsCoordTrans::UtmCoordinate m_firingUnitOriginUtm;
|
||||
LtsUtils::QPoint3D m_firingUnitOriginUtmPoint3D;
|
||||
std::vector<Core::GeoPosition> gunToTargetLine;
|
||||
|
||||
// single
|
||||
std::vector<Core::GeoPosition> singleFiringPositions; // 1..4
|
||||
|
||||
bool isObjectModifiable{true}; // will be set to false via checkNextFire by m_preStartTimer
|
||||
void reset()
|
||||
{
|
||||
annotationString.clear();
|
||||
mhPoints.clear();
|
||||
mhpWidth = 0.0;
|
||||
mhpLength = 0.0;
|
||||
mhpRotation = 0.0;
|
||||
|
||||
estimatedMaxFlightDurationMSec = 0;
|
||||
calculatedFiringAngle = 0;
|
||||
calculatedFiringSpeed = 0;
|
||||
calculatedPeakHeightAbs = 0;
|
||||
calculatedFlightDurationMsec = 0;
|
||||
calculatedMhpRotationNorthDeg = 0;
|
||||
|
||||
gunToTargetLine.clear();
|
||||
m_firingUnitOriginUtm = LtsCoordTrans::UtmCoordinate();
|
||||
m_firingUnitOriginUtmPoint3D = LtsUtils::QPoint3D();
|
||||
|
||||
singleFiringPositions.clear();
|
||||
|
||||
isObjectModifiable = true;
|
||||
}
|
||||
|
||||
Core::GeoPosition getFiringCannonGeoPosition(int explosionIndex) const
|
||||
{
|
||||
if (singleFiringPositions.empty())
|
||||
return Core::GeoPosition(std::nan(""), std::nan(""), std::nan(""));
|
||||
|
||||
const int numberCannons = singleFiringPositions.size();
|
||||
|
||||
int curIdx = explosionIndex % numberCannons;
|
||||
return singleFiringPositions[curIdx];
|
||||
}
|
||||
|
||||
} m_temporaryData;
|
||||
|
||||
|
||||
struct TracjectoryData
|
||||
{
|
||||
int index{-1};
|
||||
int buildingId{-1}; // BuildingId, which has intersection with trajectory
|
||||
std::vector<Core::GeoPosition> trajectoryGeometry;
|
||||
TrajectoryTimeAware trajectoryTimeAware;
|
||||
long flightDurationMSec{0}; // idealValue, intersection with building ist not considered
|
||||
double peakHeightAbs{0};
|
||||
};
|
||||
int m_explosionIndex {0};
|
||||
int m_lookoutChargeEffectStart {0};
|
||||
int m_lookoutChargeEffectEnd {0};
|
||||
int m_lookoutChargeEffectPaused {0};
|
||||
|
||||
rti::core::SampleIdentity m_cookie;
|
||||
bool m_firingTimeReached {false};
|
||||
bool m_firstTimeReady {true};
|
||||
QSet<int> m_readytoFire;
|
||||
QHash<QString, int> m_effectorNameToIdMap;
|
||||
QHash<int, TracjectoryData> m_trajectoryCont; // key: explosionIndex (which is ExplosionNumber-1)
|
||||
QHash<int, Database::AesEffectorData> m_effectorData; // key: explosionIndex (which is ExplosionNumber-1)
|
||||
QMap<int,AesItemView> m_aivGunToTargetTrajectoryMap; // AtEffectClusterGunToTargetLine
|
||||
QMap<int,int> m_firedPerEfector;
|
||||
QSet<int> m_firstFireSend;
|
||||
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user