Car with PxVehicleDrive4W - no suspension and no grip

I’ve been writing a car simulation in C++ reading the PhysX guide’s vehicles part (SDK version 3.2.1) and the provided SampleVehicle code. Most parts are copied from the sample vehicle.
My problem is that the suspension of the car is not working, any value I set when I configure it the suspension remains stiff and doesn’t move at all. The only parameter working is PxVehicleSuspensionData::mMaxDroop, if I set that one bigger, the length of the suspension increases.
The second problem is that I can turn the front wheels, I can set the acceleration flag in the cehicle controller and the wheels are spinning but the car doesn’t move at all, it stays there as if it was on ice.
What I do:

  1. I set the SimulationFilterData and the QueryFilterData for the ground shape, to be drivable and have COLLISION_FLAG_GROUND and COLLISION_FLAG_GROUND_AGAINST flags as in the sample vehicle code, and it is a convex mesh
  2. Create a PxVehicleDrive4W as in the sample vehicle code
  3. When updating the vehicle:
  • first I set the new keyboard inputs, and update the vehicle controller
  • then call PxVehicleSuspensionRaycasts function
  • and finally PxVehicleUpdates function

Could you help me what did I miss to set up?

Hi,

Yes, tuning the vehicles can be a bit frustrating, we are working to improve that. Changes to the scale of the world, relative to the sample world, can lead to effects like this. Could you post a repro in a simple application, or as a modification to the current Sample Vehicle?

Thanks,
Mike

Hello,
thank you, but I don’t think it would be related to the scale of the world, it rather looks like raycasting of the suspension and tire friction doesn’t work at all, I must have forgot to set up something.
First because the suspension and the friction doesn’t react, not even a little bit. Second I used all parameters for the vehicle as if they were in meters and kilograms.

Hello,

This sounds like either the tire has no load or has no friction or both.

The most common problem that results in the tire having no load is that the wheel is supported by collision rather than by the suspension spring. This can be solved by setting PxFilterData on any PxShape instances that have been added to the vehicle’s rigid body to represent wheel geometry. It can also be solved by setting the filter data given to the PxShape representing the ground. By tweaking the filter data and the filter shader it is straightforward to disable collisions between the wheels and the ground. The vehicle will then be supported only by the forces of the suspension springs and the tires will experience a downwards load equal to the suspension spring force. You can check in pvd to see if there are any contacts between any vehicle shapes and the ground under the vehicle. When there are no visible contacts then everything is set up properly.

You can also query the suspension force of the suspension with PxReal getSuspensionForce(const PxU32 tireIdx) const. The suspension force should be roughly vehicleMassgravity0.25 per suspension. If it is significantly less than this then there is a problem. The most obvious place to look is the sprung mass of the suspension: PxVehicleSuspensionData::mSprungMass. The sprung mass should be roughly one quarter of the mass of the rigid body. The exact distribution depends on how you wish to set up the car.

The tire friction could also be zero or very closer to zero. You can query the friction with PxReal getTireFriction(const PxU32 tireIdx) const;. Ideally, the friction would be close to 1.0. If the friction turns out to be very small then PxVehicleDrivableSurfaceToTireFrictionPairs might not be set up properly for the PxMaterial instance of the ground shape and the tire type (PxVehicleTireData::mTireType). The vehicle’s guide and sample show how to set this up.

You might also want to look at the mMaxCompression and mMaxDroop values stored in PxVehicleSuspensionData. A typical car has something like 0.3m of travel and is able to travel in both directions. In the case that the suspension needs to be compressed beyond the maximum compression value a custom constraint is activated to enforce the limit. If mMaxCompression was set to be a very small value then the special constraint will constantly do all the work that the suspension should have performed and the spring will end up with zero force and the tire zero load.

btw upcoming in 3.3 is a new troubleshooting section in the vehicle’s guide.

Thank you gyeoman. One problem was that the wheels were colliding with the ground because I’ve forgot to set the PxSceneDesc.filterShader to the SampleVehicleFilterShader function.
Now the wheels don’t collide with the ground but the suspension forces don’t get applied to the vehicle. The wheels fall into the ground until the chassis collides with it. Of course I did call PxVehicleSuspensionRaycasts before updating the vehicle.
I use SampleVehicle_SceneQuery.cpp module in my code unchanged.
So what could I have missed with the suspension raycasts?

Hi,

The next step is to set up the raycast filter so that raycats issued downwards from the wheels collide with the ground shape but don’t collide with the shapes of the vehicle that issues the raycast. In the sample code you can find the following:

//Set up the scene query filter data for each suspension line.
PxFilterData vehQryFilterData;
SampleVehicleSetupVehicleShapeQueryFilterData(&vehQryFilterData);
car->setSceneQueryFilterData(0, vehQryFilterData);
car->setSceneQueryFilterData(1, vehQryFilterData);
car->setSceneQueryFilterData(2, vehQryFilterData);
car->setSceneQueryFilterData(3, vehQryFilterData);

This code sets up the filter data for each raycast from each suspension.

There is also code to set up scene query filter data for car shapes and for drivable shapes such as the ground. The following functions should give you a good idea how to achieve it in your application:

SampleVehicleWheelRaycastPreFilter
SampleVehicleSetupDrivableShapeQueryFilterData
SampleVehicleSetupNonDrivableShapeQueryFilterData
SampleVehicleSetupVehicleShapeQueryFilterData

Configuring the scene query shader function and the filter data allows the suspension to selectively interact with shapes in the scene. It is important to make sure that the suspension raycasts don’t interact with vehicle shapes.

By tweaking the collision and raycast filters you can decide which shapes in your scene will be “drivable” shapes and which shapes will just bounce off the vehicle’s shapes through rigid body collision.

Gordon

Hey,

I’ve managed to fix it, now it’s working and looks good.
When setting up the ground mesh, I’ve written
shape->setSimulationFilterData( qryFilterData );
instead of
shape->setQueryFilterData( qryFilterData );
so the query filter data wasn’t set although I thought I had set it. Both functions take the same type of parameter so I didn’t even get a warning from the compiler :(
Thank you for your help, I really appreciate it.

Václav

Good to know that sorted you out.

Gordon

Thanks Gordon,

+1 for this great troubleshooting guide - I managed to have a basic working example following your debug tips.

Please nVidia moderators, keep in mind to simplify the sdk samples as it’s extremely difficult to understand what (and only what) is needed to use the different physx modules.

ricky

Have you taken a look at the snippets? If you have 3.3.0 or later its worth taking a look at the snippets that ship with the sdk. They are much simpler to follow than the old samples. There are quite a few separate vehicle snippets that show how to set up a car, control it with inputs, use multi-threading to update vehicles, change the length scale to centimetres etc.

Thanks,

Gordon