Skip to content

Commit

Permalink
Missileguidance - Fix Javelin flight profile (#10269)
Browse files Browse the repository at this point in the history
Co-authored-by: Grim <[email protected]>
Co-authored-by: PabstMirror <[email protected]>
  • Loading branch information
3 people authored Sep 5, 2024
1 parent 2f72c77 commit 391a81c
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 42 deletions.
49 changes: 40 additions & 9 deletions addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,51 @@ class CfgAmmo {

class ace_missileguidance {
enabled = 1;
minDeflection = 0.00005;
maxDeflection = 0.025;
incDeflection = 0.00005;

pitchRate = 120; // degrees per second
yawRate = 120;
stabilityCoefficient = 0.2;
bangBangGuidance = 0;

canVanillaLock = 0;

// Guidance type for munitions
defaultSeekerType = "Optic";
seekerTypes[] = {"Optic"};
seekerTypes[] = { "Optic" };

defaultSeekerLockMode = "LOBL";
seekerLockModes[] = {"LOBL"};
seekerAngle = 180;
seekerAccuracy = 1;
seekerLockModes[] = { "LOBL" };

defaultNavigationType = "Direct";
navigationTypes[] = { "Direct", "ZeroEffortMiss" };

navigationGain = 3;

seekerAngle = 180; // Angle in front of the missile which can be searched
seekerAccuracy = 1; // seeker accuracy multiplier

seekerMinRange = 0;
seekerMaxRange = 2500;
seekerMaxRange = 2500; // Range from the missile which the seeker can visually search

seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos]

// Attack profile type selection
defaultAttackProfile = "JAV_TOP";
attackProfiles[] = {"JAV_TOP", "JAV_DIR"};
attackProfiles[] = { "JAV_TOP", "JAV_DIR" };
useModeForAttackProfile = 1;

class navigationStates {
class initial {
transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition);
navigationType = "Direct";
};
class terminal {
transitionCondition = "";
navigationType = "ZeroEffortMiss";
};
// transitions from initial -> termimal
states[] = {"initial", "terminal"};
};
};
};
};
25 changes: 22 additions & 3 deletions addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ class CfgAmmo {
class ace_missileguidance {
enabled = 1;

minDeflection = 0.00005; // Minium flap deflection for guidance
maxDeflection = 0.025; // Maximum flap deflection for guidance
incDeflection = 0.00005; // The incrmeent in which deflection adjusts.
pitchRate = 120; // degrees per second
yawRate = 120;
stabilityCoefficient = 0.2;
bangBangGuidance = 0;

canVanillaLock = 0;

Expand All @@ -22,6 +23,11 @@ class CfgAmmo {
defaultSeekerLockMode = "LOBL";
seekerLockModes[] = { "LOBL" };

defaultNavigationType = "Direct";
navigationTypes[] = { "Direct", "ZeroEffortMiss" };

navigationGain = 3;

seekerAngle = 180; // Angle in front of the missile which can be searched
seekerAccuracy = 1; // seeker accuracy multiplier

Expand All @@ -34,6 +40,19 @@ class CfgAmmo {
defaultAttackProfile = "JAV_TOP";
attackProfiles[] = { "JAV_TOP", "JAV_DIR" };
useModeForAttackProfile = 1;

class navigationStates {
class initial {
transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition);
navigationType = "Direct";
};
class terminal {
transitionCondition = "";
navigationType = "ZeroEffortMiss";
};
// transitions from initial -> termimal
states[] = {"initial", "terminal"};
};
};
};
};
1 change: 1 addition & 0 deletions addons/hellfire/functions/fnc_midCourseTransition.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Public: No
*/

