DankanX37 29 Posted August 15, 2022 Hello, I recently made an Iron Dome mod: Steam workshop link I am also releasing a standalone script used for guiding the missile, currently, 3 modes are available: Augmented proportional navigation APN Proportional navigation PN Pure pursuit LOS Here is the code: You can call this function (script) by using: [missile, target, [parameters]] execVM... Parameter is an array containing: Missile max speed: The speed the missile will travel (good values between 200 and 1000) Guidance law: The law that will be used: 0 - APN (best), 1 - PN, 2 - LOS Guidance gain: A constant typically between 3 and 5 Time to max: Missile speed will increase linearly until it reaches the max //params ["_missile", "_target", "_speed",]; private _missile = param[0]; private _target = param[1]; private _parameters = param[2]; //Speed, guidance, N private _speed = _parameters select 0; private _guidance = _parameters select 1; private _N = _parameters select 2; private _timeToMax = _parameters select 3; if(isNull _target) exitWith {}; //Weird issue with APN when engaging missiles idk _targetIsMissile = (_target isKindOf "MissileBase"); //Variables for the missile and logic private _increment = 0.02; private _currSpeed = _speed / 100; private _k = 1; private _initialDist = (_missile distance _target); private _closeEncounter = false; private _medianLoops = 5; _lowestDist = _initialDist; _incrementSpeed = (_speed - _currSpeed) / _timeToMax; //Vectorial quantities _guidVel = [0,0,0]; _leadAcc = [0,0,0]; _lastB = [0,0,0]; _tgtAccNorm = [0,0,0]; private _time = time; _loop = 0; while {alive _target and alive _missile} do { //Elapsed time _deltaT = (time - _time); //Speed _currSpeed = _currSpeed + _incrementSpeed * _deltaT; _currSpeed = _currSpeed min _speed; //LOS _posA = getPosASL _missile; _posB = getPosASL _target; _LOS = _posB vectorDiff _posA; _steering = _posA vectorFromTo _posB; _dist = _missile distance _target; //Relative velocity _velA = velocity _missile; _velB = velocity _target; _relVelocity = _velB vectorDiff _velA; if(_dist < _lowestDist) then { _lowestDist = _dist; }; //Was close if(_dist < 1000) then { _closeEncounter = true; }; //Now is far if(_closeEncounter and (_dist > 1500)) then { _mine = createMine ["DemoCharge_F", getPosATL _missile, [], 0]; _mine setDamage 1; deletevehicle _missile; }; switch (_guidance) do { //APN case 0: { //Impact Time Control Cooperative Guidance Law Design Based on Modified Proportional Navigation //https://www.mdpi.com/2226-4310/8/8/231/pdf //formula [30] _tGo = (_dist/(speed _missile)*(1+ ((acos(_velA vectorCos _steering)/90)^2)/(2*(2 * _N - 1)))); if(isNil "_tgo") then {continue}; //Zero effort miss _ZEM = _LOS vectorAdd (_relVelocity vectorMultiply _tGo); _losZEM = _ZEM vectorDotProduct _steering; _nrmZEM = (_ZEM vectorDiff (_steering vectorMultiply _losZEM)); //Weird behaviour when attacking missiles if(!_targetIsMissile) then { if(_loop == _medianLoops) then { //Target accelleration _tgtAcc = _leadAcc vectorMultiply (1/_medianLoops); _tgtAccLos = _tgtAcc vectorDotProduct _steering; _tgtAccNorm = _tgtAcc vectorDiff (_steering vectorMultiply _tgtAccLos); _loop = 0; } else { _tgtAcc = (_velB vectorDiff _lastB) vectorMultiply (1/_increment); _lastB = _velB; _leadAcc = _leadAcc vectorAdd _tgtAcc; _loop = _loop + 1; }; }; //augmented prop nav with ZEM and lowered proportional gain _leadAcc = (_nrmZEM vectorMultiply _N) vectorMultiply (1/(_tGo ^ 2)) vectorAdd (_tgtAccNorm vectorMultiply (_N/4)); _guidVel = (_leadAcc vectorMultiply _increment) vectorAdd _velA; }; //PN case 1: { //Calculate omega _rotation = _LOS vectorCrossProduct _relVelocity; _distance = _LOS vectorDotProduct _LOS; _rotation = _rotation vectorMultiply (1/_distance); //Desired accelleration to intercept _leadAcc = (_relVelocity vectorMultiply _N) vectorCrossProduct _rotation; _guidVel = (_leadAcc vectorMultiply _increment) vectorAdd _velA; }; //Pure pursuit case 2: { _guidVel = _steering; } }; //Set new speed _guidVel = ((vectorNormalized _guidVel) vectorMultiply _currSpeed); _missile setVectorDir _guidVel; _missile setVelocity _guidVel; //drawLine3D [_posA, _posA vectorAdd _LOS, [1,1,1,1]]; sleep _increment; }; //If the target died or the missile timedout make it blow in mid air if(alive _missile) then { waitUntil {(getposATL _missile select 2) > 100}; if(alive _target) then { sleep random 1; }; deletevehicle _missile; _mine = createMine ["DemoCharge_F", getPosATL _missile, [], 0]; _mine setDamage 1; }; true; This is more aimed at developers who want to build missile-based systems and for one reason or the other can't use the missile locking capability. 5 Share this post Link to post Share on other sites
fn_Quiksilver 1633 Posted August 27, 2022 very cool system 🙂 Share this post Link to post Share on other sites