Add zero-effort miss. Seeker now feeds data to navigation

This commit is contained in:
Brandon Danyluk 2021-04-13 16:10:39 -06:00
parent a93eb6433d
commit 1873467deb
14 changed files with 106 additions and 63 deletions

View File

@ -22,8 +22,8 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };
defaultNavigationType = "AugmentedProportionalNavigation";
navigationTypes[] = { "AugmentedProportionalNavigation" };
defaultNavigationType = "ZeroEffortMiss";
navigationTypes[] = { "ZeroEffortMiss" };
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
seekerAngle = 50; // Angle from the shooter's view that can track the missile
@ -62,8 +62,8 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };
defaultNavigationType = "AugmentedProportionalNavigation";
navigationTypes[] = { "AugmentedProportionalNavigation" };
defaultNavigationType = "ZeroEffortMiss";
navigationTypes[] = { "ZeroEffortMiss" };
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
seekerAngle = 50; // Angle from the shooter's view that can track the missile

View File

@ -93,6 +93,7 @@ class GVAR(SeekerTypes) {
class GVAR(NavigationTypes) {
class LineOfSight {
functionName = QFUNC(navigationType_lineOfSight);
onFired = QFUNC(proNav_onFired);
};
class ProportionalNavigation {
functionName = QFUNC(navigationType_proNav);
@ -102,4 +103,7 @@ class GVAR(NavigationTypes) {
functionName = QFUNC(navigationType_augmentedProNav);
onFired = QFUNC(proNav_onFired);
};
class ZeroEffortMiss {
functionName = QFUNC(navigationType_zeroEffortMiss);
};
};

View File

@ -29,6 +29,7 @@ PREP(attackProfile_JAV_DIR);
PREP(attackProfile_JAV_TOP);
// Navigation Profiles
PREP(navigationType_zeroEffortMiss);
PREP(navigationType_augmentedProNav);
PREP(navigationType_proNav);
PREP(navigationType_lineOfSight);

View File

@ -15,49 +15,38 @@
* Public: No
*/
params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"];
_args params ["_firedEH", "", "", "", "_stateParams"];
_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_stateParams params ["", "", "", "","_navigationParams"];
_navigationParams params ["_lastMissileFrame", "_navigationGain"];
_lastMissileFrame params ["_lastTargetPosition", "_lastTargetVelocity", "_lastLineOfSight"];
_lastMissileFrame params ["_lastLineOfSight"];
_targetData params ["_targetDirection", "", "_targetVelocity", "_targetAcceleration"];
// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel
private _projectileVelocity = velocity _projectile;
private _closingVelocity = _targetVelocity vectorDiff velocity _projectile;
// integrate target velocity for realistic inference of velocity
private _targetVelocity = _lastTargetVelocity;
private _targetAcceleration = [0, 0, 0];
if (_timestep != 0) then {
_targetVelocity = (_seekerTargetPos vectorDiff _lastTargetPosition) vectorMultiply (1 / _timestep);
_targetAcceleration = (_targetVelocity vectorDiff _lastTargetVelocity) vectorMultiply (1 / _timestep);
};
private _closingVelocity = _targetVelocity vectorDiff _projectileVelocity;
private _lineOfSight = vectorNormalized (_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile);
private _targetAccelerationProjected = _lineOfSight vectorMultiply (_targetAcceleration vectorDotProduct _lineOfSight);
private _targetAccelerationProjected = _targetDirection vectorMultiply (_targetAcceleration vectorDotProduct _targetDirection);
_targetAcceleration = _targetAcceleration vectorDiff _targetAccelerationProjected;
systemChat str vectorMagnitude _targetAcceleration;
// the los rate is tiny, so we multiply by a constant of a power of ten to get more aggressive acceleration
// this is just due to how we measure our LOS delta, the vectors involved are _tiny_
private _losDelta = _lineOfSight vectorDiff _lastLineOfSight;
private _losDelta = _targetDirection vectorDiff _lastLineOfSight;
private _losRate = if (_timestep == 0) then {
0
} else {
10 * (vectorMagnitude _losDelta) / _timestep;
};
private _lateralAcceleration = (_navigationGain * _losRate);
private _lateralAcceleration = _navigationGain * _losRate;
private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration;
_commandedAcceleration = _commandedAcceleration vectorAdd (_losDelta vectorMultiply (0.5 * _navigationGain * vectorMagnitude _targetAcceleration));
// we need acceleration normal to our LOS
private _commandedAccelerationProjected = _lineOfSight vectorMultiply (_commandedAcceleration vectorDotProduct _lineOfSight);
private _commandedAccelerationProjected = _targetDirection vectorMultiply (_commandedAcceleration vectorDotProduct _targetDirection);
_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected;
if (accTime > 0) then {
_navigationParams set [0, [_seekerTargetPos, _targetVelocity, _lineOfSight]];
_navigationParams set [0, [_seekerTargetPos, _targetVelocity, _targetDirection]];
};
_commandedAcceleration

View File

@ -15,32 +15,33 @@
* Public: No
*/
params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"];
_args params ["_firedEH", "", "", "", "_stateParams"];
_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_stateParams params ["", "", "", "","_navigationParams"];
_navigationParams params [["_lastLineOfSight", [0, 0, 0]]];
_navigationParams params ["_lastLineOfSight"];
_targetData params ["_targetDirection", "", "_targetVelocity", ""];
// Semi-proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel
private _lineOfSight = vectorNormalized (_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile);
// the los rate is tiny, so we multiply by a constant of a power of ten to get more aggressive acceleration
// this is just due to how we measure our LOS delta, the vectors involved are _tiny_
private _losDelta = _lineOfSight vectorDiff _lastLineOfSight;
private _losDelta = _targetDirection vectorDiff _lastLineOfSight;
private _losRate = if (_timestep == 0) then {
0
} else {
10 * (vectorMagnitude _losDelta) / _timestep;
};
private _commandedAcceleration = (velocity _projectile) vectorMultiply _losRate;
TRACE_5("LOS NAV",_commandedAcceleration,_projectile,_losRate,_lineOfSight,_lastLineOfSight);
private _closingVelocity = _targetVelocity vectorDiff (velocity _projectile);
private _commandedAcceleration = _closingVelocity vectorMultiply _losRate;
// we need acceleration normal to our LOS
private _commandedAccelerationProjected = _lineOfSight vectorMultiply (_commandedAcceleration vectorDotProduct _lineOfSight);
_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected;
if (accTime > 0) then {
_navigationParams set [0, _lineOfSight];
_navigationParams set [0, _targetDirection];
};
_commandedAccelerationProjected

View File

@ -15,43 +15,34 @@
* Public: No
*/
params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"];
_args params ["_firedEH", "", "", "", "_stateParams"];
_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_stateParams params ["", "", "", "","_navigationParams"];
_navigationParams params ["_lastMissileFrame", "_navigationGain"];
_lastMissileFrame params ["_lastTargetPosition", "_lastTargetVelocity", "_lastLineOfSight"];
_lastMissileFrame params ["_lastLineOfSight"];
_targetData params ["_targetDirection", "", "_targetVelocity", ""];
// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel
private _projectileVelocity = velocity _projectile;
// integrate target velocity for realistic inference of velocity
private _targetVelocity = _lastTargetVelocity;
if (_timestep != 0) then {
_targetVelocity = (_seekerTargetPos vectorDiff _lastTargetPosition) vectorMultiply (1 / _timestep);
};
private _closingVelocity = _targetVelocity vectorDiff _projectileVelocity;
private _lineOfSight = vectorNormalized (_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile);
private _closingVelocity = _targetVelocity vectorDiff velocity _projectile;
// the los rate is tiny, so we multiply by a constant of a power of ten to get more aggressive acceleration
// this is just due to how we measure our LOS delta, the vectors involved are _tiny_
private _losDelta = _lineOfSight vectorDiff _lastLineOfSight;
private _losDelta = _targetDirection vectorDiff _lastLineOfSight;
private _losRate = if (_timestep == 0) then {
0
} else {
10 * (vectorMagnitude _losDelta) / _timestep;
};
private _lateralAcceleration = (_navigationGain * _losRate);
private _lateralAcceleration = _navigationGain * _losRate;
private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration;
// we need acceleration normal to our LOS
private _commandedAccelerationProjected = _lineOfSight vectorMultiply (_commandedAcceleration vectorDotProduct _lineOfSight);
private _commandedAccelerationProjected = _targetDirection vectorMultiply (_commandedAcceleration vectorDotProduct _targetDirection);
_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected;
if (accTime > 0) then {
_navigationParams set [0, [_seekerTargetPos, _targetVelocity, _lineOfSight]];
_navigationParams set [0, [_seekerTargetPos, _targetVelocity, _targetDirection]];
};
_commandedAcceleration

View File

@ -0,0 +1,38 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Determine path for projectile to take in accordance to zero-effort miss pro-nav, takes target acceleration into account. Super deadly
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* Commanded acceleration normal to LOS in world space <ARRAY>
*
* Example:
* [] call ace_missileguidance_fnc_navigationType_zeroEffortMiss
*
* Public: No
*/
params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"];
_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_stateParams params ["", "", "", "","_navigationParams"];
_navigationParams params ["", "_navigationGain"];
_targetData params ["_targetDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"];
private _vectorToTarget = _targetDirection vectorMultiply _targetRange;
private _closingVelocity = _targetVelocity vectorDiff velocity _projectile;
private _timeToGo = _targetRange / vectorMagnitude _closingVelocity;
private _zeroEffortMiss = _vectorToTarget vectorAdd (_closingVelocity vectorMultiply _timeToGo);
private _zeroEffortMissProjectiled = _targetDirection vectorMultiply (_zeroEffortMiss vectorDotProduct _targetDirection);
private _zeroEffortMissNormal = _zeroEffortMiss vectorDiff _zeroEffortMissProjectiled;
private _commandedAcceleration = _zeroEffortMissNormal vectorMultiply (_navigationGain / (_timeToGo * _timeToGo));
if (accTime > 0) then {
_navigationParams set [0, [_lineOfSight]];
};
_commandedAcceleration

View File

@ -137,7 +137,14 @@ 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, _pitchYaw select 2]],
[
// target data from missile. Must be filled by seeker for navigation to work
[0, 0, 0], // direction to target
0, // range to target
[0, 0, 0], // target velocity
[0, 0, 0] // target acceleration
]
];
private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired");
@ -166,13 +173,14 @@ if (_onFiredFunc != "") then {
};
// Reverse:
// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"];
// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData"];
// _firedEH params ["_shooter","","","","_ammo","","_projectile"];
// _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"];
// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams", "_guidanceParameters"];
// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"];
// _targetData params ["_targetDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"];
[LINKFUNC(guidancePFH),0, _args ] call CBA_fnc_addPerFrameHandler;

