I want to limit the speed of a body to some maximum (and possibly, some minimum) - what's the best way to do this?
It looks like swapping the velocity_func pointer with a version of cpBodyUpdateVelocity that clamps (cpBBClampVect) would work - but I'm not sure if the velocity_func pointer is intended to be user accessible (it's not listed as such at http://files.slembcke.net/chipmunk/chipmunk-docs.html)
(apologies if this has been asked before - I did a search and didn't find anything)
Speed limits
-
- Posts: 7
- Joined: Sat May 02, 2009 10:55 am
- Contact:
Re: Speed limits
Don't know if this is the "appropriate" way to do it, but I simply check if the length of the velocity vector is above a certain limit (cpvlength(body->v)),
then apply an opposite force of the same magnitude.
This seems to work pretty well for a vehicle simulation, but I presume there are better ways to do it.
then apply an opposite force of the same magnitude.
This seems to work pretty well for a vehicle simulation, but I presume there are better ways to do it.
-
- Posts: 4
- Joined: Wed Jun 03, 2009 12:37 pm
- Contact:
Re: Speed limits
I can see how applying forces would work, but it seems kind of messy to apply a force to limit a speed after a bunch of things have already been computed. I don't know, I could be wrong.
Looking at the code for cpBBClampVect, it's probably not what I want to do. I probably just want to compute a scaling factor based on the ratio of the length of the vector to the speed I want to limit to, and then cpvmult to scale the vector.
I guess I'm really asking whether or not replacing body->velocity_func is a sanctioned, user-accessible means of doing this sort of thing. It looks like it would be fairly clean for what I want to do, based on the limited look I've had at it - I could just call cpBodyUpdateVelocity to do what it does, and scale the resulting body->v - I just don't want to do it that way if velocity_func is considered internal/shouldn't be modified by the user/etc. etc.
(Edit: although, now that I look at what the step function is actually doing, it may be that I want to limit the velocity before it gets called, because it looks like impulses are applied after the velocity update)
Looking at the code for cpBBClampVect, it's probably not what I want to do. I probably just want to compute a scaling factor based on the ratio of the length of the vector to the speed I want to limit to, and then cpvmult to scale the vector.
I guess I'm really asking whether or not replacing body->velocity_func is a sanctioned, user-accessible means of doing this sort of thing. It looks like it would be fairly clean for what I want to do, based on the limited look I've had at it - I could just call cpBodyUpdateVelocity to do what it does, and scale the resulting body->v - I just don't want to do it that way if velocity_func is considered internal/shouldn't be modified by the user/etc. etc.
(Edit: although, now that I look at what the step function is actually doing, it may be that I want to limit the velocity before it gets called, because it looks like impulses are applied after the velocity update)
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Speed limits
Oh. Yes the position and velocity update functions are intended to be user accessible. I forgot to add that when updating the docs last weekend. (whoops) That is a very convenient place to do it so you don't have to iterate all the bodies you want to apply it to. Just set up a custom velocity function and let it do it's thing.
Clamping the velocity to a BB won't really get you what you want. It will be able to go faster in the diagonal directions. Also, a hard clamp on the velocity could cause problems. Better to push the velocity to the desired value over several frames using forces or limit the change to a certain percent.
Clamping the velocity to a BB won't really get you what you want. It will be able to go faster in the diagonal directions. Also, a hard clamp on the velocity could cause problems. Better to push the velocity to the desired value over several frames using forces or limit the change to a certain percent.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 4
- Joined: Wed Jun 03, 2009 12:37 pm
- Contact:
Re: Speed limits
(nod) - I was looking for a clamp function, cpBBClampVect came back in my search - but didn't really look into the details before I posted - once I saw the math it was doing I realized it'd let it go faster in the diagonal.
Thanks for the info, and the note about hard clamping the velocity (and for writing a physics engine, for that matter ). I may hard clamp it initially just to see how it acts, but given that I'll quickly replace that with something that'll make it converge to the limit I want over a few steps.
Thanks for the info, and the note about hard clamping the velocity (and for writing a physics engine, for that matter ). I may hard clamp it initially just to see how it acts, but given that I'll quickly replace that with something that'll make it converge to the limit I want over a few steps.
-
- Posts: 4
- Joined: Wed Jun 03, 2009 12:37 pm
- Contact:
Re: Speed limits
After looking at http://www.slembcke.net/forums/viewtopic.php?f=1&t=25 and keeping 'limit the change to a certain percent' from the above post in mind, I ended up setting body->velocity_func to something fairly close to this
It seems to work well, so far.
Code: Select all
void physicsBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) {
cpFloat v_limit, v_mag;
cpBodyUpdateVelocity(body, gravity, damping, dt);
// v_limit is really set from body->data. This is to keep it simple.
v_limit = 500;
v_mag = cpvlength(body->v);
if(v_mag > v_limit) {
float v_scale = v_limit / v_mag;
body->v = cpvmult(body->v, v_scale < 0.99 ? 0.99 : v_scale);
}
}
-
- Posts: 2
- Joined: Wed Jun 20, 2012 5:05 am
- Contact:
Re: Speed limits
Hi,
Sorry to dig up an old thread, but i'm also trying to somehow limit the speed, and i'm facing a small issue.
When calling cpSpaceStep, the integration of the position (position_func) is done before the velocity_func.
It means that if I apply an impulse outside the cpSpaceStep, the velocity is changed accordingly (apply_impulse), and the speed can be greater than expected.
Is there a proper way to handle this situation? (right now i'm clamping the speed in the velocity_func *and* in position_func callback).
Thanks a lot,
Az.
Sorry to dig up an old thread, but i'm also trying to somehow limit the speed, and i'm facing a small issue.
When calling cpSpaceStep, the integration of the position (position_func) is done before the velocity_func.
It means that if I apply an impulse outside the cpSpaceStep, the velocity is changed accordingly (apply_impulse), and the speed can be greater than expected.
Is there a proper way to handle this situation? (right now i'm clamping the speed in the velocity_func *and* in position_func callback).
Thanks a lot,
Az.
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Speed limits
No, unfortunately there is no official way to handle that. The velocity limit was meant as a very simple solution to limiting velocity. For it to work 100% correctly, it would need to clamp during both the position and velocity integration functions as well as during the solver. Running during the solver would require adding implicit constraints and would be a little expensive and wouldn't make a noticeable difference in most cases.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Who is online
Users browsing this forum: Heise IT-Markt [Crawler] and 8 guests