Jump to content
johnnyboy

terrain hugging missile script?

Recommended Posts

The great @mandoble (of OFP and ARMA 1 fame) made fabulous Mando Missile scripts that would move an object on a flight path that would hug terrain.  I've searched, but could not find, an ARMA 3 script to do the same.  One of the many cool things about Mando's script, was it could send ANY object on a terrain hugging  flight path.  What I am hoping is that such a script could force an AI helicopter to fly low an fast.  The hope is to give an AI helicopter move waypoints, but have this script take over until near destination, then AI flying takes over until pointed at next waypoint.

 

Helicopters flying at tree top level would be bad-ass (without having to use unitCapture).  Anybody know of such a script?

 

Note:  Call my lazy, but my math/physics skills are weak, so I have no intention of writing this script from scratch.  But if one exists, I'm willing to try and adapt it to work with helicopters.

 

Here's an old video of Mando's ground hugging missles:

 

 

  • Like 2

Share this post


Link to post
Share on other sites

What, you don't trust the AI to maintain tree-top height without crashing?

 

But more to the point, in RHS the Tu-95 fires cruise missiles that follow the terrain. I have no idea if it's scripted or what, but maybe there's something there for it? 

  • Thanks 1

Share this post


Link to post
Share on other sites

Oh how I wish @johnnyboy we still had mandoble around.  His missile scripts gave me HOURS of fun, destroying air, land and sea targets.

 

I don't know how much work would be required to get MM working into Arma3 ... but I bet it is significant ... but WHAT A PROJECT !!!

  • Like 4

Share this post


Link to post
Share on other sites

Well, although I do not have a refined solution, I'm familiar with the topic. Some time ago I tried to convince AI, it's actually fine idea to fly heli that way. I believe, it would be even doable, if only flyInHeight wasn't half-broken and not working for low altitudes properly. Then tried a hybrid of flyInHeight and setVelocity, result was ugly and far from OK. AI is your enemy here, so best, I have now, is somewhat promising wip using setVelocity per frame. I hope, it will at least suffice as adaptable for your needs proof of concept. It is possible, I'll be working further on this. 

 

Contour flight wip

 

Code is somewhat messy - it's a work in progress after all:

 

Spoiler

