Jump to content
thy_

Tank horizontal rotation based on marker direction

Recommended Posts

Hey. I'm coding something strongly based on it I need to make AI tanks hold positions as close as possible at some marker positions managed through Eden. My version is simpler and must be more accurate about synchronizing tank direction to the selected marker direction, with smooth movement when needed, differently when we use setDir, for example:

 

8KIdJUY.jpg

 

But this is what happens (image down below): tanks got their horizontal azimuths misaligned when compared with their selected marker direction. Even my debug messages (systemChat) don't make sense to me hehe.

 

xl8zHTr.jpg

 

 

Here, both functions that m

 

 

THY_fnc_CSWR_move = {
	// This function makes the tank goes to a marker position.
	// Return nothing.

	params ["_grp"];
	private ["_markers", "_mkrSelected", "_mkrPos", "_wp"];

	sleep 1;
	
	_markers = ["hold_1", "hold_2", "hold_3", "hold_4"];
	_mkrSelected = selectRandom _markers;
	_mkrPos = getMarkerPos _mkrSelected;
	// Adding waypoint:
	_wp = _grp addWaypoint [_mkrPos, 0]; 
	_wp setWaypointType "HOLD";
	_grp setCurrentWaypoint _wp;
	// Waiting the tank gets closer:
	waitUntil { sleep 3; (((leader _grp) distance _mkrPos) < 20) };

	// Do rotation:
	[_mkrSelected, _grp] call THY_fnc_CSWR_hold;

	// Return:
	true;
};

 

THY_fnc_CSWR_hold = {
	// This function makes the tank rotate on your own axis until it reach the same direction of a specific marker.
	// Return: nothing.

	params ["_mkr", "_grp"];
	private ["_clockwise", "_vehicle", "_directionToHold", "_dirRelative"];

	_clockwise = false;
	_vehicle = vehicle (leader _grp);
	_directionToHold = markerDir _mkr; 
	_dirRelative = _directionToHold - (getDir _vehicle);
	
	// Force the vehicle doest start to turn when still moving (rare, but happens):
	_vehicle sendSimpleCommand "STOP";
	// Wait the vehicle to brakes:
	sleep 1;

	// ------------------- NEED HELP HERE DOWN BELOW -------------------------------

	if ( abs(_dirRelative) > 2 ) then {
		
		if ( _dirRelative > 0 ) then {

			if (_dirRelative < 180) then { _clockwise = true };

		} else {

			if (_dirRelative < -180) then { _clockwise = true };
		};

		if (abs(_dirRelative) > 1) then { // Originally was: > 120 

			if (_clockwise) then { _vehicle sendSimpleCommand "RIGHT" } else { _vehicle sendSimpleCommand "LEFT" };
			
			waitUntil { 
				_dirRelative = _directionToHold - (getDir _vehicle);
				if ( _dirRelative > 180 ) then { _dirRelative = abs(360 - _dirRelative) };
				if ( _dirRelative < -180 ) then { _dirRelative = abs(_dirRelative + 360) };
				
				// Without this line, the tank will rotate on its axis non-stop:
				if ( abs(_dirRelative) <= 100 ) exitWith { true };
				false;
			};

			_vehicle sendSimpleCommand "STOPTURNING";
		};
		

		systemChat format ["[Desired %1º | Executed: %2º]", markerDir _mkr, getDir _vehicle];

		// ------------------- NEED HELP HERE ABOVE -------------------------------

		sleep 10;

		[_grp] spawn THY_fnc_CSWR_move;
	};

	// Return:
	true;
};

 

Demo: cswr-tanks-holding.stratis.zip = https://drive.google.com/file/d/1EcPiF2LFo149skR6GV63Vz6hhP7o6PlV/view?usp=share_link

 

 

  • Like 1

Share this post


Link to post
Share on other sites
6 hours ago, thy_ said:

Hey. I'm coding something strongly based on it I need to make AI tanks hold positions as close as possible at some marker positions managed through Eden. My version is simpler and must be more accurate about synchronizing tank direction to the selected

 

 

 

You can only get so accurate when you try and micromanage AI, keep that in mind.

However from my short tests this below seems to work okay, ending up within 10-15 degrees of desired direction. Playing around with the value of _dirMargin can get you better results around 10-20 degrees seems to be best for the Slammer.

 

On a few occasions when timeAcc was > 1x I noticed problems with infinite spinning but you can probably work that out from here if you need to support that. Should be fixed with updated code.

 

This will, for what I think is obvious reasons, only work for tracked vehicles that can turn on the spot. 

A wheeled vehicle would involve a lot more back and forth (both in the literal and figurative sense).

 

Should be MP compatible, the limiting factor here is "sendSimpleCommand" and it's locality requirements. They are unfortunately not listed on the BIKI.

I would imagine executing where the vehicle and group is local is probably best. 🙂

 

This code completely replaces all code inside THY_fnc_CSWR_hold.

Spoiler

// This function makes the tank rotate on your own axis until it reach the same direction of a specific marker.
// Return: nothing.

params ["_mkr", "_grp"];

private _vehicle = vehicle (leader _grp);
private _directionToHold = markerDir _mkr;

// Force the vehicle doest start to turn when still moving (rare, but happens):
_vehicle sendSimpleCommand "STOP";
// Wait the vehicle to brakes:
sleep 1;

private _dirMargin = 20;
private ["_dirRelative", "_absDirRelative", "_turnDir"];
waitUntil {

	// Compute turn parameters
	_dirRelative = ( getDir _vehicle - _directionToHold + 180 ) % 360 - 180; // Deals with wrapping effects when turning past compass north. > 0 == turn left, < 0 == turn right
	_absDirRelative = abs _dirRelative;
	_turnDir = if( _absDirRelative > _dirMargin ) then {
		// Get normalized turn direction ( 1 = left, -1 = right)
		_dirRelative / _absDirRelative
	} else { 
		// Target reach, no turning needed
		0
	};

	// Get current status
	vehicleMoveInfo _vehicle params ["", "_turnInfo"];
	//systemChat format ["TurnInfo: %1", _turnInfo];
	switch (_turnDir) do {
		case 1: {
			// Target dir is to the left
			if( _turnInfo != "LEFT" ) then {
				_vehicle sendSimpleCommand "LEFT";
				//systemChat "Left";
			};
		};
		case -1: {
			// Target dir is to the right
			if( _turnInfo != "RIGHT" ) then {
				_vehicle sendSimpleCommand "RIGHT";
				//systemChat "Right";
			};
		};

		default {
			//systemChat "Stop turning";
			_vehicle sendSimpleCommand "STOPTURNING";
			// AI is too slow to react to STOPTURNING for our needs, so disable the drivers AIs movement to stop the turn immediately.
			driver _vehicle disableAI "MOVE";
		};
	};

	// Exit out if we have finished turning or the vehicle is unable to move.
	( _turnDir == 0 ) || !canMove _vehicle || fuel _vehicle == 0
};

waitUntil {
	vehicleMoveInfo _vehicle params ["", "_turnInfo"];

	_turnInfo == "ABS" || _turnInfo == "NONE"
};	
// After small delay reenable driver's AI movement.
driver _vehicle enableAI "MOVE";

systemChat format ["[Desired %1º | Executed: %2º]", markerDir _mkr, getDir _vehicle];

sleep 10;

[_grp] spawn THY_fnc_CSWR_move;

// Return:
true;

 

 

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

×