NVIDIAGameWorks / PhysX

NVIDIA PhysX SDK
Other
3.18k stars 807 forks source link

Segmentation Fault with PhysX Vehicles with >20 vehicles #495

Open mateoguaman opened 2 years ago

mateoguaman commented 2 years ago

Hello, when I run my snippet in which I try to run more than 20 vehicles, I am getting a segmention fault when I try to increase the number of vehicles to be over 20. This happens when I try to run my snippet on CPU and GPU. Is there an internal limit on how many vehicles I can run using the Vehicle SDK?

My workstation details are:

Here is the Snippet code that I am running:

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//  * Neither the name of NVIDIA CORPORATION nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.  

// ****************************************************************************
// This snippet shows a heightfield and car simulations
// ****************************************************************************

#include <ctype.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <math.h>
#include <chrono>

#include "PxPhysicsAPI.h"

#include "../snippetcommon/SnippetPrint.h"
#include "../snippetcommon/SnippetPVD.h"
#include "../snippetutils/SnippetUtils.h"

#include "vehicle/PxVehicleUtil.h"
#include "../snippetvehiclecommon/SnippetVehicleSceneQuery.h"
#include "../snippetvehiclecommon/SnippetVehicleFilterShader.h"
#include "../snippetvehiclecommon/SnippetVehicleTireFriction.h"
#include "../snippetvehiclecommon/SnippetVehicleCreate.h"

using namespace physx;
using namespace snippetvehicle;

PxDefaultAllocator      gAllocator;
PxDefaultErrorCallback  gErrorCallback;

PxFoundation*           gFoundation = NULL;
PxPhysics*              gPhysics    = NULL;
PxCooking*              gCooking    = NULL;

PxDefaultCpuDispatcher* gDispatcher = NULL;
PxScene*                gScene      = NULL;

PxMaterial*             gMaterial   = NULL;

PxPvd*                  gPvd        = NULL;

PxHeightField*          gHf         = NULL;
PxRigidStatic*          gActor      = NULL;

static const PxU32      gGridSize   = 512;

// VEHICLE PARAMETERS
VehicleSceneQueryData*  gVehicleSceneQueryData = NULL;
PxBatchQuery*           gBatchQuery = NULL;

PxVehicleDrivableSurfaceToTireFrictionPairs* gFrictionPairs = NULL;

#define NUM_VEHICLES 21 //0
PxRigidStatic*          gHeightField = NULL;
PxVehicleDrive4W*       gVehicle4W[NUM_VEHICLES];
VehicleDesc             gVehicleDesc;

PxF32 xCoordVehicleStarts[NUM_VEHICLES];

//Define the maximum acceleration for dynamic bodies under the wheel.
#define MAX_ACCELERATION 50.0f

// Count distance traveled for all vehicles: Mateo
PxVec3 vehiclePositions[NUM_VEHICLES];
PxVec3 lastVehiclePositions[NUM_VEHICLES];
PxF32 vehicleDisplacements[NUM_VEHICLES];
PxF32 vehicleTotalDisplacements[NUM_VEHICLES];
PxF32 vehicleSpeeds[NUM_VEHICLES];
PxU32 numTimesteps = 0;

PxF32  maxDisplacement = 0;
#define TARGET_DISPLACEMENT 50.0f

static std::chrono::time_point<std::chrono::high_resolution_clock> gStart;
static std::chrono::time_point<std::chrono::high_resolution_clock> gStop;

// PxCudaContextManager* gCudaContextManager = NULL; // GPU

// #define RENDER_SNIPPET false 

