force required for body to reach certain height

Started by
9 comments, last by Fenrisulvur 14 years, 7 months ago
I'm having trouble with an formula to calculate the force required to push a body up to a certain height. That is, the body should reach a velocity of zero at the specified height. Gravity and air friction act upon the body (though perhaps the latter can be ignored as it is likely to be negligible). I want to use this to make the player jump to climb up on an obstacle. Given are: * vertical distance * body mass * gravity (9.8 m/s) * air friction coefficient The answer is probably very simple, but I don't know where to start.
Advertisement
You don't need force: you need energy. If you ignore drag, you can simply compute how much potential energy the object will have at the top of the trajectory (mass*gravity*height). You'll have to send your object upwards with that much kinetic energy, which is 1/2*mass*v^2, in case you want to compute the vertical velocity needed.

Does that answer your question?
As said before, looking for a particular force is not really going to help. There are infinite force profiles (a force is applied over time, so force would be plotted against time) which could achieve the result you desire. For example, a huge force could be applied for a small time, or a small force could be applied for a large time, and achieve the same altitude.

For your particular application you're looking for an impulse or an instantaneous change in energy as mentioned by the previous poster to give you the desired upward velocity, that when degraded by the other forces such as gravity and air resistance, will reach the target altitude. In the real world it's not practical to apply such impulses but in your game it's totally possible. In the real world you'd take the desired impulse and figure out the time span necessary to apply thrust, given the strength of your thruster.

So if your character has jet packs, you'd need to actually solve this problem (how long and hard to fire the thrusters to get him to a certain altitude) But for jumping, you just need to compute the upward velocity. In which case alvaro's answer is right on point.
As has been asked, will impulse do? Also, will the linear drag equation F = -bv be sufficient? And of course, how does your system integrate acceleration?

I nearly have an entirely analytical solution to your problem ready, but the entire approach may be major overkill. The impulse equation contains a product log, for christ's sake.
If anyone's curious, I'll post up my working later; if you want to be more specific about your system's kinematics, though, I could write something more relevant.
For the case with linear drag, you can solve the differential equation
x' ' + b*x' + g = 0

The solutions look like
x = -g*t/b - C1 * exp(-b*t)/b + C2 (*)

If you now set x(0) = 0 and x'(0) = v0, you get
C1 = v0 + g/b
C2 = C1/b

Now that you have the full equation, you can set the first derivative to 0 to see that the maximum happens at t = -b*log((g/b)/C1). Substituting that value in (*) you can compute the maximum height as a function of the initial impulse. What you really want to do is the inverse, for which I would use a numerical method (Newton-Raphson would probably do nicely).

As you see, things get messy quickly when you introduce drag, even if it's simple linear drag.

[Edited by - alvaro on September 9, 2009 8:41:18 AM]
Oh, I already solved the acceleration ODE and determined the velocity and acceleration formulae. Here's what I had written down before, feel free to peruse and judge at whim:

For the constants:
t    = timey(t) = vertical position of body at time ty(0) = vertical starting position of bodyyheight = desired vertical zenithv(t) = vertical velocity of body at time tv(0) = vertical velocity of body at time zeroa(t) = vertical acceleration of body at time tm    = body massg    = acceleration due to gravityb    = air friction coefficientFnet(t) = net force at time tI    = what we're looking for, necessary impulse at time zero


Net force:

Fnet(t) = - m*g - b*v(t)

Acceleration:
a(t) = Fnet(t)/m     = - g - b*v(t)/m

Velocity:
Firstly, observe that if:

f(x) = c*eh(x)

Then:
f'(x) = h'(x)*c*eh(x)      = h'(x)*f(x)


And also observe that if:

f(x) = c*eh(x) - k

Then:

f(x) + k = c*eh(x)

And:
f'(x) = h'(x)*c*eh(x)      = h'(x)*(f(x) + k)      = h'(x)*f(x) + h'(x)*k

We're going to use the above facts to determine velocity analytically. From the acceleration formula,

v'(t) = a(t) = - b*v(t)/m - g

we have:
      x = t   f(x) = v(t)  h'(x) = -b/m   h(x) = -b*t/mh'(x)*k = -g      k = -g/(-b/m)        = g*m/b

Therefore, subbing into f(x), we have:

v(t) = c*e-b*t/m - g*m/b

Checking the solution:
v(t) + g*m/b = c * e-b*t/mv'(t) = (-b/m) * c * e-b*t/m      = (-b/m) * (v(t) + g*m/b)      = -b*v(t)/m - g	  	  //

We also want to make sense of variable c that we picked up in the integration, so:
v(0) = c*e-b*0/m - g*m/b     = c - g*m/b   c = v(0) + g*m/b

Therefore:

v(t) = (v(0) + g*m/b)*e-b*t/m - g*m/b

Position:

y'(t) = v(t) = (v(0) + g*m/b)*e-b*t/m - g*m/b

