# How to limit steering force at low velocities

Sorry if this is posted before, but I didn't find an answer for this. I've been banging my head on this for a day now and I seems to be stuck.

I've implemented (see below) the 2D steering arrival behaviour described in http://www.red3d.com/cwr/steer/ which all works fine until there is a characters which wants to turn 180°. The character simply slows down, flips 180° and starts accelerating. I tried to illustrate this in Figure 1 (a).

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

What I would ideal like is a smoother path as seen in Figure 1 (b). I was thinking of using the clipped_speed in combination with steering 'left' or 'right', however I can't seem to figure out how to do this with vectors. If anyone could point me in the right direction, that would be great.

The implementation (using libgdx)

Vector2 target_offset = target.sub(position);
float dist = target_offset.len();
float clipped_speed = Math.min(max_speed * (dist / (20 * mass)), max_speed);

desiredVelocity = target_offset.mul(clipped_speed / dist);
steeringForce = desiredVelocity.sub(this.velocity);

truncate(steeringForce, max_force);
Vector2 acceleration = steeringForce.mul(1 / mass * 60 * delta);

truncate(velocity, max_speed);



And the code for truncate:

public void truncate(Vector2 v, float max) {
float i = v.len() != 0 ? max / v.len() : 0;

if(i < 1) {
v.mul(i);
}
}


EDIT: Using bobobobo input I think I'm there. So for those interested:

Vector2 target_offset = target.position().sub(position);

float dist = target_offset.len();
float clipped_speed = Math.min(max_speed * (dist / break_dist * mass), max_speed);

desiredVelocity = target_offset.mul(clipped_speed / dist);
steeringForce = desiredVelocity.sub(velocity);

truncate(steeringForce, max_force);
forward = steeringForce.mul(1 / mass * 60 * delta);

float a = (float) (Math.acos(velocity.nor().dot(forward.nor())) * MathUtils.radDeg);
if(Float.isNaN(a)) a = 0;

if(a > max_rot) {
if(velocity.nor().crs(forward.cpy().nor()) < 0) {
forward.setAngle(velocity.angle() - max_rot);
} else {
forward.setAngle(velocity.angle() + max_rot);
}
}

truncate(velocity, dist < break_dist * mass ? dist / (break_dist * mass) * max_speed : max_speed);


Breaking is done by just scaling the velocity linearly, which isn't really all that nice implementation wise, but it give better stopping results. So we don't overshoot.

• Just thinking out loud, it seems the main problem is the steering is simulating an object of zero size. Perhaps you can have steering at both engines and sum their forces to drive the ship? That would require them both to turn around the center of mass of the ship slowing down the rotation and possibly giving some more interesting flight characteristics. – MichaelHouse Feb 1 '13 at 23:02
• I agree that this might be more interesting, but I like to keep movement simple. Mainly because AI needs to able to navigate too. Making the physics more complex, means complexer AI for movement which I do not want to spend too much time on. But I appreciate the though! – Yannick Feb 2 '13 at 10:24