NVIDIAGameWorks / PhysX

NVIDIA PhysX SDK
Other
3.17k stars 805 forks source link

Reset actor position makes actors fly #83

Open trajcenikolovnick opened 5 years ago

trajcenikolovnick commented 5 years ago

Hello,

I have simulation of truck and semi-trailer (two 6 wheeled vehicles attached by joint). When I want to reset their position (ex: to start a scenario from the beginning) I use setGlobalPose(startTransform,false); they start flying in the scene. What is the magic to have them quietly sit on the given position?

Thanks a bunch!

Nick

PierreTerdiman commented 5 years ago

Hello,

I tried to reproduce this issue but it works fine for me. I suppose you don't have a simple repro?

trajcenikolovnick commented 5 years ago

Hi, thank you for looking into this. I do have code to reproduce the issue. It is the modified SnippetVehicleContactMod_64 to have 6 wheeled truck vehicle with semi trailer, also 6 wheeled vehicle and a cabin for the truck.

https://www.dropbox.com/s/h5k6qsvi01fi726/PhysX-4.0.tar.gz?dl=0

I am after resetting/starting the simulation from steady position. Also the cabin when reset (press any key) is doing some movement

Any hints, snippets are highly welcome

Thanks a bunch again

PierreTerdiman commented 5 years ago

Hmm if I run this in Release I can see something on-screen but the cabin is doing weird movements even the first time, not just after a reset.

And if I run it in Debug it crashes after outputting these error messages:

1072: passed 1084: passed 1086: passed Z:0 = 1.25 Z:1 = 1.25 Z:2 = -2.25 Z:3 = -2.25 Z:4 = -1.25 Z:5 = -1.25 1105: passed C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physx\src\NpRigidDynamic.cpp (342) : invalid parameter : PxRigidDynamic::clearForce: Body must be in a scene!

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physx\src\NpRigidDynamic.cpp (342) : invalid parameter : PxRigidDynamic::clearForce: Body must be in a scene!

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physx\src\NpRigidDynamic.cpp (353) : invalid parameter : PxRigidDynamic::clearTorque: Body must be in a scene!

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physx\src\NpRigidDynamic.cpp (353) : invalid parameter : PxRigidDynamic::clearTorque: Body must be in a scene!

Z:0 = -4 Z:1 = -4 Z:2 = -3 Z:3 = -3 Z:4 = -2 Z:5 = -2 C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleDrive4W.cpp (73) : invalid parameter : Illegal ackermannData.mAxleSeparation - must be greater than zero

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleComponents.cpp (159) : invalid parameter : PxVehicleAckermannGeometryData.mFrontWidth must be greater than zero

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleComponents.cpp (159) : invalid parameter : PxVehicleAckermannGeometryData.mFrontWidth must be greater than zero

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleDrive4W.cpp (54) : invalid parameter : Invalid PxVehicleCoreSimulationData.mAckermannGeometry

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleComponents.cpp (159) : invalid parameter : PxVehicleAckermannGeometryData.mFrontWidth must be greater than zero

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleComponents.cpp (159) : invalid parameter : PxVehicleAckermannGeometryData.mFrontWidth must be greater than zero

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleDrive4W.cpp (54) : invalid parameter : Invalid PxVehicleCoreSimulationData.mAckermannGeometry

C:\P4\Root\sw\physx\PhysXSDK\4.1\trunk\source\physxvehicle\src\PxVehicleDrive4W.cpp (123) : invalid parameter : PxVehicleDrive4W::setup - invalid driveData

This suggests that there are issues in the setup, which are probably responsible for the weird cabin motion.

Do you get the same errors in Debug?

trajcenikolovnick commented 5 years ago

Hi Pierre,

I havn't tried Debug yet. And yes, the cabin setup is probably not proper. All I did is I created another actor in the scene and attached it to the chasis with D6 Joint with some limits - have a look in createCabin function. It seams that some forces other then gravity are applied to me. The other issue with flying vehicle is just let it run for a minute or two and reset.

trajcenikolovnick commented 5 years ago

q

PierreTerdiman commented 5 years ago

It would be good to first fix the warnings & errors in Debug. Maybe it would also make the problems go away. It is difficult otherwise to follow what is happening (I cannot trace the code in Release so this is artificially complicated).

The "flying" part happens after the truck has been stopped by the static obstacle for a while. You can make it happen faster by moving the obstacle closer to the truck:

    const PxF32 boxZ[1] = {10.0f};

But you already call "setToRestState" on reset (multiple times even) so any accumulated force/torque should have been cleared. There might be some other accumulators that we forgot to clear, but it's hard to tell when I cannot trace the code.

trajcenikolovnick commented 5 years ago

the crash is happening due to unintialized actor for the trailer vehicles. By stepping through the actor is set in PxVehicleWheels in it's setup, but after all the checks of the parameters some of which are wrong, and the code exit 'prematurely' leaving the actor unset. And this is happening in configureUserData, vehicle->getRigidDynamicActor()->userData = actorUserData;

