From f89bf62242d4909842d9da15336c37d24db206b5 Mon Sep 17 00:00:00 2001 From: Brandon Danyluk Date: Sun, 23 May 2021 17:38:00 -0600 Subject: [PATCH] progress update: tercom now flies to acquisition basket --- addons/missileguidance/ACE_GuidanceConfig.hpp | 8 ++ addons/missileguidance/XEH_PREP.hpp | 2 + .../functions/fnc_navigationType_line.sqf | 3 + .../functions/fnc_seekerType_TERCOM.sqf | 71 ++++++++++++++ .../functions/fnc_tercom_onFired.sqf | 94 +++++++++++++++++++ addons/tomahawk/CfgAmmo.hpp | 74 +++++++++++++++ addons/tomahawk/CfgMagazines.hpp | 14 ++- addons/tomahawk/CfgVehicles.hpp | 39 +++++++- addons/tomahawk/CfgWeapons.hpp | 9 +- addons/tomahawk/stringtable.xml | 15 +++ 10 files changed, 322 insertions(+), 7 deletions(-) create mode 100644 addons/missileguidance/functions/fnc_seekerType_TERCOM.sqf create mode 100644 addons/missileguidance/functions/fnc_tercom_onFired.sqf diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 8ffea076f6..7574da6aa0 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -128,6 +128,14 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_GPS); onFired = QFUNC(gps_seekerOnFired); }; + class TERCOM { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(seekerType_TERCOM); + onFired = QFUNC(tercom_onFired); + }; }; class GVAR(NavigationTypes) { diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index eede7d19e9..3478bf67e2 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -50,6 +50,7 @@ PREP(seekerType_Doppler); PREP(seekerType_MWR); PREP(seekerType_IR); PREP(seekerType_GPS); +PREP(seekerType_TERCOM); // Attack Profiles OnFired PREP(wire_onFired); @@ -62,6 +63,7 @@ PREP(doppler_onFired); PREP(mwr_onFired); PREP(IR_onFired); PREP(gps_seekerOnFired); +PREP(tercom_onFired); // Navigation OnFired PREP(proNav_onFired); diff --git a/addons/missileguidance/functions/fnc_navigationType_line.sqf b/addons/missileguidance/functions/fnc_navigationType_line.sqf index eb809d27ab..5694b89a09 100644 --- a/addons/missileguidance/functions/fnc_navigationType_line.sqf +++ b/addons/missileguidance/functions/fnc_navigationType_line.sqf @@ -23,6 +23,9 @@ _navigationParams params ["_proportionalGain", "", "_derivativeGain", "_lastErro private _targetDistance = _projectile vectorWorldToModelVisual (_targetDir vectorMultiply _distance); private _relativeDirection = _projectile vectorWorldToModelVisual _targetDir; +_proportionalGain = 50; +_derivativeGain = 50; + private _errorX = -1 max (1 min (_targetDistance#0 / _correctionDistance)); private _errorY = -1 max (1 min (_targetDistance#2 / _correctionDistance)); diff --git a/addons/missileguidance/functions/fnc_seekerType_TERCOM.sqf b/addons/missileguidance/functions/fnc_seekerType_TERCOM.sqf new file mode 100644 index 0000000000..94c2636afd --- /dev/null +++ b/addons/missileguidance/functions/fnc_seekerType_TERCOM.sqf @@ -0,0 +1,71 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * TERCOM seeker. Checks change in height data to current change in height and figures out where it is + * TERCOM works by determining the gradient of height change where the missile is, finding the most likely candidate for that in the + * heightmap, and then plotting a course that will guide it towards the waypointed flightpath + * If you have a lot of similar gradients, this will not work as well since it could potentially lead to loss of munition + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Expected correction + * + * Example: + * [] call ace_missileguidance_fnc_seekerType_TERCOM + * + * Public: No + */ +params ["", "_args", "_seekerStateParams", "", "_timestep"]; +_args params ["_firedEH", "_launchParams", "", "", "", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_seekerStateParams params ["_heightBuffer", "_insPosition", "_seekerState", "_currentWaypoint", "_waypoints", "_heightmap"]; +_launchParams params ["", "_targetLaunchParams"]; +_targetLaunchParams params ["", "", "_launchPos"]; + +private _finalPosition = [0, 0, 0]; +switch (_seekerState) do { + case TERCOM_STATE_SEEKING_BASKET: { + // must have at least 2 waypoints, so this will never error + private _waypoint1 = _waypoints select 0; + private _waypoint2 = _waypoints select 1; + _waypoint1 params ["_positionA", "_cruiseHeight"]; + _waypoint2 params ["_positionB"]; + + private _direction = _positionA vectorFromTo _positionB; + private _position = _positionA vectorAdd (_direction vectorMultiply (0.5 * (_positionA vectorDistance _positionB))); + + _launchPos set [2, _cruiseHeight]; + _position set [2, _cruiseHeight]; + + private _desiredPathDir = _launchPos vectorFromTo _position; + + private _missilePosProjected = _launchPos vectorAdd (_desiredPathDir vectorMultiply ((_insPosition vectorDistance _launchPos) + 100)); + private _distance = _insPosition vectorDistance _missilePosProjected; + + _targetData set [2, _distance]; + _finalPosition = _missilePosProjected; + + (_heightmap select 0) params ["", "_resolution"]; + if (_insPosition inArea [_position, _resolution, _resolution, (_direction#0) atan2 (_direction#1), true]) then { + _seekerStateParams set [2, TERCOM_STATE_FOLLOWING_TERRAIN]; + }; + }; + case TERCOM_STATE_FOLLOWING_TERRAIN: { + // just brute force it, we won't usually have a lot of grids to check + }; + case TERCOM_STATE_TERMINAL: { + + }; +}; + +if (!isGamePaused && accTime > 0) then { + private _projectileVelocity = velocity _projectile; + _insPosition = _insPosition vectorAdd (_projectileVelocity vectorMultiply _timestep); + + _seekerStateParams set [1, _insPosition]; +}; + +_finalPosition diff --git a/addons/missileguidance/functions/fnc_tercom_onFired.sqf b/addons/missileguidance/functions/fnc_tercom_onFired.sqf new file mode 100644 index 0000000000..e02fa7bc7d --- /dev/null +++ b/addons/missileguidance/functions/fnc_tercom_onFired.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Sets up TERCOM state arrays + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_TERCOM_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "_seekerStateParams"]; + +// need a number that denotes maximum grid width at specified resolution +// 3 grid cells in either direction +#define MAX_GRID_WIDTH 5 + +private _minResolution = 50; +private _maxResolution = 300; + +private _waypoints = [ + [[22255.6,14042.3,0], 50], + [[19708.9,14668.1,0], 50], + [[17334.5,16922.6,0], 50], + [[13809.5,18171.9,0], 30], + [[11167.8,20575.4,0], 20], + [[6294.59,20780.3,0], 20], + [[4552.04,21492.6,0], 20] +]; +private _heightmap = []; + +private _maxWaypoints = (count _waypoints) - 1; + +{ + // at last waypoint, dont process + if (_forEachIndex == _maxWaypoints) exitWith {}; + private _nextWaypoint = _waypoints select (_forEachIndex + 1); + + _x params ["_positionA", "_cruiseHeight"]; + _nextWaypoint params ["_positionB", "_cruiseHeight"]; + + private _distance = _positionA vectorDistance _positionB; + private _direction = _positionA vectorFromTo _positionB; + private _normalDirection = [-(_direction#1), _direction#0, _direction#2]; + + private _resolution = linearConversion [0, 1, (_forEachIndex + 1) / _maxWaypoints, _maxResolution, _minResolution]; + + private _startingGridPos = _positionA vectorAdd (_normalDirection vectorMultiply (MAX_GRID_WIDTH * _resolution)); + _startingGridPos = _startingGridPos vectorDiff (_normalDirection vectorMultiply -(_resolution * 0.5)); + + for "_y" from 0 to (MAX_GRID_WIDTH * 2) do { + private _gridPos = _startingGridPos vectorAdd (_normalDirection vectorMultiply -(_resolution * _y)); + private _firstHeightmapCell = []; + for "_x" from 0 to ceil (_distance / _resolution) step 1 do { + private _heightAtPos = 0 max getTerrainHeightASL _gridPos; + + _firstHeightmapCell pushBack [_gridPos#0, _gridPos#1, _heightAtPos]; + _gridPos = _gridPos vectorAdd (_direction vectorMultiply _resolution); + }; + _heightmap pushBack [_firstHeightmapCell, _resolution * MAX_GRID_WIDTH]; + }; + +} forEach _waypoints; + +{ + { + private _m = createMarker [format ["%1", random 1e10], _x]; + _m setMarkerType "mil_dot"; + _m setMarkerText format ["%1m", _x select 2]; + } forEach (_x select 0); +} forEach _heightmap; + +{ + _x params ["_position", "_cruiseAltitude"]; + private _m = createMarker [format ["%1", random 1e10], _position]; + _m setMarkerType "mil_dot"; + _m setMarkerText format ["%1m", _cruiseAltitude]; + _m setMarkerColor "ColorRed"; +} forEach _waypoints; + +_seekerStateParams set [0, []]; // internal buffer of heights +_seekerStateParams set [1, getPosASLVisual _projectile]; // calculated current position - simulating INS guidance +_seekerStateParams set [2, TERCOM_STATE_SEEKING_BASKET]; // current state +_seekerStateParams set [3, 0]; // current waypoint +_seekerStateParams set [4, _waypoints]; +_seekerStateParams set [5, _heightmap]; + diff --git a/addons/tomahawk/CfgAmmo.hpp b/addons/tomahawk/CfgAmmo.hpp index 32c90bad28..d6b2f9b305 100644 --- a/addons/tomahawk/CfgAmmo.hpp +++ b/addons/tomahawk/CfgAmmo.hpp @@ -1,3 +1,77 @@ class CfgAmmo { + class ammo_Missile_Cruise_01; + class ammo_Missile_Cruise_01_Cluster; + + class GVAR(c): ammo_Missile_Cruise_01 { + maneuvrability = 0; + class ace_missileguidance { + enabled = 1; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "TERCOM"; + seekerTypes[] = { "TERCOM" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 50; + lineGainD = 50; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; + }; + }; + + class GVAR(d): ammo_Missile_Cruise_01_Cluster { + maneuvrability = 0; + class ace_missileguidance { + enabled = 1; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "TERCOM"; + seekerTypes[] = { "TERCOM" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 50; + lineGainD = 50; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; + }; + }; }; diff --git a/addons/tomahawk/CfgMagazines.hpp b/addons/tomahawk/CfgMagazines.hpp index ac58f21763..f1841bf221 100644 --- a/addons/tomahawk/CfgMagazines.hpp +++ b/addons/tomahawk/CfgMagazines.hpp @@ -1,4 +1,16 @@ class CfgMagazines { - + class magazine_Missiles_Cruise_01_x18; + class GVAR(c): magazine_Missiles_Cruise_01_x18 { + displayName = CSTRING(c); + displayNameShort = CSTRING(c); + descriptionShort = CSTRING(c_description); + ammo = QGVAR(c); + }; + class GVAR(d): magazine_Missiles_Cruise_01_x18 { + displayName = CSTRING(d); + displayNameShort = CSTRING(d); + descriptionShort = CSTRING(d_description); + ammo = QGVAR(d); + }; }; diff --git a/addons/tomahawk/CfgVehicles.hpp b/addons/tomahawk/CfgVehicles.hpp index e4b8ace2c1..5082dddd5a 100644 --- a/addons/tomahawk/CfgVehicles.hpp +++ b/addons/tomahawk/CfgVehicles.hpp @@ -4,18 +4,24 @@ class CfgVehicles { class Turrets; }; class B_Ship_MRLS_01_base_F: StaticMGWeapon { + class AnimationSources; class Turrets: Turrets { class MainTurret; }; }; // Use a custom ACE variant due to custom interface for launching - class GVAR(vls): B_Ship_MRLS_01_base_F { - displayName = "[ACE] Mk41 VLS"; - class AnimationSources { + class GVAR(vls_c): B_Ship_MRLS_01_base_F { + displayName = CSTRING(vls_c); + scope = 2; + scopeCurator = 2; + side = 1; + faction = "BLU_F"; + crew = "B_UAV_AI"; + class AnimationSources: AnimationSources { class Missiles_revolving { source = "ammo"; - source = "revolving"; weapon = QGVAR(c); + animPeriod = 0.001; }; }; class Turrets: Turrets { @@ -29,4 +35,29 @@ class CfgVehicles { }; }; }; + class GVAR(vls_d): B_Ship_MRLS_01_base_F { + displayName = CSTRING(vls_d); + scope = 2; + scopeCurator = 2; + side = 1; + faction = "BLU_F"; + crew = "B_UAV_AI"; + class AnimationSources: AnimationSources { + class Missiles_revolving { + source = "ammo"; + weapon = QGVAR(d); + animPeriod = 0.001; + }; + }; + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = { + QGVAR(d) + }; + magazines[] = { + QGVAR(d) + }; + }; + }; + }; }; \ No newline at end of file diff --git a/addons/tomahawk/CfgWeapons.hpp b/addons/tomahawk/CfgWeapons.hpp index 5184f83c55..c0651ee87f 100644 --- a/addons/tomahawk/CfgWeapons.hpp +++ b/addons/tomahawk/CfgWeapons.hpp @@ -1,7 +1,12 @@ class CfgWeapons { + class weapon_VLS_01; class GVAR(c): weapon_VLS_01 { - displayName = "Venator Cruise Missile"; - magazines[] = {"magazine_Missiles_Cruise_01_x18", "magazine_Missiles_Cruise_01_Cluster_x18"}; + displayName = CSTRING(c); + magazines[] = { QGVAR(c) }; + }; + class GVAR(d): weapon_VLS_01 { + displayName = CSTRING(d); + magazines[] = { QGVAR(d) }; }; }; diff --git a/addons/tomahawk/stringtable.xml b/addons/tomahawk/stringtable.xml index 740cdf3806..da9d21ae62 100644 --- a/addons/tomahawk/stringtable.xml +++ b/addons/tomahawk/stringtable.xml @@ -1,8 +1,23 @@ + + [ACE] Mk41 VLS [BGM-109C] + BGM-109C + + Cruise missile with terrain-following capabilites and an HE warhead + + + [ACE] Mk41 VLS [BGM-109D] + + + BGM-109D + + + Cruise missile with terrain-following capabilites and a cluster-munition warhead +