params ["_args", "_timestep"];
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"];
_firedEH params ["_shooter","","","","_ammo","","_projectile"];
_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"];
Expand Down
4 changes: 2 additions & 2 deletions addons/missileguidance/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ class CfgAmmo {
class ADDON {
enabled = 1;

pitchRate = 100; // degrees per second
yawRate = 100;
pitchRate = 120; // degrees per second
yawRate = 120;
stabilityCoefficient = 0.2;
bangBangGuidance = 0;

Expand Down
22 changes: 16 additions & 6 deletions addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#define STAGE_COAST 3
#define STAGE_TERMINAL 4

#define CLIMB_ANGLE 12
#define ATTACK_ANGLE 2

params ["_seekerTargetPos", "_args", "_attackProfileStateParams"];
_args params ["_firedEH"];
_firedEH params ["_shooter","","","","","","_projectile"];
Expand All @@ -30,6 +33,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos};

if (_attackProfileStateParams isEqualTo []) then {
_attackProfileStateParams set [0, STAGE_LAUNCH];
_attackProfileStateParams set [1, 0];
};

private _shooterPos = getPosASL _shooter;
Expand All @@ -44,24 +48,28 @@ TRACE_2("",_distanceToTarget,_distanceToShooter);
// Add height depending on distance for compensate
private _returnTargetPos = _seekerTargetPos;

private _attackDirection = _seekerTargetPos vectorDiff _projectilePos;
private _horizon = velocity _projectile;
_horizon set [2, 0];
_horizon = vectorNormalized _horizon;
private _attackAngle = acos (_horizon vectorCos _attackDirection);

switch (_attackProfileStateParams select 0) do {
case STAGE_LAUNCH: {
TRACE_1("STAGE_LAUNCH","");
if (_distanceToShooter < 6) then {
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2];
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,5];
} else {
_attackProfileStateParams set [0, STAGE_CLIMB];
};
};
case STAGE_CLIMB: {
TRACE_1("STAGE_CLIMB","");
// 65 is min range
private _cruisAlt = 60 * ((0 max (_distanceShooterToTarget - 65))/2000);

if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then {
if (_attackAngle >= ATTACK_ANGLE) then {
_attackProfileStateParams set [0, STAGE_TERMINAL];
} else {
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5];
private _height = _distanceShooterToTarget * tan CLIMB_ANGLE;
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height];
};
};
case STAGE_TERMINAL: {
Expand All @@ -70,5 +78,7 @@ switch (_attackProfileStateParams select 0) do {
};
};

_attackProfileStateParams set [2, _returnTargetPos];

TRACE_1("Adjusted target position",_returnTargetPos);
_returnTargetPos;
44 changes: 28 additions & 16 deletions addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#define STAGE_COAST 3
#define STAGE_TERMINAL 4

#define CRUISE_ALT 160
#define CLIMB_ANGLE 22
#define ATTACK_ANGLE 12

params ["_seekerTargetPos", "_args", "_attackProfileStateParams"];
_args params ["_firedEH"];
_firedEH params ["_shooter","","","","","","_projectile"];
Expand All @@ -30,6 +34,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos};

if (_attackProfileStateParams isEqualTo []) then {
_attackProfileStateParams set [0, STAGE_LAUNCH];
_attackProfileStateParams set [1, 0];
};

private _shooterPos = getPosASL _shooter;
Expand All @@ -44,39 +49,44 @@ TRACE_2("",_distanceToTarget,_distanceToShooter);
// Add height depending on distance for compensate
private _returnTargetPos = _seekerTargetPos;

private _attackDirection = _seekerTargetPos vectorDiff _projectilePos;
private _horizon = velocity _projectile;
_horizon set [2, 0];
_horizon = vectorNormalized _horizon;
private _attackAngle = acos (_horizon vectorCos _attackDirection);

