NVIDIAGameWorks/PhysX

Vehicles: Low Tire Load only while standing still

MeFisto94 opened this issue · 8 comments

So, I don't know if this is a tuning problem, but I am at a point where I can't properly find my way through further:
I've been diagnosing why I have severe traction problems when trying to start driving.
Actually, only the AWD configuration was really able to accelerate without wheel slip maxing out, so I was looking into the telemetry data.
It seems that the wheels aren't able to transmit power, because the tire load is very low or sometimes even 0.
It is only when I managed to get into driving, that the normalized tire load reaches values roughly around 1 (or between 3 and 4, if you account for the whole 4-wheel vehicle).
When standing still and braking, telemetry reads the tire load as 0 and when trying to gently accelerate, I get values around 1 for the combined normalized load, so 1/3rd to 1/4th per wheel.

How can I check what influences tire load, especially if there aren't any dynamics involved (stand still) and the vehicle is standing on a flat plane?

Edit: I did some more research and it appears that I only have a tireload when the moving wheels cause chassis movement. In the rest-pose, the spring is always at max droop, and even if I increase that value to be insanely high, the chassis moves upwards until the spring is at the exact point of max droop (+- floating point inaccurracies).

I'll look more into that, it has to be some faulty parameter that I pass in, but on a flat plane without anything, I'd expect the springs to be compressed, so that F = cx is satisfied, where F is the sprung mass.

Edit 2: Sorry for the monologue, but I did some more investigation and maybe it helps:
When I let the vehicle drop on it's wheels, the collision causes some force to be applied to the rigid body, but as the rigid body moves up, the force obviously decreases, up to a point where it applies (0, 0, 0). A similar observation was where I set maxDroop to 10f and it basically pushed the chassis up by 10 meters.

Now, to my understanding, we only have the chassis being a dynamic rigid body. Then we have the vehicle extension that does ray casts and ultimately applies forces to said rigid body. That would however mean, that this force would have to support the rigidbodies gravity, because it would otherwise drop down to (chassisDims.y / 2) and collide with the floor itself. This gravitational force would compress the spring away from it's rest point though.
Put differently: Why do we have an equilibrium for max droop/at zero force? It should really cause the rigidbody to move down, it's as if gravity was not enabled or the rigid body kinematic, both which are not true.
The latter is throwing a checked error and the former would cause the vehicle to fly away after the first collision with the floor, so gravity kinda is applied, also adding a manual force with a multiple of gravity doesn't change anything.

I'm kinda at another road block until I have further ideas, the code and values should be really close to the SnippetVehicle4W, so I may be doing something dumb, but I can't imagine what anymore.

The suspension travel origin has been shifted so that zero is the rest pose specified by the wheel centre position. This is discussed in the user guide in the Vehicles/Tuning Guide/PxVehicleSuspensionData section.

tldr: if you want to create a perfect spring set

maxDroop = sprungMass*gravity/suspensionStiffness

Can you try setting maxDroop to see what happens?

The suspension travel origin has been shifted so that zero is the rest pose specified by the wheel centre position.

That has kinda helped me further, because I oriented myself at

//Set the top of the wheel to be just touching the underside of the chassis.
//Begin by setting the rear-left/rear-right/front-left,front-right wheels.
wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_LEFT] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + 0*deltaZ*0.5f);

With that, the suspension can't really compress, because the wheel rigid body would collide with the chassis. Fixing that improved the situation a very little, but only with a trick.

Can you try setting maxDroop to see what happens?

That's actually what it's set to (~ 0,11 in average).

To outline what happens, I've attached a GIF. Basically, when subtracting mMaxCompression to the wheelCenterOffsets' y, the vehicle works, but only because I dropped it down from 3 meters first (because the movement speed did indeed cause tire load).

I then demonstrate how touching the brakes (setAnalogInput for ANALOG_INPUT_BRAKE) immediately cuts the tire load completely (see the lines and the warnings in the log). Then I accelerate only to come to a halt again.
When braking (actually, after standing still, I put the vehicle in neutral and depressed the brakes again), the above is happening and you can see how the vehicle goes into the broken state: Not only is the tireload 0, but the chassis is even lifted mMaxDroop beyond it's regular position while driving (compare the info log's Y component. 1.80 vs 1.91).

Now when removing the dropping (which I did by removing the +3f I had in actor.setGlobalPose), the vehicle already starts in that broken state and can't do anything.

Unity_xqWmpywTSC

Maybe a thing to note on why I can't easily share some code or confirm the sample works for me or something, is because I've based my code off https://github.com/NVIDIAGameWorks/UnityPhysXPlugin, so something in the interop could cause such issues. Unfortunately, PVD also doesn't show any actors, it only tracks scenes and some properties thereof (e.g. active actors)