RYD_LH_ContourFlight = 
	{
	params ["_heli","_vel","_alt","_safeBuff"];
	
	_gp = group _heli;
	_bbH = boundingBoxReal _heli;
	_size = ((_bbH select 1) select 0) - ((_bbH select 0) select 0);
	_addH = abs ((_bbH select 0) select 2);
	_safeBuff = _safeBuff + _addH;

	//waitUntil
		//{
		//sleep 0.03;
		if ((isNull _heli) or {not (alive _heli) or {(isNull _gp)}}) exitWith {true};

		_cP = currentPilot _heli;
		
		if (not (isTouchingGround _heli) and {(canMove _heli) and {((fuel _heli) > 0) and {not (isNull _cP) and {(alive _cP) and {not (isPlayer _cP) and {((count (waypoints _gp)) > 0)}}}}}}) then
			{
			_cw = currentWaypoint _gp;
			_cw = [_gp,_cw];
			_wPos = waypointPosition _cw;
			if (_wPos isEqualTo [0,0,0]) exitWith {};
		
			_hPos = getPosATL _heli;
			
			if (surfaceIsWater _hPos) then
				{
				_hPos = ATLtoASL _hPos
				};			
			
			_cVel = velocity _heli;

			if ((_hPos distance2D _wPos) > 100) then
				{
				_dirH = getDir _heli;
				_dir = _heli getDir _wPos;
				_diff = _dirH - _dir;
				_diff = abs ((sin _diff) atan2 (cos _diff));
				_cVelH = _cVel distance2D [0,0,0];

				if ((_diff < 1) or {(_cVelH > 10)}) then
					{
					_cVelN = _cVel distance [0,0,0];
					
					_range = _size max (_cVelN/2);
					_rad = _size + 15;
					_obstacleH = 0;
					_corr = 0;
					_moDst = _range + _rad;

					for "_i" from _size to _range step _size do
						{
						_pingPos = _heli getPos [_i,_dir];
						_objects = nearestTerrainObjects [_pingPos, [], _rad, false, true];
						
							{
							_bbr = boundingBoxReal _x;
							_top = (_x modelToWorld [0,0,((_bbr select 1) select 2)]) select 2;
							_obstacleH = _obstacleH max _top;
							if (_top > (_alt - _safeBuff)) then
								{
								_moDst = _moDst min (_heli distance2D _x);
								a1 setPosATL (_x modelToWorld [0,0,((_bbr select 1) select 2)]);//debug
								}
							}
						foreach _objects;
						};
					
					_desiredAlt = _alt max (_obstacleH + _safeBuff);
					_cAlt = _hPos select 2;						
					_diffAlt = _desiredAlt - _cAlt;
					_rPingPos = _hPos;
					
					for "_i" from _size to _range step _size do
						{
						_pingPos = _heli getPos [_i,_dir];
						_pingPos set [2,0];
						
						_corr = ((getTerrainHeightASL _pingPos) max 0) - ((getTerrainHeightASL _hPos) max 0) + _diffAlt;
						if (((abs _corr) > 0) and {(_obstacleH == 0) or {(_corr > _obstacleH)}}) then
							{
							_rPingPos = _pingPos;
							a2 setPosATL _pingPos;//debug
							_moDst = _moDst min (_heli distance2D _pingPos);
							};
						};

					_cAlt = _cAlt - (((getTerrainHeightASL _rPingPos) max 0) - ((getTerrainHeightASL _hPos) max 0));
					_diffAlt = _desiredAlt - _cAlt;	
													
					if ((_cVelN < _vel) or {((abs _diffAlt) > (10/(_cVelN max 10)))}) then
						{
						_fPos = _hPos getPos [(_moDst/((_diffAlt max 0.01)^0.5)),_dir];
						_fPos set [2,_desiredAlt];
						a3 setPosATL _fPos;//debug
						
						//_heli setPosATL _fPos;
						
						_dirV = _hPos vectorFromTo _fPos;
						_velV = _dirV vectorMultiply _vel;
						
						//_velV = [((_cVel select 0) + (_velV select 0))/2,((_cVel select 1) + (_velV select 1))/2,((_cVel select 2) + (_velV select 2))/2];
						
						//_heli setVectorUp [0,0,1];
						//_heli setDir _dir;
						_heli setVelocity _velV;
						}
					}
				}
			};

		//(false)
		//};
		
	hintSilent format ["spd: %1\nalt: %2",((velocity _heli) distance [0,0,0]),(((getPosATL _heli) select 2) min ((getPosASL _heli) select 2))];
	};
	
sleep 1;

a1 = createvehicle ["Sign_Arrow_Large_F",(player modelToWorld [0,0,10]),[],0,"CAN_COLLIDE"];//debug
a2 = createvehicle ["Sign_Arrow_Large_Blue_F",(player modelToWorld [0,0,10]),[],0,"CAN_COLLIDE"];//debug
a3 = createvehicle ["Sign_Arrow_Large_Green_F",(player modelToWorld [0,0,10]),[],0,"CAN_COLLIDE"];//debug

player moveInCargo heli1;
//_handle = [heli1,50,10,2] spawn RYD_LH_ContourFlight;

RYD_LH_EFEH = addMissionEventHandler ["EachFrame",{[heli1,100,10,2] call RYD_LH_ContourFlight}];

_wp = (group heli1) addWaypoint [(getMarkerPos "m1"),0];
_wp setWaypointType "MOVE";

 

 

As for known issues:

 

1. Still may require general calibration to make the heli better "hug the terrain" from one side while ensure no crashes from another. I wouldn't recommend to fly lower with that speed, than set currently in this version. And crashes may occur anyway in some certain situations. 

2. Tries to overfly map objects, but will ignore other objects (easy to correct).

3. Heli has a tendency to lean back all the way (AI tries to slow down?), not sure, how to prevent that in fluid way so far. Maybe I should just throw the pilot out temporarily? 🙂

4. Doesn't use any kind of horizontal obstacle bypassing ("slalom"), vertical only. 