switch( (_attackProfileStateParams select 0) ) do {
case STAGE_LAUNCH: {
TRACE_1("STAGE_LAUNCH","");
if (_distanceToShooter < 10) then {
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2];
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,5];
} else {
_attackProfileStateParams set [0, STAGE_CLIMB];
};
};
case STAGE_CLIMB: {
TRACE_1("STAGE_CLIMB","");
private _cruisAlt = 140;
if (_distanceShooterToTarget < 1250) then {
_cruisAlt = 140 * ((0 max (_distanceShooterToTarget - 150))/1250);
TRACE_1("_cruisAlt",_cruisAlt);
};
if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then {
if (_cruisAlt < 140) then {
_attackProfileStateParams set [0, STAGE_TERMINAL];
} else {
private _altitude = (ASLToAGL _projectilePos) select 2;
switch (true) do {
case (_altitude >= CRUISE_ALT): {
_attackProfileStateParams set [0, STAGE_COAST];
};
} else {
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5];
};
case (_attackAngle >= ATTACK_ANGLE): {
_attackProfileStateParams set [0, STAGE_TERMINAL];
};
default {
private _height = _distanceShooterToTarget * tan CLIMB_ANGLE;
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height];
}
}
};
case STAGE_COAST: {
TRACE_1("STAGE_COAST","");
TRACE_1("",((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2));
if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then {
TRACE_1("",_attackAngle);
if (_attackAngle >= ATTACK_ANGLE) then {
_attackProfileStateParams set [0, STAGE_TERMINAL];
} else {
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)];
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2) min CRUISE_ALT];
};
};
case STAGE_TERMINAL: {
Expand All @@ -86,5 +96,7 @@ switch( (_attackProfileStateParams select 0) ) do {
};
};

_attackProfileStateParams set [2, _returnTargetPos];

TRACE_1("Adjusted target position",_returnTargetPos);
_returnTargetPos;
2 changes: 1 addition & 1 deletion addons/missileguidance/functions/fnc_guidancePFH.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ if ((_pitchRate != 0 || {_yawRate != 0})) then {
private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName");
if (_navigationStateData isNotEqualTo []) then {
(_navigationStateData select _currentState) params ["_transitionCondition"];
private _transition = (_args call (missionNamespace getVariable [_transitionCondition, { false }]));
private _transition = ([_args, _timestep] call (missionNamespace getVariable [_transitionCondition, { false }]));
if (_transition) then {
_currentState = _currentState + 1;
_navigationStateParams set [0, _currentState];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#define STAGE_COAST 3
#define STAGE_TERMINAL 4

#define REQUIRED_STABLE_TIME 0.2
#define REQUIRED_ANGLE 1

params ["_args", "_timestep"];
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"];
_firedEH params ["_shooter","","","","_ammo","","_projectile"];
_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"];
Expand All @@ -28,6 +32,17 @@ _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateP
_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"];
_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"];

_attackProfileStateParams params ["_state"];
_state isEqualTo STAGE_TERMINAL
_attackProfileStateParams params ["_state", "_stableTime", "_target"];
private _projectileDirection = vectorNormalized velocity _projectile;
private _targetDistance = _target vectorDistance getPosASLVisual _projectile;
private _targetDirection = (getPosASLVisual _projectile) vectorFromTo _target;
private _angle = _projectileDirection vectorCos _targetDirection;
if (_angle > cos REQUIRED_ANGLE) then {
_stableTime = _stableTime + _timestep;
} else {
_stableTime = 0;
};

_attackProfileStateParams set [1, _stableTime];
_state isEqualTo STAGE_TERMINAL && _stableTime > REQUIRED_STABLE_TIME

21 changes: 18 additions & 3 deletions addons/missileguidance/functions/fnc_navigationType_direct.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,23 @@
*
* Public: No
*/
params ["_args", "", "", "_profileAdjustedTargetPos"];
_args params ["_firedEH"];
params ["_args", "_timestep", "", "_profileAdjustedTargetPos"];
_args params ["_firedEH", "", "_flightParams"];
_flightParams params ["_pitchRate", "_yawRate"];
_firedEH params ["","","","","","","_projectile"];

_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile
private _projectilePos = getPosASLVisual _projectile;

private _targetDirection = _projectilePos vectorFromTo _profileAdjustedTargetPos;
private _projectileDirection = vectorNormalized velocity _projectile;

private _deltaDirection = _targetDirection vectorDiff _projectileDirection;
_deltaDirection = _projectile vectorWorldToModelVisual _deltaDirection;
_deltaDirection = _deltaDirection vectorMultiply [_yawRate, 0, _pitchRate];
_deltaDirection = _projectile vectorModelToWorldVisual _deltaDirection;

private _iTimestep = 0;
if (_timestep != 0) then {
_iTimestep = 1 / _timestep;
};
_deltaDirection vectorMultiply _iTimestep // return

0 comments on commit 391a81c

Please sign in to comment.