mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Add zero-effort miss. Seeker now feeds data to navigation
This commit is contained in:
parent
a93eb6433d
commit
1873467deb
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user