View File

@ -29,8 +29,6 @@ if (_navigationGain == 0) then {
_navigationParams = [
[ // Last Missile Frame
[0, 0, 0], // Last target position array
[0, 0, 0], // Last target velocity
[0, 0, 0] // Last line of sight
],
_navigationGain // navigation gain of missile. Set in the navigation onFired function

View File

@ -16,7 +16,7 @@
* Public: No
*/
params ["", "_args", "_seekerStateParams"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"];
_firedEH params ["_shooter","","","","","","_projectile"];
_launchParams params ["_target","","","",""];
_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"];
@ -116,8 +116,14 @@ if !(isNull _target) then {
_seekerStateParams set [7, velocity _target];
_seekerStateParams set [8, CBA_missionTime];
_seekerStateParams set [9, false];
_targetData set [1, _projectile distance _target];
_targetData set [2, velocity _target];
_targetData set [3, 0]; // todo: acceleration
};
_targetData set [0, _projectile vectorFromTo _expectedTargetPos];
_seekerStateParams set [3, _expectedTargetPos];
_launchParams set [0, _target];
_expectedTargetPos

View File

@ -17,7 +17,7 @@
*/
params ["", "_args"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_launchParams params ["", "_targetParams"];
_targetParams params ["_target"];
@ -40,14 +40,14 @@ TRACE_2("", _angleOkay, _losOkay);
if (!_angleOkay || !_losOkay) exitWith {[0,0,0]};
TRACE_2("", _target, _foundTargetPos);
// @TODO: Configurable lead for seekers
private _projectileSpeed = (vectorMagnitude velocity _projectile);
private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos;
private _eta = _distanceToTarget / _projectileSpeed;
private _adjustDistance = (velocity _target) vectorMultiply _eta;
TRACE_3("leading target",_distanceToTarget,_eta,_adjustDistance);
//_foundTargetPos = _foundTargetPos vectorAdd _adjustDistance;
_targetData set [0, (getPosASL _projectile) vectorFromTo _foundTargetPos];
_targetData set [1, _distanceToTarget];
_targetData set [2, velocity _target];
_targetData set [3, 0];
TRACE_2("return",_foundTargetPos,(aimPos _target) distance _foundTargetPos);
_foundTargetPos;

View File

@ -16,7 +16,7 @@
* Public: No
*/
params ["", "_args"];
_args params ["_firedEH", "", "", "_seekerParams", "_stateParams"];
_args params ["_firedEH", "", "", "_seekerParams", "_stateParams", "_targetData"];
_firedEH params ["_shooter","_weapon","","","","","_projectile"];
_seekerParams params ["_seekerAngle"];
_stateParams params ["", "_seekerStateParams"];
@ -58,5 +58,7 @@ if ((_testDotProduct < (cos _seekerAngle)) || {_testIntersections isNotEqualTo [
[0, 0, 0]
};
_targetData set [0, _lookDirection];
_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj);

View File

@ -19,7 +19,7 @@
#define MAX_AVERAGES 15
params ["", "_args"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams"];
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "", "_targetData"];
_firedEH params ["","","","","","","_projectile"];
_launchParams params ["","","","","","_laserParams"];
_seekerParams params ["_seekerAngle", "", "_seekerMaxRange", "", ["_lastPositions", []], ["_lastPositionIndex", 0]];
@ -52,6 +52,11 @@ if (MAX_AVERAGES == count _lastPositions) then {
_positionSum = _positionSum vectorMultiply (1 / count _lastPositions);
};
_targetData set [0, (getPosASL _projectile) vectorFromTo _positionSum];
_targetData set [1, 0];
_targetData set [2, 0];
_targetData set [3, 0];
TRACE_3("laser target found",_foundTargetPos,_positionSum,count _lastPositions);
_positionSum

View File

@ -60,7 +60,7 @@ Navigation States:
Navigation Types:
X Augmented Pro-Nav
Zero Effort Miss
X Zero Effort Miss
General To-Do:
Add more weapons