|
| 1 | +#include "..\script_component.hpp" |
| 2 | +/* |
| 3 | + * Author: tcvm |
| 4 | + * Attempts to hold angle as fed to by seeker. Does so with a simple proportional controller |
| 5 | + * |
| 6 | + * Arguments: |
| 7 | + * Guidance Arg Array <ARRAY> |
| 8 | + * |
| 9 | + * Return Value: |
| 10 | + * Commanded acceleration normal to LOS in world space <ARRAY> |
| 11 | + * |
| 12 | + * Example: |
| 13 | + * [] call ace_missileguidance_fnc_navigationType_line |
| 14 | + * |
| 15 | + * Public: No |
| 16 | + */ |
| 17 | +// arbitrary constant |
| 18 | +#define PROPORTIONALITY_CONSTANT 20 |
| 19 | +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos", "_targetData", "_navigationParams"]; |
| 20 | +_args params ["_firedEH"]; |
| 21 | +_firedEH params ["","","","","","","_projectile"]; |
| 22 | + |
| 23 | +_navigationParams params ["_yawChange", "_pitchChange", "_lastPitch", "_lastYaw", "_initialPitch", "_pitchUp", "_lastYawRateDifference"]; |
| 24 | + |
| 25 | +// for some reason we need to multiply this. I don't know why, but it just works |
| 26 | +_pitchChange = _pitchChange * 1.5; |
| 27 | +_yawChange = _yawChange * 1.5; |
| 28 | + |
| 29 | +((velocity _projectile) call CBA_fnc_vect2polar) params ["", "_currentYaw", "_currentPitch"]; |
| 30 | + |
| 31 | +private _pitchRate = if (_timestep == 0) then { |
| 32 | + 0 |
| 33 | +} else { |
| 34 | + (_currentPitch - _lastPitch) / _timestep |
| 35 | +}; |
| 36 | +_navigationParams set [2, _currentPitch]; |
| 37 | + |
| 38 | +private _pitchModifier = if (_pitchChange == 0) then { |
| 39 | + 1 |
| 40 | +} else { |
| 41 | + abs (_pitchRate / _pitchChange) |
| 42 | +}; |
| 43 | +private _desiredPitchChange = (_pitchChange - _pitchRate) * PROPORTIONALITY_CONSTANT * _pitchModifier; |
| 44 | +_desiredPitchChange = _desiredPitchChange + _pitchUp * (_initialPitch - _currentPitch) * PROPORTIONALITY_CONSTANT * _pitchModifier; |
| 45 | + |
| 46 | +private _yawRate = if (_timestep == 0) then { |
| 47 | + 0 |
| 48 | +} else { |
| 49 | + (_currentYaw - _lastYaw) / _timestep |
| 50 | +}; |
| 51 | +_navigationParams set [3, _currentYaw]; |
| 52 | + |
| 53 | +private _yawModifier = if (_yawChange == 0) then { |
| 54 | + 1 |
| 55 | +} else { |
| 56 | + abs (_yawRate / _yawChange) |
| 57 | +}; |
| 58 | + |
| 59 | +private _yawRateDifference = _yawChange - _yawRate; |
| 60 | +private _yawChangeDerivative = if (_timestep == 0) then { |
| 61 | + 0 |
| 62 | +} else { |
| 63 | + (_yawRateDifference - _lastYawRateDifference) / _timestep |
| 64 | +}; |
| 65 | +_navigationParams set [6, _yawRateDifference]; |
| 66 | + |
| 67 | +private _desiredYawChange = _yawRateDifference * PROPORTIONALITY_CONSTANT + _yawRateDifference * 2; |
| 68 | + |
| 69 | +#ifdef DRAW_NLAW_INFO |
| 70 | +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLtoAGL getPosASLVisual _projectile, 0.75, 0.75, 0, format ["dP [%1] dY: [%2]", _desiredPitchChange, _desiredYawChange], 1, 0.025, "TahomaB"]; |
| 71 | +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], [0, 0, 1] vectorAdd ASLtoAGL getPosASLVisual _projectile, 0.75, 0.75, 0, format ["pitch proportional [%1] yaw proportional [%2]", _pitchModifier, _yawModifier], 1, 0.025, "TahomaB"]; |
| 72 | +#endif |
| 73 | + |
| 74 | +TRACE_4("nlaw pitch/yaw info",_currentPitch,_lastPitch,_currentYaw,_lastYaw); |
| 75 | +TRACE_6("nlaw navigation",_yawChange,_desiredYawChange,_pitchChange,_desiredPitchChange,_yawRate,_pitchRate); |
| 76 | + |
| 77 | +_projectile vectorModelToWorldVisual [_yawChange + _desiredYawChange, 0, _pitchChange + _desiredPitchChange] |
| 78 | + |
0 commit comments