VehicleDesc initVehicleDesc()
{
    //Set up the chassis mass, dimensions, moment of inertia, and center of mass offset.
    //The moment of inertia is just the moment of inertia of a cuboid but modified for easier steering.
    //Center of mass offset is 0.65m above the base of the chassis and 0.25m towards the front.
    const PxF32 chassisMass = 1500.0f;
    const PxVec3 chassisDims(2.5f,2.0f,5.0f);
    const PxVec3 chassisMOI
        ((chassisDims.y*chassisDims.y + chassisDims.z*chassisDims.z)*chassisMass/12.0f,
         (chassisDims.x*chassisDims.x + chassisDims.z*chassisDims.z)*0.8f*chassisMass/12.0f,
         (chassisDims.x*chassisDims.x + chassisDims.y*chassisDims.y)*chassisMass/12.0f);
    const PxVec3 chassisCMOffset(0.0f, -chassisDims.y*0.5f + 0.65f, 0.25f);

    //Set up the wheel mass, radius, width, moment of inertia, and number of wheels.
    //Moment of inertia is just the moment of inertia of a cylinder.
    const PxF32 wheelMass = 20.0f;
    const PxF32 wheelRadius = 0.5f;
    const PxF32 wheelWidth = 0.4f;
    const PxF32 wheelMOI = 0.5f*wheelMass*wheelRadius*wheelRadius;
    const PxU32 nbWheels = 4;

    VehicleDesc vehicleDesc;

    vehicleDesc.chassisMass = chassisMass;
    vehicleDesc.chassisDims = chassisDims;
    vehicleDesc.chassisMOI = chassisMOI;
    vehicleDesc.chassisCMOffset = chassisCMOffset;
    vehicleDesc.chassisMaterial = gMaterial;
    vehicleDesc.chassisSimFilterData = PxFilterData(0, 0, 0, 0);

    vehicleDesc.wheelMass = wheelMass;
    vehicleDesc.wheelRadius = wheelRadius;
    vehicleDesc.wheelWidth = wheelWidth;
    vehicleDesc.wheelMOI = wheelMOI;
    vehicleDesc.numWheels = nbWheels;
    vehicleDesc.wheelMaterial = gMaterial;
    vehicleDesc.wheelSimFilterData = PxFilterData(0, 0, 0, 0);

    return vehicleDesc;
}

static PxHeightField* createHeightField()
{
    PxHeightFieldSample samples[(gGridSize+1)*(gGridSize+1)];
    for (PxU32 i = 0; i < (gGridSize+1)*(gGridSize+1); i++)
    {
        // samples[i].height = rand() % 10 + 1;
        samples[i].height = rand() % 10 + 1;
        // samples[i].height = rand()/RAND_MAX;
        samples[i].materialIndex0 = 0;
        samples[i].materialIndex1 = 0;
    }

    PxHeightFieldDesc hfDesc;
    hfDesc.nbColumns = gGridSize;// + 1;
    hfDesc.nbRows = gGridSize;// + 1;
    hfDesc.convexEdgeThreshold = 3;
    hfDesc.samples.data = samples;
    hfDesc.samples.stride = sizeof(PxHeightFieldSample);

    PxHeightField* hf = gCooking->createHeightField(hfDesc, gPhysics->getPhysicsInsertionCallback());

    if (!hf)
        printf("Creating the height field failed");
    // printf("Heightfield created \n");

    return hf;
}

static void createDrivableStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
{
    PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
    for (PxU32 i = 0; i<size;i++)
    {
        for (PxU32 j = 0; j<size;j++)
        {
            // PxTransform localTm(PxVec3(PxReal(j*2), 0, PxReal(i*2)) * halfExtent);
            // PxTransform localTm(PxVec3(PxReal(j)+halfExtent, 0, PxReal(i)+halfExtent));
            PxTransform localTm(PxVec3(PxReal(j)+halfExtent, 0, PxReal(i)+halfExtent));
            PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));

            PxBoxGeometry boxGeom(PxVec3(halfExtent, halfExtent, halfExtent));
            PxShape* shape = PxRigidActorExt::createExclusiveShape(*body, boxGeom, *gMaterial);

            PxFilterData simFilterData(COLLISION_FLAG_OBSTACLE, COLLISION_FLAG_OBSTACLE_AGAINST, PxPairFlag::eMODIFY_CONTACTS | PxPairFlag::eDETECT_CCD_CONTACT, 0);
            shape->setSimulationFilterData(simFilterData);
            PxFilterData qryFilterData;
            setupDrivableSurface(qryFilterData);
            shape->setQueryFilterData(qryFilterData);

            PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
            gScene->addActor(*body);
        }
    }
    shape->release();
}

void keyPress(unsigned char key, const PxTransform& camera)
{
    PX_UNUSED(camera);
    PX_UNUSED(key);
}

void printPositions()
{
    // Print vehicle positions
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        float pos_x, pos_y, pos_z;
        pos_x = vehiclePositions[i].x;
        pos_y = vehiclePositions[i].y;
        pos_z = vehiclePositions[i].z;

        std::cout << "Timestep: " << numTimesteps << ". "<< "Vehicle " << i << " has position: (" << pos_x << ", " << pos_y << ", " << pos_z << ")\n";
    }
}

void initializePositions()
{
    // Obtain first pose for all vehicles:
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        vehiclePositions[i] =  gVehicle4W[i]->getRigidDynamicActor()->getGlobalPose().p;
        lastVehiclePositions[i] = PxVec3(vehiclePositions[i]);

        vehicleDisplacements[i] = 0;
        vehicleTotalDisplacements[i] = 0;
    }
    // lastVehiclePositions = PxVec3(vehiclePositions);
}

