# 2D Newtonian Braking Acceleration

## The Scenario:

I have a 2D ship AI which needs to rotate around the z axis to face its target. All over the ship are thrusters (empties). The script must use Rigidbody2D.AddForceAtPosition() in the Update() or FixedUpdate() methods to move and rotate the ship. The ship is restricted to a maximum torque, which is calculated per thruster using the following at Start():

``````angularForce = 0f;
foreach (Transform t in ThrusterParent) {
if (t.GetComponent<P_Thruster>()) {
P_Thruster tp = t.GetComponent<P_Thruster>();
if (tp.roll == 1) {	// Dealing with rightward rotation only
float effectiveness = 0f;
if (tp.y != 0) {	// If we can push upwards
effectiveness = Mathf.Abs(tp.transform.localPosition.x);
}
if (tp.x != 0) {	// If we can push rightwards
effectiveness = Mathf.Abs(tp.transform.localPosition.y);
}

angularForce += effectiveness * tp.Force * Mathf.Sin(Vector2.Angle(tp.transform.forward, transform.right));	// Torque formula
}
}
}
``````

## The Problem:

Using a kinematic equation, it is perhaps easy to work things out such as braking distance and stopping distance, but those values have displacement as the subject. Instead, I need acceleration to be the subject.

For a stationary target, that is perhaps behind the AI, it is safe to say that the AI can apply maximum torque and then apply opposing torque at halfway to come to a stop, facing its target. But when the target is moving, such an assumption is no longer relevant.

Presently, I get the angle between the AI and the target, and clamp that to 0 and 1. This works, but the AI ship ends up ‘oscillating’ - as it’s rotation passes its target, it applies opposing force, and goes back the other way, like a pendulum. Instead, the AI needs to output a constantly updating torque.

I’m thinking I’m just overlooking things and the answer is really simple. Hopefully someone can help me out.

This is wrong:

``````Mathf.Sin(Vector2.Angle(tp.transform.forward, transform.right))
``````

It should be

``````Mathf.Sin(Vector2.Angle(tp.transform.forward, transform.right) * Mathf.Deg2Rad)
``````

Note that calculating the required thruster force to actually apply only a torque on an irregular object is quite difficult. Keep in mind that linear forces that are applied off-center create both, linear acceleration as well as an angular acceleration. Also keep in mind that the angular acceleration depends on the inertia tensor.

Finally i like to add that Unity’s physics system does not preserve angular momentum. It just preserves angular velocity. This might actually make it a bit easier

edit
I just realized that we talk about 2d physics ^^.