Jump to content
panther42

Proof of concept testing: setVelocityTransformation

Recommended Posts

I'm working on a proof of concept for a "fast/hot" helicopter landing using setVelocityTransformation.  Could be used for planes, etc.

The version I'm currently testing is using time, as given on the wiki page for setVelocityTransformation.  I'm also working on a variation with distance to landing.

My testing has shown helicopters will increase altitude ~ 600m out from landing point to bleed off velocity, prior to landing (of course depending on velocity prior).

I start manipulating with setVelocityTransformation once they reach ~ 500m out.  This is more of a glide slope landing, than a high above, drop down now, approach.

My problem is that EachFrame eventHandler (addMissionEventHandler) actually moves the heliopter back at first (away from), as if the "time" captured prior to eventHandler running is not lining up with current position.

Any ideas on how to correct this?  May not be even possible with my approach.

Set up (simplified):

Spoiler

Spawn helicopter/crew via BIS_fnc_spawnVehicle 3000m away from player position.

create helipad at player positon

helicopter doMove to helipad position

500m out from landing run setVelocityTransformation in EachFrame eventhandler

Once helicopter reaches < 15m above ground, break out of eventhandler

helicopter land "GET IN"

helicopter flyInHeight 0

 

Of course there are other variables involved, such as utilizing time.  I've done tests with t1 = time, t2 = time + x(insert value here).  Used time + diag_fps, etc.

 

Simplified version of the code used in an addAction:

Spoiler

private ["_gridPos", "_posCaller", "_spawnPos", "_spawnDir", "_spawnRange", "_vecDir", "_markerLZ", "_heliSpawn", "_heliPilot", "_typeHeli", "_lz", "_targetPad", "_maxDist"];

params ["_tgt", "_caller", "_actIdx", "_args"];

_tgt removeaction _actIdx;

_gridPos = mapGridPosition getPos player;
group player setGroupID ["Mako 30"];
_posCaller = getPos player;
_spawnDir = getDir player; // face the direction you want helicopter to arrive from
_spawnRange = 3000;     // distance to spawn the helicopter from player location
sleep 0.3;

player sideChat format ["CROSSROAD this is Mako 30, requesting immediate extraction. Location is at grid %1, over.", _gridPos];

sleep 5;
[playerSide,"HQ"] sideChat "Mako 30 this is CROSSROAD, affirmative on the helicopter request.  Razor 04 will make contact when inbound, out.";

/********************************************************************
spawn helicopter
********************************************************************/
_spawnPos = _posCaller getPos [_spawnRange, _spawnDir];
_vecDir = _spawnPos getDir _posCaller;
_markerLZ = getMarkerPos "marker_LZ";
_heliSpawn = [];

call {
	if (playerSide isEqualTo west) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["B_Heli_Transport_01_F","B_Heli_Transport_03_F"], WEST] call BIS_fnc_spawnVehicle};
	if (playerSide isEqualTo east) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["O_Heli_Light_02_F","O_Heli_Transport_04_covered_F"], EAST] call BIS_fnc_spawnVehicle};
	if (playerSide isEqualTo resistance) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["I_Heli_light_03_F","I_Heli_Transport_02_F"], RESISTANCE] call BIS_fnc_spawnVehicle};
	if (playerSide isEqualTo civilian) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["C_Heli_Light_01_civil_F","C_IDAP_Heli_Transport_02_F"], CIVILIAN] call BIS_fnc_spawnVehicle};
};

_heliSpawn params ["_heli", "_crewHeli", "_grpHeli"];
_heliPilot = driver _heli;
_grpHeli setGroupID ["Razor 04"];
_heliPilot setskill 0.7;
_heliPilot setCombatMode "YELLOW";
_heliPilot setBehaviour "CARELESS";
_heliPilot setRank "CAPTAIN";
_grpHeli selectLeader _heliPilot;
heli = _heli;
sleep 1;

_typeHeli = typeOf _heli;
_lz = []; 
_maxDist = 50; 
while { count _lz < 1 } do 
	{ 
		_lz = _markerLZ findEmptyPosition [0 , _maxDist, _typeHeli]; 
		_maxDist = _maxDist + 50; 
	};

_targetPad = createVehicle ["Land_HelipadEmpty_F",[0,0,0], [], 0, "CAN_COLLIDE"];
_targetPad setPosATL _lz;
destLZ = getPosASLVisual _targetPad;
_heli doMove _lz;
_heli flyInHeightASL [200, 100, 400];

waitUntil {sleep .5; (_heli distance2d _lz) <= 600}; 
_heliPilot sideChat "Mako 30 this is Razor 04, we are inbound to your position... Razor 04 Out";

waituntil {(_heli distance2d _lz) <= 500};
vDVfinal = vectorDirVisual _heli vectorAdd (getPosASLVisual _heli vectorFromTo destLZ);
t1 = time;
t2 = time + 60; //diag_fps; //90;

private _idEF = addMissionEventHandler ["EachFrame",
{
	if (!(alive heli) || !(canMove heli) || (getPosATLVisual heli select 2) < 15 || (getPosASLVisual heli vectorDistance destLZ) < 5) then 
	{
		removeMissionEventHandler ["EachFrame", _thisEventHandler];
		//Heli action ["LandGear", Heli];
		heli land "GET IN";
		//heli setVectorUp surfaceNormal position heli;
		heli flyInHeight 0;
	};	
	
	private _interval = linearConversion [t1, t2, time, 0, 1];
	
	heli setVelocityTransformation [
		getPosASLVisual heli, 
		destLZ, 
		velocityModelSpace heli, 
		[0,0,0], 
		vectorDirVisual heli, 
		vDVfinal, 		
		vectorUpVisual heli, 
		[0,0,1],
		_interval
	];
}];

[_heli,_lz] spawn 
{ 
	params ["_heli", "_lz"]; 
	waituntil { sleep 1; (_heli distance2d _lz) <= 200};
	private _dir = _lz getDir _heli;
	
	while {(alive _heli && canMove _heli) && {(getPosATL _heli select 2) > 2 || isTouchingGround _heli}} do
	{
		0 setWindDir _dir;
		sleep .5;
	};
};

 

 Any thoughts/comments would be appreciated.

Edited by panther42
I'm an idiot, changed t1 to time - 3 and works

Share this post


Link to post
Share on other sites

Did anyone, even out of curiosity, try the code posted?  Of course parts of it can be ripped out (chat, etc) to test.

I'm interested if anyone came up with better values.  I.E. instead of time, use diag_tickTime, or diag_frameNo.  Some formula of fps.

Too much lag for use?

Not worth the time?

Does using this eliminate pilots in "hot" landing zone not wanting to land?

Tried on other aircraft?  I was thinking planes landing at non-configured airports.  I used to use parts of Mando land for A2 landing on Nimitz.

 

I have not been able to test all situations/formulas, but am interested in any input.

 

Share this post


Link to post
Share on other sites

if u like people to try your code then you should make it as easy as possible to get some interest on it.

I personaly don't like to write an addAction or something else to test other peoples code. Best thing for me is something which I can just throw into debug console or maybe in a vehicles init field.

This way I can test it in editors temp mission without setting up a proper mission for it and without have to think about it much.

just a suggestion ... 

 

Mankind is a lazy thing!

Share this post


Link to post
Share on other sites

Fair enough @sarogahtyp.

Paste the following in debug console:

Spoiler

0 = [] spawn 
{
	private ["_posCaller", "_spawnPos", "_spawnDir", "_spawnRange", "_vecDir", "_markerLZ", "_heliSpawn", "_heliPilot", "_typeHeli", "_lz", "_targetPad", "_maxDist"];

	_posCaller = getPos player;
	_spawnDir = getDir player; // face the direction you want helicopter to arrive from
	_spawnRange = 3000;     // distance to spawn the helicopter from player location

	_spawnPos = _posCaller getPos [_spawnRange, _spawnDir];
	_vecDir = _spawnPos getDir _posCaller;

	_heliSpawn = [];

	call {
		if (playerSide isEqualTo west) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["B_Heli_Transport_01_F","B_Heli_Transport_03_F"], WEST] call BIS_fnc_spawnVehicle};
		if (playerSide isEqualTo east) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["O_Heli_Light_02_F","O_Heli_Transport_04_covered_F"], EAST] call BIS_fnc_spawnVehicle};
		if (playerSide isEqualTo resistance) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["I_Heli_light_03_F","I_Heli_Transport_02_F"], RESISTANCE] call BIS_fnc_spawnVehicle};
		if (playerSide isEqualTo civilian) exitWith {_heliSpawn = [_spawnPos, _vecDir, selectRandom ["C_Heli_Light_01_civil_F","C_IDAP_Heli_Transport_02_F"], CIVILIAN] call BIS_fnc_spawnVehicle};
	};

	_heliSpawn params ["_heli", "_crewHeli", "_grpHeli"];
	_heliPilot = driver _heli;
	_heliPilot setskill 0.7;
	_heliPilot setCombatMode "YELLOW";
	_heliPilot setBehaviour "CARELESS";
	_heliPilot setRank "CAPTAIN";
	_grpHeli selectLeader _heliPilot;
	heli = _heli;

	_typeHeli = typeOf _heli;
	_lz = []; 
	_maxDist = 50; 
	while { count _lz < 1 } do 
		{ 
			_lz = _posCaller findEmptyPosition [0 , _maxDist, _typeHeli]; 
			_maxDist = _maxDist + 50; 
		};

	_targetPad = createVehicle ["Land_HelipadEmpty_F",[0,0,0], [], 0, "CAN_COLLIDE"];
	_targetPad setPosATL _lz;
	destLZ = getPosASLVisual _targetPad;
	private _tPmark = createVehicle["sign_arrow_F",ASLtoATL destLZ,[],0,"CAN_COLLIDE"];
	_heli doMove destLZ; //_lz;
	_heli flyInHeightASL [200, 100, 400];

	waituntil {(_heli distance2d _lz) <= 475};
	vDVfinal = vectorDirVisual _heli vectorAdd (getPosASLVisual _heli vectorFromTo destLZ);
	t1 = time - 3;
	t2 = time + (2 * diag_fps);

	private _idEF = addMissionEventHandler ["EachFrame",
	{
		if (!(alive heli) || !(canMove heli) || (getPosATLVisual heli select 2) <= 15 || (getPosASLVisual heli vectorDistance destLZ) < 5) then 
		{
			removeMissionEventHandler ["EachFrame", _thisEventHandler];
			heli land "GET IN";
			{heli animateDoor [_x,1]} forEach ['door_L','door_R'];
			heli flyInHeight 0;
		};

		private _interval = linearConversion [t1, t2, time, 0, 1];
		
		heli setVelocityTransformation [
			getPosASLVisual heli, 
			destLZ, 
			velocityModelSpace heli, 
			[0,0,0], 
			vectorDirVisual heli, 
			vDVfinal, 		
			vectorUpVisual heli, 
			[0,0,1],
			_interval
		];
	}];

	[_heli,_lz] spawn 
	{ 
		params ["_heli", "_lz"]; 
		waituntil { sleep 1; (_heli distance2d _lz) <= 200};
		private _dir = _lz getDir _heli;
		
		while {(alive _heli && canMove _heli) && {(getPosATL _heli select 2) > 2 || isTouchingGround _heli}} do
		{
			0 setWindDir _dir;
			sleep .5;
		};
	};
};

 

 

Share this post


Link to post
Share on other sites

Okay, I tested a bit and imo it works very good but has some problems as well:

 

- for me the landing is a bit too fast. I guess its not really realistic

- it has problems in wooden areas to find a proper landing place and crashes into trees sometimes

- if I m in water then it finds a position on shore but partially in water and therefore the heli gets damaged from water and AI is dismounting

- it has problems i I am on high buildings (in tanoa) heli crashes straight into the building Im standing on.

 

I would use BIS_fnc_findSafePos instead of findEmptyPosition. 

With BIS_fnc_findSafePos you are able to look for a wider landing area which is also not on shore. You just need to use boundingBoxReal or maybe sizeOf to get the dimensions of helicopter and than you can add some meters (maybe depending on heli dimensions) to get a proper landiing area

 

Edit:

Imo bigger helis should land slower than small ones maybe depending on sizeOf as well.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

@sarogahtyp, thanks for the testing.
It's not necessarily a test of the "other" mechanics of the script, so to speak, but a test of setVelocityTransformation in relation to use with helicopter (in this case), or possibly other aircraft.

Does it work, can it work with better input numbers, is it useless...

There are plenty of other methods, this is just an option.
All setup, like distance from landing point to start landing, creating the landing point location, adjustment of the duration (I.E. bit too fast) would be user preference.

If you set flyInHeightASL, or flyInHeight to a higher number, obviously, your approach angle will be higher/may avoid obstacles.

As for the water position, this could be alleviated by simply creating a marker at your position (ASL conversion), and creating the helipad at that location, or, as you noted BIS_fnc_findSafePos/another method.

Perhaps I was not "clear" enough with the title of thread "Proof of concept testing: setVelocityTransformation".

I appreciate all of the testing you have done.  My example was thrown together to test the application of setVelocityTransformation on aircraft, specifically helicopters.

 

As a side note, while researching this command, I found a post by @Harzach which I thought was pretty cool.  This specific post has the link to updated video.

 

Share this post


Link to post
Share on other sites

I'm not physics qualified to give you any detailed feedback, but I tried this with slicks and in Cam Lao Nam, and it works great for me.  I think this coupled with Rydygier's hug terrain script will be great for some fast Prairie Fire extracts.

 

Edit:  Hah!  I see you posted over there also.

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

×