Matthias
Matthias

Reputation: 10379

Calculating the speed of a moving object based on its distance to a target

I am writing a simulation in which an object moves in a 2D world towards a target position, stored as vector target(x,y). The object position is stored as position vector pos(x,y) as well. The object contains two more vectors, the desired movement velocity dv(x,y), as well as the current movement velocity cv(x,y). At the start of the simulation both these velocity vectors are initial, i.e. set to (0,0).

When the object should move towards the target position, I calcuate the desired velocity vector dv, normalize it, and scale it by a movement speed value:

dv.set(target).sub(pos).normalize()
dv.scale(speed)

I want to make the movement look more realistic, that's why I use two velocity vectors. dv tells the full speed I want to move the object, and cv holds the real speed the object currently moves at.

Then at each frame (update step) the current velocity cv is set based on the desired velocity dv and an acceleration value acc. This is done by simply calculating the difference between cv and dv and clamping this difference to acc. That way the object starts to move slowly and accelerates gradually to eventually reach full speed.

So far this is working fine. Now I want to make use of acc for deceleration as well. When the distance between pos and target is at a certain value, the desired velocity dv should be set to (0,0), so that the object gradually decelerates until it comes to a full stop at the target position.

My question is: How can I calculate at which distance I need to set dv to (0,0) (i.e. tell the system to stop movement), so that the object decelerates correctly to stop exactly at the target position?

Upvotes: 2

Views: 4536

Answers (2)

user3386109
user3386109

Reputation: 34829

You're doing a discrete time simulation of motion. One way to keep things simple is to perform the calculations in a way that makes acceleration and deceleration symmetrical. In other words, the distance traveled while accelerating should be the same as the distance traveled while decelerating. As an example, assume

  • acceleration is 5
  • top speed is 13
  • the object begins decelerating as soon as it reaches top speed

Here's how the discrete time simulation would progress

first tick
  old speed = 0
  new speed = 5
  distance  = 5

second tick
  old speed = 5
  new speed = 10
  distance  = 15

third tick
  old speed = 10
  new speed = 13
  distance  = 28  <-- total distance while accelerating

fourth tick
  old speed = 13
  distance  = 41
  new speed = 10  <-- not 8!!!

fifth tick
  old speed = 10
  distance  = 51
  new speed =  5

sixth tick
  old speed =  5
  distance  = 56  <-- Yay, twice the distance, we have symmetry
  new speed =  0

There are two key points here

  • While accelerating the speed is updated first and then the distance is updated. While decelerating the order is reversed, the distance is updated first, and then the speed.
  • When decelerating, it's important to keep the adjusted speed as a multiple of the acceleration

In the C programming language, the following code could be used to update the speed during deceleration

if ( old_speed % acceleration != 0 )                   // if speed is not a multiple of acceleration
   new_speed = old_speed - old_speed % acceleration;   //   reduce speed to a multiple of acceleration
else                                                   // otherwise
   new_speed = old_speed - acceleration;               //   reduce speed by acceleration

If acceleration and deceleration are symmetrical, then computing the deceleration distance is the same as computing the acceleration distance.

distance = acceleration * (1+2+3+ ... +N) + fudge_factor

where

  • N is top_speed / acceleration truncated to an integer, e.g. 13/5 ==> 2
  • fudge_factor is 0 if top speed is a multiple of acceleration, or top_speed otherwise

The computation can be simplified by noting that

1+2+3+ ... +N = N * (N+1) / 2

In C, the total distance travelled while decelerating could be computed as follows

int top_speed = 13;
int acceleration = 5;

int N = top_speed / acceleration;     // Note: in C, integer division truncates

int fudge = 0;
if ( top_speed % acceleration != 0 )
    fudge = top_speed;

int distance = acceleration * (N * (N+1)) / 2 + fudge;

Upvotes: 1

AndyG
AndyG

Reputation: 41100

Use the kinematic equations:

vf2 = vi2 + 2 * a * d

  • vf is your final velocity, or 0 (the speed you want to be going)

  • vi is your initial velocity, given (the speed your object is currently moving).

  • a is acceleration

  • d is distance.

Solve for d:

  • 2*a*d = vf2 - vi2

  • 2*a*d = 0 - vi2

assume acceleration is negative, so multiply both sides by -1

  • 2*|a|*d = vi2

|a| is the absolute value of your acceleration (deceleration in your case)

  • d = vi2 / (2*|a|)

Upvotes: 1

Related Questions