I am trying to fix the errornous setup data, but still learning PhysX so maybe you can help on this too.

here is the trace:

0 0x0000000000415b9d in snippetvehicle::configureUserData (vehicle=0xfe4cc0,

actorUserData=0xd79ad0 <gTrailerActorUserData>, 
shapeUserDatas=0xd79af0 <gTrailerShapeUserDatas>)
at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.cpp:165

1 0x0000000000414f21 in snippetvehicle::createVehicle4W (vehicle4WDesc=...,

physics=0xf67ed0, cooking=0xf88ab0)
at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetvehiclecommon/SnippetVehicle4WCreate.cpp:448

2 0x000000000040fa1a in initPhysics ()

at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetvehiclecontactmod/SnippetVehicleContactMod.cpp:1140

3 0x00000000004121bb in renderLoop ()

at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetvehiclecontactmod/SnippetVehicleContactModRender.cpp:116

4 0x0000000000410cd4 in snippetMain ()

at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetvehiclecontactmod/SnippetVehicleContactMod.cpp:1274

5 0x000000000040a542 in main (argc=1, argv=0x7fffffffd288)

at /home/simuser/Dev/PhysX-4.0/physx/snippets/snippetcommon/ClassicMain.cpp:34
trajcenikolovnick commented 5 years ago

hi again,

I finally managed to clean the warnings&errors and to make it run in debug without crash. Attached are the files.

SnippetVehicle4WCreate.cpp.txt SnippetVehicleContactMod.cpp.txt

PierreTerdiman commented 5 years ago

I see multiple issues so far:

a) you are using joints without initializing the extensions library. We should probably output an error message in this case but meanwhile, add this before PxInitVehicleSDK:

PxInitExtensions(*gPhysics, gPvd);

b) your reset positions aren't the same as the initial starting positions. They're slightly different. But fixing that doesn't make the issue go away.

c) what kind of joint are you trying to create between the truck and the trailer? I don't understand why you use a drive here:

j->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(0, 100, FLT_MAX, true))

But removing it doesn't fix the problem anyway.

d) you create the trailer in front of the truck and then let the joint correct its position. That's not ideal since the correction might be a bit violent and responsible for the issue when you reset things. I didn't have time to fix this one yet but it might be relevant.

(to be continued)

PierreTerdiman commented 5 years ago

Looks like there might be something missing in our setToRestState() function. Meanwhile, can you try to move these lines after PxVehicleUpdates() ?

gScene->simulate(timestep);
gScene->fetchResults(true);
trajcenikolovnick commented 5 years ago

That helped! I did some tests and the truck is no more 'flying' after reset.

c) what kind of joint are you trying to create between the truck and the trailer? I don't understand why you use a drive here:

I thought the best is to have SphericalJoint but couldn't made it work nicely and while still learning physX the D6Joint is the best I have come up with

b) your reset positions aren't the same as the initial starting positions. They're slightly different. But fixing that doesn't make the issue go away.

Can you provide the fix for this too? If I made the cabin not to shake on reset and init I think we will be fine

Thanks a bunch for so far !

PierreTerdiman commented 5 years ago

Using a D6Joint is fine, it's just the drive part I'm not sure about - I don't think you need a drive in this test, the motion is already taken care of by the vehicle object.

The fix was just to add this at the start:

static PxTransform gStartTransforms[NUM_VEHICLES];

And then save the poses at init time:

    PxTransform startTransform(PxVec3(xCoordVehicleStarts[i], (vehicleDesc.chassisDims.y*0.5f + vehicleDesc.wheelRadius + 1.0f), 0), PxQuat(PxIdentity));
    gStartTransforms[i] = startTransform;

And then reuse these poses at reset time:

// PxTransform startTransform(PxVec3(xCoordVehicleStarts[i], (0.5f*0.5f + 0.75f+ 1.0f), 0), PxQuat(PxIdentity)); PxTransform startTransform = gStartTransforms[i];

You can compare both the commented out startTransform and the saved ones to see the differences.

As mentioned the positions of the trailers were also incorrect. You add a "+7" here but I think the correct offset is "-5":

            startTransform.p.z -= 5.f;
PierreTerdiman commented 5 years ago

In any case congratulations for finding a very old and obscure bug in the vehicle library. I'm running unit tests right now and it will be fixed in the next release.

trajcenikolovnick commented 5 years ago

thanks for the credit and the help with this one. It was a major one. Hope I will fix the rest of it.

Thanks again Cheers

trajcenikolovnick commented 5 years ago

Hi Piere,

I tried (for about a week) to resolve the joint connected actors movements on reset and I failed. Since it is part of the code shared in this thread I am reopening it with asking for hints on this too, if you can have a look. I am after steady reset of all actors