How to limit turning when using steering forces

Hi,

I am using steering forces to control the movement of my AI, however I am having trouble limiting their steering for extreme turns, and turns at low velocity.

n78fe

Figure 1 - where red is the velocity and green the desired direction

Figure 1 (a) is what currently happens when no limit is applied and ,ideally, I would like to implement what is seen in Figure 1 (b).

I get the total steering force that I want to apply to my pawn, get the angle to that destination and check to see if it greater than the maximum turn rate of the pawn.

//Calculate Acceleration
Acceleration = (TotalSteeringForce / I->GetMass());

//Get desired change in velocity
newVelocity = HelmData.ActualVelocity + (Acceleration * DeltaTime);

// Max Turn
if (newVelocity.Size() > 0)
{
	float maxTurn = I->GetMaxTurnRate() * DeltaTime;
	
	angleToDestination = FMath::RadiansToDegrees(acos(FVector::DotProduct(newVelocity.GetSafeNormal(), I->GetHelmComponent()->GetForwardVector().GetSafeNormal())));

	if (angleToDestination > maxTurn)
	{
		//UE_LOG(LogTemp, Warning, TEXT("Helm Controller - Turn angle too great"));
		newVelocity = CorrectVelocity(HelmData.ActualVelocity, newVelocity, maxTurn, I->GetMass(), DeltaTime);
	}
}

This seems to correctly fire the CorrectVelocity function at the appropriate time, however the issue is that I struggle to limit the turn to the requested velocity based on its current velocity in a smooth fashion. This is what I have got for that function, however it doesnt seem to work at all.

//Calculate change in angle per tick
float x = (requestedVelocity.X * (cos(maxTurn))) - (requestedVelocity.Y * sin(maxTurn));
float y = (requestedVelocity.X * (sin(maxTurn))) + (requestedVelocity.Y * cos(maxTurn));

//Calculate new steering vector from mass
FVector returnVector = FVector(x, y, 0.0);
returnVector = (returnVector / (mass / 200)) * delta;

return returnVector + currentVelocity;

Does anyone know how more appropriately limit the turning velocity?

One option is to add some turning drag, that counter-torques whatever the current spin is.
Decide on some maximum turning rate, and then get the current spin. If the absolute value of the spin Z is greater than your limit, then add the counter-torque (times some multiplier)

“Sphere” in this blueprint is the pawn physical component.
A good maximum spin rate in degrees is something between 500 and 2000 degrees per second, typically.
I forget what the exact unit of torque is, but it’s something pretty ludicrous where you need very large numbers to get the expected effect IIRC.

1 Like

Thanks for replying.

I’ve had a look at implementing what you have suggested, and unfortunately the angular velocity always returns as 0,0,0. This maybe due to how I apply the force to my component as I set the linear velocity with the new force I want.

Would the idea of a counter-torque or counter-force work for a linear velocity?

Yeah, my suggestion only works if you’re actually using real physical simulation using the physics engine.

If you set the position/direction directly on your own, why don’t you limit turning in that same operation as well?