Manually calculating acceleration and velocity?

This had me stuck for days, any help would be super appreciated

Making a rocket game, and long story short I need to freeze the rocket GameObject within the scene, but still calculate what its velocity and acceleration would were it still moving.

To do this I had hoped to just rearrange F = MA, using the force of the engines and mass of the rocket to find acceleration, and use that to derive the velocity, but this seems to give values far lower than when the rocket does move throughout the scene and I just use rigidbody.velocity to find acceleration, after applying force to it the normal way…here’s my code

rb2d.AddForce(new Vector2(xForce, yForce), ForceMode2D.Impulse);

Using this to apply force, and calculating acceleration using…

        newTime = Time.time;
        newVelocity = rb2d.velocity.magnitude;
        acceleration = ((newVelocity - oldVelocity) / (newTime - oldTime));
        oldTime = newTime;
        oldVelocity = newVelocity;
        //calculates the acceleration by dividing the change in speed by change in time
        return acceleration;

I get a value of about 16 ms^-2, but when I freeze the GameObject, and calculate it’s acceleration using

                stasisAcceleration.x = xForce / rb2d.mass;
                stasisAcceleration.y = (yForce / rb2d.mass) - Physics2D.gravity.y;

NB: xForce and yForce are exactly the same value as before

I get a much smaller value, in fact the value I get is around -0.2ms^-2, as it thinks the acceleration due to gravity is the greater than the acceleration due to the yForce.

What am I doing wrong here? Why is my manual calculation for acceleration giving a value way lower than it should be?

Thanks in advance :slight_smile:
Fred T.A

1 Like

Are you applying an impulse force every frame? Impulse forces apply a change in velocity based on the mass of the Rigidbody every frame, which is a different behavior from natural forces. The Force force mode calculates a real acceleration (change in velocity per second) and applies the change in velocity dependent on how much time has passed since the last physics update.

Impulse should be understood as a 1-tick change in velocity based on mass. If you have ~60 of these every second and then measure the average acceleration, you’ll get some number-- if you assume the impulse value is in Newtons and calculate the instantaneous acceleration, you’ll get some smaller number, unless the fixed time step is greater than 1 second for some reason.

Since the velocity change is applied over a tiny amount of time, its equivalent force is higher by a factor of the number of physics updates per second. The impulse unit is not kilogram-meters per second per second, but rather kilogram-meters per second per fixed time step.

Try using ForceMode2D.Force, and I think you’ll find that the rocket can’t overcome gravity, making the instantaneous calculation correct if you neglect normal force from any ground that may be present. Obviously the next step is to increase the force.

If for some reason it needs to be an impulse, I guess dividing the force value by fixedDeltaTime would give a more accurate instantaneous calculation.

By the way, Physics2D.gravity.y is a one-dimensional vector, and so should be added to the thrust acceleration, not subtracted. The direction is already contained within the value (-9.81 by default). I’m not sure why you got a small negative value, since the calculated thrust acceleration should be small, and you are subtracting -9.81 from that, so it should be close to positive 9.81. Your calculation suggests that the input y-force is negative.

3 Likes

Than’s so much for taking the time to explain this so clearly, really got me out of a jam, dividing the force by the Time.FixedDeltaTime gives the correct result, I’ll remember the difference between the force and impulse force modes in the future :slight_smile:

Also, I have my own algorithm that calculates grav field strength with altitude, which leaves the resulting value as a positive number, which is why I subtract it instead of adding

2 Likes