void updatePositions()
{
    // lastVehiclePositions = PxVec3(vehiclePositions);
    // Obtain first pose for all vehicles:
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        lastVehiclePositions[i] = PxVec3(vehiclePositions[i]);
        vehiclePositions[i] =  gVehicle4W[i]->getRigidDynamicActor()->getGlobalPose().p;
    }
}

void computeDisplacements()
{
    PxF32 maxDispSoFar = 0;
    // Compute displacements for all vehicles
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        float xDisp = vehiclePositions[i].x - lastVehiclePositions[i].x;
        float yDisp = vehiclePositions[i].y - lastVehiclePositions[i].y;
        float zDisp = vehiclePositions[i].z - lastVehiclePositions[i].z;

        PxF32 displacement = sqrt(xDisp*xDisp + yDisp*yDisp + zDisp*zDisp);
        vehicleDisplacements[i] = displacement;
        vehicleTotalDisplacements[i] = vehicleTotalDisplacements[i] + vehicleDisplacements[i];

        vehicleSpeeds[i] = vehicleDisplacements[i] * 60.0f;

        if (vehicleTotalDisplacements[i] > maxDispSoFar)
        {
            maxDispSoFar = vehicleTotalDisplacements[i];
        }
        maxDisplacement = maxDispSoFar;
    }

}

void printDisplacements()
{
    // Print displacements
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        std::cout << "Timestep: " << numTimesteps << ". " << "Vehicle " << i << " has time step displacement: " << vehicleDisplacements[i] << ", total displacement: " << vehicleTotalDisplacements[i] << ", speed: "  << vehicleSpeeds[i] << std::endl;
    }

    std::cout << "-->Max displacement: " << maxDisplacement << std::endl; 
}