Edit: the behavior is very sensitive to mMaxDroop. If I, for instance, increase maxDroop by 0.1f, I get the wheel lifting behavior even after the "air drop" of the car. I am completely clueless now.

Actually, after re-considering the settings and moving away from the template in favour of the target car, I got back into the broken state.
There I am asking myself: Should the relaxed position (wheel center offset) be without the load of the chassis mass or with it?
I assume it's the same position, because apparently the gravity of the chassis is not considered for the spring compression, because the wheel offset and thus the raycast start moves down.

Either way, I was able to finally work around the problem by just setting mMaxDroop to 0f. That way, I just never get in the situation, where the car is boosted up (since droop never applies forces) and thus I always have the tire load I expect to have.
Now this is obviously a workaround and as soon as not driving on a flat plane causes issues, which is why I'd love to diagnose this further, but need assistance for that.

I guess the next thing to check are the raycasts, because their start position is too high? though since the chassis seems unaffected by gravity (and hence not moving back to 1.80, when there is NO suspension force pushing up), the ray casts can't adjust and move the suspension into compression anyway.

Another observation, though: The suspension force on the wheel body should pull it up when it's drooping, so I wonder why that doesn't happen. Like the force should point into the opposite direction than when compressing, obviously.

The mass of the rigid body is accounted for in the spring force. More correctly, the force starts at sprungMass * gravity and then adds on stiffness * jounce where jounce is the distance from the rest pose. The assumption is that the rest pose generates a force close to M * g. The user guide discusses this in some detail.

The rest pose is guaranteed because it is the pose that generates the force upwards that exactly matches the effect of gravity downards. I suspect the problem you have is that you have deviated too far from a perfect linear spring. This can be corrected by setting maxDroop to the correct value so that maxDroop * springStrength = sprungMass * gravity. The key point with physx vehices is that we do not impose this as a hard rule because it might stand in the way of fun handling. However, you can impose it as a hard rule by setting maxDroop to have the value of a perfect linear spring, as discussed above and in the user guide.

The raycasts always start at the top of the wheel at maximum compression pose and end at the bottom of the wheel at maximum droop pose. The position and length of the suspension is independent of any force applied and are dependent only on the suspension travel limits.

The body of the vehicle should be affected by gravity. The vehicle's rigid body is updated in the physx scene update, which applies gravity and the forces computed by the vehicle update. Have you definitely set the physx scene and PxRigidDynamic to apply gravity?

The mass of the rigid body is accounted for in the spring force. More correctly, the force starts at sprungMass * gravity and then adds on stiffness * jounce where jounce is the distance from the rest pose. The assumption is that the rest pose generates a force close to M * g. The user guide discusses this in some detail.

Yeah, I was unclear on that. The force between chassis and wheels is disregarded, because it's assumed they move in sync, so that explains why the rest pose is the expected pose with the chassis load on.

The body of the vehicle should be affected by gravity. The vehicle's rigid body is updated in the physx scene update, which applies gravity and the forces computed by the vehicle update. Have you definitely set the physx scene and PxRigidDynamic to apply gravity?

I have confirmed that, yeah. Actually my guess was completely wrong, because the vehicle does drop from above, it was just that when the wheels had floor contact, that things have gone wrong.

Either way, I finally managed to setup Pvd, is there anything specific I can look for that helps me?
I can see how the raycast is happening and the related contact normal? I can see some orange crosses on the contact surface, what do they mean?

grafik

(In theory, my max compression is a bit too high, because otherwise the chassis would collide with the ground, but this is clearly not here).

Still, the suspension force is reported as 0 and jounce as -0.11 (negative mMaxDroop, suspSprungMasses[i] * 9.81f / 35000f)
I'm sorry for not being able to provide much helpful information, it's really strange because it kinda should just work, I guess.

The orange crosses look like contact points. This means the vehicle is supported by both rigid body contact and suspension. This is something you definitely do not want because it means the suspension does not generate the force required to load the tire.

I recommend disabling collision on the wheel shapes.

That was it!
Thank you soo much. I can't believe I spent over a week just to find out I forgot to set the CollisionFilter on the SceneDesc....
I migrated everything from the VehicleSnippets over, besides the exact setup for the scene, because I thought this to be regular boilerplate, but it turns out without VehicleShaderFilter I am missing the whole logic around the collision flag stuff.

Now I can finally play around with setting up the suspension strength and then progress with the rest :D

Very glad it worked out and turned out to be something simple to fix.