y(t) = (v(0) + g*m/b)*e-b*t/m/(-b/m) - g*m*t/b + C

y(t) = C - (v(0) + g*m/b)*m*e-b*t/m/b - g*m*t/b

And as for the C:
y(0) = C - (v(0) + g*m/b)*m*e-b*0/m/b - g*m*0/b     = C - (v(0) + g*m/b)*m/b   C = y(0) + (v(0) + g*m/b)*m/b

Therefore:

y(t) = y(0) + (v(0) + g*m/b)*m/b - (v(0) + g*m/b)*m*e-b*t/m/b - g*m*t/b

And finally,

y(t) = y(0) + (v(0) + g*m/b)*(1 + e-b*t/m)*m/b - g*m*t/b

y(t) = y(0) + (v(0) + g*m/b)*(1 - e-b*t/m)*m/b - g*m*t/b

EDIT: as jjd (see below) pointed out, there was a mistake in this line, which I have now corrected. This revision should stand up to scrutiny, taking t=0 of y(t) properly produces y(0) and taking dy/dt produces v(t) as should happen.
Let me know if you find any other errors.


tbh, this is the first time I've actually integrated that all the way analytically. Let me know if I've made any mistakes. >_>

More soon - finding t for v(t) = 0 and subbing it into y(t) (turning y(t) into yheight), and rearranging for v(0) will give the required impulse, but not without a Lambert W in there somewhere.

Also, I am just crazy enough to try collision detection with these formulae. This is like back in high school when I wouldn't accept that polynomial division "just works"... >_>


EDIT: I'm likely to edit this one a lot, mainly for formatting and to slot in extra lines of working for clarification's sake. I've been thinking about starting a tutorial covering analytical integration of kinematics once I've got it all working, so this might be a good starting point.

[Edited by - Fenrisulvur on September 12, 2009 2:10:26 AM]
Oh, wow.

Yes I meant the force to be applied as impulse, not over time, though the latter may be interesting as well (for now i want to keep things simple).

I figured g * m * d would give me something usefull, but when plugged in it didn't quite work in my simulation. Seems the force is far to small, so I must be missing something (perhaps something to do with timestep).

I also could not imagine it would be easy to calculate with drag. I'll have a shot at implementing the above.

Thanks guys!
You said you want an impulse and then you said the force was too small. So i have to assume that you're still trying to apply a force rather than impulse. Dont. You can, but dont do it.

The order that you shoudl do things is probably:

A.) Apply a real impulse, let the integrator solve it.
B.) Just explicitly set the new velocity
C.) Add the impulse as a force.

Impulse = Kg * m / s

So if you want to add 3m/s to the players velocity

a.) you'd apply an impulse of 3 * Mass of character.
b.) you'd set the velocity = current velocity + 3
c.) you'd apply a force of 3 * mass / dt where dt is the timestep the force will be applied for (one game step) since newtons units are Kg * m/s^2

All i did there was explain the relationship between explictly setting the velocity, impulses, and forces over a single timestep. I didnt attempt at all to explain how to compute the ideal delta v. The previous poster touched on that. Use the hang time algorithm, compute how fast you would be going if you fell from the desired height, negate that velocity, and you've found your jump velocity to reach that height.
Quote:Original post by Fenrisulvur
y(t) = y(0) + (v(0) + g*m/b)*(1 + e-b*t/m)*m/b - g*m*t/b

tbh, this is the first time I've actually integrated that all the way analytically. Let me know if I've made any mistakes. >_>


Good effort Fenrisulvar, and well written! Unfortunately there are a bunch of mistakes. It's important to check that your answers make sense at the end, kind of a sanity check. In this case, when t = 0, you'll find that y(0) != y(0).

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Fixed, as noted in an edit message in my post above; and thanks.