void initPhysics(bool /*interactive*/)
{
    // printf("Initializing physics\n");
    srand(0);
    gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);

    gPvd = PxCreatePvd(*gFoundation);
    PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
    gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);

    gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);

    // // GPU
    // PxCudaContextManagerDesc cudaContextManagerDesc;
    // #ifdef RENDER_SNIPPET
    //     // cudaContextManagerDesc.interopMode = PxCudaInteropMode::OGL_INTEROP;  
    //  cudaContextManagerDesc.interopMode = PxCudaInteropMode::NO_INTEROP;//Choose interop mode. As the snippets use OGL, we select OGL_INTEROP
    //     //when using D3D, cudaContextManagerDesc.graphicsDevice must be set as the graphics device pointer.
    // #else
    //     cudaContextManagerDesc.interopMode = PxCudaInteropMode::NO_INTEROP;
    // #endif

    // gCudaContextManager = PxCreateCudaContextManager(*gFoundation, cudaContextManagerDesc, PxGetProfilerCallback());
    // if( gCudaContextManager )
    // {
    //  if( !gCudaContextManager->contextIsValid() )
    //  {
    //      gCudaContextManager->release();
    //      gCudaContextManager = NULL;
    //  }
    // }    

    // // END GPU

    // Keep for heightfield only
    PxCookingParams cookingParams(gPhysics->getTolerancesScale());

    gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, cookingParams);

    PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
    sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);

    PxU32 numWorkers = 1;
    gDispatcher = PxDefaultCpuDispatcherCreate(numWorkers);
    sceneDesc.cpuDispatcher = gDispatcher;
    sceneDesc.filterShader  = VehicleFilterShader;

    // // GPU
    // sceneDesc.cudaContextManager = gCudaContextManager;  
    // sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS;    //Enable GPU dynamics - without this enabled, simulation (contact gen and solver) will run on the CPU.
    // sceneDesc.flags |= PxSceneFlag::eENABLE_PCM;         //Enable PCM. PCM NP is supported on GPU. Legacy contact gen will fall back to CPU
    // sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION;   //Improve solver stability by enabling post-stabilization.
    // sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU;       //Enable GPU broad phase. Without this set, broad phase will run on the CPU.
    // sceneDesc.gpuMaxNumPartitions = 8;                       //Defines the maximum number of partitions used by the solver. Only power-of-2 values are valid. 
    // //A value of 8 generally gives best balance between performance and stability.

    // // END GPU

    gScene = gPhysics->createScene(sceneDesc);

    PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
    if(pvdClient)
    {
        pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
        pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
        pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
    }

    gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);

    /////////////////////////////////////////////

    PxInitVehicleSDK(*gPhysics);
    PxVehicleSetBasisVectors(PxVec3(0,1,0), PxVec3(0,0,1));
    PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
    PxVehicleSetMaxHitActorAcceleration(MAX_ACCELERATION);

    //Create the batched scene queries for the suspension raycasts.
    gVehicleSceneQueryData = VehicleSceneQueryData::allocate(NUM_VEHICLES, PX_MAX_NB_WHEELS, 1, NUM_VEHICLES, WheelSceneQueryPreFilterBlocking, NULL, gAllocator);
    gBatchQuery = VehicleSceneQueryData::setUpBatchedSceneQuery(0, *gVehicleSceneQueryData, gScene);

    //Create the friction table for each combination of tire and surface type.
    gFrictionPairs = createFrictionPairs(gMaterial);

    // Create heightfield
    PxHeightField* hf = createHeightField();
    gHf = hf;
    // const PxU32 hfSize = 8;
    const PxReal hfScale = 0.1f; //1.0f; // this is how wide one heightfield square is
    const PxReal heightScale = 0.01f; //0.01f; //0.01f;
    PxTransform pose = PxTransform(PxIdentity);
    // pose.p = PxVec3(-(hfSize/2*hfScale),0,-(hfSize/2*hfScale));
    pose.p = PxVec3(0,0,0);
    PxRigidStatic* hfActor = gPhysics->createRigidStatic(pose);
    if(!hfActor) 
        printf("creating heightfield actor failed");

    PxHeightFieldGeometry hfGeom(gHf, PxMeshGeometryFlags(), heightScale, hfScale, hfScale);
    PxShape* hfShape = PxRigidActorExt::createExclusiveShape(*hfActor, hfGeom, *gMaterial);
    if(!hfShape) 
        printf("creating heightfield shape failed");

    PxFilterData groundPlaneSimFilterData(COLLISION_FLAG_GROUND, COLLISION_FLAG_GROUND_AGAINST, 0, 0);
    hfShape->setSimulationFilterData(groundPlaneSimFilterData);
    PxFilterData qryFilterData;
    setupDrivableSurface(qryFilterData);
    hfShape->setQueryFilterData(qryFilterData);

    // START TIMER
    gStart = std::chrono::high_resolution_clock::now();
    gScene->addActor(*hfActor);

    // createDrivableStack(PxTransform(PxVec3(0,5.5,0)), gGridSize, 0.5f);

    // VEHICLE SETUP

    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        gVehicle4W[i] = NULL;
        // xCoordVehicleStarts[i] = 50.0f * i;
        xCoordVehicleStarts[i] =  25.0f * i;
    }

    gVehicleDesc = initVehicleDesc();
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {   VehicleDesc vehicleDesc = initVehicleDesc();
        gVehicle4W[i] = createVehicle4W(vehicleDesc, gPhysics, gCooking);
        // PxTransform startTransform(PxVec3(xCoordVehicleStarts[i], (vehicleDesc.chassisDims.y*0.5f + vehicleDesc.wheelRadius + 1.0f), 0), PxQuat(PxIdentity));
        PxTransform startTransform(PxVec3(vehicleDesc.chassisDims.x*0.5f + xCoordVehicleStarts[i], (vehicleDesc.chassisDims.y*0.5f + vehicleDesc.wheelRadius + 1.0f), vehicleDesc.chassisDims.z*0.5f), PxQuat(PxIdentity));
        gVehicle4W[i]->getRigidDynamicActor()->setGlobalPose(startTransform);
        gScene->addActor(*gVehicle4W[i]->getRigidDynamicActor());

        //Set the vehicle to rest in first gear.
        //Set the vehicle to use auto-gears.
        gVehicle4W[i]->setToRestState();
        gVehicle4W[i]->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
        gVehicle4W[i]->mDriveDynData.setUseAutoGears(true);

        gVehicle4W[i]->mDriveDynData.setAnalogInput(PxVehicleDrive4WControl::eANALOG_INPUT_ACCEL, 1.0f);

        // gVehicle4W[i]->mDriveDynData.setEngineRotationSpeed(10.0f/vehicleDesc.wheelRadius);
        gVehicle4W[i]->getRigidDynamicActor()->setLinearVelocity(PxVec3(0.0f, 0.0f, 10.0f));
    }

    initializePositions();
    // std::cout << "\n\nStarting vehicle positions:" << std::endl;
    // printPositions();
    computeDisplacements();
    // printDisplacements();

}

