Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,84 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
#include <QString>
#include "DiscreteType.hpp"
#include "PolygonParamType.hpp"
#include "CWParamType.hpp"
#include "StandardType.hpp"
namespace N_Ballistic
{
/**
* This is the container class for ammunitions
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:04:46
*/
struct Ammunition
{
public:
/**
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:10:21
*/
struct AmmunInfoType
{
QString m_Name;
/**
* Caliber of the ammunition, usually the diameter
*/
Float64 m_Caliber = 0.0;
/**
* The nominal shooting range
*/
Float64 m_Range = 0.0;
/**
* The initial velocity
*/
Float64 m_Speed = 0.0;
Float64 m_TimeOut = 0.0;
/**
* The calculation algorithm, can be "Generic", "PitonBressant" or "DAntonio"
*/
QString m_Algorithm;
/**
* Can be "OnTimer" or "OnDetonate"
*/
QString m_ReasonToDetonate;
/**
* This is the value of devivation of the ammunition (impact position variance)
*/
Float64 m_Deviation = 0.0;
/**
* This is the value of derivation of the ammunition (impact position right drift)
*/
Float64 m_Derivation = 0.0;
};
DiscreteType m_DiscreteParams;
PolygonParamType m_PolygonParams;
Ammunition::AmmunInfoType m_AmmunInfo;
StandardType m_StandardParams;
CWParamType m_CWParams;
};
}
@@ -0,0 +1,64 @@
/**
* @RDE_HEADER@
* Service Base
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
namespace N_Ballistic
{
// siehe SF_munitionsart_et
/*
enum ammunitionTypeIndirectFire {
UNKNOWN = 0,
STEILFEUER_HE_AZ = 1,
STEILFEUER_HE_DZ = 2,
STEILFEUER_BOMBLET = 3,
STEILFEUER_SM_ART = 4,
NEBEL = 5,
MOERSER = 9,
MOERSER_AZ = 10,
MOERSER_ANNZ = 11,
FLAEFLU_BK = 20,
FLAEFLU_RAKETE = 21,
FLAEFLU_BOMBLET = 22,
FLAEFLU_SB = 23,
IGLA = 25,
MK19_M430 = 111,
MK19_M385 = 112
};*/
enum ammunitionTypeIndirectFire { // TODO clarify values
UNKNOWN = 0,
STEILFEUER_HE_AZ = 371,
STEILFEUER_HE_DZ = 372,
STEILFEUER_BOMBLET = 373,
STEILFEUER_SM_ART = 374,
NEBEL = 385,
MOERSER = 381,
MOERSER_AZ = 381,
MOERSER_ANNZ = 381,
FLAEFLU_BK = 471,
FLAEFLU_RAKETE = 472,
FLAEFLU_BOMBLET = 473,
FLAEFLU_SB = 474,
IGLA = 25,
MK19_M430 = 27,
MK19_M385 = 26
};
enum ammunitionTypeOSAG {
UNKNOWN_OSAG = 0,
MK19_M385_OSAG = 26,
MK19_M430_OSAG = 27,
M1A2_PRC_OSAG = 30,
M1A2_PRX_OSAG = 31,
VLAP_PRC_OSAG = 32,
VLAP_PRX_OSAG = 33,
SMK_OSAG = 34,
CLUSTER_OSAG = 35,
MORTAR_PRC_OSAG = 217,
MORTAR_PRX_OSAG = 218
};
}
@@ -0,0 +1,219 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "BallisticService.hpp"
// from cpp_includes
#include "FireControlPiton.hpp"
#include "TrajectoryDiscrete.hpp"
#include "TrajectoryPiton.hpp"
#include "FireControlAntonio.hpp"
#include "TrajectoryDecoy.hpp"
#include "FireControlBase.hpp"
#include "FireControlDecoy.hpp"
#include "TrajectoryBase.hpp"
#include "TrajectoryAntonio.hpp"
#include "FireControlDiscrete.hpp"
#include "FireControlRungeKutta.hpp"
#include "TrajectoryRungeKutta.hpp"
#include "FireControlRungeKuttaSimple.hpp"
#include "TrajectoryRungeKuttaSimple.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// ## Constructors (generated)
// ---------------------------------------------------------------
BallisticService::BallisticService()
: m_logger(CesGeoPairing::getLogger("Plugin.GeoPairing.BallisticService"))
{}
// ---------------------------------------------------------------
// initializes the BallisticService with an Ammunition config
// file
// ---------------------------------------------------------------
bool BallisticService::init(const QString &a_configPath,
const QString &a_configFile,
const QString &a_ammunitionFile)
{
m_Initialized = false;
m_configPath = a_configPath;
m_configFile = a_configFile;
m_ammunitionFile = a_ammunitionFile;
INFO_LOG(m_logger) << "init";
m_ammuConfig = N_ConfigSystem::AmmuConfig::getInstance();
QString FileName = a_configPath + QLatin1Char('/') + a_ammunitionFile;
INFO_LOG(m_logger) << "FileName=" << FileName;
m_ammuConfig->initFilename(FileName);
m_Initialized = true;
return true;
}
// ---------------------------------------------------------------
// Creates an interface of according to the given parameters
// ---------------------------------------------------------------
bool BallisticService::createInterfaceOf(IUnknown **app_interface, E_TypeOfInterface a_typeInterface, const QString &a_ammuName)
{
if (!m_Initialized)
{
ERROR_LOG(m_logger) << "Class is not initialized" ;
return false;
}
Ammunition *configuredAmmunition;
E_TypeOfImpl e_impl = e_ImplBase;
DEBUG_LOG(m_logger) << "Target Interface Pointer : " << app_interface ;
DEBUG_LOG(m_logger) << "Searching in available ammunitions for " << a_ammuName ;
//iterate over all Ammunition nodes and find the corresponding Ammunition name
bool bAmmunitionFound = false;
//for (Ammunition *ammunition : m_BallisticConfiguration.m_Ammunition)
//for (Ammunition *ammunition : m_ammuConfig->GetAmmunitions())
QVector<N_Ballistic::Ammunition>* ammunitions = m_ammuConfig->GetAmmunitions();
for ( int i = 0; i < ammunitions->size(); i++)
{
N_Ballistic::Ammunition ammunition = m_ammuConfig->GetAmmunitions()->at(i);
//find ammunition
configuredAmmunition = &ammunition;
DEBUG_LOG(m_logger) << "Ammunition found: " << configuredAmmunition->m_AmmunInfo.m_Name ;
if (configuredAmmunition->m_AmmunInfo.m_Name == a_ammuName)
{
bAmmunitionFound = true;
if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("DAntonio"))
e_impl = e_ImplAntonio;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Piton"))
e_impl = e_ImplPiton;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Discrete"))
e_impl = e_ImplDiscrete;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Decoy"))
e_impl = e_ImplDecoy;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("RungeKutta"))
e_impl = e_ImplRungeKutta;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("RungeKuttaSimple"))
e_impl = e_ImplRungeKuttaSimple;
else if (configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Generic") ||
configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Standard") ||
configuredAmmunition->m_AmmunInfo.m_Algorithm == QStringLiteral("Base"))
e_impl = e_ImplBase;
else
{
ERROR_LOG(m_logger) << "Configured Algorithm not known :"
<< configuredAmmunition->m_AmmunInfo.m_Algorithm;
return false;
}
break;
}
}
if (!bAmmunitionFound)
{
ERROR_LOG(m_logger) << "Desired ammunition was not found :" << a_ammuName ;
return false;
}
// find out which algorithm to use for the given ammunition
switch (a_typeInterface)
{
case e_IFireControl:
{
FireControlBase *p_firecontrol = nullptr;
switch (e_impl)
{
case e_ImplBase:
p_firecontrol = new FireControlBase("FireControlBase");
break;
case e_ImplPiton:
p_firecontrol = new FireControlPiton;
break;
case e_ImplAntonio:
p_firecontrol = new FireControlAntonio;
break;
case e_ImplDiscrete:
p_firecontrol = new FireControlDiscrete;
break;
case e_ImplDecoy:
p_firecontrol = new FireControlDecoy;
break;
case e_ImplRungeKutta:
p_firecontrol = new FireControlRungeKutta;
break;
case e_ImplRungeKuttaSimple:
p_firecontrol = new FireControlRungeKuttaSimple;
break;
default:
ERROR_LOG(m_logger) << "Implementation does not exist: " << e_impl ;
*app_interface = nullptr;
return false;
}
p_firecontrol->init(*configuredAmmunition);
p_firecontrol->addRef();
*app_interface = p_firecontrol;
break;
}
case e_ITrajectory:
{
TrajectoryBase *p_trajectorybase = nullptr;
switch (e_impl)
{
case e_ImplBase:
p_trajectorybase = new TrajectoryBase("TrajectoryBase");
break;
case e_ImplPiton:
p_trajectorybase = new TrajectoryPiton;
break;
case e_ImplAntonio:
p_trajectorybase = new TrajectoryAntonio;
break;
case e_ImplDiscrete:
p_trajectorybase = new TrajectoryDiscrete;
break;
case e_ImplDecoy:
p_trajectorybase = new TrajectoryDecoy;
break;
case e_ImplRungeKutta:
p_trajectorybase = new TrajectoryRungeKutta;
break;
case e_ImplRungeKuttaSimple:
p_trajectorybase = new TrajectoryRungeKuttaSimple;
break;
default:
ERROR_LOG(m_logger) << "Implementation does not exist: " << e_impl ;
*app_interface = nullptr;
return false;
}
p_trajectorybase->init(*configuredAmmunition);
p_trajectorybase->addRef();
*app_interface = p_trajectorybase;
break;
}
default:
ERROR_LOG(m_logger) << "Interface does not exist: " << a_typeInterface ;
*app_interface = nullptr;
return false;
}
return true;
}
} // namespace N_Ballistic
@@ -0,0 +1,104 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "IUnknown.hpp"
#include "../logger.h"
#include <GBL_ConfigSystem/ammuconfig.h>
// manual class imports
namespace N_Ballistic
{
/**
* The factory class for ballistic interfaces
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:36:13
*/
class BallisticService
{
public:
/**
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:45:18
*/
enum E_TypeOfImpl
{
e_ImplBase = 0,
e_ImplPiton = 1,
e_ImplAntonio = 2,
e_ImplDiscrete = 3,
e_ImplDecoy = 4,
e_ImplRungeKutta = 5,
e_ImplRungeKuttaSimple = 6
};
/**
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:43:40
*/
enum E_TypeOfInterface
{
e_IFireControl = 0,
e_ITrajectory = 1,
e_ITerrainInfo = 2
};
/**
* initializes the BallisticService with an Ammunition config file
*
* @param a_configFilename xml file name
*/
bool init(const QString &a_configPath,
const QString &a_configFile,
const QString &a_ammunitionFile);
/**
* Creates an interface of according to the given parameters
*
* @param app_interface Interface pointer
* @param a_typeInterface Type of desired interface
* @param a_ammuName Name of ammunition
*/
bool createInterfaceOf(IUnknown **app_interface, E_TypeOfInterface a_typeInterface, const QString &a_ammuName);
QString getConfigPath() const { return m_configPath; }
QString getConfigFile() const { return m_configFile; }
QString getAmmunitionFile() const { return m_ammunitionFile; }
/**
* ## Constructors (generated)
*/
BallisticService();
private:
bool m_Initialized = false;
QString m_configPath;
QString m_configFile;
QString m_ammunitionFile;
N_ConfigSystem::AmmuConfig *m_ammuConfig = nullptr;
CesGeoPairing::LOGGER_T m_logger;
};
}
@@ -0,0 +1,66 @@
#
# CMake file für ballistische Berechnungen
# $Id$
# $HeadURL$
# $Author$
#
SET(my_SRCS
AmmunitionTypes.hpp
BallisticService.cpp
FireControlAntonio.cpp
FireControlBase.cpp
FireControlDiscrete.cpp
FireControlPiton.cpp
FireControlRungeKutta.cpp
TrajectoryAntonio.cpp
TrajectoryBase.cpp
TrajectoryDecoy.cpp
TrajectoryDiscrete.cpp
TrajectoryPiton.cpp
TrajectoryRungeKutta.cpp
TrajectoryRungeKuttaSimple.cpp
)
SET(my_HDRS
Ammunition.hpp
BallisticService.hpp
CWParamType.hpp
DiscreteType.hpp
FireControlAntonio.hpp
FireControlBase.hpp
FireControlDecoy.hpp
FireControlDiscrete.hpp
FireControlPiton.hpp
FireControlRungeKutta.hpp
FireControlRungeKuttaSimple.hpp
IBallisticConfigurator.hpp
IFireControl.hpp
ITrajectory.hpp
IUnknown.hpp
PolygonParamType.hpp
StandardType.hpp
TrajectoryAntonio.hpp
TrajectoryBase.hpp
TrajectoryDecoy.hpp
TrajectoryDiscrete.hpp
TrajectoryPiton.hpp
TrajectoryRungeKutta.hpp
TrajectoryRungeKuttaSimple.hpp
)
NGL_ADD_LIBRARY(AAR SV FW_Ballistic STATIC ${my_SRCS} ${my_HDRS})
NGL_TARGET_INCLUDE_DIRECTORIES(FW_Ballistic
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(FW_Ballistic
GBL_ConfigSystem
GBL_Global
Qt5::Core
NGLLogger
GBL_Types
svcCesCommon
)
NGL_INSTALL_TARGET(FW_Ballistic)
@@ -0,0 +1,38 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <QVector>
namespace N_Ballistic
{
/**
* Representation of ballistic classes with CW values
*
* @author Daniel.Schmid
* @version 1.0
* @created 22-Jul-2010 13:32:10
*/
struct CWParamType
{
QVector<double> m_CW;
QVector<double> m_V0;
QVector<double> m_XW;
double m_Weight = 0.0;
bool m_Valid = false;
};
}
@@ -0,0 +1,77 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
// manual class imports
namespace N_Ballistic
{
/**
* Discrete representation of ballistic values
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:09:31
*/
class DiscreteType
{
public:
/**
* Container for DerivationType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:10:03
*/
struct DerivationType
{
Float64 m_CT2 = 0.0;
Float64 m_CY = 0.0;
Float64 m_C0 = 0.0;
};
/**
* Container for AxisParamType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:09:50
*/
struct AxisParamType
{
Float64 m_CA = 0.0;
Float64 m_CT2 = 0.0;
Float64 m_CT1 = 0.0;
Float64 m_CAlpha2 = 0.0;
Float64 m_CAlpha1 = 0.0;
Float64 m_CRho = 0.0;
Float64 m_CV = 0.0;
Float64 m_C0 = 0.0;
};
DiscreteType::AxisParamType m_YAxis;
DiscreteType::AxisParamType m_ZAxis;
DiscreteType::AxisParamType m_XAxis;
DiscreteType::DerivationType m_Derivation;
bool m_Valid = false;
};
}
@@ -0,0 +1,406 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "FireControlAntonio.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the class with the ballistic configuration
// ---------------------------------------------------------------
bool FireControlAntonio::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "FireControlAntonio::init : initialising..." ;
if (a_ammunition.m_StandardParams.m_Valid)
{
m_CRhoT = a_ammunition.m_StandardParams.m_Time.m_CRhoT;
m_CRhoA = a_ammunition.m_StandardParams.m_Angle.m_CRhoA;
INFO_LOG(m_logger) << "m_CRhoT : " << m_CRhoT ;
INFO_LOG(m_logger) << "m_CRhoA : " << m_CRhoA ;
m_UseStandard = true;
m_InitialAmmuVelocityV0constX0 = a_ammunition.m_AmmunInfo.m_Speed;
INFO_LOG(m_logger) << "m_InitialAmmuVelocityV0constX0 = " << m_InitialAmmuVelocityV0constX0 ;
}
else if (a_ammunition.m_PolygonParams.m_Valid)
{
m_InitialAX = a_ammunition.m_PolygonParams.m_InitialAX;
INFO_LOG(m_logger) << "m_InitialAX : " << m_InitialAX ;
int axcount = a_ammunition.m_PolygonParams.m_AX.size();
for (int i = 0; i < axcount; i++)
{
m_AX.push_back(a_ammunition.m_PolygonParams.m_AX[i].m_Coeff);
INFO_LOG(m_logger) << "AX " << a_ammunition.m_PolygonParams.m_AX[i].m_Index << " = " << a_ammunition.m_PolygonParams.m_AX[i].m_Coeff ;
}
int aycount = a_ammunition.m_PolygonParams.m_AY.size();
for (int i = 0; i < aycount; i++)
{
m_AY.push_back(a_ammunition.m_PolygonParams.m_AY[i].m_Coeff);
INFO_LOG(m_logger) << "AY " << a_ammunition.m_PolygonParams.m_AY[i].m_Index << " = " << a_ammunition.m_PolygonParams.m_AY[i].m_Coeff ;
}
m_UsePolynom = true;
m_InitialAmmuVelocityV0constX0 = a_ammunition.m_AmmunInfo.m_Speed;
INFO_LOG(m_logger) << "m_InitialAmmuVelocityV0constX0 = " << m_InitialAmmuVelocityV0constX0 ;
}
else
{
ERROR_LOG(m_logger) << "Parameters missing..." ;
return false;
}
if (!FireControlBase::init(a_ammunition))
return false;
INFO_LOG(m_logger) << "FireControlAntonio::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
if (m_UseStandard)
return getFlightTimeStandard(a_distance, a_initialAmmuVelocity, a_terrainAngle, a_airDensity);
if (m_UsePolynom)
return getFlightTimePolynom(a_distance, a_initialAmmuVelocity, a_terrainAngle, a_airDensity);
ERROR_LOG(m_logger) << "UseStandard or UsePolynom not set..." ;
return 0.0;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
if (m_UseStandard)
return getFireAngleStandard(a_distance, a_initialAmmuVelocity, a_terrainAngle, a_airDensity);
if (m_UsePolynom)
return getFireAnglePolynom(a_distance, a_initialAmmuVelocity, a_terrainAngle, a_airDensity);
ERROR_LOG(m_logger) << "UseStandard or UsePolynom not set..." ;
return 0.0;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFlightTimeStandard(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity)
{
Float64 d_second;
Float64 d_temp; // temp value
Float64 d_laserDistY; // Y laser value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (a_distance < 1.0)
{
ERROR_LOG(m_logger) << "a_distance is not valid : " << a_distance ;
return 0.0;
}
if (a_airDensity < 0.0)
{
ERROR_LOG(m_logger) << "a_airDensity is not valid : " << a_airDensity ;
return 0.0;
}
if (a_initialAmmuVelocity < 1.0)
{
ERROR_LOG(m_logger) << "a_initialAmmuVelocity is not valid : " << a_initialAmmuVelocity ;
return 0.0;
}
if (a_terrainAngle > M_PI_2 || a_terrainAngle < -M_PI_2)
{
ERROR_LOG(m_logger) << "a_terrainAngle is not valid : " << a_terrainAngle ;
return 0.0;
}
// t = Xe /(v0 * cos(Gamma) * corr)
// corr = 1 - cRhoT * Rho * Xe
//
// Gamma - terrain angle
// Rho - air density
// v0 - initial ammu velocity
// cRhoT - parameter
//----------------------------------------------------------
d_laserDistY = a_distance * cos(a_terrainAngle);
d_temp = 1.0 - (m_CRhoT * a_airDensity * d_laserDistY);
d_second = d_laserDistY / (a_initialAmmuVelocity * cos(a_terrainAngle) * d_temp);
if (d_second < 0.0)
d_second = 0.0;
return d_second;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFireAngleStandard(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity)
{
Float64 d_square; // square part of the function
Float64 d_tan; // tangent value of the function
N_Types::Radian64 o_tsi; // firing angle
Float64 d_correction; // correction value
Float64 d_temp; // temp value
Float64 d_laserDistZ; // Z laser value
Float64 d_laserDistY; // Y laser value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (a_distance < 1.0)
{
ERROR_LOG(m_logger) << "a_distance is not valid : " << a_distance ;
return 0.0;
}
if (a_airDensity < 0.0)
{
ERROR_LOG(m_logger) << "a_airDensity is not valid : " << a_airDensity ;
return 0.0;
}
if (a_initialAmmuVelocity < 1.0)
{
ERROR_LOG(m_logger) << "a_initialAmmuVelocity is not valid : " << a_initialAmmuVelocity ;
return 0.0;
}
if (a_terrainAngle > M_PI_2 || a_terrainAngle < -M_PI_2)
{
ERROR_LOG(m_logger) << "a_terrainAngle is not valid : " << a_terrainAngle ;
return 0.0;
}
// Tsi = atan((1/2) * ((Xe/c) - sqrt))
// sqrt = pow((Xe/c), 2) - 4 * (Ye + c) / c
// c = (9.81 * pow(Xe, 2) / ( 2 * pow(v0, 2))) / (corr1 * corr2)
// corr1 = pow((1 - cRhoA * Rho * Xe), 2)
// corr2 = 1 + cRhoT * Rho * Xe
// Xe = D * cos(Gamma)
//
// Gamma - terrain angle
// Rho - air density
// v0 - initial ammu velocity
// cRhoA, constA - constants
//----------------------------------------------------------
d_laserDistZ = a_distance * sin(a_terrainAngle);
d_laserDistY = a_distance * cos(a_terrainAngle);
d_temp = 1 + (m_CRhoA * a_airDensity * d_laserDistY);
d_correction = N_SST::G * pow(d_laserDistY, Float64(2));
d_correction /= (2.0 * pow(a_initialAmmuVelocity, Float64(2)));
d_correction /= d_temp;
d_temp = pow((1 - (m_CRhoT * a_airDensity * d_laserDistY)), Float64(2));
d_correction /= d_temp;
d_square = pow((d_laserDistY / d_correction), Float64(2));
d_square -= ((4.0 * (d_laserDistZ + d_correction)) / d_correction);
d_square = sqrt(d_square);
d_tan = (d_laserDistY / d_correction) - d_square;
d_tan /= 2.0;
o_tsi = atan(d_tan);
o_tsi -= a_terrainAngle;
return o_tsi;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFlightTimePolynom(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity)
{
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (a_distance < 1.0)
{
ERROR_LOG(m_logger) << "a_distance is not valid : " << a_distance ;
return 0.0;
}
if (a_airDensity < 0.0)
{
ERROR_LOG(m_logger) << "a_airDensity is not valid : " << a_airDensity ;
return 0.0;
}
if (a_initialAmmuVelocity < 1.0)
{
ERROR_LOG(m_logger) << "a_initialAmmuVelocity is not valid : " << a_initialAmmuVelocity ;
return 0.0;
}
if (a_terrainAngle > M_PI_2 || a_terrainAngle < -M_PI_2)
{
ERROR_LOG(m_logger) << "a_terrainAngle is not valid : " << a_terrainAngle ;
return 0.0;
}
Float64 d_time = 0;
Float64 d_prevtime = 0;
Float64 d_distance = 0; // Y laser value
Float64 d_ax = 0; // ax coefficient
d_distance = a_distance * cos(a_terrainAngle);
d_ax = m_InitialAX;
d_time = getTimeForAx(d_distance, d_ax, a_initialAmmuVelocity, a_airDensity);
int iteration_counter = 0;
while (d_time - d_prevtime < 0.001)
{
iteration_counter++;
d_prevtime = d_time;
d_ax = getAxForTime(d_time);
d_time = getTimeForAx(d_distance, d_ax, a_initialAmmuVelocity, a_airDensity);
if (iteration_counter > 20)
{
WARNING_LOG(m_logger) << "Iteration interupted at 20 loops..." ;
break;
}
}
return d_time;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlAntonio::getFireAnglePolynom(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity)
{
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (a_distance < 1.0)
{
ERROR_LOG(m_logger) << "a_distance is not valid : " << a_distance ;
return 0.0;
}
if (a_airDensity < 0.0)
{
ERROR_LOG(m_logger) << "a_airDensity is not valid : " << a_airDensity ;
return 0.0;
}
if (a_initialAmmuVelocity < 1.0)
{
ERROR_LOG(m_logger) << "a_initialAmmuVelocity is not valid : " << a_initialAmmuVelocity ;
return 0.0;
}
if (a_terrainAngle > M_PI_2 || a_terrainAngle < -M_PI_2)
{
ERROR_LOG(m_logger) << "a_terrainAngle is not valid : " << a_terrainAngle ;
return 0.0;
}
N_Types::Radian64 o_tsi; // firing angle
Float64 d_correction; // correction value
Float64 d_temp; // temp value
Float64 d_time; // flight time
Float64 d_distance; // effective distance
Float64 d_ay;
d_distance = a_distance * cos(a_terrainAngle);
d_time = getFlightTimePolynom(d_distance, a_initialAmmuVelocity, a_terrainAngle, a_airDensity);
d_ay = getAyForTime(d_time);
// g * x
// tan tsi = -----------------------------
// 2 * v0^2 * (1 - ay * p * x)^2
d_correction = N_SST::G * d_distance;
d_correction /= (2.0 * pow(a_initialAmmuVelocity, Float64(2)));
d_temp = pow((1 - (d_ay * a_airDensity * d_distance)), Float64(2));
d_correction /= d_temp;
o_tsi = atan(d_correction);
o_tsi -= a_terrainAngle;
return o_tsi;
}
// ---------------------------------------------------------------
Float64 FireControlAntonio::getTimeForAx(Float64 a_distance, Float64 a_ax, Float64 a_velocity, Float64 a_airDensity)
{
Float64 d_time = 0;
// x
// d_time = -----------------------
// v0 * (1 - ax * p * x)
d_time = a_distance / a_velocity;
d_time /= 1 - (a_ax * a_airDensity * a_distance);
return d_time;
}
// ---------------------------------------------------------------
Float64 FireControlAntonio::getAxForTime(Float64 a_time) const
{
Float64 d_ax = 0;
//
// ax = (ax0 * t^0) + (ax1 * t^1) + (ax2 * t^2) + (ax3 * t^3) ...
//
for (unsigned int i = 0; i < m_AX.size(); i++)
d_ax += m_AX[i] * pow(a_time, i);
return d_ax;
}
// ---------------------------------------------------------------
Float64 FireControlAntonio::getAyForTime(Float64 a_time) const
{
Float64 d_ay = 0;
//
// ay = (ay0 * t^0) + (ay1 * t^1) + (ay2 * t^2) + (ay3 * t^3) ...
//
for (unsigned int i = 0; i < m_AY.size(); i++)
d_ay += m_AY[i] * pow(a_time, i);
return d_ay;
}
} // namespace N_Ballistic
@@ -0,0 +1,153 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class imports
#include "FireControlBase.hpp"
namespace N_Ballistic
{
/**
* D'Antonio implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 15:01:21
*/
class FireControlAntonio : public FireControlBase
{
public:
/**
* ## Constructors (generated)
*/
FireControlAntonio() : FireControlBase("FireControlAntonio") {}
/**
* initializes the class with the ballistic configuration
*
* @param a_ammunition
*/
bool init(const Ammunition &a_ammunition) override;
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
protected:
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFlightTimeStandard(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity);
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFireAngleStandard(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity);
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFlightTimePolynom(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity);
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFireAnglePolynom(const Float64 a_distance, const Float64 a_initialAmmuVelocity,
const N_Types::Radian64 &a_terrainAngle, const Float64 a_airDensity);
/**
*
* @param a_distance
* @param a_ax
* @param a_velocity
* @param a_airDensity
*/
static Float64 getTimeForAx(Float64 a_distance, Float64 a_ax, Float64 a_velocity, Float64 a_airDensity);
/**
*
* @param a_time
*/
Float64 getAxForTime(Float64 a_time) const;
/**
*
* @param a_time
*/
Float64 getAyForTime(Float64 a_time) const;
private:
/**
* air density correction constant
*/
Float64 m_CRhoT = 0;
/**
* air density correction constant
*/
Float64 m_CRhoA = 0;
Float64 m_InitialAX = 0;
std::vector<Float64> m_AX;
std::vector<Float64> m_AY;
bool m_UseStandard = false;
bool m_UsePolynom = false;
};
}
@@ -0,0 +1,259 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "FireControlBase.hpp"
namespace N_Ballistic
{
FireControlBase::FireControlBase(const char *loggerName)
: m_logger(CesGeoPairing::getLogger(loggerName))
{
}
FireControlBase::~FireControlBase()
{
deinit();
}
// ---------------------------------------------------------------
// Using this function a reference to the interface is added.
// ---------------------------------------------------------------
SInt32 FireControlBase::addRef()
{
return m_MyRefCounter++;
}
// ---------------------------------------------------------------
// Calling this function the reference from the interface may
// be removed.
// ---------------------------------------------------------------
SInt32 FireControlBase::release()
{
--m_MyRefCounter;
if (m_MyRefCounter <= 0)
{
delete this;
return 0;
}
else
return m_MyRefCounter;
}
// ---------------------------------------------------------------
// initializes the class with the ballistic configuration
// ---------------------------------------------------------------
bool FireControlBase::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
if (a_ammunition.m_StandardParams.m_Valid)
{
TRACE_LOG(m_logger) << "FireControlBase::init : initialising StandardParams..." ;
m_InitialAmmuVelocityV0constX1 = a_ammunition.m_StandardParams.m_Speed.m_V0ConstX1;
m_InitialAmmuVelocityV0constX0 = a_ammunition.m_StandardParams.m_Speed.m_V0ConstX0;
m_CrossWindConstX3 = a_ammunition.m_StandardParams.m_CrossWind.m_ConstX3;
m_CrossWindConstX2 = a_ammunition.m_StandardParams.m_CrossWind.m_ConstX2;
m_CrossWindConstX1 = a_ammunition.m_StandardParams.m_CrossWind.m_ConstX1;
m_CrossWindConstX0 = a_ammunition.m_StandardParams.m_CrossWind.m_ConstX0;
}
m_Initialized = true;
TRACE_LOG(m_logger) << "m_InitialAmmuVelocityV0constX1 : " << m_InitialAmmuVelocityV0constX1 ;
TRACE_LOG(m_logger) << "m_InitialAmmuVelocityV0constX0 : " << m_InitialAmmuVelocityV0constX0 ;
TRACE_LOG(m_logger) << "m_CrossWindConstX3 : " << m_CrossWindConstX3 ;
TRACE_LOG(m_logger) << "m_CrossWindConstX2 : " << m_CrossWindConstX2 ;
TRACE_LOG(m_logger) << "m_CrossWindConstX1 : " << m_CrossWindConstX1 ;
TRACE_LOG(m_logger) << "m_CrossWindConstX0 : " << m_CrossWindConstX0 ;
TRACE_LOG(m_logger) << "FireControlBase::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlBase::getFlightTime(const Float64 a_distance,
const Float64 a_initialAmmuVelocity,
const N_Types::Radian64,
const Float64)
{
Float64 d_second;
Float64 d_temp; // temp value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (a_distance < 1.0 || a_initialAmmuVelocity < 1.0)
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
d_temp = a_distance * N_SST::G / pow(a_initialAmmuVelocity, Float64(2));
d_second = 2 * a_initialAmmuVelocity / N_SST::G;
d_second *= sin(0.5 * asin(d_temp));
if (d_second < 0.0)
d_second = 0.0;
return d_second;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlBase::getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
N_Types::Radian64 o_tsi; // firing angle
Float64 d_temp; // temp value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if ((a_distance < 1.0) ||
(a_airDensity < 0.0) ||
(a_initialAmmuVelocity < 1.0) ||
(a_terrainAngle > M_PI_2) ||
(a_terrainAngle < -M_PI_2))
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
d_temp = a_distance * N_SST::G / pow(a_initialAmmuVelocity, Float64(2));
o_tsi = asin(d_temp) / 2;
o_tsi -= a_terrainAngle;
return o_tsi;
}
// ---------------------------------------------------------------
// This function corrects the fire angle due to the cross wind,
// if the following are given
// ---------------------------------------------------------------
N_Types::Radian64 FireControlBase::getCrossWindCorrection(const Float64 a_crossWind, const Float64 a_distance)
{
Float64 d_deviation; // deviation of the ammu due the cross wind of 1m/sec
Float64 d_deviationTotal; // total deviation of the ammu due the cross wind
N_Types::Radian64 d_traverse; // deviation angle
if (!m_Initialized)
{
ERROR_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if (m_CrossWindConstX3 == 0 &&
m_CrossWindConstX2 == 0 &&
m_CrossWindConstX1 == 0 &&
m_CrossWindConstX0 == 0)
{
WARNING_LOG(m_logger) << "The class uses probably not initialized parameters" ;
return 0.0;
}
d_deviation = m_CrossWindConstX3 * pow(a_distance, Float64(3)) +
m_CrossWindConstX2 * pow(a_distance, Float64(2)) +
m_CrossWindConstX1 * a_distance +
m_CrossWindConstX0;
d_deviationTotal = d_deviation * a_crossWind;
d_traverse = atan2(d_deviationTotal, a_distance);
return d_traverse;
}
// ---------------------------------------------------------------
// returns the air density, provided the following are given
// ---------------------------------------------------------------
Float64 FireControlBase::getAirDensity(const Float64 a_atmosphericPressure, const Float64 a_airTemperature)
{
const Float64 d_FIXED_CONST = 0.348368; // fixed constant of the function
Float64 d_kelvin;
Float64 d_rho;
if ((a_atmosphericPressure <= 1.0) ||
(a_airTemperature <= -N_SST::ZERO_CELSIUS_IN_KELVIN))
{
ERROR_LOG(m_logger) << "The parameters are not correct, Pressure=" << a_atmosphericPressure << ", Temp=" << a_airTemperature ;
return 1.0;
}
d_kelvin = a_airTemperature + N_SST::ZERO_CELSIUS_IN_KELVIN;
d_rho = d_FIXED_CONST * a_atmosphericPressure / d_kelvin;
return d_rho;
}
// ---------------------------------------------------------------
// This function corrects the fire angle due to the cross wind,
// if the following are given
// ---------------------------------------------------------------
Float64 FireControlBase::getCrossWind(const N_Types::Coord3 &a_crossWind, const Float64 a_turretDir)
{
N_Types::Coord3 o_wind = a_crossWind;
o_wind.rotateZ(-a_turretDir); // rotate back
return o_wind.getX();
}
// ---------------------------------------------------------------
// returns the theritical initial ammu velocity of the
// ammunition
// ---------------------------------------------------------------
Float64 FireControlBase::getInitialAmmuVelocity(const Float64 a_temperature)
{
const Float64 d_BASE_TEMPERATURE = 21.0; // deg.centigrade
Float64 f_InitialAmmuVelocity = m_InitialAmmuVelocityV0constX0;
Float64 f_Celsius = a_temperature - d_BASE_TEMPERATURE;
f_InitialAmmuVelocity += (m_InitialAmmuVelocityV0constX1 * f_Celsius);
return f_InitialAmmuVelocity;
}
// ---------------------------------------------------------------
// deinitializes class
// ---------------------------------------------------------------
bool FireControlBase::deinit()
{
m_Initialized = false;
return true;
}
} // namespace N_Ballistic
@@ -0,0 +1,153 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include "../logger.h"
// from stereotyped includes
#include "IFireControl.hpp"
#include "Ammunition.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Base implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 15:01:07
*/
class FireControlBase : public IFireControl
{
public:
explicit FireControlBase(const char *loggerName);
virtual ~FireControlBase();
/**
* Using this function a reference to the interface is added.
*/
SInt32 addRef();
/**
* Calling this function the reference from the interface may be removed.
*/
SInt32 release();
/**
* initializes the class with the ballistic configuration
*
* @param a_ammunition
*/
virtual bool init(const Ammunition &a_ammunition);
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity);
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity);
/**
* This function corrects the fire angle due to the cross wind, if the following
* are given
*
* @param a_crossWind wind speed
* @param a_distance distance from gun
*/
N_Types::Radian64 getCrossWindCorrection(const Float64 a_crossWind, const Float64 a_distance);
/**
* returns the air density, provided the following are given
*
* @param a_atmosphericPressure Pressure
* @param a_airTemperature Temperature
*/
virtual Float64 getAirDensity(const Float64 a_atmosphericPressure, const Float64 a_airTemperature);
/**
* This function corrects the fire angle due to the cross wind, if the following
* are given
*
* @param a_crossWind Wind direction
* @param a_turretDir Direction of Turret
*/
virtual Float64 getCrossWind(const N_Types::Coord3 &a_crossWind, const Float64 a_turretDir);
/**
* returns the theritical initial ammu velocity of the ammunition
*
* @param a_temperature Temperature
*/
virtual Float64 getInitialAmmuVelocity(const Float64 a_temperature);
protected:
SInt32 m_MyRefCounter = 0;
bool m_Initialized = false;
/**
* initial velocity constants
*/
Float64 m_InitialAmmuVelocityV0constX1 = 0;
/**
* initial velocity constants
*/
Float64 m_InitialAmmuVelocityV0constX0 = 0;
/**
* cross wind constants
*/
Float64 m_CrossWindConstX3 = 0;
/**
* cross wind constants
*/
Float64 m_CrossWindConstX2 = 0;
/**
* cross wind constants
*/
Float64 m_CrossWindConstX1 = 0;
/**
* cross wind constants
*/
Float64 m_CrossWindConstX0 = 0;
/**
* logger object
*/
NGL::INGLLogger &m_logger;
/**
* deinitializes class
*/
bool deinit();
};
}
@@ -0,0 +1,41 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "FireControlBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Decoy implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 15:01:59
*/
class FireControlDecoy : public FireControlBase
{
public:
/**
* ## Constructors (generated)
*/
FireControlDecoy() : FireControlBase("FireControlDecoy") {}
};
}
@@ -0,0 +1,185 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "FireControlDiscrete.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the class with the ballistic configuration
// ---------------------------------------------------------------
bool FireControlDiscrete::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "FireControlDiscrete::init : initialising..." ;
m_CT = a_ammunition.m_StandardParams.m_Time.m_CT;
m_CV0T = a_ammunition.m_StandardParams.m_Time.m_CV0T;
m_CRhoT = a_ammunition.m_StandardParams.m_Time.m_CRhoT;
m_ConstT = a_ammunition.m_StandardParams.m_Time.m_ConstT;
m_CA = a_ammunition.m_StandardParams.m_Angle.m_CA;
m_CV0A = a_ammunition.m_StandardParams.m_Angle.m_CV0A;
m_CGammaA = a_ammunition.m_StandardParams.m_Angle.m_CGammaA;
m_CRhoA = a_ammunition.m_StandardParams.m_Angle.m_CRhoA;
m_ConstA = a_ammunition.m_StandardParams.m_Angle.m_ConstA;
if (!FireControlBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "m_CT : " << m_CT ;
TRACE_LOG(m_logger) << "m_CV0T : " << m_CV0T ;
TRACE_LOG(m_logger) << "m_CRhoT : " << m_CRhoT ;
TRACE_LOG(m_logger) << "m_ConstT : " << m_ConstT ;
TRACE_LOG(m_logger) << "m_CA : " << m_CA ;
TRACE_LOG(m_logger) << "m_CV0A : " << m_CV0A ;
TRACE_LOG(m_logger) << "m_CGammaA : " << m_CGammaA ;
TRACE_LOG(m_logger) << "m_CRhoA : " << m_CRhoA ;
TRACE_LOG(m_logger) << "m_ConstA : " << m_ConstA ;
TRACE_LOG(m_logger) << "FireControlDiscrete::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlDiscrete::getFlightTime(const Float64 a_distance,
const Float64 a_initialAmmuVelocity,
const N_Types::Radian64,
const Float64 a_airDensity)
{
Float64 d_second;
Float64 d_exp;
Float64 d_correction;
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if ((a_distance < 1.0) ||
(a_airDensity < 0.0) ||
(a_initialAmmuVelocity < 1.0))
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
// The firing time of the ammunition is calculated using the
// following formula:
// T(x,v0,rho) = (1 / m_CT * rho * v0) *
// (e**(d_cT * rho * x) -1) *
// ((d_cV0T * v0) + (d_cRhoT * rho) + m_ConstT)
// rho - air density -- kg/m**3
// x - distance -- meter
// T - firing time -- second
// v0 - initial velocity -- meter per second.
// m_VT - exponential constant for time
// m_CV0T - initial velocity correction constant
// m_CRhoT - air density correction constant
// m_ConstT - function constant
//----------------------------------------------------------
d_correction = ((m_CV0T * a_initialAmmuVelocity) +
(m_CRhoT * a_airDensity) +
m_ConstT);
d_exp = (exp(m_CT * a_airDensity * a_distance)) - 1.0;
d_second = (1.0 / (m_CT * a_airDensity * a_initialAmmuVelocity)) *
(d_exp) *
(d_correction);
if (d_second < 0.0)
d_second = 0.0;
return d_second;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlDiscrete::getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
const Float64 d_FIXED_CONST = 4.905; // fixed constant of the function
Float64 d_exp; // exponential patr of the function
Float64 d_square; // square part of the function
Float64 d_tan; // tangent value of the function
N_Types::Radian64 o_tsi; // firing angle
Float64 d_correction; // correction value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if ((a_distance < 1.0) ||
(a_airDensity < 0.0) ||
(a_initialAmmuVelocity < 1.0) ||
(a_terrainAngle > M_PI_2) ||
(a_terrainAngle < -M_PI_2))
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
// The firing angle of the ammunition is calculated using the formula:
// A(x,gamma,v0,rho) = arctan((4.905/x) * ((1/d_cA*Rho*v0) *
// ((e**(d_cA*Rho*x)-1) -- exp
// )**2 -- square
// ) -- arctan
// * correction
// correction =
// ((d_cGammaA * gamma) +
// (d_cV0A * v0) +
// (d_cRhoA * Rho) +
// (d_constA)
// )
// where:
// rho - air density -- kg/m**3
// x - distance -- meter
// A - firing angle -- radian
// gamma - angle to terrain -- radian
// v0 - initial velocity
// m_CA - exponential constant for angle
// m_CGammaA - terrain angle correction constant for angle
// m_CV0A; - initial velocity correction constant for angle
// m_CRhoA; - air density correction constant for angle
// m_ConstA; - function constant for angle
//----------------------------------------------------------
d_exp = ((exp(m_CA * a_airDensity * a_distance)) - 1.0);
d_square = pow(((1.0 / (m_CA * a_airDensity * a_initialAmmuVelocity)) * (d_exp)), Float64(2));
d_tan = (d_FIXED_CONST / a_distance) * d_square;
o_tsi = atan(d_tan);
d_correction = (m_CGammaA * a_terrainAngle) +
(m_CV0A * a_initialAmmuVelocity) +
(m_CRhoA * a_airDensity) +
m_ConstA;
o_tsi = o_tsi * d_correction;
return o_tsi;
}
} // namespace N_Ballistic
@@ -0,0 +1,106 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class imports
#include "FireControlBase.hpp"
namespace N_Ballistic
{
/**
* Discrete implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 15:01:42
*/
class FireControlDiscrete : public FireControlBase
{
public:
/**
* ## Constructors (generated)
*/
FireControlDiscrete() : FireControlBase("FireControlDiscrete") {}
/**
* initializes the class with the ballistic configuration
*
* @param a_ammunition
*/
bool init(const Ammunition &a_ammunition) override;
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
protected:
/**
* air density correction constant
*/
Float64 m_CT = 0;
/**
* air density correction constant
*/
Float64 m_CV0T = 0;
/**
* air density correction constant
*/
Float64 m_CRhoT = 0;
/**
* air density correction constant
*/
Float64 m_ConstT = 0;
/**
* air density correction constant
*/
Float64 m_CA = 0;
/**
* air density correction constant
*/
Float64 m_CV0A = 0;
/**
* air density correction constant
*/
Float64 m_CRhoA = 0;
/**
* air density correction constant
*/
Float64 m_ConstA = 0;
/**
* air density correction constant
*/
Float64 m_CGammaA = 0;
};
}
@@ -0,0 +1,164 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "FireControlPiton.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the class with the ballistic configuration
// ---------------------------------------------------------------
bool FireControlPiton::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "FireControlPiton::init : initialising..." ;
m_CRhoT = a_ammunition.m_StandardParams.m_Time.m_CRhoT;
m_ConstT = a_ammunition.m_StandardParams.m_Time.m_ConstT;
m_CRhoA = a_ammunition.m_StandardParams.m_Angle.m_CRhoA;
m_ConstA = a_ammunition.m_StandardParams.m_Angle.m_ConstA;
if (!FireControlBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "m_CRhoT : " << m_CRhoT ;
TRACE_LOG(m_logger) << "m_ConstT : " << m_ConstT ;
TRACE_LOG(m_logger) << "m_CRhoA : " << m_CRhoA ;
TRACE_LOG(m_logger) << "m_ConstA : " << m_ConstA ;
TRACE_LOG(m_logger) << "FireControlPiton::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlPiton::getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
const Float64 d_THREE_OVER_TWO = 3.0 / 2.0;
const Float64 d_TWO_OVER_NINE = 2.0 / 9.0;
Float64 d_second;
Float64 d_correction;
Float64 d_temp; // temp value
Float64 d_laserDistY; // Y laser value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if ((a_distance < 1.0) ||
(a_airDensity < 0.0) ||
(a_initialAmmuVelocity < 1.0) ||
(a_terrainAngle > M_PI_2) ||
(a_terrainAngle < -M_PI_2))
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
// t = (2.0 / (9.0 * v0 * cos(Gamma))) * corr1
// corr1 = (pow(corr2, 2/3) - 1) / KT
// corr2 = 1 + (3 * KT * Xe)
// KT = cRhoT * Rho + constT
// Gamma - terrain angle
// Rho - air density
// v0 - initial ammu velocity
// cRhoT, constT - parameter
//----------------------------------------------------------
// f_LaserDistZ = a_Distance * sin(a_TerrainAngle);
d_laserDistY = a_distance * cos(a_terrainAngle);
d_temp = (m_CRhoT * a_airDensity) + m_ConstT;
d_correction = 1 + (3.0 * d_temp * d_laserDistY);
d_correction = pow(d_correction, d_THREE_OVER_TWO);
d_correction -= 1.0;
d_correction /= d_temp;
d_second = (d_TWO_OVER_NINE * d_correction) /
(a_initialAmmuVelocity * cos(a_terrainAngle));
if (d_second < 0.0)
d_second = 0.0;
return d_second;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlPiton::getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity)
{
Float64 d_square; // square part of the function
Float64 d_tan; // tangent value of the function
N_Types::Radian64 o_tsi; // firing angle
Float64 d_correction; // correction value
Float64 d_temp; // temp value
Float64 d_laserDistZ; // Z laser value
Float64 d_laserDistY; // Y laser value
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return 0.0;
}
if ((a_distance < 1.0) ||
(a_airDensity < 0.0) ||
(a_initialAmmuVelocity < 1.0) ||
(a_terrainAngle > M_PI_2) ||
(a_terrainAngle < -M_PI_2))
{
ERROR_LOG(m_logger) << "The parameters are not correct" ;
return 0.0;
}
// Tsi = atan((1/2) * ((Xe/c) - sqrt))
// sqrt = pow((Xe/c), 2) - 4 * (Ye + c) / c
// c = 9.81 * pow(Xe, 2) * (1 + k + Xe) / ( 2 * pow(v0, 2))
// k = cRhoA * Rho + constA
// Xe = D * cos(Gamma)
//
// Gamma - terrain angle
// Rho - air density
// v0 - initial ammu velocity
// cRhoA, constA - constants
//----------------------------------------------------------
d_laserDistZ = a_distance * sin(a_terrainAngle);
d_laserDistY = a_distance * cos(a_terrainAngle);
d_temp = (m_CRhoA * a_airDensity) + m_ConstA;
d_correction = N_SST::G * pow(d_laserDistY, Float64(2)) * (1.0 + (d_temp * d_laserDistY));
d_correction /= (2.0 * pow(a_initialAmmuVelocity, Float64(2)));
d_square = pow((d_laserDistY / d_correction), Float64(2));
d_square -= ((4.0 * (d_laserDistZ + d_correction)) / d_correction);
d_square = sqrt(d_square);
d_tan = (d_laserDistY / d_correction) - d_square;
d_tan /= 2.0;
o_tsi = atan(d_tan);
o_tsi -= a_terrainAngle;
return o_tsi;
}
} // namespace N_Ballistic
@@ -0,0 +1,86 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class imports
#include "FireControlBase.hpp"
namespace N_Ballistic
{
/**
* Piton Bressant implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 15:01:30
*/
class FireControlPiton : public FireControlBase
{
public:
/**
* ## Constructors (generated)
*/
FireControlPiton() : FireControlBase("FireControlPiton") {}
/**
* initializes the class with the ballistic configuration
*
* @param a_ammunition
*/
bool init(const Ammunition &a_ammunition) override;
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
protected:
/**
* air density correction constant
*/
Float64 m_CRhoT = 0;
/**
* air density correction constant
*/
Float64 m_CRhoA = 0;
/**
* air density correction constant
*/
Float64 m_ConstT = 0;
/**
* air density correction constant
*/
Float64 m_ConstA = 0;
};
}
@@ -0,0 +1,88 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "FireControlRungeKutta.hpp"
#include "TrajectoryRungeKutta.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// returns the flight time of the projectile in seconds
// ---------------------------------------------------------------
Float64 FireControlRungeKutta::getFlightTime(const Float64,
const Float64,
const N_Types::Radian64,
const Float64)
{
Q_ASSERT(false);
ERROR_LOG(m_logger) << "This algorithm has no implementation for flight time" ;
return -1;
}
// ---------------------------------------------------------------
// returns the firing angle of the projectile if the following
// are given
// ---------------------------------------------------------------
Float64 FireControlRungeKutta::getFireAngle(const Float64,
const Float64,
const N_Types::Radian64,
const Float64)
{
Q_ASSERT(false);
ERROR_LOG(m_logger) << "This algorithm has no implementation for fire angle" ;
return 0;
}
// ---------------------------------------------------------------
// returns the air density, provided the following are given
// ---------------------------------------------------------------
Float64 FireControlRungeKutta::getAirDensity(const Float64 a_atmosphericPressure, const Float64 a_airTemperature)
{
const Float64 d_FIXED_CONST = 0.348368; // fixed constant of the function
Float64 d_kelvin;
Float64 d_rho;
if ((a_atmosphericPressure <= 1.0) ||
(a_airTemperature <= -N_SST::ZERO_CELSIUS_IN_KELVIN))
{
ERROR_LOG(m_logger) << "The parameters are not correct, Pressure=" << a_atmosphericPressure << ", Temp=" << a_airTemperature ;
return 1.0;
}
TrajectoryRungeKutta::m_Temp = a_airTemperature;
DEBUG_LOG(m_logger) << "Temp for Trajectory set: " << TrajectoryRungeKutta::m_Temp ;
d_kelvin = a_airTemperature + N_SST::ZERO_CELSIUS_IN_KELVIN;
d_rho = d_FIXED_CONST * a_atmosphericPressure / d_kelvin;
return d_rho;
}
// ---------------------------------------------------------------
// returns the theritical initial ammu velocity of the
// ammunition
// ---------------------------------------------------------------
Float64 FireControlRungeKutta::getInitialAmmuVelocity(const Float64 a_temperature)
{
TrajectoryRungeKutta::m_TempWeapon = a_temperature;
DEBUG_LOG(m_logger) << "Temp for Weapon set: " << TrajectoryRungeKutta::m_TempWeapon ;
return 0.0;
}
} // namespace N_Ballistic
@@ -0,0 +1,77 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "FireControlBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* RungeKutta implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 22-Jul-2010 11:44:20
*/
class FireControlRungeKutta : public FireControlBase
{
public:
FireControlRungeKutta(const char *loggerName = nullptr)
: FireControlBase(loggerName ? loggerName : "FireControlRungeKutta")
{}
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) override;
/**
* returns the air density, provided the following are given
*
* @param a_atmosphericPressure Pressure
* @param a_airTemperature Temperature
*/
Float64 getAirDensity(const Float64 a_atmosphericPressure, const Float64 a_airTemperature) override;
/**
* returns the theritical initial ammu velocity of the ammunition
*
* @param a_temperature Temperature
*/
Float64 getInitialAmmuVelocity(const Float64 a_temperature) override;
};
}
@@ -0,0 +1,39 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "FireControlRungeKutta.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Simple RungeKutta implementation for fire calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 22-Jul-2010 12:11:39
*/
class FireControlRungeKuttaSimple : public FireControlRungeKutta
{
public:
FireControlRungeKuttaSimple() : FireControlRungeKutta("FireControlRungeKuttaSimple") {}
};
}
@@ -0,0 +1,48 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "Ammunition.hpp"
// manual class imports
class QString;
namespace N_Ballistic
{
/**
* This is the interface to the ballistic configuration mecanism
*
* @author Daniel.Schmid
* @version 1.0
* @created 11-Aug-2009 16:14:34
*/
class IBallisticConfigurator
{
public:
virtual ~IBallisticConfigurator() = default;
/**
* load the configfile and creates ammunition objects for all found entries
*
* @param a_configFilename
* @param a_ammunitions
*/
virtual bool loadAmmunitions(const QString &a_configFilename, std::vector<Ammunition *> &a_ammunitions) = 0;
};
}
@@ -0,0 +1,91 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include <GBL_Types/Radian64.hpp>
#include <GBL_Types/Coord3.hpp>
#include "IUnknown.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Interface for fire control implementations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:37:13
*/
class IFireControl : public IUnknown
{
public:
/**
* returns the flight time of the projectile in seconds
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFlightTime(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) = 0;
/**
* returns the firing angle of the projectile if the following are given
*
* @param a_distance distance to the target
* @param a_initialAmmuVelocity initial velocity
* @param a_terrainAngle gun angle to terrain
* @param a_airDensity air density
*/
virtual Float64 getFireAngle(const Float64 a_distance, const Float64 a_initialAmmuVelocity, const N_Types::Radian64 a_terrainAngle, const Float64 a_airDensity) = 0;
/**
* This function corrects the fire angle due to the cross wind, if the following
* are given
*
* @param a_crossWind wind speed
* @param a_distance distance from gun
*/
virtual N_Types::Radian64 getCrossWindCorrection(const Float64 a_crossWind, const Float64 a_distance) = 0;
/**
* returns the air density
*
* @param a_atmosphericPressure Pressure
* @param a_airTemperature Temperature
*/
virtual Float64 getAirDensity(const Float64 a_atmosphericPressure, const Float64 a_airTemperature) = 0;
/**
* This function corrects the fire angle due to the cross wind
*
* @param a_crossWind Wind direction
* @param a_turretDir Direction of Turret
*/
virtual Float64 getCrossWind(const N_Types::Coord3 &a_crossWind, const Float64 a_turretDir) = 0;
/**
* returns the theritical initial ammu velocity of the ammunition
*
* @param a_temperature Temperature
*/
virtual Float64 getInitialAmmuVelocity(const Float64 a_temperature) = 0;
};
}
@@ -0,0 +1,117 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "IUnknown.hpp"
#include <GBL_Types/Angle3.hpp>
#include <GBL_Types/Coord3.hpp>
// manual class imports
namespace N_Ballistic
{
/**
* Interface for trajectory implementations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:36:55
*/
class ITrajectory : public IUnknown
{
public:
virtual ~ITrajectory() = default;
/**
* initializes the object with the following parameters
*
* @param a_gunPos Position of the gun
* @param a_gunAngle Shooting angle of the gun
* @param a_crossWind lateral wind
* @param a_airDensity
* @param a_initialAmmuSpeed ammunition speed
*/
virtual bool init(const N_Types::Coord3 &a_gunPos,
const N_Types::Angle3 &a_gunAngle,
const Float64 a_crossWind,
const Float64 a_airDensity,
const Float64 a_initialAmmuSpeed) = 0;
/**
* calculates the next tracer point using the delta time
*
* @param a_deltaTime time difference to last call
*/
virtual bool move(const Float64 a_deltaTime) = 0;
/**
* returns the current position of the tracer
*/
virtual const N_Types::Coord3 &getPosition() const = 0;
/**
* returns the current orientation of the tracer
*/
virtual const N_Types::Angle3 &getOrient() const = 0;
/**
* returns the acceleration/deceleration vector
*/
virtual const N_Types::Coord3 &getAccel() const = 0;
/**
* returns the velocity vector
*/
virtual const N_Types::Coord3 &getVelocity() const = 0;
/**
* this function returns the state of the tracer
*/
virtual bool isActive() const = 0;
/**
* deactivate a tracer
*/
virtual void deactivate() = 0;
/**
* sets an integer ID of the bullet, used for SimMunitionIDs
*
* @param a_id
*/
virtual void setID(SInt32 a_id) = 0;
/**
* gets an integer ID of the bullet, used for SimMunitionIDs
*/
virtual SInt32 getID() const = 0;
/**
* if a bullet detonates after a certain timeout, defined by the timeout in the
* config file
*/
virtual bool IsDetonateOnTimer() const = 0;
/**
* if a bullet detonates on either terrain or object impact
*/
virtual bool IsDetonateOnImpact() const = 0;
};
}
@@ -0,0 +1,49 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
// manual class imports
namespace N_Ballistic
{
/**
* Base Interface for all interfaces used in this package
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 13:41:51
*/
class IUnknown
{
public:
virtual ~IUnknown() = default;
/**
* Using this function a reference to the interface is added.
*/
virtual SInt32 addRef() = 0;
/**
* Calling this function the reference from the interface may be removed.
*/
virtual SInt32 release() = 0;
};
}
@@ -0,0 +1,53 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
#include <vector>
namespace N_Ballistic
{
/**
* Polygonal representation of ballistic values
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:07:22
*/
struct PolygonParamType
{
/**
* Container for PolyCoefficientType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:08:15
*/
struct PolyCoefficientType
{
SInt32 m_Index = 0;
Float64 m_Coeff = 0.0;
};
std::vector<PolyCoefficientType> m_AY;
std::vector<PolyCoefficientType> m_AX;
Float64 m_InitialAX = 0.0;
bool m_Valid = false;
};
}
@@ -0,0 +1,106 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
namespace N_Ballistic
{
/**
* Standard values of ammunition
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:08:46
*/
struct StandardType
{
/**
* Container for CrossWindType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:10:42
*/
struct CrossWindType
{
Float64 m_ConstX3 = 0.0;
Float64 m_ConstX2 = 0.0;
Float64 m_ConstX1 = 0.0;
Float64 m_ConstX0 = 0.0;
};
/**
* Container for AngleType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:10:34
*/
struct AngleType
{
Float64 m_CA = 0.0;
Float64 m_CGammaA = 0.0;
Float64 m_CV0A = 0.0;
Float64 m_CRhoA = 0.0;
Float64 m_ConstA = 0.0;
};
/**
* Container for SpeedType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:11:00
*/
struct SpeedType
{
/**
* Initial ammunition velocity
*/
Float64 m_V0ConstX1 = 0.0;
/**
* Correction constant in function of temperature
*/
Float64 m_V0ConstX0 = 0.0;
};
/**
* Container for TimeType
*
* @author Daniel.Schmid
* @version 1.0
* @created 10-Aug-2009 11:11:08
*/
struct TimeType
{
Float64 m_CT = 0.0;
Float64 m_CV0T = 0.0;
Float64 m_CRhoT = 0.0;
Float64 m_ConstT = 0.0;
};
StandardType::TimeType m_Time;
StandardType::SpeedType m_Speed;
StandardType::AngleType m_Angle;
StandardType::CrossWindType m_CrossWind;
bool m_Valid = false;
};
}
@@ -0,0 +1,186 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryAntonio.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryAntonio::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "TrajectoryAntonio::init : initialising..." ;
if (a_ammunition.m_StandardParams.m_Valid)
{
m_CRhoY1 = a_ammunition.m_StandardParams.m_Time.m_CRhoT;
m_CRhoZ1 = a_ammunition.m_StandardParams.m_Angle.m_CRhoA;
m_UseStandard = true;
INFO_LOG(m_logger) << "m_CRhoY1 : " << m_CRhoY1 ;
INFO_LOG(m_logger) << "m_CRhoZ1 : " << m_CRhoZ1 ;
}
else if (a_ammunition.m_PolygonParams.m_Valid)
{
m_InitialAX = a_ammunition.m_PolygonParams.m_InitialAX;
INFO_LOG(m_logger) << "m_InitialAX : " << m_InitialAX ;
int axcount = a_ammunition.m_PolygonParams.m_AX.size();
for (int i = 0; i < axcount; i++)
{
m_AX.push_back(a_ammunition.m_PolygonParams.m_AX[i].m_Coeff);
INFO_LOG(m_logger) << "AX " << a_ammunition.m_PolygonParams.m_AX[i].m_Index << " = " << a_ammunition.m_PolygonParams.m_AX[i].m_Coeff ;
}
int aycount = a_ammunition.m_PolygonParams.m_AY.size();
for (int i = 0; i < aycount; i++)
{
m_AY.push_back(a_ammunition.m_PolygonParams.m_AY[i].m_Coeff);
INFO_LOG(m_logger) << "AY " << a_ammunition.m_PolygonParams.m_AY[i].m_Index << " = " << a_ammunition.m_PolygonParams.m_AY[i].m_Coeff ;
}
m_UsePolynom = true;
}
else
{
ERROR_LOG(m_logger) << "Parameters missing..." ;
return false;
}
if (!TrajectoryBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "TrajectoryAntonio::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryAntonio::getNextPoint()
{
if (m_UseStandard)
return getNextPointStandard();
if (m_UsePolynom)
return getNextPointPolynom();
ERROR_LOG(m_logger) << "Initialisation not correct" ;
return N_Types::Coord3();
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryAntonio::getNextPointStandard()
{
Float64 d_correction;
Float64 d_tmpConst;
N_Types::Coord3 o_coord3;
m_MyTime += m_Tact;
d_correction = 1.0 +
(m_CRhoY1 *
m_AirDensity *
m_InitialAmmuSpeed *
cos(m_GunAngle.m_P) *
m_MyTime);
o_coord3.m_Y = (m_InitialAmmuSpeed * cos(m_GunAngle.m_P) * m_MyTime) / d_correction;
d_correction = N_SST::G * pow(o_coord3.m_Y, 2.0);
d_correction /= (2.0 * pow(m_InitialAmmuSpeed, 2.0) * pow(cos(m_GunAngle.m_P), 2.0));
d_correction /= (1.0 + m_CRhoZ1 * m_AirDensity * o_coord3.m_Y);
d_tmpConst = 1.0 - m_CRhoY1 * m_AirDensity * o_coord3.m_Y;
d_tmpConst = pow(d_tmpConst, 2.0);
d_correction /= d_tmpConst;
o_coord3.m_Z = (o_coord3.m_Y * tan(m_GunAngle.m_P)) - d_correction;
d_correction = o_coord3.m_Y / (m_InitialAmmuSpeed * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_MyTime - d_correction);
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryAntonio::getNextPointPolynom()
{
Float64 d_correction = 0.0;
Float64 d_tmpConst = 0.0;
Float64 d_ax = 0.0;
Float64 d_ay = 0.0;
N_Types::Coord3 o_coord3;
m_MyTime += m_Tact;
//
// ax = (ax0 * t^0) + (ax1 * t^1) + (ax2 * t^2) + (ax3 * t^3) ...
//
for (unsigned int i = 0; i < m_AX.size(); i++)
d_ax += m_AX[i] * pow(m_MyTime, i);
for (unsigned int i = 0; i < m_AY.size(); i++)
d_ay += m_AY[i] * pow(m_MyTime, i);
// v0 * t
// x = ---------------------
// 1 + (ax * p * v0 * t)
d_correction = 1.0 +
(d_ax *
m_AirDensity *
m_InitialAmmuSpeed *
m_MyTime);
// INFO_LOG(m_logger) << "AX:" << d_ax << " AD:" << m_AirDensity << " IS:" << m_InitialAmmuSpeed << " MT:" << m_MyTime << " C:" << d_correction ;
o_coord3.m_Y = (m_InitialAmmuSpeed * m_MyTime) / d_correction;
// g * x
// y = x * ( tan (a) - ----------------------------- )
// 2 * v0^2 * (1- ay * p * x)^2
d_correction = N_SST::G * o_coord3.m_Y;
d_correction /= (2.0 * pow(m_InitialAmmuSpeed, 2.0));
d_tmpConst = 1.0 - d_ay * m_AirDensity * o_coord3.m_Y;
d_tmpConst = pow(d_tmpConst, 2.0);
d_correction /= d_tmpConst;
o_coord3.m_Z = o_coord3.m_Y * (tan(m_GunAngle.m_P) - d_correction);
// x
// z = w * ( t - ---- )
// v0
d_correction = o_coord3.m_Y / m_InitialAmmuSpeed;
o_coord3.m_X = m_CrossWind * (m_MyTime - d_correction);
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
} // namespace N_Ballistic
@@ -0,0 +1,82 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* D'Antonio implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 14:27:28
*/
class TrajectoryAntonio : public TrajectoryBase
{
public:
/**
* ## Constructors (generated)
*/
TrajectoryAntonio() : TrajectoryBase("TrajectoryAntonio") {}
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
bool init(const Ammunition &a_ammunition) override;
protected:
std::vector<Float64> m_AX;
std::vector<Float64> m_AY;
Float64 m_CRhoY1 = 0;
Float64 m_CRhoZ1 = 0;
Float64 m_InitialAX = 0;
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
private:
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPointStandard();
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPointPolynom();
private:
bool m_UseStandard = false;
bool m_UsePolynom = false;
};
}
@@ -0,0 +1,254 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryBase.hpp"
#include "../logger.h"
namespace N_Ballistic
{
TrajectoryBase::TrajectoryBase(const char *loggerName)
: m_logger(CesGeoPairing::getLogger(loggerName))
{
}
TrajectoryBase::~TrajectoryBase()
{
deinit();
}
// ---------------------------------------------------------------
// Using this function a reference to the interface is added.
// ---------------------------------------------------------------
SInt32 TrajectoryBase::addRef()
{
return m_MyRefCounter++;
}
// ---------------------------------------------------------------
// Calling this function the reference from the interface may
// be removed.
// ---------------------------------------------------------------
SInt32 TrajectoryBase::release()
{
--m_MyRefCounter;
if (m_MyRefCounter <= 0)
{
delete this;
return 0;
}
else
return m_MyRefCounter;
}
// ---------------------------------------------------------------
// initializes the object with the following parameters
// ---------------------------------------------------------------
bool TrajectoryBase::init(const N_Types::Coord3 &a_gunPos, const N_Types::Angle3 &a_gunAngle, const Float64 a_crossWind, const Float64 a_airDensity, const Float64 a_initialAmmuSpeed)
{
m_GunPos = a_gunPos;
m_GunAngle = a_gunAngle;
m_CrossWind = a_crossWind;
m_AirDensity = a_airDensity;
m_InitialAmmuSpeed = a_initialAmmuSpeed;
if (m_Deviation != 0)
{
INFO_LOG(m_logger) << "Deviation taken into account: " << m_Deviation ;
Float64 l_deviationRandomized = m_Deviation * (Float64)(rand() % 100) / 100.0;
INFO_LOG(m_logger) << "l_deviationRandomized = " << l_deviationRandomized ;
N_Types::Coord3 o_dev(l_deviationRandomized, 1000.0, 0.0);
//INFO_LOG(m_logger) << "o_dev = " << o_dev ;
Float64 l_angleRandomized = rand() % 360;
INFO_LOG(m_logger) << "l_angleRandomized = " << l_angleRandomized ;
N_Types::Radian64 l_angleRad;
l_angleRad.setDegree(l_angleRandomized);
o_dev = o_dev.rotateY(l_angleRad);
N_Types::Angle3 o_angle;
o_angle.m_H = o_dev.getPolar3().getAzimuth();
o_angle.m_P = o_dev.getPolar3().getElevation();
//INFO_LOG(m_logger) << "o_angle = " << o_angle << END_LOG
m_GunAngle = m_GunAngle + o_angle;
}
N_Types::Coord3 o_coord3(0.0, 1.0, 0.0);
o_coord3 = o_coord3.rotate(m_GunAngle);
m_Velocity = o_coord3 * m_InitialAmmuSpeed;
m_MyTime = 0.0;
m_MyAngle = m_GunAngle.m_P;
m_MyPoints[0] = m_GunPos;
m_MyPoints[1] = m_GunPos;
m_Active = true;
return true;
}
// ---------------------------------------------------------------
// calculates the next tracer point using the delta time
// ---------------------------------------------------------------
bool TrajectoryBase::move(const Float64 a_deltaTime)
{
if (!m_Initialized)
{
WARNING_LOG(m_logger) << "The class is not initialized" ;
return false;
}
if (!m_Active)
{
ERROR_LOG(m_logger) << "Call init(gunPos, gunAngle, ...) first" ;
return false;
}
m_Tact = a_deltaTime;
m_MyPoints[0] = m_MyPoints[1];
m_MyPoints[1] = getNextPoint();
// set velovity, acceleration, orientation and time out of the tracer
setVelAccelOrientTimeOut();
return true;
}
// ---------------------------------------------------------------
// deactivate a tracer
// ---------------------------------------------------------------
void TrajectoryBase::deactivate()
{
m_Active = false;
}
// ---------------------------------------------------------------
// sets an integer ID of the bullet, used for SimMunitionIDs
// ---------------------------------------------------------------
void TrajectoryBase::setID(SInt32 a_id)
{
m_MyID = a_id;
}
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryBase::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "TrajectoryBase::init : initialising..." ;
m_TimeOutCycles = a_ammunition.m_AmmunInfo.m_TimeOut / 1000.0;
m_TimeOut = m_TimeOutCycles;
m_Deviation = a_ammunition.m_AmmunInfo.m_Deviation;
if (a_ammunition.m_AmmunInfo.m_ReasonToDetonate == QStringLiteral("OnTimer"))
{
m_IsDetonateOnTimer = true;
m_IsDetonateOnImpact = false;
}
if (a_ammunition.m_AmmunInfo.m_ReasonToDetonate == QStringLiteral("OnImpact"))
{
m_IsDetonateOnTimer = false;
m_IsDetonateOnImpact = true;
}
TRACE_LOG(m_logger) << "TrajectoryBase::init : initialized successfully!" ;
TRACE_LOG(m_logger) << "m_TimeOutCycles : " << m_TimeOutCycles ;
m_Initialized = true;
return true;
}
// ---------------------------------------------------------------
// deinitializes the class
// ---------------------------------------------------------------
bool TrajectoryBase::deinit()
{
m_Initialized = false;
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryBase::getNextPoint()
{
N_Types::Coord3 o_coord3;
Float64 d_correction;
m_MyTime += m_Tact;
o_coord3.m_Y = m_InitialAmmuSpeed * m_MyTime * cos(m_MyAngle);
o_coord3.m_Z = (m_InitialAmmuSpeed * m_MyTime * sin(m_MyAngle)) -
(N_SST::G * pow(m_MyTime, 2.0) / 2.0);
d_correction = o_coord3.m_Y / (m_InitialAmmuSpeed * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_MyTime - d_correction);
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
// ---------------------------------------------------------------
// computes the velocity, acceleration, orientation and time
// out of the tracer
// ---------------------------------------------------------------
void TrajectoryBase::setVelAccelOrientTimeOut()
{
N_Types::Polar3 o_polar3;
if (m_TimeOut <= 0)
m_MyPoints[1] = m_MyPoints[0];
m_Velocity = (m_MyPoints[1] - m_MyPoints[0]) / m_Tact;
m_Acceleration = (m_Velocity - m_VelocityLast) / m_Tact;
m_VelocityLast = m_Velocity;
o_polar3 = m_Velocity.getPolar3();
m_Orientation.m_H = o_polar3.m_Azimuth;
m_Orientation.m_P = o_polar3.m_Elevation;
m_Orientation.m_R = 0.0;
m_CycleCount++;
m_TimeOut -= m_Tact;
if (m_TimeOut < 0)
{
INFO_LOG(m_logger) << "Bullet timed out : " << m_TimeOutCycles ;
m_Active = false;
}
}
} // namespace N_Ballistic
@@ -0,0 +1,247 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#include <GBL_Global/Types.hpp>
#include <NGLLogger/INGLLogger.h>
// from stereotyped includes
#include "ITrajectory.hpp"
#include "Ammunition.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Base implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 14:26:59
*/
class TrajectoryBase : public ITrajectory
{
public:
explicit TrajectoryBase(const char *loggerName);
virtual ~TrajectoryBase();
/**
* Using this function a reference to the interface is added.
*/
SInt32 addRef() override;
/**
* Calling this function the reference from the interface may be removed.
*/
SInt32 release() override;
/**
* initializes the object with the following parameters
*
* @param a_gunPos Position of the gun
* @param a_gunAngle Shooting angle of the gun
* @param a_crossWind lateral wind
* @param a_airDensity Air density
* @param a_initialAmmuSpeed ammunition speed
*/
bool init(const N_Types::Coord3 &a_gunPos,
const N_Types::Angle3 &a_gunAngle,
const Float64 a_crossWind,
const Float64 a_airDensity,
const Float64 a_initialAmmuSpeed) override;
/**
* calculates the next tracer point using the delta time
*
* @param a_deltaTime time difference to last call
*/
bool move(const Float64 a_deltaTime) override;
/**
* returns the current position of the tracer
*/
const N_Types::Coord3 &getPosition() const override { return m_MyPoints[1]; }
/**
* returns the current orientation of the tracer
*/
const N_Types::Angle3 &getOrient() const override { return m_Orientation; }
/**
* returns the acceleration/deceleration vector
*/
const N_Types::Coord3 &getAccel() const override { return m_Acceleration; }
/**
* returns the velocity vector
*/
const N_Types::Coord3 &getVelocity() const override { return m_Velocity; }
/**
* this function returns the state of the tracer
*/
bool isActive() const override { return m_Active; }
/**
* deactivate a tracer
*/
void deactivate() override;
/**
* sets an integer ID of the bullet, used for SimMunitionIDs
*
* @param a_id
*/
void setID(SInt32 a_id) override;
/**
* gets an integer ID of the bullet, used for SimMunitionIDs
*/
SInt32 getID() const override { return m_MyID; }
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
virtual bool init(const Ammunition &a_ammunition);
/**
* if a bullet detonates after a certain timeout, defined by the timeout in the
* config file
*/
bool IsDetonateOnTimer() const override { return m_IsDetonateOnTimer; }
/**
* if a bullet detonates on either terrain or object impact
*/
bool IsDetonateOnImpact() const override { return m_IsDetonateOnImpact; }
protected:
/**
* Instance reference counter
*/
SInt32 m_MyRefCounter = 0;
/**
* initial gun position
*/
N_Types::Coord3 m_GunPos;
/**
* initial gun angle
*/
N_Types::Angle3 m_GunAngle;
/**
* cross wind in m/s
*/
Float64 m_CrossWind = 0;
/**
* AirDensity
*/
Float64 m_AirDensity = 0;
Float64 m_InitialAmmuSpeed = 0;
/**
* stores the alive state of the bullet. as soon as the bullet is deactivated, it
* is destroyed in the next cycle
*/
bool m_Active = false;
/**
* time since launch
*/
Float64 m_MyTime = 0;
/**
* current flying angle
*/
Float64 m_MyAngle = 0;
/**
* array of last and current position
*/
N_Types::Coord3 m_MyPoints[2] = {};
/**
* current acceleration
*/
N_Types::Coord3 m_Acceleration;
/**
* current velocity
*/
N_Types::Coord3 m_Velocity;
/**
* last velocity
*/
N_Types::Coord3 m_VelocityLast;
/**
* current orientation
*/
N_Types::Angle3 m_Orientation;
Float64 m_Tact = 0;
SInt32 m_CycleCount = 0;
bool m_Initialized = false;
/**
* Time in ms to detonate
*/
Float64 m_TimeOutCycles = 0;
/**
* time to detonate, decremented variable
*/
Float64 m_TimeOut = 0;
/**
* SimMunitionID
*/
SInt32 m_MyID = 0;
/**
* timed detonation of grenades
*/
bool m_IsDetonateOnTimer = false;
/**
* bullet detonates on impact
*/
bool m_IsDetonateOnImpact = false;
/**
* This is the value of devivation of the ammunition, which helps to simulate the
* variation between the different shoots
*/
Float64 m_Deviation = 0;
/**
* This is the value of derivation of the ammunition, which helps to simulate the
* right drift due to the rotation of the bullet
*/
Float64 m_Derivation = 0;
/**
* logger object
*/
NGL::INGLLogger &m_logger;
/**
* deinitializes the class
*/
virtual bool deinit();
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
virtual N_Types::Coord3 getNextPoint();
/**
* computes the velocity, acceleration, orientation and time out of the tracer
*/
void setVelAccelOrientTimeOut();
};
}
@@ -0,0 +1,93 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryDecoy.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryDecoy::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
INFO_LOG(m_logger) << "initialising..." ;
m_SinkingVelocity = a_ammunition.m_StandardParams.m_Speed.m_V0ConstX1;
m_HeightRange = a_ammunition.m_AmmunInfo.m_Range;
//a_ammunition.m_StandardParams->m_Speed->m_V0ConstX0 >> m_InitialAmmuSpeed;
if (!TrajectoryBase::init(a_ammunition))
return false;
m_Sinking = false;
TRACE_LOG(m_logger) << "m_SinkingVelocity : " << m_SinkingVelocity ;
TRACE_LOG(m_logger) << "m_InitialAmmuSpeed : " << m_InitialAmmuSpeed ;
TRACE_LOG(m_logger) << "m_HeightRange : " << m_HeightRange ;
TRACE_LOG(m_logger) << "initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryDecoy::getNextPoint()
{
N_Types::Coord3 o_coord3;
m_MyTime += m_Tact;
o_coord3.m_Y = m_InitialAmmuSpeed * m_MyTime * cos(m_MyAngle);
if (!m_Sinking)
{
Float64 d_steigend = (m_InitialAmmuSpeed * m_MyTime * sin(m_MyAngle));
Float64 d_gravity = (N_SST::G * pow(m_MyTime, 2.0) / 2.0);
o_coord3.m_Z = d_steigend - d_gravity;
Float64 d_correction = o_coord3.m_Y / (m_InitialAmmuSpeed * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_MyTime - d_correction);
if (o_coord3.m_Z > m_HeightRange)
{
INFO_LOG(m_logger) << "Start sinking" ;
m_SinkingPoint = o_coord3;
m_Sinking = true;
}
m_SinkingStartTime = m_MyTime;
INFO_LOG(m_logger) << "Ascending: Time=" << m_MyTime << " Height=" << o_coord3.m_Z << " Side=" << o_coord3.m_X ;
}
if (m_Sinking)
{
o_coord3.m_Z = m_SinkingPoint.m_Z - (m_SinkingVelocity * (m_MyTime - m_SinkingStartTime));
o_coord3.m_X = m_SinkingPoint.m_X - (m_CrossWind * (m_MyTime - m_SinkingStartTime));
INFO_LOG(m_logger) << "Sinking: Time=" << m_MyTime << " Height=" << o_coord3.m_Z << " Side=" << o_coord3.m_X ;
}
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
} // namespace N_Ballistic
@@ -0,0 +1,66 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Decoy implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 14:27:46
*/
class TrajectoryDecoy : public TrajectoryBase
{
public:
/**
* ## Constructors (generated)
*/
TrajectoryDecoy() : TrajectoryBase("TrajectoryDecoy") {}
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
bool init(const Ammunition &a_ammunition) override;
protected:
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
private:
Float64 m_SinkingVelocity = 0;
Float64 m_HeightRange = 0;
Float64 m_SinkingStartTime = 0;
N_Types::Coord3 m_SinkingPoint;
bool m_Sinking = false;
};
}
@@ -0,0 +1,136 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryDiscrete.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryDiscrete::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
if (!a_ammunition.m_DiscreteParams.m_Valid)
{
ERROR_LOG(m_logger) << "a_Ammunition.m_DiscreteParams is not valid" ;
return false;
}
TRACE_LOG(m_logger) << "TrajectoryPiton::init : initialising..." ;
m_CAY = a_ammunition.m_DiscreteParams.m_YAxis.m_CA;
m_CT2Y = a_ammunition.m_DiscreteParams.m_YAxis.m_CT2;
m_CT1Y = a_ammunition.m_DiscreteParams.m_YAxis.m_CT1;
m_CAlpha2Y = a_ammunition.m_DiscreteParams.m_YAxis.m_CAlpha2;
m_CAlpha1Y = a_ammunition.m_DiscreteParams.m_YAxis.m_CAlpha1;
m_CRhoY = a_ammunition.m_DiscreteParams.m_YAxis.m_CRho;
m_CVY = a_ammunition.m_DiscreteParams.m_YAxis.m_CV;
m_C0Y = a_ammunition.m_DiscreteParams.m_YAxis.m_C0;
m_CAZ = a_ammunition.m_DiscreteParams.m_ZAxis.m_CA;
m_CT2Z = a_ammunition.m_DiscreteParams.m_ZAxis.m_CT2;
m_CT1Z = a_ammunition.m_DiscreteParams.m_ZAxis.m_CT1;
m_CAlpha2Z = a_ammunition.m_DiscreteParams.m_ZAxis.m_CAlpha2;
m_CAlpha1Z = a_ammunition.m_DiscreteParams.m_ZAxis.m_CAlpha1;
m_CVZ = a_ammunition.m_DiscreteParams.m_ZAxis.m_CV;
m_C0Z = a_ammunition.m_DiscreteParams.m_ZAxis.m_C0;
m_CAX = a_ammunition.m_DiscreteParams.m_XAxis.m_CA;
m_CAlpha1X = a_ammunition.m_DiscreteParams.m_XAxis.m_CAlpha1;
m_C0X = a_ammunition.m_DiscreteParams.m_XAxis.m_C0;
if (!TrajectoryBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "m_CAY : " << m_CAY ;
TRACE_LOG(m_logger) << "m_CT2Y : " << m_CT2Y ;
TRACE_LOG(m_logger) << "m_CT1Y : " << m_CT1Y ;
TRACE_LOG(m_logger) << "m_CAlpha2Y : " << m_CAlpha2Y ;
TRACE_LOG(m_logger) << "m_CAlpha1Y : " << m_CAlpha1Y ;
TRACE_LOG(m_logger) << "m_CRhoY : " << m_CRhoY ;
TRACE_LOG(m_logger) << "m_CVY : " << m_CVY ;
TRACE_LOG(m_logger) << "m_C0Y : " << m_C0Y ;
TRACE_LOG(m_logger) << "m_CAZ : " << m_CAZ ;
TRACE_LOG(m_logger) << "m_CT2Z : " << m_CT2Z ;
TRACE_LOG(m_logger) << "m_CT1Z : " << m_CT1Z ;
TRACE_LOG(m_logger) << "m_CAlpha2Z : " << m_CAlpha2Z ;
TRACE_LOG(m_logger) << "m_CAlpha1Z : " << m_CAlpha1Z ;
TRACE_LOG(m_logger) << "m_CVZ : " << m_CVZ ;
TRACE_LOG(m_logger) << "m_C0Z : " << m_C0Z ;
TRACE_LOG(m_logger) << "m_CAX : " << m_CAX ;
TRACE_LOG(m_logger) << "m_CAlpha1X : " << m_CAlpha1X ;
TRACE_LOG(m_logger) << "m_C0X : " << m_C0X ;
TRACE_LOG(m_logger) << "TrajectoryPiton::init : initialized successfully!" ;
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryDiscrete::getNextPoint()
{
Float64 d_correction;
Float64 d_tmpConst;
N_Types::Coord3 o_coord3;
m_MyTime += m_Tact;
d_tmpConst = 1 - exp(-m_CAY * m_AirDensity * m_MyTime * m_InitialAmmuSpeed * cos(m_MyAngle));
d_tmpConst /= m_AirDensity * m_CAY;
d_correction = m_CT2Y * pow(m_MyTime, 2.0);
d_correction += m_CT1Y * m_MyTime;
d_correction += m_CAlpha2Y * pow(m_MyAngle, 2.0);
d_correction += m_CAlpha1Y * m_MyAngle;
d_correction += m_CRhoY * m_AirDensity;
d_correction += m_CVY * m_InitialAmmuSpeed;
d_correction += m_C0Y;
o_coord3.m_Y = d_tmpConst * d_correction;
d_tmpConst = 1 - (m_CAZ * m_AirDensity * m_MyTime * m_InitialAmmuSpeed * cos(m_MyAngle));
d_tmpConst *= N_SST::G * pow(m_MyTime, 2.0) / 2;
d_correction = m_CT2Z * pow(m_MyTime, 2.0);
d_correction += m_CT1Z * m_MyTime;
d_correction += m_CAlpha2Z * pow(m_MyAngle, 2.0);
d_correction += m_CAlpha1Z * m_MyAngle;
d_correction += m_CVZ * m_InitialAmmuSpeed;
d_correction += m_C0Z;
o_coord3.m_Z = o_coord3.m_Y * tan(m_MyAngle) - (d_tmpConst * d_correction);
d_tmpConst = m_CAX * o_coord3.m_Y;
d_tmpConst += m_CAlpha1X * m_MyAngle;
d_tmpConst += m_C0X;
d_tmpConst *= o_coord3.m_Y;
d_tmpConst /= m_InitialAmmuSpeed;
o_coord3.m_X = m_CrossWind * (m_MyTime - d_tmpConst);
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
} // namespace N_Ballistic
@@ -0,0 +1,78 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Discrete implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 14:27:55
*/
class TrajectoryDiscrete : public TrajectoryBase
{
public:
/**
* ## Constructors (generated)
*/
TrajectoryDiscrete() : TrajectoryBase("TrajectoryDiscrete") {}
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
bool init(const Ammunition &a_ammunition) override;
protected:
Float64 m_CAY = 0;
Float64 m_CT2Y = 0;
Float64 m_CT1Y = 0;
Float64 m_CAlpha2Y = 0;
Float64 m_CAlpha1Y = 0;
Float64 m_CRhoY = 0;
Float64 m_CVY = 0;
Float64 m_C0Y = 0;
Float64 m_CAZ = 0;
Float64 m_CT2Z = 0;
Float64 m_CT1Z = 0;
Float64 m_CAlpha2Z = 0;
Float64 m_CAlpha1Z = 0;
Float64 m_CVZ = 0;
Float64 m_C0Z = 0;
Float64 m_CAX = 0;
Float64 m_CAlpha1X = 0;
Float64 m_C0X = 0;
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
};
}
@@ -0,0 +1,85 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryPiton.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryPiton::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "TrajectoryPiton::init : initialising...";
m_CRhoY1 = a_ammunition.m_StandardParams.m_Time.m_CRhoT;
m_CRhoYC = a_ammunition.m_StandardParams.m_Time.m_ConstT;
m_CRhoZ1 = a_ammunition.m_StandardParams.m_Angle.m_CRhoA;
m_CRhoZC = a_ammunition.m_StandardParams.m_Angle.m_ConstA;
if (!TrajectoryBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "m_CRhoY1 : " << m_CRhoY1;
TRACE_LOG(m_logger) << "m_CRhoYC : " << m_CRhoYC;
TRACE_LOG(m_logger) << "m_CRhoZ1 : " << m_CRhoZ1;
TRACE_LOG(m_logger) << "m_CRhoZC : " << m_CRhoZC;
TRACE_LOG(m_logger) << "TrajectoryPiton::init : initialized successfully!";
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryPiton::getNextPoint()
{
const Float64 d_TWO_OVER_THREE = 2.0 / 3.0;
Float64 d_correction;
Float64 d_tmpConst;
N_Types::Coord3 o_coord3;
m_MyTime += m_Tact;
d_correction = (m_CRhoY1 * m_AirDensity) + m_CRhoYC;
d_tmpConst = (4.5 * m_MyTime * d_correction * m_InitialAmmuSpeed * cos(m_GunAngle.m_P)) + 1.0;
d_tmpConst = pow(d_tmpConst, d_TWO_OVER_THREE);
d_tmpConst -= 1.0;
o_coord3.m_Y = d_tmpConst / (d_correction * 3.0);
d_correction = m_CRhoZ1 * m_AirDensity + m_CRhoZC;
d_correction *= o_coord3.m_Y;
d_correction += 1.0;
d_correction *= (N_SST::G * pow(o_coord3.m_Y, 2.0));
d_tmpConst = pow(cos(m_GunAngle.m_P), 2.0);
d_correction /= (2.0 * pow(m_InitialAmmuSpeed, 2.0) * d_tmpConst);
o_coord3.m_Z = (o_coord3.m_Y * tan(m_GunAngle.m_P)) - d_correction;
d_correction = o_coord3.m_Y / (m_InitialAmmuSpeed * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_MyTime - d_correction);
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_GunPos;
return o_coord3;
}
} // namespace N_Ballistic
@@ -0,0 +1,63 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Piton Bressant implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 07-Aug-2009 14:27:37
*/
class TrajectoryPiton : public TrajectoryBase
{
public:
/**
* ## Constructors (generated)
*/
TrajectoryPiton() : TrajectoryBase("TrajectoryPiton") {}
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
bool init(const Ammunition &a_ammunition) override;
protected:
Float64 m_CRhoY1 = 0;
Float64 m_CRhoYC = 0;
Float64 m_CRhoZ1 = 0;
Float64 m_CRhoZC = 0;
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
};
}
@@ -0,0 +1,196 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryRungeKutta.hpp"
#include "../logger.h"
using N_Ballistic::TrajectoryRungeKutta;
using namespace N_Ballistic;
// static member initialization
Float64 TrajectoryRungeKutta::m_Temp = 0;
Float64 TrajectoryRungeKutta::m_TempWeapon = 0;
// ---------------------------------------------------------------
// initializes the object with the ammunition parameters
// ---------------------------------------------------------------
bool TrajectoryRungeKutta::init(const Ammunition &a_ammunition)
{
m_Initialized = false;
TRACE_LOG(m_logger) << "TrajectoryRungeKutta::init : initialising...";
if (a_ammunition.m_CWParams.m_Valid)
{
int cwcount = a_ammunition.m_CWParams.m_CW.size();
for (int i = 0; i < cwcount; i++)
{
m_CWCoeff.push_back(a_ammunition.m_CWParams.m_CW[i]);
TRACE_LOG(m_logger) << "CW " << i << " = " << a_ammunition.m_CWParams.m_CW[i];
}
int v0count = a_ammunition.m_CWParams.m_V0.size();
for (int i = 0; i < v0count; i++)
{
m_V0Coeff.push_back(a_ammunition.m_CWParams.m_V0[i]);
TRACE_LOG(m_logger) << "V0 " << i << " = " << a_ammunition.m_CWParams.m_V0[i];
}
int xwcount = a_ammunition.m_CWParams.m_XW.size();
for (int i = 0; i < xwcount; i++)
{
m_XWCoeff.push_back(a_ammunition.m_CWParams.m_XW[i]);
TRACE_LOG(m_logger) << "XW " << i << " = " << a_ammunition.m_CWParams.m_XW[i];
}
m_Weight = a_ammunition.m_CWParams.m_Weight;
m_Radius = 0.5 * a_ammunition.m_AmmunInfo.m_Caliber / 1000.0;
TRACE_LOG(m_logger) << "Weight = " << m_Weight;
TRACE_LOG(m_logger) << "Radius = " << m_Radius;
}
else
{
ERROR_LOG(m_logger) << "Parameters missing...";
return false;
}
m_Derivation = a_ammunition.m_AmmunInfo.m_Derivation;
if (!TrajectoryBase::init(a_ammunition))
return false;
TRACE_LOG(m_logger) << "TrajectoryRungeKutta::init : initialized successfully!";
return true;
}
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryRungeKutta::getNextPoint()
{
Float64 l_Gamma = 0.0065;
Float64 l_Temp0 = N_SST::ZERO_CELSIUS_IN_KELVIN + m_Temp;
Float64 l_A = pow(m_Radius, 2.0) * M_PI;
Float64 l_M = m_Weight;
m_MyTime += m_Tact;
Float64 l_Temp = l_Temp0 - (l_Gamma * m_H);
Float64 l_Rho = 4.171E-11 * pow(l_Temp, 4.2559);
Float64 l_q = l_M / l_A;
// Schritt 1
Float64 l_Vn = sqrt(pow(m_Vx, 2.0) + pow(m_Vy, 2.0));
Float64 l_Mx1 = -m_CW * (l_Rho / 2) * l_Vn * (m_Vx / l_q);
Float64 l_My1 = (-m_CW * (l_Rho / 2) * l_Vn * (m_Vy / l_q)) - N_SST::G;
Float64 l_Vx1 = m_Vx + (l_Mx1 * (m_Tact / 2.0));
Float64 l_Vy1 = m_Vy + (l_My1 * (m_Tact / 2.0));
Float64 l_V1 = sqrt(pow(l_Vx1, 2.0) + pow(l_Vy1, 2.0));
// Schritt 2
Float64 l_Mx2 = -m_CW * (l_Rho / 2) * l_V1 * (l_Vx1 / l_q);
Float64 l_My2 = (-m_CW * (l_Rho / 2) * l_V1 * (l_Vy1 / l_q)) - N_SST::G;
Float64 l_Vx2 = l_Vx1 + (l_Mx2 * (m_Tact / 2.0));
Float64 l_Vy2 = l_Vy1 + (l_My2 * (m_Tact / 2.0));
Float64 l_V2 = sqrt(pow(l_Vx2, 2.0) + pow(l_Vy2, 2.0));
// Schritt 3
Float64 l_Mx3 = -m_CW * (l_Rho / 2) * l_V2 * (l_Vx2 / l_q);
Float64 l_My3 = (-m_CW * (l_Rho / 2) * l_V2 * (l_Vy2 / l_q)) - N_SST::G;
Float64 l_Vx3 = l_Vx2 + (l_Mx3 * m_Tact);
Float64 l_Vy3 = l_Vy2 + (l_My3 * m_Tact);
Float64 l_V3 = sqrt(pow(l_Vx3, 2.0) + pow(l_Vy3, 2.0));
// Schritt 4
Float64 l_Mx4 = -m_CW * (l_Rho / 2) * l_V3 * (l_Vx3 / l_q);
Float64 l_My4 = (-m_CW * (l_Rho / 2) * l_V3 * (l_Vy3 / l_q)) - N_SST::G;
Float64 l_Mx = (l_Mx1 + (2 * l_Mx2) + (2 * l_Mx3) + l_Mx4) / 6.0;
Float64 l_My = (l_My1 + (2 * l_My2) + (2 * l_My3) + l_My4) / 6.0;
Float64 l_Vx = m_Vx + l_Mx * m_Tact;
Float64 l_Vy = m_Vy + l_My * m_Tact;
N_Types::Coord3 o_coord3;
o_coord3.m_Y = 0.5 * (m_Vx + l_Vx) * m_Tact;
o_coord3.m_Z = 0.5 * (m_Vy + l_Vy) * m_Tact;
// Correction for Wind (approximative, not confirmed)
if (m_XW != 0 && m_CrossWind != 0)
{
Float64 d_correction = o_coord3.m_Y / (m_Vx * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_Tact - d_correction) / m_XW;
}
// correction for derivation (right drift due to rotation of bullet)
if (m_Derivation != 0)
o_coord3.m_X += o_coord3.m_Y * m_Derivation;
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_MyPoints[0];
m_H = o_coord3.m_Z;
m_Vx = l_Vx;
m_Vy = l_Vy;
return o_coord3;
}
// ---------------------------------------------------------------
// initializes the object with the following parameters
// ---------------------------------------------------------------
bool TrajectoryRungeKutta::init(const N_Types::Coord3 &a_gunPos, const N_Types::Angle3 &a_gunAngle, const Float64 a_crossWind, const Float64 a_airDensity, const Float64 a_initialAmmuSpeed)
{
bool l_Ret = TrajectoryBase::init(a_gunPos, a_gunAngle, a_crossWind, a_airDensity, a_initialAmmuSpeed);
m_V0 = a_initialAmmuSpeed;
m_CW = 0;
m_XW = 0;
bool l_CWFound = false;
for (size_t i = 0; i < m_V0Coeff.size(); i++)
{
if (m_V0Coeff[i] == m_V0)
{
m_CW = m_CWCoeff[i];
m_XW = m_XWCoeff[i];
l_CWFound = true;
break;
}
}
if (!l_CWFound)
ERROR_LOG(m_logger) << "CW Value for Speed " << m_V0 << " could not be found !";
m_H = m_GunPos.m_Z;
m_Vx = m_V0 * cos(m_GunAngle.m_P);
m_Vy = m_V0 * sin(m_GunAngle.m_P);
INFO_LOG(m_logger) << "Initial Values: H=" << m_H << " CW=" << m_CW << " V0=" << m_V0;
INFO_LOG(m_logger) << " Vx=" << m_Vx << " Vy=" << m_Vy;
INFO_LOG(m_logger) << " XW=" << m_XW ;
return l_Ret;
}
@@ -0,0 +1,85 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryBase.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* RungeKutta implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 22-Jul-2010 11:39:16
*/
class TrajectoryRungeKutta : public TrajectoryBase
{
public:
TrajectoryRungeKutta(const char *loggerName = "TrajectoryRungeKutta") : TrajectoryBase(loggerName) {}
static Float64 m_Temp;
static Float64 m_TempWeapon;
/**
* initializes the object with the ammunition parameters
*
* @param a_ammunition ammunition definion from xml file
*/
bool init(const Ammunition &a_ammunition) override;
/**
* initializes the object with the following parameters
*
* @param a_gunPos Position of the gun
* @param a_gunAngle Shooting angle of the gun
* @param a_crossWind lateral wind
* @param a_airDensity Air density
* @param a_initialAmmuSpeed ammunition speed
*/
bool init(const N_Types::Coord3 &a_gunPos,
const N_Types::Angle3 &a_gunAngle,
const Float64 a_crossWind,
const Float64 a_airDensity,
const Float64 a_initialAmmuSpeed) override;
protected:
std::vector<Float64> m_CWCoeff;
std::vector<Float64> m_V0Coeff;
std::vector<Float64> m_XWCoeff;
Float64 m_Vx = 0;
Float64 m_Vy = 0;
Float64 m_H = 0;
Float64 m_T = 0;
Float64 m_V0 = 0;
Float64 m_CW = 0;
Float64 m_XW = 0;
Float64 m_Weight = 0;
Float64 m_Radius = 0;
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
};
}
@@ -0,0 +1,84 @@
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "TrajectoryRungeKuttaSimple.hpp"
namespace N_Ballistic
{
// ---------------------------------------------------------------
// calculates the next point of a tracer using the algorithm
// implemented in the current class
// ---------------------------------------------------------------
N_Types::Coord3 TrajectoryRungeKuttaSimple::getNextPoint()
{
Float64 l_Gamma = 0.0065;
Float64 l_Temp0 = N_SST::ZERO_CELSIUS_IN_KELVIN + m_Temp;
Float64 l_A = pow(m_Radius, 2.0) * M_PI;
Float64 l_M = m_Weight;
m_MyTime += m_Tact;
// INFO_LOG(m_logger) << "-------------- dT=" << m_Tact << " Total=" << m_MyTime << END_LOG;
Float64 l_Temp = l_Temp0 - (l_Gamma * m_H);
// INFO_LOG(m_logger) << "Temp=" << l_Temp << " auf Höhe " << m_H << END_LOG;
Float64 l_Rho = 4.171E-11/* * pow(10, -11)*/ * pow(l_Temp, 4.2559);
Float64 l_q = l_M / l_A;
// INFO_LOG(m_logger) << "Rho=" << l_Rho << " für q=" << l_q << " Fläche=" << l_A << " Masse=" << l_M << END_LOG;
// Schritt 1
Float64 l_Vn = sqrt(pow(m_Vx, 2.0) + pow(m_Vy, 2.0));
// INFO_LOG(m_logger) << "Vn=" << l_Vn << " für Vx=" << m_Vx << " Vy=" << m_Vy << END_LOG;
Float64 l_Mx = -m_CW * (l_Rho / 2) * l_Vn * (m_Vx / l_q);
Float64 l_My = (-m_CW * (l_Rho / 2) * l_Vn * (m_Vy / l_q)) - N_SST::G;
// INFO_LOG(m_logger) << "Mx=" << l_Mx << " My=" << l_My << END_LOG;
Float64 l_Vx = m_Vx + l_Mx * m_Tact;
Float64 l_Vy = m_Vy + l_My * m_Tact;
// INFO_LOG(m_logger) << "Vx=" << l_Vx << " Vy=" << l_Vy << END_LOG;
N_Types::Coord3 o_coord3;
o_coord3.m_Y = 0.5 * (m_Vx + l_Vx) * m_Tact; // Beware: 2 different coordinate systems used here !!
o_coord3.m_Z = 0.5 * (m_Vy + l_Vy) * m_Tact;
// INFO_LOG(m_logger) << "dX=" << o_coord3.m_Y << " dy=" << o_coord3.m_Z << END_LOG;
// Correction for Wind (approximative, not confirmed)
if (m_XW != 0 && m_CrossWind != 0)
{
Float64 d_correction = o_coord3.m_Y / (m_Vx * cos(m_GunAngle.m_P));
o_coord3.m_X = m_CrossWind * (m_Tact - d_correction) / m_XW;
}
// correction for derivation (right drift due to rotation of bullet)
if (m_Derivation != 0)
o_coord3.m_X += o_coord3.m_Y * m_Derivation;
o_coord3 = o_coord3.rotateZ(m_GunAngle.m_H);
o_coord3 = o_coord3 + m_MyPoints[0];
m_H = m_GunPos.m_Z + o_coord3.m_Z;
// INFO_LOG(m_logger) << "-> Pos=" << o_coord3 << END_LOG;
m_Vx = l_Vx;
m_Vy = l_Vy;
// INFO_LOG(m_logger) << "Vx=" << m_Vx << " Vy=" << m_Vy << END_LOG;
return o_coord3;
}
} // namespace N_Ballistic
@@ -0,0 +1,47 @@
#pragma once
// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// from stereotyped includes
#include "TrajectoryRungeKutta.hpp"
// manual class imports
namespace N_Ballistic
{
/**
* Simple RungeKutta implementation for trajectory calculations
*
* @author Daniel.Schmid
* @version 1.0
* @created 22-Jul-2010 12:12:41
*/
class TrajectoryRungeKuttaSimple : public TrajectoryRungeKutta
{
public:
TrajectoryRungeKuttaSimple() : TrajectoryRungeKutta("TrajectoryRungeKuttaSimple") {}
protected:
/**
* calculates the next point of a tracer using the algorithm implemented in the
* current class
*/
N_Types::Coord3 getNextPoint() override;
};
}