5. The flight aerodynamically not so realistic - too sharp movement changes. 

 

 

If not good enough, the last resort, I guess, would be support of commands like setVelocityTransformation or vectorLinearConversion. Or brutal setPosing per frame even. 

 

PS Missiles are easier as for the flight IIRC. No AI to struggle with. Just you, the missile and velocity vectors math (I share your pain in vector math regard though). 

  • Like 3

Share this post


Link to post
Share on other sites

Hey @Rydygier, thanks for this.  Its funny and great that you are the one to reply, because it's your Hermes heli support script I was experimenting with (awesome script BTW).  I had great success with setVelocityModelSpace in getting AI drivers to accelerate on straight segments of roads for a chase sequence, and hoped that might be simple solution for helis.  But, as you said the result was ugly (they put their nose down and bobbed along stupidly).  That's when I decided to make this post (after remembering Mando's flying tractor).

 

4 hours ago, Rydygier said:

Maybe I should just throw the pilot out temporarily

Haha.  Definitely worth a try.  I think I set drivers enableSimulation false while accelerating on roads so they wouldn't fight the setVelocityModelSpace. Then re-enable them before next turn in road.

 

4 hours ago, Rydygier said:

PS Missiles are easier as for the flight IIRC. No AI to struggle with. Just you, the missile and velocity vectors math (I share your pain in vector math regard though)

Exactly, once they are on course and speed > X, disable the pilot(s).  Then re-enable them when they are X meters from next waypoint.  Worth a shot.  Hopefully they don't freak out when they regain consciousness!

4 hours ago, Rydygier said:

If not good enough, the last resort, I guess, would be support of commands like setVelocityTransformation or vectorLinearConversion. Or brutal setPosing per frame even. 

 

A few years ago I took a shot at train movement by looking at unitCapture and unitPlay, and trying to reconstruct that movement dynamically.  But failed.

 

I'll take a look at your WIP script.  But I guess I'm really hoping you are working on this to add it to your kick-ass Hermes script?  We need fast choppers for evac that have a chance of surviving!

 

Keep up the good fight, and thanks for all your contributions to the community.

  • Like 4

Share this post


Link to post
Share on other sites
Quote

3. Heli has a tendency to lean back all the way (AI tries to slow down?), not sure, how to prevent that in fluid way so far.

 

Disabling pilot's simulation seems effectless in this regard, actual throwing pilot out makes heli fall (could be compensated by additional vertical velocity, but complications...).

 

However addTorque does the trick:

 

						_heli addTorque (_heli vectorModelToWorld [10000,0,0]);
						_heli setVelocity _velV;

 

  • Like 2

Share this post


Link to post
Share on other sites

There's a tension between two contradictory goals that need to coexist somehow within this code: fly low without crashing (which is hard) and do it in believeable/fluid manner (which is harder, I do not dare call it "realistic" anyway). So I'm still fiddling with the code, bouncing between these two, trying to break this impass with some fresh approach or at least to find tolerable middle ground. Here's some wip test recorded (closer to the first goal, so not very pretty nor the lowest flight so far, I saw, but no crash):

 

 

For comparison, a more risky parameters (less steep maneuvers allowed) for better fluidity, still no crash despite The Cliff of Death trial, so I guess, that's new optimum:

 

 

 

No idea, how successful I'll be at the end, but the work continues. 

  • Like 5

Share this post


Link to post
Share on other sites

This is fantastic Rydgier.  Even the first test looked acceptable to me.  I can't wait to see the final outcome.  This will be a significant game changer IMO.  :hyper:

  • Like 2

Share this post


Link to post
Share on other sites

Seems reliable enough for the release, still could use more testing for sure...

 

And yes, next I'll see, if I can adapt it to work inside Hermes Airlift Services, would be nice addition I guess. 

 

  • Like 3

Share this post


Link to post
Share on other sites

Spent some time trying to get a group of Hueys to follow a river at tree top height with only a limited success. BI Wiki says minimum is 40m but I think my choppers were always a bit higher than that. (probably more like 60+)

 

Thanks for continuing to give us goodies that you make.

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×