Anyway, sorry, guys, I really should've got back here and finished my response days ago - unfortunately I've been having trouble deriving a final answer, even after doing it by hand thrice and feeding it to Wolfram|Alpha countless times.
As stated above, finding the formula for required Impulse is just a matter of finding t for v(t) = 0, subbing it into y(t) and rearranging for v(0)*, and multiplying by mass**. Here's my working:
    v(t) = (v(0) + g*m/b)*e-b*t/m - g*m/b                    set v(t) = 0    (v(0) + g*m/b)*e-b*t/m = g*m/b          take the natural log of both sides    ln(v(0) + g*m/b) - b*t/m = ln(g*m/b)          subtract ln(v(0) + g*m/b), multiply by -1                       b*t/m = ln(v(0) + g*m/b) - ln(g*m/b)                             = ln((v(0) + g*m/b)/(g*m/b))                             = ln(((bv(0) + g*m)/b) * b/(g*m))                             = ln(b*v(0)/(g*m) + 1)          multiply by m, divide by b                           t = m*ln(b*v(0)/(g*m) + 1)/b    y(t) = y(0) + (v(0) + g*m/b)*m/b - (v(0) + g*m/b)*m*e-b*t/m/b - g*m*t/b                sub t = m*ln(b*v(0)/(g*m) + 1)/b                also (v(0) + g*m/b)*e-b*t/m = g*m/b    y(t) = y(0) + (v(0) + g*m/b)*m/b - m*(g*m/b)/b - g*m*(m*ln(b*v(0)/(g*m) + 1)/b)/b          subtract y(0), multiply by b, divide by m    b*(y(t) - y(0))/m = v(0) + g*m/b - g*m/b - g(m*ln(b*v(0)/(g*m) + 1)/b)                                          = v(0) - g*m*ln(b*v(0)/(g*m) + 1)/b          take the exponent of both sides    eb*(y(t) - y(0))/m = ev(0) - g*m*ln(b*v(0)/(g*m) + 1)/b                             = ev(0)*e-g*m*ln(b*v(0)/(g*m) + 1)/b                             = ev(0)*e-g*m*ln(b*v(0)/(g*m) + 1)/b                             = ev(0)*(b*v(0)/(g*m) + 1)-g*m/b          raise both sides to the power of -b/(g*m)(eb*(y(t) - y(0))/m)-b/(g*m) = (e*v(0)(b*v(0)/(g*m) + 1)-g*m/b)-b/(g*m)   e-(b^2)*(y(t) - y(0))/((m^2)*g) = (b*v(0)/(g*m) + 1)*e-b*v(0)/(g*m)          multiply both sides by -e-1   -e-1-(b^2)*(y(t) - y(0))/((m^2)*g) = (-b*v(0)/(g*m) - 1)*e-b*v(0)/(g*m) - 1          apply the Lambert W function       -b*v(0)/(g*m) - 1 = W(-e-1-(b^2)*(y(t) - y(0))/((m^2)*g))          and finally, add one, divide by (g*m), and multiply by -b       v(0) = -(g*m)*(W(-e-1-(b^2)*(y(t) - y(0))/((m^2)*g)) + 1)/b

And Wolfram|Alpha agrees.

However, some test data:
b = 1
g = 9.8
m = 10
y(t) = 300
y(0) = 0

Consider this curve, produced using the test data above and a v(0) value of 100. As you can see, y(t) peaks at ~300, making it reasonable to assume that plugging our test data into our new v(0) formula should produce a result of ~100.

Unforunately, we have a problem.

I've tested it at various stages, and found every step up to the application of the Lambert W to evaluate correctly with the test data; however, I've also tested results from Wolfram|Alpha's Lambert W function and found its results to be consistent (unless it evaluates kek erroneously, too). So, basically, I'm out of ideas.
If anyone with a greater understanding of the problem and/or the mathematics involved wants to step in and point out where I've gone wrong, I'd be immensely grateful at this pont.

Anyway, that's enough of the analytical approach for now.


*Actually, this assumes vertical velocity prior to the jump is zero. The general solution's pretty simple from there: Impulse = m*(v(0) - vprior)

**An Impulse is a change in momentum, not velocity.

Quote:Original post by remdul
Oh, wow.

Yes I meant the force to be applied as impulse, not over time, though the latter may be interesting as well (for now i want to keep things simple).

I figured g * m * d would give me something usefull, but when plugged in it didn't quite work in my simulation. Seems the force is far to small, so I must be missing something (perhaps something to do with timestep).

Hmm, as in (acceleration due to gravity) * (mass) * (displacement)? I'd expect that to give a larger impulse than required, unless the mass of the body is significantly less than 1.
EDIT: I should point out that bzroom is probably right in saying that you're integrating it improperly, too.

Anyway, in an effort to give you a working, in-the-ballpark formula, this is without drag:
F(t) = -mga(t) = -gv(t) = -gt + v(0)y(t) =  -(1/2)gt^2 + v(0)t + y(0)set v(t) = 0   v(0) = gt      t = v(0)/gyheight = -(1/2)g(v(0)/g)2 + v(0)(v(0)/g) + y(0)          = -(1/2)v(0)2/g + v(0)2/g + y(0)          = (1 - 1/2)v(0)2/g + y(0)          = (1/2)v(0)2/g + y(0)    yheight - y(0) = (1/2)v(0)2/g2g(yheight - y(0)) = v(0)2                   v(0) = sqrt(2g(yheight - y(0)))

It worked in my tests; let me know if it produces useful results.

And finally, if you want something accurate to the system you're using it in, tell us how your system's force integration currently works. The precise formula in a Verlet system would differ from the precise formula for a Euler system, etc, and it'll probably be a hell of a lot easier to produce a formula for such systems than for an analytical system (which is a rare beast in the wild, as far as game integrators are concerned).

[Edited by - Fenrisulvur on September 18, 2009 5:34:39 PM]

This topic is closed to new replies.

Advertisement