Speed limits

Official forum for the Chipmunk2D Physics Library.
Post Reply
anomie
Posts: 4
Joined: Wed Jun 03, 2009 12:37 pm
Contact:

Speed limits

Post by anomie »

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)
patrickC
Posts: 7
Joined: Sat May 02, 2009 10:55 am
Contact:

Re: Speed limits

Post by patrickC »

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.
anomie
Posts: 4
Joined: Wed Jun 03, 2009 12:37 pm
Contact:

Re: Speed limits

Post by anomie »

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)
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Speed limits

Post by slembcke »

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.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
anomie
Posts: 4
Joined: Wed Jun 03, 2009 12:37 pm
Contact:

Re: Speed limits

Post by anomie »

(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.
anomie
Posts: 4
Joined: Wed Jun 03, 2009 12:37 pm
Contact:

Re: Speed limits

Post by anomie »

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

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);
	}
}
It seems to work well, so far.
Azreal42
Posts: 2
Joined: Wed Jun 20, 2012 5:05 am
Contact:

Re: Speed limits

Post by Azreal42 »

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.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Speed limits

Post by slembcke »

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/
Post Reply

Who is online

Users browsing this forum: Heise IT-Markt [Crawler] and 8 guests