// ************************************************************************** // // (C) Copyright 2009 Swiss SIMTEC AG // // ************************************************************************** // // $HeadURL$ // $LastChangedBy$ // $LastChangedDate$ // $LastChangedRevision$ // // ************************************************************************** // manual class headers #include "GeoPairingImplFiredBulletBalistic.hpp" #include // from cpp_includes #include #include #include #include #include "geo_settings.h" namespace N_GeoPairingImpl { // --------------------------------------------------------------- // Constructur taking the SensorData as input values // --------------------------------------------------------------- GeoPairingImplFiredBulletBalistic::GeoPairingImplFiredBulletBalistic(const GeoPairingImplSensorData &a_sensorData, const char *loggerName) : GeoPairingImplFiredBullet(a_sensorData, loggerName ? loggerName : "GeoPairingImplFiredBulletBalistic") { m_UtmSensor.setLlPositionDegree(m_SensorData.WeaponPositionLat, m_SensorData.WeaponPositionLong, m_SensorData.WeaponPositionHeight); m_ballisticService = std::make_shared(); m_ballisticService->init(N_GeoPairingImpl::Settings::cesGeopairingIniPath(), N_GeoPairingImpl::Settings::cesGeopairingIniFile(), N_GeoPairingImpl::Settings::cesAmmunitionIniFile()); m_SensorData.IgnitionType = a_sensorData.IgnitionType; } // --------------------------------------------------------------- // Performs the calculation of the trajectory and also returns // the result of calculation // --------------------------------------------------------------- GeoPairingImplFiredBullet::E_CalcResult GeoPairingImplFiredBulletBalistic::calculate(const std::shared_ptr &ballisticService) { m_ballisticService = ballisticService; E_CalcResult l_cr = e_NONE; N_ConfigSystem::GeoConfig *l_config = N_ConfigSystem::GeoConfig::getInstance(); QMap ammuMap = l_config->getAmmuMap(); QMap > chargeMap = l_config->getChargeMap(); INFO_LOG(m_logger) << "----------- Calculating Impact -----------"; N_Types::Coord3 l_sensorPos(m_UtmSensor.utmEasting(), m_UtmSensor.utmNorthing(), m_UtmSensor.height()); INFO_LOG(m_logger) << "l_sensorPos : " << l_sensorPos; N_Math::GeoCoord l_checkUtm; l_checkUtm.setTotalUtmPosition(l_sensorPos.m_X, l_sensorPos.m_Y, l_sensorPos.m_Z, m_UtmSensor.utmZone(), m_UtmSensor.northP()); N_Types::Coord3 l_checkPos(l_checkUtm.latDeg(), l_checkUtm.lonDeg(), l_checkUtm.height()); INFO_LOG(m_logger) << "o_checkPos : " << l_checkPos; INFO_LOG(m_logger) << "m_SensorData.AmmunitionType : " << m_SensorData.AmmunitionType; QString l_ammunition = ammuMap[m_SensorData.AmmunitionType]; INFO_LOG(m_logger) << "l_ammunition=" << l_ammunition; // ---------------- Preparing Calculation N_Ballistic::IFireControl *lp_fireControl = nullptr; if (!m_ballisticService) { ERROR_LOG(m_logger) << "!m_ballisticService"; return l_cr; } bool ok = m_ballisticService->createInterfaceOf((N_Ballistic::IUnknown **)&lp_fireControl, N_Ballistic::BallisticService::e_IFireControl, l_ammunition); if (!ok) { ERROR_LOG(m_logger) << "couldn't create interface "; return l_cr; } if (!lp_fireControl) { ERROR_LOG(m_logger) << "couldn't initialize fireControl for " << l_ammunition; return l_cr; } double l_density = lp_fireControl->getAirDensity(m_MeteoData.AirPressure, m_MeteoData.Temperature); INFO_LOG(m_logger) << "l_density = " << l_density; INFO_LOG ( m_logger) << "getInitialAmmuVelocity=" << m_SensorData.WeaponTemperature; double l_initialspeed = lp_fireControl->getInitialAmmuVelocity(m_SensorData.WeaponTemperature); INFO_LOG ( m_logger) << "l_initialspeed=" << l_initialspeed; QMap >::iterator chargeIt = chargeMap.find(m_SensorData.AmmunitionType); if (chargeIt != chargeMap.end()) { QVector l_charges = chargeMap[m_SensorData.AmmunitionType]; if (m_SensorData.ChargeType >= 0 && m_SensorData.ChargeType < l_charges.size()) { l_initialspeed = l_charges[m_SensorData.ChargeType]; INFO_LOG(m_logger) << "Charge chosen for " << l_ammunition << " : " << l_initialspeed; } } else INFO_LOG(m_logger) << "l_initialspeed = " << l_initialspeed; GeoPairingImplTrajectoryData::TrajectoryPoint tpSensor; tpSensor.m_H = l_sensorPos.m_Z; tpSensor.m_Vel = l_initialspeed; tpSensor.m_Rho = l_density; m_TrajectoryData.m_Points.push_back(tpSensor); N_Types::Radian64 l_windDir; l_windDir.setDegree(m_MeteoData.WindDirection); N_Types::Coord3 l_windAngle(0, m_MeteoData.WindSpeed, 0); l_windAngle = l_windAngle.rotateZ(l_windDir); INFO_LOG(m_logger) << "o_windAngle = " << l_windAngle; double l_crossWind = l_windAngle.rotateZ(-m_SensorData.WeaponAzimuth).getX(); INFO_LOG(m_logger) << "l_crossWind = " << l_crossWind; // ------------------ Prepare Trajectory N_Ballistic::ITrajectory *lp_trajectory = nullptr; //if (!BallisticService::createInterfaceOf((IUnknown **)&lp_trajectory, BallisticService::e_ITrajectory, l_ammunition)) //m_ballisticService->createInterfaceOf((IUnknown **)&lp_fireControl, BallisticService::e_IFireControl, l_ammunition); m_ballisticService->createInterfaceOf((N_Ballistic::IUnknown **)&lp_trajectory, N_Ballistic::BallisticService::e_ITrajectory, l_ammunition); if (!lp_trajectory) { ERROR_LOG(m_logger) << "Couldn't create Trajectory object for " << l_ammunition; return l_cr; } N_Types::Angle3 l_sensorAngle(m_SensorData.WeaponAzimuth, m_SensorData.WeaponElevation, 0); INFO_LOG(m_logger) << "o_sensorAngle : " << l_sensorAngle; if (!lp_trajectory->init(l_sensorPos, l_sensorAngle, l_crossWind, l_density, l_initialspeed)) { lp_trajectory->release(); ERROR_LOG(m_logger) << "Couldn't initialize Trajectory"; return l_cr; } // ------------------- Loop Trajectory double l_time = 0; QString s_Precision = QStringLiteral("Precision"); QString s_DeltaTime = QStringLiteral("DeltaTime"); double l_timeDelta = l_config->getFloat(s_Precision, s_DeltaTime, 0.05); INFO_LOG(m_logger) << "Used Precision DeltaTime = " << l_timeDelta; N_Types::Coord3 l_pos; while (lp_trajectory->isActive()) { l_time += l_timeDelta; lp_trajectory->move(l_timeDelta); if (m_SensorData.IgnitionType == 0 && !lp_trajectory->isActive()) { INFO_LOG(m_logger) << "Timeout of Bullet! IgnitionType=" << m_SensorData.IgnitionType; l_cr = e_TIMEOUT; break; } l_pos = lp_trajectory->getPosition(); N_Math::GeoCoord l_checkUtmShadow; l_checkUtmShadow.setTotalUtmPosition(l_pos.m_X, l_pos.m_Y, l_pos.m_Z, m_UtmSensor.utmZone(), m_UtmSensor.northP()); N_Types::Coord3 l_checkPosShadow(l_checkUtmShadow.lonDeg(), l_checkUtmShadow.latDeg(), l_checkUtmShadow.height()); INFO_LOG(m_logger) << "l_pos " << " X=" << l_pos.getX() << " Y=" << l_pos.getY() << " Z=" << l_pos.getZ() << " m_X=" << l_pos.m_X << " m_Y=" << l_pos.m_Y << " m_Z=" << l_pos.m_Z << " l_checkUtm.height=" << l_checkUtmShadow.height() << " l_checkPos.z=" << l_checkPosShadow.getZ(); double l_height = 0; if (checkTerrainHit(l_checkPosShadow, l_height)) { INFO_LOG(m_logger) << "deactivate"; lp_trajectory->deactivate(); l_cr = e_OK; } else { if (m_SensorData.IgnitionType > 0 && l_time > m_SensorData.IgnitionType) { INFO_LOG(m_logger) << "deactivate"; lp_trajectory->deactivate(); l_cr = e_OK; INFO_LOG(m_logger) << "Detonation by Timer : " << m_SensorData.IgnitionType; } } GeoPairingImplTrajectoryData::TrajectoryPoint tpImpact; tpImpact.m_X = l_pos.m_X - l_sensorPos.m_X; tpImpact.m_Y = l_pos.m_Y - l_sensorPos.m_Y; tpImpact.m_Z = l_pos.m_Z - l_sensorPos.m_Z; tpImpact.m_H = l_height; tpImpact.m_Vel = lp_trajectory->getVelocity().magnitude(); tpImpact.m_Time = l_time; m_TrajectoryData.m_Points.push_back(tpImpact); } l_pos = lp_trajectory->getPosition(); // INFO_LOG(m_logger) << "Total Distance = " << l_pos.length(l_sensorPos); INFO_LOG(m_logger) << "Total Time = " << l_time; lp_trajectory->release(); lp_fireControl->release(); INFO_LOG(m_logger) << "l_pos : " << l_pos; double l_Distance = l_pos.length(l_sensorPos); INFO_LOG(m_logger) << "l_Distance = " << l_Distance; N_Math::GeoCoord l_impactUtm; l_impactUtm.setTotalUtmPosition(l_pos.m_X, l_pos.m_Y, l_pos.m_Z, m_UtmSensor.utmZone(), m_UtmSensor.northP()); INFO_LOG(m_logger) << "l_impactUtm (lat/lon/h) : " << l_impactUtm.latDeg() << "/" << l_impactUtm.lonDeg() << "/" << l_impactUtm.height() << " zone=" << m_UtmSensor.utmZone() << " northP=" << m_UtmSensor.northP(); m_ImpactData.AmmunitionType = m_SensorData.AmmunitionType; m_ImpactData.ImpactTime = m_SensorData.FireTime + l_time; m_ImpactData.ImpactPositionLat = l_impactUtm.latDeg(); m_ImpactData.ImpactPositionLong = l_impactUtm.lonDeg(); m_ImpactData.ImpactPositionHeight = l_impactUtm.height(); return l_cr; } // --------------------------------------------------------------- bool GeoPairingImplFiredBulletBalistic::checkTerrainHit(const N_Types::Coord3 &a_pos, double &a_height) { a_height = 0; INFO_LOG(m_logger) << "checkTerrainHit" << " a_pos.m_Z=" << a_pos.m_Z << " m_UtmSensor.height()=" << m_UtmSensor.height(); return a_pos.m_Z < m_UtmSensor.height(); } } // namespace N_GeoPairingImpl