ChronoEngine:Demo bricks

From ChronoWiki

(Redirected from Demo bricks)
Jump to: navigation, search

Another tutorial about collisions. Create a stack of geometric primitives. Bodies are Irrlicht nodes of the special class ChBodySceneNode, which encapsulates ChBody items).

void create_some_falling_items(ChSystem& mphysicalSystem, ISceneManager* msceneManager, IVideoDriver* driver)
{

	ChBodySceneNode* mrigidBody;

	video::ITexture* cubeMap = driver->getTexture("../data/cubetexture.png");

	for (int ai = 0; ai < 1; ai++)  // N. of walls
	{
		for (int bi = 0; bi < 10; bi++)  // N. of vert. bricks
		{
			for (int ui = 0; ui < 15; ui++)  // N. of hor. bricks
			{
				mrigidBody = (ChBodySceneNode*)addChBodySceneNode_easyBox(
													&mphysicalSystem, msceneManager,
													0.8,
													ChVector<>(-8+ui*4.0+2*(bi%2),  1.0+bi*2.0, ai*6),
													ChQuaternion<>(1,0,0,0),
													ChVector<>(3.96,2,4) );
				mrigidBody->GetBody()->SetFriction(0.4f);
				mrigidBody->setMaterialTexture(0,	cubeMap);
			}
		}
	}


	// Create the floor using
	// fixed rigid body of 'box' type:

	mrigidBody = (ChBodySceneNode*)addChBodySceneNode_easyBox(
											&mphysicalSystem, msceneManager,
											1.0,
											ChVector<>(0,-2,0),
											ChQuaternion<>(1,0,0,0),
											ChVector<>(550,4,550) );
	mrigidBody->GetBody()->SetBodyFixed(true);
	mrigidBody->GetBody()->SetFriction(0.4f);

Create a ball that will collide with the wall. Then set its mass, inertia, friction and initial speed.

double mradius = 3;
	double density = 1;
	double mmass = (4./3.)*CH_C_PI*pow(mradius,3)*density;
	double minert = (2./5.)* mmass * pow(mradius,2);

	mrigidBody = (ChBodySceneNode*)addChBodySceneNode_easySphere(
										&mphysicalSystem, msceneManager,
										mmass, // mass
										ChVector<>(0, 3, -8), // pos
										mradius, // radius
										20,  // hslices, for rendering
										15); // vslices, for rendering

	// set moment of inertia (more realisic than default 1,1,1).
	mrigidBody->GetBody()->SetInertiaXX(ChVector<>(minert,minert,minert));
	mrigidBody->GetBody()->SetPos_dt(ChVector<>(0,0,16));
	mrigidBody->GetBody()->SetFriction(0.4f);

	// Some aesthetics for 3d view..
	mrigidBody->addShadowVolumeSceneNode();
	//mrigidBody->setMaterialTexture(0,	sphereMap);

}

Create the main program, with usual Irrlicht visualization:

int main(int argc, char* argv[])
{
	DLL_CreateGlobals();

	// Create a ChronoENGINE physical system
	ChSystem mphysicalSystem;

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


	// Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene:
	ChIrrWizard::add_typical_Logo  (application.GetDevice());
	ChIrrWizard::add_typical_Sky   (application.GetDevice());
	ChIrrWizard::add_typical_Lights(application.GetDevice(), core::vector3df(30.f, 200.f,  90.f), core::vector3df(30.f, 80.f, -60.f), 590,  400);
	ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(-15,14,-30), core::vector3df(0,5,0));



	//
	// HERE YOU CREATE THE MECHANICAL SYSTEM OF CHRONO...
	//


	// Create all the rigid bodies.
	create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver());

Switch the solver to the LCP_ITERATIVE_SOR_MULTITHREAD, that can exploit multicore processors. It has a good speed/precision tradeoff.

mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR_MULTITHREAD);

If you turn on the sleeping algorithm, objects that do not move for a while can enter a 'sleep' state, to save CPU computational power. Note: The feature is still experimental.

mphysicalSystem.SetUseSleeping(false);

Note: you can increase the max.iteration number of the solver. This is strictly related to precision. The lower the number of iterations, the faster the simulation, but the lower the precision. This is expecially visile in simulations of stacked objects, like this, where low precision ends in bricks slowly 'sinking' inside each other, or bouncing unnaturally. So, if this happens, increase the iteration number:

mphysicalSystem.SetMaxPenetrationRecoverySpeed(1.6); // used by Anitescu stepper only
	mphysicalSystem.SetIterLCPmaxItersSpeed(40);
	mphysicalSystem.SetIterLCPmaxItersStab(20); // unuseful for Anitescu, only Tasora uses this

Note that 'warm starting' for the solver can be turned on to increase precision without having to increase too much the iteration count; however this is a trick that sometimes gives artifacts (diverging solution) and should be used carefully.

mphysicalSystem.SetIterLCPwarmStarting(true);

Perform the simulation with the usual while() cycle:

while(application.GetDevice()->run())
	{
		application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));

		application.DrawAll();

		mphysicalSystem.DoStepDynamics( 0.01);

		application.GetVideoDriver()->endScene();
	}



	return 0;
}
Personal tools