Fix SACLOS missiles

This commit is contained in:
Brandon Danyluk 2021-04-20 18:11:44 -06:00
parent aea24c6de4
commit 9d26335271
13 changed files with 129 additions and 35 deletions

View File

@ -69,8 +69,11 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };
defaultNavigationType = "LineOfSight";
navigationTypes[] = { "LineOfSight" };
defaultNavigationType = "Line";
navigationTypes[] = { "Line" };
lineGainP = 3;
lineGainD = 2.3;
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
seekerAngle = 30; // Angle from the shooter's view that can track the missile

View File

@ -22,8 +22,11 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };
defaultNavigationType = "LineOfSight";
navigationTypes[] = { "LineOfSight" };
defaultNavigationType = "Line";
navigationTypes[] = { "Line" };
lineGainP = 3;
lineGainD = 2.1;
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
seekerAngle = 15; // Angle from the shooter's view that can track the missile
@ -64,8 +67,11 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };
defaultNavigationType = "LineOfSight";
navigationTypes[] = { "LineOfSight" };
defaultNavigationType = "Line";
navigationTypes[] = { "Line" };
lineGainP = 3;
lineGainD = 3;
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
seekerAngle = 15; // Angle from the shooter's view that can track the missile
@ -74,7 +80,7 @@ class CfgAmmo {
seekerMinRange = 80;
seekerMaxRange = 2000; // Range from the missile which the seeker can visually search
correctionDistance = 6; // distance from center of crosshair where missile slows down
correctionDistance = 1; // distance from center of crosshair where missile slows down
offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair.
// Attack profile type selection

View File

@ -123,6 +123,10 @@ class GVAR(SeekerTypes) {
};
class GVAR(NavigationTypes) {
class Line {
functionName = QFUNC(navigationType_line);
onFired = QFUNC(line_onFired);
};
class LineOfSight {
functionName = QFUNC(navigationType_lineOfSight);
onFired = QFUNC(proNav_onFired);

View File

@ -36,6 +36,7 @@ PREP(navigationType_zeroEffortMiss);
PREP(navigationType_augmentedProNav);
PREP(navigationType_proNav);
PREP(navigationType_lineOfSight);
PREP(navigationType_line);
// Seeker search functions
PREP(seekerType_SALH);
@ -59,6 +60,7 @@ PREP(gps_seekerOnFired);
// Navigation OnFired
PREP(proNav_onFired);
PREP(line_onFired);
// State transitions
PREP(javelin_midCourseTransition);

View File

@ -24,24 +24,12 @@ _attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_random
private _projectilePos = getPosASL _projectile;
private _shooterPos = getPosASL _shooter;
private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos);
private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos;
if (_distanceToProjectile > _seekerMaxRangeSqr || { _seekerTargetPos isEqualTo [0, 0, 0] } || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith {
// return position 50m infront of projectile
_projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0])
if (_seekerTargetPos isEqualTo [0, 0, 0] || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith {
// return position 50m infront of projectile and a bit up to get out of the way of the ground
_projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 3])
};
private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos);
_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset;
_seekerTargetPos vectorAdd _crosshairOffset
private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2];
private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair
// Adjust the impulse due to near-zero values creating wobbly missiles?
private _correction = _fovImpulse;
_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction;
private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection);
_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile)

View File

@ -24,7 +24,6 @@ _attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_random
private _projectilePos = getPosASL _projectile;
private _shooterPos = getPosASL _shooter;
private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos);
private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos;
if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith {
@ -44,9 +43,9 @@ if (_seekerTargetPos isEqualTo [0, 0, 0] || { _distanceToProjectile < _seekerMin
/*if (lineIntersectsSurfaces [getPosASL _shooter, _projectilePos, _shooter] isNotEqualTo []) then {
_attackProfileStateParams set [1, true];
};*/
// return position 50m infront of projectile
_projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0])
// return position 50m infront of projectile and a bit up to get out of the way of the ground
_projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 3])
};
_seekerTargetPos vectorAdd (_shooterDir vectorMultiply 30);
_seekerTargetPos vectorAdd _crosshairOffset

View File

