Tank Turret Gimbal Lock - Quaternions?

When aiming my turret around, as soon as my aim crosses the negative Y axis in the world, the turret wants to spin a full 360 in the other direction to aim toward that direction from the far side. Ben makes an offhand reference to quaternions, and looking them up I get the idea that they’re complex vectors that can handle multiple rotations without freaking out, which seems very applicable to this situation. Looking further in the course, it doesn’t look like this issue is ever addressed. Practically, how can I implement FQuats to resolve this?

As a sanity check, my code for TankTurret.cpp is on github here:

1 Like

Ah, I just got to lecture 83 (“Improving Tank Aiming”), the solution was of course much simpler than quats, probably because our case doesn’t involve a full sphere of possible rotations; we’re just concerned about one axis.

If you haven’t gotten there yet, the solution is to just get the absolute value of the DeltaRotator.Yaw and check if it’s less than 180. If it’s greater than 180, get its negative value.

void UTankAimingComponent::MoveBarrelTowards(FVector AimDirection)
{
	if (!ensure(Barrel && Turret)) { return; }

	auto BarrelRotator = Barrel->GetForwardVector().Rotation();
	auto AimAsRotator = AimDirection.Rotation();
	auto DeltaRotator = AimAsRotator - BarrelRotator;

	Barrel->Elevate(DeltaRotator.Pitch);

	if (FMath::Abs(DeltaRotator.Yaw) < 180)
	{
		Turret->Rotate(DeltaRotator.Yaw);
	}
	else
	{
		Turret->Rotate(-DeltaRotator.Yaw);
	}
}
3 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms