Пример #1
0
    // Use convex decomposition for collision detection with the Trelleborg tire
    SoilbinWheel(ChSystemNSC* system, ChVector<> mposition, double mass, ChVector<>& inertia) {
        ChCollisionModel::SetDefaultSuggestedEnvelope(0.005);
        ChCollisionModel::SetDefaultSuggestedMargin(0.004);

        // Create the wheel body
        wheel = std::make_shared<ChBody>();
        wheel->SetPos(mposition);
        wheel->SetMass(mass);
        wheel->SetInertiaXX(inertia);
        wheel->GetMaterialSurfaceNSC()->SetFriction(0.4f);
        wheel->SetCollide(true);

        // Visualization mesh
        auto tireMesh = std::make_shared<ChTriangleMeshConnected>();
        tireMesh->LoadWavefrontMesh(GetChronoDataFile("tractor_wheel.obj"), true, true);
        auto tireMesh_asset = std::make_shared<ChTriangleMeshShape>();
        tireMesh_asset->SetMesh(tireMesh);
        wheel->AddAsset(tireMesh_asset);

        // Contact mesh
        wheel->GetCollisionModel()->ClearModel();
        // Describe the (invisible) colliding shape by adding the 'carcass' decomposed shape and the
        // 'knobs'. Since these decompositions are only for 1/15th of the wheel, use for() to pattern them.
        for (double mangle = 0; mangle < 360.; mangle += (360. / 15.)) {
            ChQuaternion<> myrot;
            ChStreamInAsciiFile myknobs(GetChronoDataFile("tractor_wheel_knobs.chulls").c_str());
            ChStreamInAsciiFile myslice(GetChronoDataFile("tractor_wheel_slice.chulls").c_str());
            myrot.Q_from_AngAxis(mangle * (CH_C_PI / 180.), VECT_X);
            ChMatrix33<> mm(myrot);
            wheel->GetCollisionModel()->AddConvexHullsFromFile(myknobs, ChVector<>(0, 0, 0), mm);
            wheel->GetCollisionModel()->AddConvexHullsFromFile(myslice, ChVector<>(0, 0, 0), mm);
        }
        wheel->GetCollisionModel()->BuildModel();

        // Add wheel body to system
        system->AddBody(wheel);
    }
Пример #2
0
int main(int argc, char* argv[])
{
	// In CHRONO engine, The DLL_CreateGlobals() - DLL_DeleteGlobals(); pair is needed if
	// global functions are needed. 
	DLL_CreateGlobals();

	// Create a Chrono::Engine physical system
	ChSystem mphysicalSystem;

	// Create the Irrlicht visualization (open the Irrlicht device, 
	// bind a simple user interface, etc. etc.)
	ChIrrApp application(&mphysicalSystem, L"Assets for Irrlicht visualization",core::dimension2d<u32>(800,600),false, true);


	// Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene:
	application.AddTypicalLogo();
	application.AddTypicalSky();
	application.AddTypicalLights();
	application.AddTypicalCamera(core::vector3df(0,4,-6));

 
  

	//
	// EXAMPLE 1: 
	//

	// Create a ChBody, and attach some 'assets' 
	// that define 3D shapes. These shapes can be shown
	// by Irrlicht or POV postprocessing, etc...
	// Note: these assets are independent from collision shapes!

			// Create a rigid body as usual, and add it 
			// to the physical system:
	ChSharedPtr<ChBody> mfloor(new ChBody);
	mfloor->SetBodyFixed(true);

			// Define a collision shape 
	mfloor->GetCollisionModel()->ClearModel();
	mfloor->GetCollisionModel()->AddBox(10,0.5,10, &ChVector<>(0,-1,0));
	mfloor->GetCollisionModel()->BuildModel();
	mfloor->SetCollide(true);

			// Add body to system
	application.GetSystem()->Add(mfloor);

			// ==Asset== attach a 'box' shape.
			// Note that assets are managed via shared pointer, so they 
			// can also be shared). Do not forget AddAsset() at the end!
	ChSharedPtr<ChBoxShape> mboxfloor(new ChBoxShape);
	mboxfloor->GetBoxGeometry().Pos = ChVector<>(0,-1,0);
	mboxfloor->GetBoxGeometry().Size = ChVector<>(10,0.5,10);
	mfloor->AddAsset(mboxfloor);

			// ==Asset== attach color asset. 
	ChSharedPtr<ChVisualization> mfloorcolor(new ChVisualization);
	mfloorcolor->SetColor(ChColor(0.3,0.3,0.6));
	mfloor->AddAsset(mfloorcolor);

	/*
			//  ==Asset== IRRLICHT! Add a ChIrrNodeAsset so that Irrlicht will be able
			// to 'show' all the assets that we added to the body! 
			// OTHERWISE: use the application.AssetBind() function as at the end..
	ChSharedPtr<ChIrrNodeAsset> mirr_asset_floor(new ChIrrNodeAsset);
	mirr_asset_floor->Bind(mfloor, application);
	mfloor->AddAsset(mirr_asset_floor);
	*/


	//
	// EXAMPLE 2: 
	//

	// Textures, colors, asset levels with transformations.
	// This section shows how to add more advanced types of assets
	// and how to group assets in ChAssetLevel containers.

			// Create the rigid body as usual (this won't move,
			// it is only for visualization tests)
	ChSharedPtr<ChBody> mbody(new ChBody);
	mbody->SetBodyFixed(true);
	application.GetSystem()->Add(mbody);

			// ==Asset== Attach a 'sphere' shape  
	ChSharedPtr<ChSphereShape> msphere(new ChSphereShape);
	msphere->GetSphereGeometry().rad = 0.5;
	msphere->GetSphereGeometry().center = ChVector<>(-1,0,0);
	mbody->AddAsset(msphere);

			// ==Asset== Attach also a 'box' shape 
	ChSharedPtr<ChBoxShape> mbox(new ChBoxShape);
	mbox->GetBoxGeometry().Pos = ChVector<>(1,1,0);
	mbox->GetBoxGeometry().Size = ChVector<>(0.3,0.5,0.1);
	mbody->AddAsset(mbox);

			// ==Asset== Attach also a 'cylinder' shape 
	ChSharedPtr<ChCylinderShape> mcyl(new ChCylinderShape);
	mcyl->GetCylinderGeometry().p1  = ChVector<>(2,-0.2,0);
	mcyl->GetCylinderGeometry().p2  = ChVector<>(2.2,0.5,0);
	mcyl->GetCylinderGeometry().rad = 0.3;
	mbody->AddAsset(mcyl);

			// ==Asset== Attach color. To set colors for all assets  
			// in the same level, just add this:
	ChSharedPtr<ChVisualization> mvisual(new ChVisualization);
	mvisual->SetColor(ChColor(0.9,0.4,0.2));
	mbody->AddAsset(mvisual);
	
			// ==Asset== Attach a level that contains other assets.
			// Note: a ChAssetLevel can define a rotation/translation respect to paren level,
			// Note: a ChAssetLevel can contain colors or textures: if any, they affect only objects in the level.
	ChSharedPtr<ChAssetLevel> mlevelA(new ChAssetLevel);

				// ==Asset== Attach, in this level, a 'Wavefront mesh' asset, 
				// referencing a .obj file:
	ChSharedPtr<ChObjShapeFile> mobjmesh(new ChObjShapeFile);
	mobjmesh->SetFilename("../data/forklift_body.obj");
	mlevelA->AddAsset(mobjmesh);

				// ==Asset== Attach also a texture, that will affect only the 
				// assets in mlevelA:
	ChSharedPtr<ChTexture> mtexture(new ChTexture);
	mtexture->SetTextureFilename("../data/bluwhite.png");
	mlevelA->AddAsset(mtexture);
	
			// Change the position of mlevelA, thus moving also its sub-assets:
	mlevelA->GetFrame().SetPos(ChVector<>(0,0,2));
	mbody->AddAsset(mlevelA);

			// ==Asset== Attach sub level, then add to it an array of sub-levels, 
			// each rotated, and each containing a displaced box, thus making a 
			// spiral of cubes
	ChSharedPtr<ChAssetLevel> mlevelB(new ChAssetLevel);
	for (int j = 0; j<20; j++)
	{
				// ==Asset== the sub sub level..
		ChSharedPtr<ChAssetLevel> mlevelC(new ChAssetLevel);

					// ==Asset== the contained box..
		ChSharedPtr<ChBoxShape> msmallbox(new ChBoxShape);
		msmallbox->GetBoxGeometry().Pos = ChVector<>(0.4,0,0);
		msmallbox->GetBoxGeometry().Size = ChVector<>(0.1,0.1,0.01);
		mlevelC->AddAsset(msmallbox);

		ChQuaternion<> mrot;
		mrot.Q_from_AngAxis(j*21*CH_C_DEG_TO_RAD, ChVector<>(0,1,0));
		mlevelC->GetFrame().SetRot(mrot);
		mlevelC->GetFrame().SetPos(ChVector<>(0,j*0.02,0));

		mlevelB->AddAsset(mlevelC);
	}

	mbody->AddAsset(mlevelB);

			// ==Asset== Attach a video camera. This will be used by Irrlicht, 
			// or POVray postprocessing, etc. Note that a camera can also be 
			// put in a moving object.
	ChSharedPtr<ChCamera> mcamera(new ChCamera);
	mcamera->SetAngle(50);
	mcamera->SetPosition(ChVector<>(-3,4,-5));
	mcamera->SetAimPoint(ChVector<>(0,1,0));
	mbody->AddAsset(mcamera);

	/*
			//  ==Asset== IRRLICHT! Add a ChIrrNodeAsset so that Irrlicht will be able
			// to 'show' all the assets that we added to the body! 
			// OTHERWISE: use the application.AssetBind() function as at the end..
	ChSharedPtr<ChIrrNodeAsset> mirr_asset(new ChIrrNodeAsset);
	mirr_asset->Bind(mbody, application);
	mbody->AddAsset(mirr_asset);
	*/



	//
	// EXAMPLE 3: 
	//

	// Create a ChParticleClones cluster, and attach 'assets' 
	// that define a single "sample" 3D shape. This will be shown 
	// N times in Irrlicht.
	
			// Create the ChParticleClones, populate it with some random particles,
			// and add it to physical system:
	ChSharedPtr<ChParticlesClones> mparticles(new ChParticlesClones);

			// Note: coll. shape, if needed, must be specified before creating particles
	mparticles->GetCollisionModel()->ClearModel();
	mparticles->GetCollisionModel()->AddSphere(0.05);
	mparticles->GetCollisionModel()->BuildModel();
	mparticles->SetCollide(true);
		
			// Create the random particles 
	for (int np=0; np<100; ++np)
		mparticles->AddParticle(ChCoordsys<>(ChVector<>(ChRandom()-2,1.5,ChRandom()+2)));

			// Do not forget to add the particle cluster to the system:
	application.GetSystem()->Add(mparticles);

			//  ==Asset== Attach a 'sphere' shape asset.. it will be used as a sample 
			// shape to display all particles when rendering in 3D! 
	ChSharedPtr<ChSphereShape> mspherepart(new ChSphereShape);
	mspherepart->GetSphereGeometry().rad = 0.05;
	mparticles->AddAsset(mspherepart);

	/*
			//  ==Asset== IRRLICHT! Add a ChIrrNodeAsset so that Irrlicht will be able
			// to 'show' all the assets that we added to the body! 
			// OTHERWISE: use the application.AssetBind() function as at the end!
	ChSharedPtr<ChIrrNodeAsset> mirr_assetpart(new ChIrrNodeAsset);
	mirr_assetpart->Bind(mparticles, application);
	mparticles->AddAsset(mirr_assetpart);
	*/



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


			// ==IMPORTANT!== Use this function for adding a ChIrrNodeAsset to all items
			// in the system. These ChIrrNodeAsset assets are 'proxies' to the Irrlicht meshes.
			// If you need a finer control on which item really needs a visualization proxy in 
			// Irrlicht, just use application.AssetBind(myitem); on a per-item basis.

	application.AssetBindAll();

			// ==IMPORTANT!== Use this function for 'converting' into Irrlicht meshes the assets
			// that you added to the bodies into 3D shapes, they can be visualized by Irrlicht!

	application.AssetUpdateAll();


	// 
	// THE SOFT-REAL-TIME CYCLE
	//

	application.SetStepManage(true);
	application.SetTimestep(0.01);
	application.SetTryRealtime(true);

	while(application.GetDevice()->run()) 
	{
		application.BeginScene();

		application.DrawAll();
		
		application.DoStep();
			
		application.EndScene();  
	}
	
 
 
	// Remember this at the end of the program, if you started
	// with DLL_CreateGlobals();
	DLL_DeleteGlobals();

	return 0;
}
Пример #3
0
    // functions
    TestMech(ChSystemNSC* system,
             std::shared_ptr<ChBody> wheelBody,
             double binWidth = 1.0,
             double binLength = 2.0,
             double weightMass = 100.0,
             double springK = 25000,
             double springD = 100) {
        ChCollisionModel::SetDefaultSuggestedEnvelope(0.003);
        ChCollisionModel::SetDefaultSuggestedMargin(0.002);

        ChQuaternion<> rot;
        rot.Q_from_AngAxis(ChRandom() * CH_C_2PI, VECT_Y);

        // *******
        // Create a soil bin with planes. bin width = x-dir, bin length = z-dir
        // Note: soil bin depth will always be ~ 1m
        // *******
        double binHeight = 1.0;
        double wallWidth = std::min<double>(binWidth, binLength) / 10.0;  // wall width = 1/10 of min of bin dims

        // create the floor
        auto cubeMap = std::make_shared<ChTexture>();
        cubeMap->SetTextureFilename(GetChronoDataFile("concrete.jpg"));

        floor = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, wallWidth, binLength + wallWidth / 2.0, 1.0, true, true);
        floor->SetPos(ChVector<>(0, -0.5 - wallWidth / 2.0, 0));
        floor->SetBodyFixed(true);
        floor->GetMaterialSurfaceNSC()->SetFriction(0.5);
        floor->AddAsset(cubeMap);
        system->AddBody(floor);

        // add some transparent walls to the soilBin, w.r.t. width, length of bin
        wall1 = std::make_shared<ChBodyEasyBox>(wallWidth, binHeight, binLength, 1.0, true, true);
        wall1->SetPos(ChVector<>(-binWidth / 2.0 - wallWidth / 2.0, 0, 0));
        wall1->SetBodyFixed(true);
        system->AddBody(wall1);

        wall2 = std::make_shared<ChBodyEasyBox>(wallWidth, binHeight, binLength, 1.0, true, false);
        wall2->SetPos(ChVector<>(binWidth / 2.0 + wallWidth / 2.0, 0, 0));
        wall2->SetBodyFixed(true);
        system->AddBody(wall2);

        wall3 = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, binHeight, wallWidth, 1.0, true, false);
        wall3->SetPos(ChVector<>(0, 0, -binLength / 2.0 - wallWidth / 2.0));
        wall3->SetBodyFixed(true);
        system->AddBody(wall3);

        // wall 4
        wall4 = std::make_shared<ChBodyEasyBox>(binWidth + wallWidth / 2.0, binHeight, wallWidth, 1.0, true, true);
        wall4->SetPos(ChVector<>(0, 0, binLength / 2.0 + wallWidth / 2.0));
        wall4->SetBodyFixed(true);
        system->AddBody(wall4);

        // ******
        // make a truss, connect it to the wheel via revolute joint
        // single rotational DOF will be driven with a user-input for torque
        // *****
        auto bluMap = std::make_shared<ChTexture>();
        bluMap->SetTextureFilename(GetChronoDataFile("blu.png"));
        ChVector<> trussCM = wheelBody->GetPos();

        truss = std::make_shared<ChBodyEasyBox>(0.2, 0.2, 0.4, 300.0, false, true);
        truss->SetPos(trussCM);
        truss->SetMass(5.0);
        truss->AddAsset(bluMap);
        system->AddBody(truss);

        // create the revolute joint between the wheel and spindle
        spindle = std::make_shared<ChLinkLockRevolute>();
        spindle->Initialize(truss, wheelBody, ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y)));
        system->AddLink(spindle);

        // create a torque between the truss and wheel
        torqueDriver = std::make_shared<ChLinkEngine>();
        torqueDriver->Initialize(truss, wheelBody, ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_Y)));
        torqueDriver->Set_eng_mode(ChLinkEngine::ENG_MODE_TORQUE);
        system->AddLink(torqueDriver);

        // ******
        // create a body that will be used as a vehicle weight
        ChVector<> weightCM = ChVector<>(trussCM);
        weightCM.y() += 1.0;  // note: this will determine the spring free length

        suspweight = std::make_shared<ChBodyEasyBox>(0.2, 0.4, 0.2, 5000.0, false, true);
        suspweight->SetPos(weightCM);
        suspweight->SetMass(weightMass);
        suspweight->AddAsset(bluMap);
        system->AddBody(suspweight);

        // create the translational joint between the truss and weight load
        auto translational = std::make_shared<ChLinkLockPrismatic>();
        translational->Initialize(truss, suspweight,
                                  ChCoordsys<>(trussCM, chrono::Q_from_AngAxis(CH_C_PI / 2, VECT_X)));
        system->AddLink(translational);

        // create a spring between spindle truss and weight
        spring = std::make_shared<ChLinkSpring>();
        spring->Initialize(truss, suspweight, false, trussCM, suspweight->GetPos());
        spring->Set_SpringK(springK);
        spring->Set_SpringR(springD);
        system->AddLink(spring);

        // create a prismatic constraint between the weight and the ground
        auto weightLink = std::make_shared<ChLinkLockOldham>();
        weightLink->Initialize(suspweight, floor,
                               ChCoordsys<>(weightCM, chrono::Q_from_AngAxis(CH_C_PI / 2.0, VECT_Y)));
        system->AddLink(weightLink);
    }