@ -61,10 +61,10 @@ if ((_pitchRate != 0 || {_yawRate != 0}) && {_profileAdjustedTargetPos isNotEqua
};
private _commandedAcceleration = [_args, _timestep, _seekerTargetPos, _profileAdjustedTargetPos] call (missionNamespace getVariable _navigationFunction);
private _commandedAcceleration = [_args, _timestep, _seekerTargetPos, _profileAdjustedTargetPos, _targetData, _navigationParameters] call (missionNamespace getVariable _navigationFunction);
if (isNil "_commandedAcceleration") exitWith {
systemChat _navigationFunction;
systemChat format ["Error in %1", _navigationFunction];
ERROR_MSG("_commandedAcceleration is nil! Guidance cancelled");
};

View File

@ -0,0 +1,33 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Sets up line state arrays (called from missileGuidance's onFired).
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* None
*
* Example:
* [] call ace_missileguidance_fnc_line_onFired
*
* Public: No
*/
params ["_firedEH", "", "", "", "_stateParams"];
_firedEH params ["","","","","","","_projectile"];
_stateParams params ["", "", "", "", "_navigationParams"];
private _ammoConfig = configOf _projectile;
private _p = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainP");
private _d = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainD");
private _correctionDistance = getNumber (_ammoConfig >> QUOTE(ADDON) >> "correctionDistance");
_navigationParams set [0, _p];
_navigationParams set [1, _i];
_navigationParams set [2, _d];
_navigationParams set [3, 0];
_navigationParams set [4, 0];
_navigationParams set [5, _correctionDistance];

View File

@ -0,0 +1,55 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Assumes targetDir is pointing toward line we want to stay on
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* Commanded acceleration normal to LOS in world space <ARRAY>
*
* Example:
* [] call ace_missileguidance_fnc_navigationType_line
*
* Public: No
*/
params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos", "_targetData", "_navigationParams"];
_args params ["", "", "_flightParams"];
_targetData params ["", "_targetDir", "_distance"];
_flightParams params ["_pitchRate", "_yawRate"];
_navigationParams params ["_proportionalGain", "", "_derivativeGain", "_lastErrorX", "_lastErrorY", "_correctionDistance"];
private _targetDistance = _projectile vectorWorldToModelVisual (_targetDir vectorMultiply _distance);
private _relativeDirection = _projectile vectorWorldToModelVisual _targetDir;
private _errorX = 1 min (_targetDistance#0 / _correctionDistance);
private _errorY = 1 min (_targetDistance#2 / _correctionDistance);
private _pX = _proportionalGain * _errorX;
private _dX = if (_timestep != 0) then {
_derivativeGain * (_errorX - _lastErrorX) / _timestep
} else {
0
};
private _pY = _proportionalGain * _errorY;
private _dY = if (_timestep != 0) then {
_derivativeGain * (_errorY - _lastErrorY) / _timestep
} else {
0
};
private _accelerationX = _pX + _dX;
private _accelerationY = _pY + _dY;
private _commandedAcceleration = [
_accelerationX,
0,
_accelerationY
];
_navigationParams set [3, _errorX];
_navigationParams set [4, _errorY];
_projectile vectorModelToWorldVisual _commandedAcceleration;

View File

@ -156,7 +156,7 @@ private _args = [_this,
getNumber ( _config >> "seekerMaxRange" ),
getNumber ( _config >> "seekerMinRange" )
],
[ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_pitchYaw select 1, 0, _pitchYaw select 2]],
[ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_pitchYaw select 1, 0, 1.5 + (_pitchYaw select 2)]],
[
// target data from missile. Must be filled by seeker for navigation to work
[0, 0, 0], // direction to target
@ -199,7 +199,7 @@ if (_onFiredFunc != "") then {
// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"];
// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"];
// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"];
// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams", "_guidanceParameters"];
// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"];
// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"];
// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"];

View File

@ -58,7 +58,10 @@ if ((_testDotProduct < (cos _seekerAngle)) || {_testIntersections isNotEqualTo [
[0, 0, 0]
};
private _returnPos = _shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj);
_targetData set [0, _lookDirection];
_targetData set [2, _returnPos distance getPosASLVisual _projectile];
_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj);
_returnPos

View File

@ -46,3 +46,4 @@ _attackProfileStateParams set [5, _minDistanceSqr];
_attackProfileStateParams set [6, _wireCutSource];
_attackProfileStateParams set [7, _distanceAheadOfMissile];

View File

@ -50,8 +50,8 @@ Navigation Types:
X Dragon - NA
Metis - Wire/Beam Guidance
HOT - Wire/Beam Guidance
X Metis - Wire/Beam Guidance
X HOT - Wire/Beam Guidance
Vikhr - Wire/Beam Guidance
X DAGR - APN
@ -83,7 +83,7 @@ Navigation State Machine:
Navigation Types:
X Augmented Pro-Nav
X Zero Effort Miss
Wire/Beam Guided
X Wire/Beam Guided
Predicted Line of Sight
General To-Do: