implement course state machine

This commit is contained in:
Brandon Danyluk 2021-04-14 02:29:27 -06:00
parent a485399c5e
commit d0775283e3
8 changed files with 89 additions and 9 deletions

View File

@ -31,8 +31,8 @@ class CfgAmmo {
seekerMaxRange = 4000; // Range from the missile which the seeker can visually search
// Attack profile type selection
defaultAttackProfile = "LIN";
attackProfiles[] = {"LIN"};
defaultAttackProfile = "DIR";
attackProfiles[] = {"DIR"};
};
};

View File

@ -85,8 +85,8 @@ class CfgAmmo {
defaultSeekerLockMode = "LOBL";
seekerLockModes[] = { "LOBL" };
defaultNavigationType = "ZeroEffortMiss";
navigationTypes[] = { "ZeroEffortMiss" };
defaultNavigationType = "LineOfSight";
navigationTypes[] = { "LineOfSight", "ZeroEffortMiss" };
navigationGain = 3;
@ -102,6 +102,19 @@ class CfgAmmo {
defaultAttackProfile = "JAV_TOP";
attackProfiles[] = { "JAV_TOP", "JAV_DIR" };
useModeForAttackProfile = 1;
class navigationStates {
class initial {
transitionCondition = QFUNC(javelin_midCourseTransition);
navigationType = "LineOfSight";
};
class terminal {
transitionCondition = "";
navigationType = "ZeroEffortMiss";
};
// transitions from initial -> termimal
states[] = {"initial", "terminal"};
};
};
};
class ACE_Javelin_FGM148_static: ACE_Javelin_FGM148 {

View File

@ -52,3 +52,6 @@ PREP(IR_onFired);
// Navigation OnFired
PREP(proNav_onFired);
// State transitions
PREP(javelin_midCourseTransition);

View File

@ -19,10 +19,11 @@
BEGIN_COUNTER(guidancePFH);
params ["_args", "_pfID"];
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData"];
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateParams"];
_firedEH params ["_shooter","","","","_ammo","","_projectile"];
_launchParams params ["","_targetLaunchParams","","","","","_navigationType"];
_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParameters", "_guidanceParameters"];
_navigationStateParams params ["_currentState", "_navigationStateData"];
if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith {
[_pfID] call CBA_fnc_removePerFrameHandler;
@ -47,15 +48,30 @@ _targetData set [1, _projectilePos vectorFromTo _profileAdjustedTargetPos];
// If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection
if ((_pitchRate != 0 || {_yawRate != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,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 }]));
if (_transition) then {
_currentState = _currentState + 1;
_navigationStateParams set [0, _currentState];
};
_navigationType = (_navigationStateData select _currentState) select 1;
_navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName")
};
private _commandedAcceleration = [_args, _timestep, _seekerTargetPos, _profileAdjustedTargetPos] call (missionNamespace getVariable _navigationFunction);
if (isNil "_commandedAcceleration") exitWith {
systemChat _navigationFunction;
ERROR_MSG("_commandedAcceleration is nil! Guidance cancelled");
};
#ifdef DRAW_GUIDANCE_INFO
private _projectilePosAGL = ASLToAGL _projectilePos;
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], _projectilePosAGL vectorAdd [0, 0, 1], 0.75, 0.75, 0, str _commandedAcceleration, 1, 0.025, "TahomaB"];
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], _projectilePosAGL vectorAdd [0, 0, 2], 0.75, 0.75, 0, _navigationType, 1, 0.025, "TahomaB"];
drawLine3D [_projectilePosAGL, _projectilePosAGL vectorAdd _commandedAcceleration, [1, 0, 1, 1]];
#endif

View File

@ -0,0 +1,27 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Sets up IR state arrays (called from missileGuidance's onFired).
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* None
*
* Example:
* [] call ace_missileguidance_fnc_IR_onFired
*
* Public: No
*/
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"];
_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", "_guidanceParameters"];
_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"];
_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"];
_targetRange <= 500

View File

@ -30,7 +30,7 @@ private _losDelta = _attackProfileDirection vectorDiff _lastLineOfSight;
private _losRate = if (_timestep == 0) then {
0
} else {
1 * (vectorMagnitude _losDelta) / _timestep;
10 * (vectorMagnitude _losDelta) / _timestep;
};
private _closingVelocity = _targetVelocity vectorDiff (velocity _projectile);

View File

@ -92,6 +92,8 @@ if (isNil "_target") then {
};
};
_targetPos = getPosASLVisual _target;
// Array for seek last target position
private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1;
private _lastKnownPosState = [_seekLastTargetPos];
@ -115,6 +117,24 @@ if (isNumber (_config >> "pitchRate")) then {
_bangBang = 1 == getNumber (_config >> "bangBangGuidance");
};
private _navigationStateSubclass = _config >> "navigationStates";
private _states = getArray (_navigationStateSubclass >> "states");
private _navigationStateData = [];
private _initialState = "";
if (_states isNotEqualTo []) then {
_initialState = _states select 0;
{
private _stateClass = _navigationStateSubclass >> _x;
_navigationStateData pushBack [
getText (_stateClass >> "transitionCondition"),
getText (_stateClass >> "navigationType")
];
} forEach _states;
};
private _pitchYaw = (vectorDir _projectile) call CBA_fnc_vect2Polar;
TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType);
private _args = [_this,
@ -145,7 +165,8 @@ private _args = [_this,
0, // range to target
[0, 0, 0], // target velocity
[0, 0, 0] // target acceleration
]
],
[0, _navigationStateData]
];
private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired");
@ -174,7 +195,7 @@ if (_onFiredFunc != "") then {
};
// Reverse:
// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData"];
// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"];
// _firedEH params ["_shooter","","","","_ammo","","_projectile"];
// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"];
// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"];

View File

@ -3,7 +3,7 @@
#include "\z\ace\addons\main\script_mod.hpp"
#define DRAW_GUIDANCE_INFO
#define ENABLE_PROJECTILE_CAMERA
// #define ENABLE_PROJECTILE_CAMERA
#define DEBUG_MODE_FULL
#define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS