Jumpy raycast-vehicle

This topic is 2584 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm currently trying to get the ships for our game Pulsedrive to hover. For this I'm using a raycast-vehicle-style function which shoots a ray for each of the 4 corners to the bottom to calculate the forces.
That works quite well so far, the problem is just that my ships won't stop to jump up and down.

I read something about the Damping, and even implemented it into the code, but it doesn't seem to help. I used this page as a reference:
http://www.digitalrune.com/Support/Blog/tabid/719/EntryId/91/Car-Physics-for-3D-Games.aspx

The function for calculating the rays goes like this:
 float DoRaycastPhysics(float PrevCompression, vector3 Point, float DeltaTime) { const float SHIP_SUSPENSION_STIFFNESS = 20.0f; const float SHIP_DAMPING = 0.15f; vector3 Pos = Ship.GetLocation(); vector3 Susp = Ship.TransformDirection(Point); // Rotate wheel location float Susp_Length = 2.0; // Rest length float TireRad = 2.0f; // Tire radius vector3 RayOrigin = Pos + Susp; float RayLength = Susp_Length + TireRad; // Shoot the ray vector3 Nrm; float Dist = World.TraceEx(RayOrigin, vector3(0,-1,0), 1000, Nrm); vector3 HitPos = (vector3(0,-1,0)*Dist); // Local float Compression; if(Dist < RayLength) { Compression = Dist - TireRad; // Ray hit something, calculate the Compression }else { Compression = Susp_Length; // Didn't hit, set the compression to "rested"-state } // Calculate the SuspensionForce --- (Problem here?) float SuspensionForce = SHIP_SUSPENSION_STIFFNESS * (Susp_Length - Compression) + SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime; // Apply the force from the hit location in local space Ship.ApplyForce(vector3(0,SuspensionForce,0), HitPos); return Compression; } 

Does anyone see what my problem could be?

Share on other sites
Also, does someone know a good resource for raycast vehicles? There's almost nothing on the web. Probably I can solve the problem myself then.

Share on other sites
This one here seemed very good:
http://www.gamedev.net/topic/394292-demosource-of-marco-monsters-car-physics-tutorial/

You can also look at Box2D and Bullet. They both have some examples of raycast vehicles if I remember correctly

Share on other sites
If the ship keeps jumping up and down, then there might be a problem with your damping. The line

float SuspensionForce = SHIP_SUSPENSION_STIFFNESS * (Susp_Length - Compression) + SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime;

looks a lot like a Hookes law damped spring. The problem might be with the second term:
 + SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime;

where the term

(PrevCompression - Compression) * DeltaTime;

should represent the ships vertical velocity, but probably doesnt since the equation looks wrong. Try to replace it with this algorithm:

(Compression - PrevCompression) / DeltaTime;

Which calculates the velocity based on the mean value theorem. If it doesn't work, try changing the sign or change the SHIP_DAMPING value.

Cheers,
Mike

Share on other sites
Thanks for the reply! Unfortunately your solution doesn't seem to help. Or I am simply using the wrong values.

I have changed the function to this:
 float DoRaycastPhysics(float PrevCompression, vector3 Point, float DeltaTime) { vector3 Pos = Ship.GetLocation(); vector3 Susp = Ship.TransformDirection(Point); // Rotate wheel location float Susp_Length = 4.0; // Rest length float TireRad = 0.5f; // Tire radius float RestLength = Susp_Length; // Resting length vector3 RayOrigin = Pos + Susp; float RayLength = Susp_Length + TireRad; // Shoot the ray vector3 Nrm; float Dist = abs(World.TraceEx(RayOrigin, vector3(0,-1,0), 1000, Nrm)); vector3 HitPos = Susp+(vector3(0,-1,0)*Dist); float Compression=Susp_Length; if(Dist < RayLength) { Compression = Dist - TireRad; // Ray hit something, calculate the Compression } float SuspensionForce; if( Ship.GetLinearVelocity().y > 0) { // Extending SuspensionForce = SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Compression - PrevCompression) / DeltaTime; }else { // Compressing SuspensionForce = SuspensionStiffness * (RestLength - Compression) + CompressDamping * (Compression - PrevCompression) / DeltaTime; } // Apply the force from the hit location in local space Ship.ApplyForce(vector3(0,SuspensionForce,0), HitPos); return Compression; }

My vehicle is still jumping around.

Maybe I am using the wrong values?
SuspensionStiffness = 30
ExtendDamping = 2.3
CompressDamping = 4.4

I tried others, sure, but none seem to work out.

What works, at least a bit, is to multiply the SuspensionStiffness of the "Extending"-branch with 0.01f, but that doesn't seem a very "right" solution I guess.

Share on other sites
First, this code doesn't seem to make any sense. The force should always be applied, not only when vertical velocity is positive. Also, the two equations are identical.

if( Ship.GetLinearVelocity().y > 0) { // Extending SuspensionForce = SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Compression - PrevCompression) / DeltaTime; }else { // Compressing SuspensionForce = SuspensionStiffness * (RestLength - Compression) + CompressDamping * (Compression - PrevCompression) / DeltaTime; } 

Instead of all the above, simply write:

 SuspensionForce = -(SuspensionStiffness * (RestLength - Compression) + ExtendDamping * Ship.GetLinearVelocity().y); 

If it still doesn't work, try changing signs and coefficient values.
Cheers,
Mike

Share on other sites
Wow, it works! Thank you, Mike!

Still, I had to change the sign:
 SuspensionForce = abs(SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Ship.GetLinearVelocity().y)); 

Again, thank you!

Share on other sites
You're welcome, always glad to help. :-)

The abs() does seem a little strange to me though, and if it only works with it, I think there may be a bug hiding somewhere else in your code. Have you tried this:

SuspensionForce = -SuspensionStiffness * (RestLength - Compression) - ExtendDamping * Ship.GetLinearVelocity().y;

Notice there are two signs you can change independently of each other, suspension force and damping force. Good bug huntin'

Cheers,
Mike

Share on other sites
Ah, I forgot to take the "abs()" out when editing my post.

This is what's in my code:
SuspensionForce = (SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Ship.GetLinearVelocity().y)); 

Works like a charm.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• Forum Statistics

• Total Topics
633736
• Total Posts
3013601
×