new_docker_build.sh gains Group 12 (212 GUI/Data plugins); fixes LtsUtilsGuiDds visibility (LTO-stripped exports), LtsProjectionWorkstation unity name shadow, 6 unity-off dirs (dup file-scope statics, ddsftc INTERFACE sources) and reconfigures BUILD_FILTERMANAGEMENT/BUILD_PLUGINS_SERVICEMONITOR=ON
996 lines
37 KiB
C++
Executable File
996 lines
37 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* GeoPairing
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "GeoPairing.hpp"
|
|
|
|
#include <GeoPairingImpl/GeoPairingImplFactory.hpp>
|
|
#include <GeoPairingImpl/GeoPairingImplDted.hpp>
|
|
#include <GeoPairingImpl/GeoPairingImplBalistic.hpp>
|
|
#include <GeoPairingImpl/GeoPairingDataFireReport.hpp>
|
|
#include <Schusstafel.h>
|
|
#include <QtCore/QScopedPointer>
|
|
#include <FW_Ballistic/AmmunitionTypes.hpp>
|
|
#include <GBL_ConfigSystem/ammuconfig.h>
|
|
#include "../settings.h"
|
|
|
|
static const double ANGULAR_MIL = 6400.0 / 360.0;
|
|
using namespace N_GeoPairingImpl;
|
|
using namespace N_ConfigSystem;
|
|
using namespace CentralEffectSimulation;
|
|
using namespace NGL;
|
|
|
|
GeoPairing::GeoPairing(const std::shared_ptr<N_Ballistic::BallisticService> &ballisticService)
|
|
: //m_airTargets(new ZSSIWI::AirTargetsInt)
|
|
//, m_automaticCannon(new ZSSIWI::AutomaticCannonInt)
|
|
//, m_geoPairingData(new ZSSIWI::GeoPairingDataInt)
|
|
//, m_mortarHowitzer(new ZSSIWI::MortarHowitzerInt)
|
|
//, m_surfaceToAir(new ZSSIWI::SurfaceToAirInt)
|
|
m_ballisticService(ballisticService)
|
|
, m_logger(CesGeoPairing::getLogger("Plugin.GeoPairing.GeoPairing"))
|
|
{
|
|
INFO_LOG(m_logger) << "konfigPath = " << ballisticService->getConfigPath() ;
|
|
|
|
const QString s_configPath = ballisticService->getConfigPath();
|
|
INFO_LOG(m_logger) << "GeoPairing Config location : " << s_configPath ;
|
|
|
|
GeoPairingImpl *l_impl = new GeoPairingImplDted;
|
|
INFO_LOG(m_logger) << "--> Installing GeoPairingImplDted..." ;
|
|
GeoPairingImplFactory::setImpl(l_impl);
|
|
readAmmunitionIni();
|
|
|
|
// initialize the GeoPairing implementation
|
|
if (!GeoPairingImplFactory::initialize(s_configPath))
|
|
{
|
|
ERROR_LOG(m_logger) << "Couldn't initialize GeoPairingImplFactory with GeoPairingImplDted!" ;
|
|
|
|
l_impl = new GeoPairingImplBalistic();
|
|
INFO_LOG(m_logger) << "--> Installing GeoPairingImplBalistic...";
|
|
GeoPairingImplFactory::setImpl(l_impl);
|
|
if (!GeoPairingImplFactory::initialize(s_configPath))
|
|
{
|
|
ERROR_LOG(m_logger) << "Couldn't initialize GeoPairingImplFactory with GeoPairingImplBalistic!" ;
|
|
abort();
|
|
}
|
|
else
|
|
INFO_LOG(m_logger) << "GeoPairingImplBalistic correctly initialized" ;
|
|
}
|
|
else
|
|
INFO_LOG(m_logger) << "GeoPairingImplDted correctly initialized" ;
|
|
|
|
#ifdef _PSEUDO_TARGETS_
|
|
// initial lat long position
|
|
// N_Math::GeoCoord l_UtmPos;
|
|
// l_UtmPos.setLlPositionDegree(22.5, 40.5, 59);
|
|
//
|
|
// const SInt32 l_NbrOfObjects = 4;
|
|
//
|
|
// std::cout << "Creating Pseudotargets : " << l_NbrOfObjects << std::endl;
|
|
//
|
|
// N_Types::Coord3 l_Direction(0, 1000, 0);
|
|
//
|
|
// for (int i=0;i<l_NbrOfObjects/2; i++)
|
|
// {
|
|
// N_Types::Coord3 l_PosInitial;
|
|
// l_PosInitial.m_X = l_UtmPos.m_UtmEast;
|
|
// l_PosInitial.m_Y = l_UtmPos.m_UtmNorth;
|
|
// l_PosInitial.m_Z = l_UtmPos.m_UtmHeight;
|
|
//
|
|
// l_PosInitial += l_Direction;
|
|
//
|
|
// N_Math::GeoCoord l_Utm1;
|
|
// l_Utm1.setTotalUtmPosition(l_PosInitial.m_X, l_PosInitial.m_Y, l_PosInitial.m_Z, l_UtmPos.m_UtmZone, l_UtmPos.m_UtmZoneChar);
|
|
//
|
|
// ZSSIWI::AirTargetsInt::AirTarget l_Target;
|
|
// l_Target.playerId = i+1;
|
|
// l_Target.positionLat = l_Utm1.m_LlLat;
|
|
// l_Target.positionLon = l_Utm1.m_LlLong;
|
|
// l_Target.positionAlt = l_Utm1.m_LlHeight;
|
|
// l_Target.positionTime = 1;
|
|
// l_Target.state = 0;
|
|
//
|
|
// m_airTargets->getAirTargetsList().append(l_Target);
|
|
//
|
|
// l_Direction = l_Direction.rotateZ(-M_PI / (l_NbrOfObjects/2));
|
|
// }
|
|
|
|
ZSSIWI::AirTargetsInt::AirTarget l_Target;
|
|
l_Target.playerId = 7701;
|
|
l_Target.positionLat = 53.0412;
|
|
l_Target.positionLon = 8.87471;
|
|
l_Target.positionAlt = 120;
|
|
l_Target.positionTime = 1;
|
|
l_Target.state = 0;
|
|
|
|
m_airTargets->getAirTargetsList().append(l_Target);
|
|
|
|
#endif
|
|
|
|
INFO_LOG(m_logger) << "Initialization finished";
|
|
}
|
|
|
|
void GeoPairing::calculateAirFire(const QByteArray &transparentData,
|
|
const QHash<int, CentralEffectSimulation::HandlerParticipant::CesParticipantData> &aircrafts)
|
|
{
|
|
INFO_LOG(m_logger) << "calculateAirFire (IGLA)..." ;
|
|
|
|
GeoPairingDataFireReport l_Report;
|
|
if (!l_Report.parse(transparentData))
|
|
{
|
|
WARNING_LOG(m_logger) << "Error: Couldn't parse Fire Report" ;
|
|
return;
|
|
}
|
|
|
|
if (aircrafts.size() == 0)
|
|
{
|
|
INFO_LOG(m_logger) << "No Aircraft available";
|
|
return;
|
|
}
|
|
|
|
QScopedPointer<GeoPairingImplAirTargetUpdater> l_Updater(GeoPairingImplFactory::createAirTargetUpdater());
|
|
QHashIterator<int, HandlerParticipant::CesParticipantData> i(aircrafts);
|
|
while (i.hasNext())
|
|
{
|
|
i.next();
|
|
SInt32 vulnerabilityState = i.value().vulnerabilityState;
|
|
Float64 lat = i.value().pos().lat() * 180 / M_PI;
|
|
Float64 lon = i.value().pos().lon() * 180 / M_PI;
|
|
DEBUG_LOG(m_logger) << "GeoPairing::calculateAirFire"
|
|
<< "\nl_Updater->update : " << i.key()
|
|
<< "\n: participantId=" << i.value().participantId()
|
|
<< "\n participantTypeId= " << i.value().participantTypeId()
|
|
<< "\n pos lat=" << lat
|
|
<< "\n lon=" << lon
|
|
<< "\n alt=" << i.value().pos().z()
|
|
<< "\n posTime=" << i.value().sampleTime()
|
|
<< "\n state=" << i.value().vulnerabilityState
|
|
<< "\n state (SInt32)=" << vulnerabilityState;
|
|
l_Updater->update(i.value().participantId(),
|
|
lat,
|
|
lon,
|
|
i.value().pos().z(),
|
|
i.value().sampleTime() / 1000, //s
|
|
vulnerabilityState);
|
|
}
|
|
|
|
// Prepare SensorData to take into account terrain altitude and geomagnetic differences
|
|
GeoPairingImplSensorData l_SensorData;
|
|
l_SensorData.WeaponPositionLat = m_PositionLat;
|
|
l_SensorData.WeaponPositionLong = m_PositionLon;
|
|
l_SensorData.FireTime = m_Time;
|
|
l_SensorData.WeaponElevation = 0;
|
|
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire (createSensorData)"
|
|
<< "\nl_SensorData.WeaponPositionLat = " << l_SensorData.WeaponPositionLat
|
|
<< "\nl_SensorData.WeaponPositionLong = " << l_SensorData.WeaponPositionLong
|
|
<< "\nl_SensorData.WeaponAzimuth=" << l_SensorData.WeaponAzimuth
|
|
<< "\nl_SensorData.WeaponElevation=" << l_SensorData.WeaponElevation
|
|
<< "\nl_SensorData.FireTime = " << l_SensorData.FireTime
|
|
;
|
|
SInt32 l_DeviceID = GeoPairingImplFactory::createSensorData(&l_SensorData, transparentData);
|
|
|
|
INFO_LOG(m_logger) << "createSensorData -> SensorData.WeaponAzimuth=" << l_SensorData.WeaponAzimuth
|
|
<< "\nl_SensorData.WeaponElevation=" << l_SensorData.WeaponElevation;
|
|
if (l_DeviceID == -1)
|
|
{
|
|
ERROR_LOG(m_logger) << "Couldn't create SensorData" ;
|
|
return;
|
|
}
|
|
|
|
m_PositionHeight = l_SensorData.WeaponPositionHeight;
|
|
|
|
Float64 l_Azimuth = -l_SensorData.WeaponAzimuth * 180 / M_PI; // negate to convert ccw back to cw
|
|
Float64 l_Elevation = l_SensorData.WeaponElevation * 180 / M_PI;
|
|
|
|
|
|
if (l_Report.m_DeviceID == PAN_GP_REQUEST_IGLA)
|
|
{
|
|
INFO_LOG(m_logger) << " -> IGLA : Request Target Detection " ;
|
|
|
|
QScopedPointer<GeoPairingImplAirTargetCache> l_Cache(GeoPairingImplFactory::createAirTargetCache(m_equipmentNumber));
|
|
|
|
int l_TargetPlayerId = 0;
|
|
uint64_t l_ImpactTime = 0;
|
|
|
|
INFO_LOG(m_logger) << "-> IGLA : Request Target Detection -> searchAirTarget (vor dem aufruf)"
|
|
<< "\nl_Elevation = " << l_Elevation
|
|
<< "\nl_Azimuth = " << l_Azimuth
|
|
;
|
|
|
|
|
|
bool l_TargetFound = searchAirTarget(l_Elevation, l_Azimuth, l_TargetPlayerId, l_ImpactTime);
|
|
|
|
INFO_LOG(m_logger) << "-> IGLA : Request Target Detection -> searchAirTarget (nach dem aufruf)"
|
|
<< "\nl_TargetFound = " << l_TargetFound
|
|
<< "\nl_TargetPlayerId = " << l_TargetPlayerId
|
|
<< "\nl_ImpactTime = " << l_ImpactTime
|
|
;
|
|
|
|
bool l_CachedTrackingState = l_Cache->getLatestTrackState(l_TargetPlayerId);
|
|
UInt32 l_CachedTrackingTime = l_Cache->getLatestTrackTime(l_TargetPlayerId);
|
|
|
|
INFO_LOG(m_logger) << "-> IGLA : Retrieved Target Detection Results from Cache"
|
|
<< "\nl_CachedTrackingState = " << l_CachedTrackingState
|
|
<< "\nl_CachedTrackingTime = " << l_CachedTrackingTime
|
|
;
|
|
|
|
SInt32 l_DeltaTime = m_Time - l_CachedTrackingTime;
|
|
bool l_TimeoutPassed = l_DeltaTime > static_cast<SInt32>(l_Cache->getCacheTimeout());
|
|
|
|
|
|
if (l_TargetFound != l_CachedTrackingState || l_TimeoutPassed)
|
|
{
|
|
// prepare response for player
|
|
m_reportTarget.playerId = i.value().participantId();
|
|
m_reportTarget.sendData.clear();
|
|
m_reportTarget.sendData.append(0xEB); // Report Target Detection
|
|
|
|
UInt8 l_DetectionResult = ((UInt8) l_TargetFound) & 0x03;
|
|
l_DetectionResult += (l_Report.m_IGLARequestNbr << 2);
|
|
m_reportTarget.sendData.append(l_DetectionResult);
|
|
// add 3 reserved bytes
|
|
m_reportTarget.sendData.append((char)0x00);
|
|
m_reportTarget.sendData.append((char)0x00);
|
|
m_reportTarget.sendData.append((char)0x00);
|
|
m_reportTarget.send = true;
|
|
|
|
// Richtung Gefechtsfeld
|
|
INFO_LOG(m_logger) << "<-- EC : Report Target Detection " ;
|
|
INFO_LOG(m_logger) << "Target Found : " << l_TargetFound ;
|
|
|
|
//m_geoPairingData->sendData(m_PlayerId, l_SendData.data(), l_SendData.size() );
|
|
|
|
l_Cache->storeLatestTrackState(l_TargetPlayerId, m_Time, l_TargetFound);
|
|
}
|
|
}
|
|
INFO_LOG(m_logger) << "\n\nPAN_GP_REPORT_IGLA m_DeviceID=" << l_Report.m_DeviceID
|
|
<< " PAN_GP_REPORT_IGLA=" << PAN_GP_REPORT_IGLA;
|
|
if (l_Report.m_DeviceID == PAN_GP_REPORT_IGLA)
|
|
{
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire " ;
|
|
|
|
int l_TargetPlayerId = 0;
|
|
UInt64 l_ImpactTime = 0;
|
|
|
|
QScopedPointer<GeoPairingImplAirTargetTracker> l_Tracker(GeoPairingImplFactory::createAirTargetTracker());
|
|
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire (l_Tracker->setPosition)"
|
|
<< "\nm_PositionLat = " << m_PositionLat
|
|
<< "\nm_PositionLon = " << m_PositionLon
|
|
<< "\nm_PositionHeight = " << m_PositionHeight
|
|
;
|
|
|
|
l_Tracker->setPosition(m_PositionLat, m_PositionLon, m_PositionHeight);
|
|
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire (setTime)"
|
|
<< "\nm_Time = " << m_Time ;
|
|
|
|
l_Tracker->setTime(m_Time);
|
|
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire (vor l_Tracker->track)"
|
|
<< "\nl_Azimuth = " << l_Azimuth
|
|
<< "\nl_Elevation = " << l_Elevation
|
|
<< "\nl_TargetPlayerId = " << l_TargetPlayerId
|
|
<< "\nl_ImpactTime = " << l_ImpactTime
|
|
;
|
|
|
|
bool l_TargetFound = l_Tracker->track(l_Azimuth, l_Elevation, l_TargetPlayerId, l_ImpactTime);
|
|
|
|
INFO_LOG(m_logger) << "--> IGLA : Report Target Fire (nach l_Tracker->track)"
|
|
<< "\nl_TargetFound = " << l_TargetFound ;
|
|
|
|
if (l_TargetFound)
|
|
{
|
|
int l_AmmunitionType = N_Ballistic::IGLA;
|
|
m_fireToAircraft.participantIdTarget = l_TargetPlayerId;
|
|
m_fireToAircraft.impactTime = l_ImpactTime;
|
|
m_fireToAircraft.ammunitionTypeId = l_AmmunitionType;
|
|
m_fireToAircraft.equipmentNumberGunner = m_equipmentNumber;
|
|
|
|
if (l_Tracker->hitCheck(l_TargetPlayerId, l_Report.m_IGLAModeAuto, l_Report.m_IGLAChangeOverPressed))
|
|
{
|
|
//m_surfaceToAir->fire(l_TargetPlayerId, l_ImpactTime, l_AmmunitionType, m_PlayerId, true);
|
|
m_fireToAircraft.hit = true;
|
|
INFO_LOG(m_logger) << "Air Target " << l_TargetPlayerId << " in reach and hit" ;
|
|
}
|
|
else
|
|
{
|
|
//m_surfaceToAir->fire(l_TargetPlayerId, l_ImpactTime, l_AmmunitionType, m_PlayerId, false);
|
|
m_fireToAircraft.hit = false;
|
|
INFO_LOG(m_logger) << "Air Target " << l_TargetPlayerId << " in reach, but not hit" ;
|
|
}
|
|
}
|
|
else
|
|
INFO_LOG(m_logger) << "No Air Target withing reach..." ;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void GeoPairing::calculateAreaFire(const QByteArray &transparentData,
|
|
const std::shared_ptr<N_Ballistic::BallisticService> &ballisticService)
|
|
{
|
|
INFO_LOG(m_logger) << "calculateAreaFire (MK19)..." ;
|
|
|
|
// Prepare SensorData for Implementation
|
|
GeoPairingImplSensorData l_SensorData;
|
|
l_SensorData.WeaponPositionLat = m_PositionLat;
|
|
l_SensorData.WeaponPositionLong = m_PositionLon;
|
|
l_SensorData.FireTime = m_Time;
|
|
|
|
GeoPairingDataFireReport l_Report;
|
|
if (!l_Report.parse(transparentData))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error: Couldn't parse Fire Report" ;
|
|
return;
|
|
}
|
|
SInt32 l_DeviceID = GeoPairingImplFactory::createSensorData(&l_SensorData, transparentData);
|
|
if (l_DeviceID == -1)
|
|
{
|
|
ERROR_LOG(m_logger) << "Couldn't create SensorData" ;
|
|
return;
|
|
}
|
|
|
|
QScopedPointer<GeoPairingImplFiredBullet> l_FiredBullet(GeoPairingImplFactory::createFiredBullet(l_SensorData));
|
|
if (l_FiredBullet == nullptr)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error: Couldn't create FiredBullet object" ;
|
|
return;
|
|
}
|
|
|
|
double l_FieldWidth = 0;
|
|
double l_FieldLength = 0;
|
|
double l_Duration = 0;
|
|
double l_Heading = 0;
|
|
UInt8 nbrRounds = 0;
|
|
|
|
nbrRounds = l_Report.m_MK19NbrRounds;
|
|
l_FiredBullet->calculateSalve(ballisticService, nbrRounds, l_FieldWidth, l_FieldLength, l_Duration, l_Heading);
|
|
GeoPairingImplImpactData *l_ImpactData = l_FiredBullet->getImpactData();
|
|
if (l_ImpactData == nullptr)
|
|
{
|
|
ERROR_LOG(m_logger) << "Error: Couldn't create ImpactData object" ;
|
|
return;
|
|
}
|
|
|
|
N_Ballistic::ammunitionTypeIndirectFire l_AmmunitionType;
|
|
N_Ballistic::ammunitionTypeOSAG l_AmmunitionTypeOSAG;
|
|
switch (l_SensorData.AmmunitionType)
|
|
{
|
|
case MK19Type_m385:
|
|
l_AmmunitionType = N_Ballistic::MK19_M385;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::MK19_M385_OSAG;
|
|
INFO_LOG(m_logger) << "Wirkfeld Ammunition MK19_M385" ;
|
|
break;
|
|
case MK19Type_m430:
|
|
l_AmmunitionType = N_Ballistic::MK19_M430;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::MK19_M430_OSAG;
|
|
INFO_LOG(m_logger) << "Wirkfeld Ammunition MK19_M430" ;
|
|
break;
|
|
default:
|
|
ERROR_LOG(m_logger) << "Default Ammunition. Must not be called : " << l_SensorData.AmmunitionType ;
|
|
return;
|
|
}
|
|
|
|
// Richtung Zentrale
|
|
|
|
// * Create an area fire to CTAS
|
|
// * @param playerId Id of the player
|
|
// * @param impactTime Time of impact
|
|
// * @param fireDuration Duration [sec] of the fire
|
|
// * @param impactAreaLat Latitude - Centercoordinate of impact-area
|
|
// * @param impactAreaLon Longitude - Centercoordinate of impact-area
|
|
// * @param impactAreaDimensionWidth Width [m] of impact-area
|
|
// * Width: At right angle to the direction gunner position to impact position
|
|
// * @param impactAreaDimensionDepth Depth [m] of impact-area.
|
|
// * Depth: Direction of gunner position to impact position
|
|
// * @param direction Direction from gunner position to impact position.
|
|
// * Angle of rotation [0.01 degree] counterclockwise against direction east.
|
|
// * @param numberOfImpacts Number of impacts
|
|
// * @param ammunitionType Type of the ammunition
|
|
/*
|
|
m_automaticCannon->areaFire(m_PlayerId,
|
|
l_ImpactData->ImpactTime,
|
|
l_Duration,
|
|
l_ImpactData->ImpactPositionLat,
|
|
l_ImpactData->ImpactPositionLong,
|
|
l_FieldWidth,
|
|
l_FieldLength,
|
|
l_Heading,
|
|
nbrRounds,
|
|
l_AmmunitionType,
|
|
l_AmmunitionTypeOSAG);*/
|
|
m_areaFireToCtas.playerId = m_equipmentNumber;
|
|
m_areaFireToCtas.impactTime = l_ImpactData->ImpactTime;
|
|
m_areaFireToCtas.duration = l_Duration;
|
|
m_areaFireToCtas.impactPositionLat = l_ImpactData->ImpactPositionLat;
|
|
m_areaFireToCtas.impactPositionLong = l_ImpactData->ImpactPositionLong;
|
|
m_areaFireToCtas.fieldWidth = l_FieldWidth;
|
|
m_areaFireToCtas.fieldLength = l_FieldLength;
|
|
m_areaFireToCtas.heading = l_Heading;
|
|
m_areaFireToCtas.nbrRounds = nbrRounds;
|
|
m_areaFireToCtas.ammunitionType = l_AmmunitionType;
|
|
m_areaFireToCtas.ammunitionTypeOSAG = l_AmmunitionTypeOSAG;
|
|
m_areaFireToCtas.hit = true;
|
|
|
|
INFO_LOG(m_logger) << "calculateAreaFire m_equipmentNumber=" << m_equipmentNumber
|
|
<< " ImpactTime=" << l_ImpactData->ImpactTime
|
|
<< " ImpactPositionLat=" << l_ImpactData->ImpactPositionLat
|
|
<< " ImpactPositionLong=" << l_ImpactData->ImpactPositionLong
|
|
<< " l_AmmunitionType=" << l_AmmunitionType
|
|
<< " l_AmmunitionTypeOSAG=" << l_AmmunitionTypeOSAG
|
|
<< " l_DeviceID=" << l_DeviceID;
|
|
m_DeviceID = l_DeviceID;
|
|
|
|
}
|
|
|
|
|
|
void GeoPairing::calculateSingleFire(const QByteArray &transparentData, const std::shared_ptr<N_Ballistic::BallisticService> &ballisticService)
|
|
{
|
|
INFO_LOG(m_logger) << "calculateSingleFire ..." ;
|
|
|
|
ElevationError error_elevation = ElevationError::NoError;
|
|
int error_charge = 0;
|
|
int error_mun = 0;
|
|
bool usage_ok = true;
|
|
|
|
// Prepare SensorData for Implementation
|
|
GeoPairingImplSensorData l_SensorData;
|
|
l_SensorData.WeaponPositionLat = m_PositionLat;
|
|
l_SensorData.WeaponPositionLong = m_PositionLon;
|
|
l_SensorData.FireTime = m_Time;
|
|
l_SensorData.IgnitionType = -1; // Unknown
|
|
|
|
SInt32 l_DeviceID = GeoPairingImplFactory::createSensorData(&l_SensorData, transparentData, error_mun);
|
|
INFO_LOG(m_logger) << "l_DeviceID=" << l_DeviceID;
|
|
if (l_DeviceID == -1)
|
|
{
|
|
ERROR_LOG(m_logger) << "Couldn't create SensorData" ;
|
|
return;
|
|
}
|
|
|
|
QScopedPointer<GeoPairingImplFiredBullet> l_FiredBullet(GeoPairingImplFactory::createFiredBullet(l_SensorData));
|
|
if ((l_DeviceID == PAN_GP_REPORT_G5_G6) || (l_DeviceID == PAN_GP_REPORT_M109) || (l_DeviceID == PAN_GP_REPORT_MORTAR))
|
|
{
|
|
// Fuer die Waffe G5/G6 wird die Entfernung aus einer Schusstafel-Datei ausgelesen
|
|
// und nicht ueber einen ballistischen Algorithmus berechnet
|
|
Schusstafel::TAFEL_NAMEN_ET tafelName = Schusstafel::ST_AUFSATZ;
|
|
//std::string pfad = "./";
|
|
QString pfadQstr = CesGeoPairing::Settings::cesGeopairingIniPath() + QStringLiteral("/");
|
|
std::string pfad = pfadQstr.toStdString();
|
|
std::string munart;
|
|
INFO_LOG(m_logger) << "Vor switch AmmunitionType=" << l_SensorData.AmmunitionType
|
|
<< " ChargeType=" << l_SensorData.ChargeType;
|
|
|
|
// Ammunition HE-M1
|
|
switch (l_SensorData.AmmunitionType)
|
|
{
|
|
case HE_M1A2:
|
|
{
|
|
INFO_LOG(m_logger) << "HE_M1A2";
|
|
switch (l_SensorData.ChargeType)
|
|
{
|
|
case 0:
|
|
munart = "HE-M1-M64Base-TableE";
|
|
break;
|
|
case 1:
|
|
munart = "HE-M1-M64Incr3-TableE";
|
|
break;
|
|
case 2:
|
|
munart = "HE-M1-M64Incr4-TableE";
|
|
break;
|
|
case 3:
|
|
munart = "HE-M1-M64Incr5-TableE";
|
|
break;
|
|
case 4:
|
|
munart = "HE-M1-M64Incr5BaseBleed-TableE";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case M60mm_m385:
|
|
case M60mm_m430:
|
|
{
|
|
INFO_LOG(m_logger) << "M60mm_m385 M60mm_m430";
|
|
switch (l_SensorData.IgnitionType) // ChargeType = Ladung...
|
|
{
|
|
// Todo: Umbenennen und ggf. Zuordnung korrigieren
|
|
case 0:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-Lad1";
|
|
munart = "Moerser-60mm-Lad1";
|
|
break;
|
|
case 1:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-Lad2";
|
|
munart = "Moerser-60mm-Lad2";
|
|
break;
|
|
case 2:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-Lad3";
|
|
munart = "Moerser-60mm-Lad3";
|
|
break;
|
|
case 3:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-Lad4";
|
|
munart = "Moerser-60mm-Lad4";
|
|
break;
|
|
case 4:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-Lad5";
|
|
munart = "Moerser-60mm-Lad5";
|
|
break;
|
|
case 5:
|
|
INFO_LOG(m_logger) << "Moerser-60mm-La6";
|
|
munart = "Moerser-60mm-Lad6";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case VLAP_M9703:
|
|
{
|
|
INFO_LOG(m_logger) << "VLAP_M9703";
|
|
// Sonderfall Ammunition VLAP-M64. Da hier nur 5 x M64 Incr als Ladung vorhanden ist.
|
|
// Sollten wir eine andere Ladung aus dem Gefechtsfeld bekommen, dann Munition HE M1A2 benutzen
|
|
switch (l_SensorData.ChargeType)
|
|
{
|
|
case 0:
|
|
munart = "HE-M1-M64Base-TableE";
|
|
break;
|
|
case 1:
|
|
munart = "HE-M1-M64Incr3-TableE";
|
|
break;
|
|
case 2:
|
|
munart = "HE-M1-M64Incr4-TableE";
|
|
break;
|
|
case 3:
|
|
munart = "VLAP-M64Incr5-TableE";
|
|
break;
|
|
case 4:
|
|
munart = "VLAP-M64Incr5-TableE";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case SMK_BE_M2:
|
|
{
|
|
switch (l_SensorData.ChargeType)
|
|
{
|
|
case 0:
|
|
munart = "SMK-BE-RED-RED-PHOSPH-M1-M64Base-TableE";
|
|
break;
|
|
case 1:
|
|
munart = "SMK-BE-RED-RED-PHOSPH-M1-M64Incr3-TableE";
|
|
break;
|
|
case 2:
|
|
munart = "SMK-BE-RED-RED-PHOSPH-M1-M64Incr4-TableE";
|
|
break;
|
|
case 3:
|
|
munart = "SMK-BE-RED-RED-PHOSPH-M1-M64Incr5-TableE";
|
|
break;
|
|
case 4:
|
|
munart = "SMK-BE-RED-RED-PHOSPH-M1-M64Incr5BaseBleed-TableE";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case CLUSTER_HEHC_M9609:
|
|
{
|
|
switch (l_SensorData.ChargeType)
|
|
{
|
|
case 0:
|
|
munart = "Cluster-M64Base-TableE";
|
|
break;
|
|
case 1:
|
|
munart = "Cluster-M64BaseIncr3-TableE";
|
|
break;
|
|
case 2:
|
|
munart = "Cluster-M64BaseIncr4-TableE";
|
|
break;
|
|
case 3:
|
|
munart = "Cluster-M64BaseIncr5-TableE";
|
|
break;
|
|
case 4:
|
|
munart = "Cluster-M64BaseIncr5BaseBleed-TableE";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (munart.empty())
|
|
{
|
|
WARNING_LOG(m_logger) << "No valid charge type " << l_SensorData.ChargeType <<
|
|
" for ammunition " << l_SensorData.AmmunitionType <<
|
|
" (internal ids!)" ;
|
|
munart = "HE-M1-M64Base-TableE";
|
|
error_mun = 1; //Keine richtige Muntion/Charge Kombination
|
|
}
|
|
|
|
std::string suffix = ".sus";
|
|
DEBUG_LOG(m_logger) << "schusstafel pfad=" << pfad
|
|
<< " munart=" << munart
|
|
<< " suffix=" << suffix;
|
|
Schusstafel schusstafel(pfad, munart, suffix);
|
|
|
|
float entfernung1 = 0.0;
|
|
float aufsatz1 = 0.0;
|
|
float flugzeit1 = 0.0;
|
|
float drift1 = 0.0;
|
|
|
|
float entfernung2 = 0.0;
|
|
float aufsatz2 = 0.0;
|
|
float flugzeit2 = 0.0;
|
|
float drift2 = 0.0;
|
|
|
|
float elevation = l_SensorData.WeaponElevation.getZeroTo360();
|
|
float arg_wert = elevation * ANGULAR_MIL * MILRAD; // Funktion will den Wert in milrad
|
|
float zielhoehenwinkel = 0.0;
|
|
double evalMil = elevation * ANGULAR_MIL; //angular mil
|
|
|
|
//Wir holen uns nur bei der Haubitze die Daten
|
|
const GeoPCharge mun = m_geoPMunMap.value(l_SensorData.AmmunitionType + 1).value(l_SensorData.ChargeType);
|
|
|
|
//Der type l_DeviceID gibt an, ob es sich um eine G5/G6 oder M109 handelt.
|
|
usage_ok = mun.checkArty(l_DeviceID, evalMil, error_elevation, error_charge);
|
|
|
|
double elevationGrad = l_SensorData.WeaponElevation.getDegree();
|
|
if (elevationGrad <= 0.0)
|
|
{
|
|
INFO_LOG(m_logger) << "Elevation ist <= 0 Grad. Entfernung wird auf 50% des ersten Wertes aus der Schusstafel festgesetzt" ;
|
|
// Dazu aus der minimal moeglichen Elevation die Entfernung bestimmen und halbieren
|
|
float minEval = mun.minEleval * MILRAD;
|
|
DEBUG_LOG(m_logger) << "schusstafel tafelName=" << tafelName
|
|
<< " minEval=" << minEval
|
|
<< "zielhoehenwinkel=" << zielhoehenwinkel;
|
|
|
|
schusstafel.ST_artillerie(tafelName, minEval, zielhoehenwinkel, &entfernung1, &aufsatz1, &flugzeit1, &drift1,
|
|
&entfernung2, &aufsatz2, &flugzeit2, &drift2);
|
|
entfernung1 = entfernung1 / 2;
|
|
flugzeit1 = flugzeit1 / 2;
|
|
}
|
|
else if (elevationGrad >= 90.0)
|
|
{
|
|
INFO_LOG(m_logger) << "Elevation ist >= 90 Grad. Entfernung wird auf den letzten Wert aus der Schusstafel festgesetzt" ;
|
|
// Dazu aus der maximal moeglichen Elevation die Entfernung bestimmen
|
|
double maxEval = mun.maxEleval * MILRAD;
|
|
DEBUG_LOG(m_logger) << "schusstafel tafelName=" << tafelName
|
|
<< " maxEval=" << maxEval
|
|
<< "zielhoehenwinkel=" << zielhoehenwinkel;
|
|
schusstafel.ST_artillerie(tafelName, maxEval, zielhoehenwinkel, &entfernung1, &aufsatz1, &flugzeit1, &drift1,
|
|
&entfernung2, &aufsatz2, &flugzeit2, &drift2);
|
|
}
|
|
else
|
|
{
|
|
DEBUG_LOG(m_logger) << "schusstafel tafelName=" << tafelName
|
|
<< " arg_wert=" << arg_wert
|
|
<< "zielhoehenwinkel=" << zielhoehenwinkel;
|
|
schusstafel.ST_artillerie(tafelName, arg_wert, zielhoehenwinkel, &entfernung1, &aufsatz1, &flugzeit1, &drift1,
|
|
&entfernung2, &aufsatz2, &flugzeit2, &drift2);
|
|
}
|
|
|
|
INFO_LOG(m_logger) << "Schusstafel " << munart << ".sus: "
|
|
<< "Entfernung [m]: " << entfernung1
|
|
<< " Elevation [mil]: " << evalMil
|
|
<< " Drift [grad]: " << drift1 * 180 / M_PI
|
|
<< " Drift [mil]: " << drift1 * 180 / M_PI *ANGULAR_MIL
|
|
<< " Flugzeit [s]: " << flugzeit1 ;
|
|
|
|
l_FiredBullet->calculateG5G6(entfernung1, drift1, flugzeit1);
|
|
}
|
|
else
|
|
{
|
|
// != G5G6 && != M109
|
|
INFO_LOG(m_logger) << "calculate(ballisticService)";
|
|
l_FiredBullet->calculate(ballisticService);
|
|
}
|
|
|
|
GeoPairingImplImpactData *l_ImpactData = l_FiredBullet->getImpactData();
|
|
if (!l_ImpactData)
|
|
{
|
|
ERROR_LOG(m_logger) << "No impact Data available";
|
|
return;
|
|
}
|
|
|
|
N_Ballistic::ammunitionTypeIndirectFire l_AmmunitionType = N_Ballistic::UNKNOWN;
|
|
N_Ballistic::ammunitionTypeOSAG l_AmmunitionTypeOSAG = N_Ballistic::UNKNOWN_OSAG;
|
|
if ((l_DeviceID != PAN_GP_REPORT_G5_G6) && (l_DeviceID != PAN_GP_REPORT_M109))
|
|
{
|
|
l_AmmunitionTypeOSAG = N_Ballistic::UNKNOWN_OSAG;
|
|
switch (l_SensorData.AmmunitionType)
|
|
{
|
|
case MortarType1:
|
|
default:
|
|
l_AmmunitionType = N_Ballistic::MOERSER;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::MORTAR_PRC_OSAG;
|
|
break;
|
|
case MortarType2:
|
|
l_AmmunitionType = N_Ballistic::NEBEL;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::MORTAR_PRX_OSAG;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Zuordnung Geopairing - Code -> sys_db.munitionsarten (OSAG-Code)
|
|
// 4 -> 30 oder 31
|
|
// 5 -> 33 oder 32
|
|
// 6 -> 34
|
|
// 7 -> 35
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_HE_AZ;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::UNKNOWN_OSAG;
|
|
switch (l_SensorData.AmmunitionType)
|
|
{
|
|
case HE_M1A2:
|
|
switch (l_SensorData.IgnitionTypeG5G6)
|
|
{
|
|
case IgnitionTypePercussion:
|
|
default:
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_HE_AZ;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::M1A2_PRC_OSAG;
|
|
break;
|
|
case IgnitionTypeProximity:
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_HE_DZ;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::M1A2_PRX_OSAG;
|
|
break;
|
|
}
|
|
break;
|
|
case VLAP_M9703:
|
|
switch (l_SensorData.IgnitionTypeG5G6)
|
|
{
|
|
case IgnitionTypePercussion:
|
|
default:
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_HE_AZ;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::VLAP_PRC_OSAG;
|
|
break;
|
|
case IgnitionTypeProximity:
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_HE_DZ;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::VLAP_PRX_OSAG;
|
|
break;
|
|
}
|
|
break;
|
|
case SMK_BE_M2:
|
|
l_AmmunitionType = N_Ballistic::NEBEL;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::SMK_OSAG;
|
|
break;
|
|
case CLUSTER_HEHC_M9609:
|
|
l_AmmunitionType = N_Ballistic::STEILFEUER_BOMBLET;
|
|
l_AmmunitionTypeOSAG = N_Ballistic::CLUSTER_OSAG;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// TODO: wird alles nicht ausgewertet
|
|
// -> in TES-UAE wurde in diesem Fall ein zt_artillery_usage_error_rt telegramm erzeugt was später ausgewertet wurde
|
|
// wird also einen RP in AHTC geben wenn es auffällt
|
|
Q_UNUSED(error_elevation);
|
|
Q_UNUSED(error_charge);
|
|
Q_UNUSED(error_mun);
|
|
Q_UNUSED(usage_ok);
|
|
|
|
// Richtung Zentrale
|
|
// Der ammunitionType ist in zssiwi_service_base.hpp zu finden
|
|
// TODO m_mortarHowitzer
|
|
// Treffer Einzelfeuer zum DDS schicken:
|
|
|
|
//int wirkfeld_id = m_mortarHowitzer->impact(m_equipmentNumber,
|
|
// l_ImpactData->ImpactTime,
|
|
// l_ImpactData->ImpactPositionLat,
|
|
// l_ImpactData->ImpactPositionLong,
|
|
// l_AmmunitionType,
|
|
// l_AmmunitionTypeOSAG,
|
|
// l_DeviceID);
|
|
QString latStr = QString::number(l_ImpactData->ImpactPositionLat, 'f', 8);
|
|
QString lonStr = QString::number(l_ImpactData->ImpactPositionLong, 'f', 8);
|
|
INFO_LOG(m_logger) << "calculateSingleFire m_equipmentNumber=" << m_equipmentNumber
|
|
<< " ImpactTime=" << l_ImpactData->ImpactTime
|
|
<< " ImpactPositionLat=" << latStr
|
|
<< " ImpactPositionLong=" << lonStr
|
|
<< " l_AmmunitionType=" << l_AmmunitionType
|
|
<< " l_AmmunitionTypeOSAG=" << l_AmmunitionTypeOSAG
|
|
<< " l_DeviceID=" << l_DeviceID;
|
|
m_DeviceID = l_DeviceID;
|
|
m_singleFireToCtas.impactTime = l_ImpactData->ImpactTime;
|
|
m_singleFireToCtas.impactPositionLat = l_ImpactData->ImpactPositionLat;
|
|
m_singleFireToCtas.impactPositionLong = l_ImpactData->ImpactPositionLong;
|
|
m_singleFireToCtas.ammunitionType = l_AmmunitionType;
|
|
m_singleFireToCtas.hit = true;
|
|
|
|
}
|
|
|
|
bool GeoPairing::geoPairingData(const std::shared_ptr<N_Ballistic::BallisticService> &ballisticService,
|
|
int equipmentNumber,
|
|
qint64 time,
|
|
double positionLat,
|
|
double positionLon,
|
|
const QByteArray &transparentDataAr,
|
|
const QHash<int, CentralEffectSimulation::HandlerParticipant::CesParticipantData> &aircrafts)
|
|
{
|
|
// first of all, we save the basic info that is directly available
|
|
m_equipmentNumber = equipmentNumber;
|
|
m_Time = time;
|
|
m_PositionLat = positionLat;
|
|
m_PositionLon = positionLon;
|
|
m_ballisticService = ballisticService;
|
|
|
|
m_fireToAircraft.hit = false;
|
|
m_singleFireToCtas.hit = false;
|
|
m_areaFireToCtas.hit = false;
|
|
m_reportTarget.send = false;
|
|
|
|
INFO_LOG(m_logger) << "--------------- geoPairingData empfangen! -----------------" ;
|
|
INFO_LOG(m_logger) << "playerId = " << m_equipmentNumber ;
|
|
INFO_LOG(m_logger) << "time = " << (SInt64) m_Time ;
|
|
INFO_LOG(m_logger) << "positionLat = " << m_PositionLat ;
|
|
INFO_LOG(m_logger) << "positonLon = " << m_PositionLon ;
|
|
INFO_LOG(m_logger) << "tr.Data-Size = " << transparentDataAr.size() ;
|
|
|
|
INFO_LOG(m_logger) << "transparentData = " << transparentDataAr.toHex() ;
|
|
|
|
QHashIterator<int, CentralEffectSimulation::HandlerParticipant::CesParticipantData> i(aircrafts);
|
|
while (i.hasNext())
|
|
{
|
|
i.next();
|
|
DEBUG_LOG(m_logger) << i.key() << ": participantId=" << i.value().participantId()
|
|
<< " participantTypeId= " << i.value().participantTypeId()
|
|
<< " pos lat=" << i.value().pos().lat()
|
|
<< " pos lon=" << i.value().pos().lon()
|
|
<< " z=" << i.value().pos().z();
|
|
}
|
|
|
|
|
|
GeoPairingDataBase l_Header;
|
|
|
|
if (!l_Header.parse(transparentDataAr))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error: Couldn't parse header of transparent Data!" ;
|
|
return false;
|
|
}
|
|
|
|
UInt8 l_MessageID = l_Header.m_MessageID;
|
|
PanGeoPairingDeviceId l_DeviceID = l_Header.m_DeviceID;
|
|
INFO_LOG(m_logger) << "l_MessageID = " << std::hex << (int)l_MessageID ;
|
|
INFO_LOG(m_logger) << "l_DeviceID = " << l_DeviceID ;
|
|
|
|
if (l_MessageID == 0xE3) // Firing_Report
|
|
{
|
|
INFO_LOG(m_logger) << "--> E3 : Firing Report " ;
|
|
|
|
switch (l_DeviceID)
|
|
{
|
|
case PAN_GP_REPORT_MORTAR:
|
|
case PAN_GP_REPORT_G5_G6:
|
|
case PAN_GP_REPORT_M109:
|
|
calculateSingleFire(transparentDataAr, ballisticService);
|
|
INFO_LOG(m_logger) << "PAN_GP_REPORT_MORTAR PAN_GP_REPORT_G5_G6 PAN_GP_REPORT_M109 calculateSingleFire";
|
|
break;
|
|
case PAN_GP_REPORT_MK19:
|
|
calculateAreaFire(transparentDataAr, ballisticService);
|
|
break;
|
|
case PAN_GP_REPORT_IGLA:
|
|
case PAN_GP_REQUEST_IGLA:
|
|
calculateAirFire(transparentDataAr, aircrafts);
|
|
INFO_LOG(m_logger) << "PAN_GP_REPORT_IGLA PAN_GP_REQUEST_IGLA ";
|
|
break;
|
|
default:
|
|
WARNING_LOG(m_logger) << "--> Unknown DeviceID " << l_DeviceID << " used !" ;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING_LOG(m_logger) << "--> Unknown MessageID used ! " ;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GeoPairing::setMeteo(double winddirection, double windspeed, double temperature, double pressure)
|
|
{
|
|
// create the global meteodata object
|
|
GeoPairingImplMeteoData l_meteoData;
|
|
|
|
l_meteoData.AirPressure = pressure;
|
|
l_meteoData.Temperature = temperature;
|
|
l_meteoData.WindDirection = winddirection;
|
|
l_meteoData.WindSpeed = windspeed;
|
|
|
|
GeoPairingImplFactory::setMeteoData(l_meteoData);
|
|
}
|
|
|
|
bool GeoPairing::searchAirTarget(double a_elevation, double azimuth, int &playerId, uint64_t &impactTime)
|
|
{
|
|
INFO_LOG(m_logger) << "searchAirTarget (IGLA)..." ;
|
|
|
|
QScopedPointer<GeoPairingImplAirTargetTracker> l_Tracker(GeoPairingImplFactory::createAirTargetTracker());
|
|
|
|
l_Tracker->setPosition(m_PositionLat, m_PositionLon, m_PositionHeight);
|
|
l_Tracker->setTime(m_Time);
|
|
return l_Tracker->track(azimuth,
|
|
a_elevation,
|
|
playerId,
|
|
impactTime);
|
|
}
|
|
|
|
void GeoPairing::readAmmunitionIni()
|
|
{
|
|
AmmuConfig *ammuConfig;
|
|
QString FileName = CesGeoPairing::Settings::cesGeopairingIniPath() + QStringLiteral("/") + CesGeoPairing::Settings::cesAmmunitionIniFile();
|
|
|
|
ammuConfig = AmmuConfig::getInstance();
|
|
ammuConfig->initFilename(FileName);
|
|
|
|
//Zu erst holen wir uns alle WaffenTypen
|
|
const QVector<int> typesList = ammuConfig->getIntegerVector(QStringLiteral("WeaponRestriction"), QStringLiteral("Types"));
|
|
|
|
DEBUG_LOG(m_logger) << "typesList.size=" << typesList.size();
|
|
//Wir holen uns alle Munitionen die in Frage kommen heraus // evtl mit Liste?
|
|
const QVector<int> ammoList = ammuConfig->getIntegerVector(QStringLiteral("WeaponRestriction"), QStringLiteral("AmmoList"));
|
|
DEBUG_LOG(m_logger) << "ammoList=" << ammoList.size();
|
|
for (int ammo : ammoList)
|
|
{
|
|
DEBUG_LOG(m_logger) << "ammoListValue=" << ammo;
|
|
|
|
QString eleGroup = QStringLiteral("Ammunition") + QStringLiteral("P") + QString::number(ammo) + QStringLiteral("/CWParams");
|
|
const QVector<double> minElevataion = ammuConfig->getFloatVector(eleGroup, QStringLiteral("ElevMin"));
|
|
DEBUG_LOG(m_logger) << "ammo = " << ammo << " minElevataion.size() =" << minElevataion.size()
|
|
<< " " << eleGroup << "/" << QStringLiteral("ElevMin");
|
|
|
|
const QVector<double> maxElevataion = ammuConfig->getFloatVector(eleGroup, QStringLiteral("ElevMax"));
|
|
DEBUG_LOG(m_logger) << "ammo = " << ammo << " maxElevataion.size() =" << maxElevataion.size() << eleGroup << "/" << QStringLiteral("ElevMax");
|
|
|
|
if (minElevataion.size() != maxElevataion.size())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Invalid Ammunition Config for : Ammunition" << ammo ;
|
|
continue;
|
|
}
|
|
// Get Allowd fpr all Types
|
|
|
|
QMap<int, GeoPCharge> mun;
|
|
QMap<int, QMap<int, bool> > allowedCombi;
|
|
|
|
for (int weaponTypeId : typesList)
|
|
{
|
|
QString alloweKey = QStringLiteral("Allowed") + QString::number(weaponTypeId);
|
|
const QMap<int, bool> allowed = ammuConfig->getBoolMap(eleGroup, alloweKey);
|
|
DEBUG_LOG(m_logger) << "alloweKey allowed.size() =" << allowed.size() << " " << eleGroup << "/" << alloweKey;
|
|
allowedCombi.insert(weaponTypeId, allowed);
|
|
//DEBUG_LOG(m_logger) << "allowedCombi.insert(" << weaponTypeId <<", " << allowed << ")";
|
|
}
|
|
|
|
for (int j = 0; j < minElevataion.size(); j++)
|
|
{
|
|
|
|
int _chargeId = j;
|
|
double _minEleval = minElevataion.at(j);
|
|
double _maxEleval = maxElevataion.at(j);
|
|
QMap<int, bool> allowedCombiForCharge;
|
|
for (int weaponTypeId : typesList)
|
|
{
|
|
//hier holen wir nur den erlaubtstatus für die jeweilige ChargeElevation und packen sie in die
|
|
//Map des ChargeType
|
|
allowedCombiForCharge.insert(weaponTypeId, allowedCombi.value(weaponTypeId).value(j));
|
|
DEBUG_LOG(m_logger) << "allowedCombiForCharge.insert(" << weaponTypeId << ", " << allowedCombi.value(weaponTypeId).value(j) << ")";
|
|
}
|
|
GeoPCharge geoPCharge = GeoPCharge(_chargeId, _minEleval, _maxEleval, allowedCombiForCharge);
|
|
mun.insert(j, geoPCharge);
|
|
}
|
|
m_geoPMunMap.insert(ammo, mun);
|
|
}
|
|
DEBUG_LOG(m_logger) << "m_geoPMunMap.size=" << m_geoPMunMap.size();
|
|
|
|
}
|