Fix javelin flight profile

This commit is contained in:
Bailey Danyluk 2024-08-28 01:43:18 -06:00
parent d56a3a6a95
commit 6d3cd25778
7 changed files with 84 additions and 30 deletions

View File

@ -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"];

View File

@ -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;

View File

@ -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"];
@ -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;
@ -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: {
@ -70,5 +78,7 @@ switch (_attackProfileStateParams select 0) do {
};
};
_attackProfileStateParams set [2, _returnTargetPos];
TRACE_1("Adjusted target position",_returnTargetPos);
_returnTargetPos;

View File

@ -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"];
@ -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;
@ -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: {
@ -86,5 +96,7 @@ switch( (_attackProfileStateParams select 0) ) do {
};
};
_attackProfileStateParams set [2, _returnTargetPos];
TRACE_1("Adjusted target position",_returnTargetPos);
_returnTargetPos;

View File

@ -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];

View File

@ -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"];
@ -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

View File

@ -14,8 +14,24 @@
*
* 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 _magnitude = _profileAdjustedTargetPos vectorDistance _projectilePos;
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