void stepPhysics(bool /*interactive*/)
{
    const PxF32 timestep = 1.0f/60.0f;

    // Set the vehicles to accelerate forwards.
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        gVehicle4W[i]->mDriveDynData.setAnalogInput(PxVehicleDrive4WControl::eANALOG_INPUT_ACCEL, 1.0f);
    }

    //Scene update.
    gScene->simulate(timestep);
    gScene->fetchResults(true);

    //Raycasts.
    PxVehicleWheels* vehicles[NUM_VEHICLES];
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        vehicles[i] = gVehicle4W[i];
    }
    PxRaycastQueryResult* raycastResults = gVehicleSceneQueryData->getRaycastQueryResultBuffer(0);
    const PxU32 raycastResultsSize = gVehicleSceneQueryData->getQueryResultBufferSize();
    PxVehicleSuspensionRaycasts(gBatchQuery, NUM_VEHICLES, vehicles, raycastResultsSize, raycastResults);

    //Vehicle update.
    const PxVec3 grav = gScene->getGravity();
    PxWheelQueryResult wheelQueryResults[PX_MAX_NB_WHEELS][NUM_VEHICLES];

    PxVehicleWheelQueryResult vehicleQueryResults[NUM_VEHICLES]; 

    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        vehicleQueryResults[i] = {wheelQueryResults[i], gVehicle4W[i]->mWheelsSimData.getNbWheels()};
    }

    PxVehicleUpdates(timestep, grav, *gFrictionPairs, NUM_VEHICLES, vehicles, vehicleQueryResults);

    numTimesteps = numTimesteps + 1;
    updatePositions();
    // std::cout << "\n==========\n";
    // printPositions();
    computeDisplacements();
    // printDisplacements();

}

void cleanupPhysics(bool /*interactive*/)
{
    for (PxU32 i = 0; i < NUM_VEHICLES; i++)
    {
        gVehicle4W[i]->getRigidDynamicActor()->release();
        gVehicle4W[i]->free();
    }
    PX_RELEASE(gBatchQuery);
    gVehicleSceneQueryData->free(gAllocator);
    PX_RELEASE(gFrictionPairs);
    PxCloseVehicleSDK();

    PX_RELEASE(gScene);
    PX_RELEASE(gDispatcher);
    // PX_RELEASE(gCudaContextManager); // GPU
    PX_RELEASE(gPhysics);
    PX_RELEASE(gCooking);
    if(gPvd)
    {
        PxPvdTransport* transport = gPvd->getTransport();
        gPvd->release();    gPvd = NULL;
        PX_RELEASE(transport);
    }
    // PX_RELEASE(gCudaContextManager); // GPU
    PX_RELEASE(gFoundation);

    printf("SnippetRacer done.\n");
}

// int snippetMain(int, const char*const*)
// {
// #ifdef RENDER_SNIPPET
//  extern void renderLoop();
//  renderLoop();
// #else
//  static const PxU32 frameCount = 100;
//  initPhysics(false);
//  for(PxU32 i=0; i<frameCount; i++)
//      printf("Step %d\n", i);
//      stepPhysics(false);
//  cleanupPhysics(false);
// #endif

//  return 0;
// }

// Simulator for 50 meters
int snippetMain(int, const char*const*)
{
    // gStart = std::chrono::high_resolution_clock::now();
// #ifdef RENDER_SNIPPET
//  extern void renderLoop();
//  renderLoop();
// #else
    // static const PxU32 frameCount = 100;
    initPhysics(false);
    // while(maxDisplacement < TARGET_DISPLACEMENT)
    while (numTimesteps < 300)
    {
        // printf("Step %d\n", i);
        stepPhysics(false);
    }
    gStop = std::chrono::high_resolution_clock::now();
    cleanupPhysics(false);
// #endif
    // gStop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(gStop - gStart);
    std::cout << "Time taken by function: "
         << duration.count() << " microseconds" << std::endl;

    std::cout << "Number of timesteps: " << numTimesteps << std::endl;
    return 0;
}

When I run this with a debugger (gdb), I get the following stack trace:

(gdb) run
Starting program: /home/mateo/PhysX/physx/bin/linux.clang/checked/SnippetCleanRacer_64 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7163700 (LWP 210583)]

Thread 1 "SnippetCleanRac" received signal SIGSEGV, Segmentation fault.
0x000000013ff33334 in ?? ()
(gdb) x 0x13ff33334
0x13ff33334:    Cannot access memory at address 0x13ff33334
(gdb) backtrace
#0  0x000000013ff33334 in ?? ()
#1  0x0000000000000000 in ?? ()
gyeomannvidia commented 2 years ago

Hallo,

There is no limit to the number of vehicles in physx. We actually have a snippet that instantiates 1024 vehicles and simulates them on multiple threads. You can take a look in SnippetVehicleMultithreading. Can you try running that snippet to see what happens?

Cheers,

Gordon