示例#1
0
int main(int argc, char* argv[])
{
	// Create a ChronoENGINE physical system
	ChSystem mphysicalSystem;

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


	// 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());
	ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(0,1.5,-3));

 
	// Create all the rigid bodies.

	create_items(application);
 

	class MyContactCallback : public ChSystem::ChCustomCollisionPointCallback
	{
		public:	virtual void ContactCallback(
								const collision::ChCollisionInfo& mcontactinfo, ///< get info about contact (cannot change it)				
								ChMaterialCouple&  material )			  		///< you can modify this!	
		{
			// Set compliance (normal and tangential at once)
			material.compliance  = STATIC_COMPLIANCE; 
			material.complianceT = material.compliance ;
			material.dampingf = 0.2f;
		};
		ChSystem* msystem;
	};

	MyContactCallback mycontact_callback;  // create the callback object
	mycontact_callback.msystem = &mphysicalSystem; // will be used by callback
	// Tell the system to use the callback above, per each created contact!
	mphysicalSystem.SetCustomCollisionPointCallback(&mycontact_callback);
 

	// Use this function for adding a ChIrrNodeAsset to all already created items (ex. a floor, a wall, etc.)
	// Otherwise use application.AssetBind(myitem); on a per-item basis.
	application.AssetBindAll();
	application.AssetUpdateAll();

	
	// Modify some setting of the physical system for the simulation, if you want

	mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_BARZILAIBORWEIN);
	//mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
	mphysicalSystem.SetIterLCPmaxItersSpeed(60);
	mphysicalSystem.SetIterLCPmaxItersStab(5);
	mphysicalSystem.SetParallelThreadNumber(1);

	//mphysicalSystem.SetUseSleeping(true);

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

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

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

		application.DrawAll();
		
		align_spheres(application); // just to simplify test, on y axis only

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

	return 0;
}
示例#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 ChronoENGINE physical system
	ChSystem mphysicalSystem; 

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

 
	// 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(70.f, 120.f, -90.f), core::vector3df(30.f, 80.f, 60.f), 290,  190);
	ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(-15,14,-30), core::vector3df(0,5,0)); 

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

 
	// Create all the rigid bodies.
    create_wall_bodies (mphysicalSystem);
	//create_jengatower_bodies (mphysicalSystem);


	// Use this function for adding a ChIrrNodeAsset to all items
	// 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();

	// Use this function for 'converting' into Irrlicht meshes the assets 
	// into Irrlicht-visualizable meshes
	application.AssetUpdateAll();


  
	// Prepare the physical system for the simulation 

	mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR_MULTITHREAD);

	mphysicalSystem.SetUseSleeping(false);

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

	//
	// THE SOFT-REAL-TIME CYCLE
	//
 
	application.SetStepManage(true);
	application.SetTimestep(0.02);

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

		ChIrrTools::drawGrid(application.GetVideoDriver(), 5,5, 20,20, 
			ChCoordsys<>(ChVector<>(0,0.2,0),Q_from_AngAxis(CH_C_PI/2,VECT_X)), video::SColor(50,90,90,150),true);

		application.DrawAll();

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

 	// Remember this at the end of the program, if you started
	// with DLL_CreateGlobals();
	DLL_DeleteGlobals();

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

	ChSystem * system = new ChSystem();
	system->SetMaxiter(100);
	system->SetIterLCPmaxItersSpeed(100);
	system->SetTol(0);
	system->SetTolSpeeds(0);

	ChLcpSystemDescriptor *mdescriptor = new ChLcpSystemDescriptor();
	ChContactContainer *mcontactcontainer = new ChContactContainer();
	//ChCollisionSystemBulletGPU *mcollisionengine = new ChCollisionSystemBulletGPU();
	ChCollisionSystemBullet *mcollisionengine = new ChCollisionSystemBullet();
	system->ChangeLcpSystemDescriptor(mdescriptor);
	system->ChangeContactContainer(mcontactcontainer);
	system->ChangeCollisionSystem(mcollisionengine);
	system->SetIntegrationType(ChSystem::INT_ANITESCU);
	system->SetLcpSolverType(ChSystem::LCP_ITERATIVE_APGD);
	system->SetStep(timestep);
	system->Set_G_acc(ChVector<>(0, gravity, 0));

	ChSharedBodyPtr floor(new ChBody);

	ChSharedBodyPtr chassis(new ChBody);

	ChSharedBodyPtr axle_F(new ChBody);
	ChSharedBodyPtr axle_C(new ChBody);
	ChSharedBodyPtr axle_R(new ChBody);

	ChSharedBodyPtr leg_FR(new ChBody);
	ChSharedBodyPtr leg_FL(new ChBody);
	ChSharedBodyPtr leg_CR(new ChBody);
	ChSharedBodyPtr leg_CL(new ChBody);
	ChSharedBodyPtr leg_RR(new ChBody);
	ChSharedBodyPtr leg_RL(new ChBody);

	InitObject(floor, 1.0, ChVector<>(0, -3.5, 0), Quaternion(1, 0, 0, 0), 1, 1, 0, true, true, -20, -20);
	InitObject(chassis, 1, ChVector<>(0, 0, 0), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 0, 1);
	InitObject(axle_F, 1, ChVector<>(0, 0, chassisL / 2), Q_from_AngZ(CH_C_PI / 2.0), 1, 1, 0, false, false, -2, -2);
	InitObject(axle_C, 1, ChVector<>(0, 0, 0), Q_from_AngZ(CH_C_PI / 2.0), 1, 1, 0, false, false, -2, -2);
	InitObject(axle_R, 1, ChVector<>(0, 0, -chassisL / 2), Q_from_AngZ(CH_C_PI / 2.0), 1, 1, 0, false, false, -2, -2);
	InitObject(leg_FR, 1, ChVector<>((axleL + legW) / 2.0, -legL / 2.0, chassisL / 2), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);
	InitObject(leg_FL, 1, ChVector<>(-(axleL + legW) / 2.0, legL / 2.0, chassisL / 2), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);
	InitObject(leg_CR, 1, ChVector<>(-(axleL + legW) / 2.0, -legL / 2.0, 0), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);
	InitObject(leg_CL, 1, ChVector<>((axleL + legW) / 2.0, legL / 2.0, 0), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);
	InitObject(leg_RR, 1, ChVector<>((axleL + legW) / 2.0, -legL / 2.0, -chassisL / 2), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);
	InitObject(leg_RL, 1, ChVector<>(-(axleL + legW) / 2.0, legL / 2.0, -chassisL / 2), Quaternion(1, 0, 0, 0), 1, 1, 0, true, false, 2, 2);

	AddCollisionGeometry(floor, BOX, ChVector<>(10, 1 / 2.0, 10), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(chassis, ELLIPSOID, ChVector<>(1, 1, 1), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(axle_F, ELLIPSOID, ChVector<>(0.5 / 2.0, axleL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(axle_C, ELLIPSOID, ChVector<>(0.5 / 2.0, axleL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(axle_R, ELLIPSOID, ChVector<>(0.5 / 2.0, axleL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_FR, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_FL, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_CR, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_CL, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_RR, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));
	AddCollisionGeometry(leg_RL, ELLIPSOID, ChVector<>(legW / 2.0, legL / 2.0, 0.5 / 2.0), Vector(0, 0, 0), Quaternion(1, 0, 0, 0));

	floor->SetInertiaXX(Vector(1,1,1));
	chassis->SetInertiaXX(Vector(1,1,1));
	axle_F->SetInertiaXX(Vector(1,1,1));
	axle_C->SetInertiaXX(Vector(1,1,1));
	axle_R->SetInertiaXX(Vector(1,1,1));
	leg_FR->SetInertiaXX(Vector(1,1,1));
	leg_FL->SetInertiaXX(Vector(1,1,1));
	leg_CR->SetInertiaXX(Vector(1,1,1));
	leg_CL->SetInertiaXX(Vector(1,1,1));
	leg_RR->SetInertiaXX(Vector(1,1,1));
	leg_RL->SetInertiaXX(Vector(1,1,1));

	FinalizeObject(floor, (ChSystem *) system);
	FinalizeObject(chassis, (ChSystem *) system);
	FinalizeObject(axle_F, (ChSystem *) system);
	FinalizeObject(axle_C, (ChSystem *) system);
	FinalizeObject(axle_R, (ChSystem *) system);
	FinalizeObject(leg_FR, (ChSystem *) system);
	FinalizeObject(leg_FL, (ChSystem *) system);
	FinalizeObject(leg_CR, (ChSystem *) system);
	FinalizeObject(leg_CL, (ChSystem *) system);
	FinalizeObject(leg_RR, (ChSystem *) system);
	FinalizeObject(leg_RL, (ChSystem *) system);

	ChSharedBodyPtr chassis_ptr = ChSharedBodyPtr(chassis);
	ChSharedBodyPtr axle_F_ptr = ChSharedBodyPtr(axle_F);
	ChSharedBodyPtr axle_C_ptr = ChSharedBodyPtr(axle_C);
	ChSharedBodyPtr axle_R_ptr = ChSharedBodyPtr(axle_R);
	ChSharedBodyPtr leg_FR_ptr = ChSharedBodyPtr(leg_FR);
	ChSharedBodyPtr leg_FL_ptr = ChSharedBodyPtr(leg_FL);
	ChSharedBodyPtr leg_CR_ptr = ChSharedBodyPtr(leg_CR);
	ChSharedBodyPtr leg_CL_ptr = ChSharedBodyPtr(leg_CL);
	ChSharedBodyPtr leg_RR_ptr = ChSharedBodyPtr(leg_RR);
	ChSharedBodyPtr leg_RL_ptr = ChSharedBodyPtr(leg_RL);

//	ChSharedPtr<ChLinkLockLock> axle_FR(new ChLinkLockLock);
//	axle_FR->Initialize(leg_FR_ptr, axle_F_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_FR);
////
//	ChSharedPtr<ChLinkLockLock> axle_FL(new ChLinkLockLock);
//	axle_FL->Initialize(leg_FL_ptr, axle_F_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_FL);
//
//	ChSharedPtr<ChLinkLockLock> axle_CR(new ChLinkLockLock);
//	axle_CR->Initialize(leg_CR_ptr, axle_C_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_CR);
//
//	ChSharedPtr<ChLinkLockLock> axle_CL(new ChLinkLockLock);
//	axle_CL->Initialize(leg_CL_ptr, axle_C_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_CL);
//
//	ChSharedPtr<ChLinkLockLock> axle_RR(new ChLinkLockLock);
//	axle_RR->Initialize(leg_RR_ptr, axle_R_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_RR);
//
//	ChSharedPtr<ChLinkLockLock> axle_RL(new ChLinkLockLock);
//	axle_RL->Initialize(leg_RL_ptr, axle_R_ptr, ChCoordsys<>(VNULL));
//	system->AddLink(axle_RL);

	// Create engine between axles and chassis
	GetLog() << "Creating Motors\n";

//	ChSharedPtr<ChLinkEngine> eng_F(new ChLinkEngine);
//	eng_F->Initialize(axle_F_ptr, chassis_ptr, ChCoordsys<>(ChVector<>(0, 0, chassisL / 2), Q_from_AngY(CH_C_PI / 2)));
//	eng_F->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); // also works as revolute support
//	eng_F->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED);
//	if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(eng_F->Get_spe_funct()))
//		mfun->Set_yconst(1); // rad/s  angular speed
//	system->AddLink(eng_F);

	ChSharedPtr<ChLinkEngine> eng_C(new ChLinkEngine);
	eng_C->Initialize(axle_C_ptr, chassis_ptr, ChCoordsys<>(ChVector<>(0, 0, 0), Q_from_AngY(CH_C_PI / 2)));
	eng_C->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); // also works as revolute support
	eng_C->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED);
	if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(eng_C->Get_spe_funct()))
		mfun->Set_yconst(1); // rad/s  angular speed
	system->AddLink(eng_C);

//	ChSharedPtr<ChLinkEngine> eng_R(new ChLinkEngine);
//	eng_R->Initialize(axle_R_ptr, chassis_ptr, ChCoordsys<>(ChVector<>(0, 0, -chassisL / 2), Q_from_AngY(CH_C_PI / 2)));
//	eng_R->Set_shaft_mode(ChLinkEngine::ENG_SHAFT_LOCK); // also works as revolute support
//	eng_R->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED);
//	if (ChFunction_Const* mfun = dynamic_cast<ChFunction_Const*>(eng_R->Get_spe_funct()))
//		mfun->Set_yconst(1); // rad/s  angular speed
//	system->AddLink(eng_R);

	system->DoStepDynamics(timestep);
	system->DoStepDynamics(timestep);

	exit(0);

	ChOpenGLManager * window_manager = new ChOpenGLManager();
	ChOpenGL openGLView(window_manager, system, 800, 600, 0, 0, "Test_Solvers");
	openGLView.render_camera->camera_position = glm::vec3(0, -5, -10);
	openGLView.render_camera->camera_look_at = glm::vec3(0, -5, 0);
	openGLView.render_camera->camera_scale = .5;
	openGLView.SetCustomCallback(RunTimeStep);
	openGLView.StartSpinning(window_manager);
	window_manager->CallGlutMainLoop();

	DLL_DeleteGlobals();

	return 0;
}
示例#4
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 ChronoENGINE physical system
	ChSystem mphysicalSystem;

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

 
	// Easy shortcuts to add logo, camera, lights and sky in Irrlicht scene:
	ChIrrWizard::add_typical_Lights(application.GetDevice());
	ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(0,14,-40));



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

 
	application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
	application.GetVideoDriver()->endScene(); 
	GetLog() << "  ** PLEASE WAIT FOR INITIALIZATION! \n  ** This may take seconds or minutes..\n\n";

    
	// Prepare the physical system for the simulation
 
	mphysicalSystem.SetIntegrationType(ChSystem::INT_ANITESCU); 
	//mphysicalSystem.SetIntegrationType(ChSystem::INT_TASORA); 

	//mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SYMMSOR); // here would be the better choiche since the wall is build ground up.
	//mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
	//mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_JACOBI); 
	//mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR_MULTITHREAD); 
	//mphysicalSystem.SetParallelThreadNumber(4);

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


	// Test convergence for varying omega 
	//
	// (solver:SOR)
	//
	if (false)
	{
		ChStreamOutAsciiFile data_err_SOR_Niter("data_err_SOR_Niter.dat");
		ChStreamOutAsciiFile data_dgamma_SOR_Niter("data_dgamma_SOR_Niter.dat");
		int plotframe = 500;
		int ntestspheres = 220;

		mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
		mphysicalSystem.SetIterLCPmaxItersSpeed(80);
		mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 

		ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
		msolver->SetRecordViolation(true);

		for (double momega = 0.2; (momega <= 1.401 && application.GetDevice()->run()); momega +=0.2)
		{
			ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

			mphysicalSystem.SetIterLCPomega(0.8);
			mphysicalSystem.SetIterLCPsharpnessLambda(1.0);
			mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0);

				// create spheres and walls, and insert into that scene node
			ChSetRandomSeed(123);
			create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, ntestspheres, 1.6, 10); 

			int totframes = 0;
										// ------- begin simulation loop -----
			while(application.GetDevice()->run())
			{
				totframes++;

				application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
				application.DrawAll();

				if (totframes==plotframe)
				{
					mphysicalSystem.SetIterLCPomega(momega);
					mphysicalSystem.SetIterLCPsharpnessLambda(0.7);
					mphysicalSystem.SetMaxPenetrationRecoverySpeed(0.0);
				}

				// integrate
				mphysicalSystem.DoStepDynamics(0.01);

				application.GetVideoDriver()->endScene(); 

				//***PLOT***
				if (totframes==plotframe)
				{
					GetLog()<< "Saving data\n";
					ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
					for (int k=0; k< msolver->GetViolationHistory().size(); k++)
					{
						data_err_SOR_Niter <<  msolver->GetViolationHistory()[k] << " ";
					}
					for (int j=0; j< msolver->GetDeltalambdaHistory().size(); j++)
					{
						data_dgamma_SOR_Niter <<  msolver->GetDeltalambdaHistory()[j] << " ";
					}
				}


				

				if(totframes>plotframe) break;

			}							// ------- end of simulation loop -----

			GetLog()<< "  num contacts " << mphysicalSystem.GetNcontacts() << "\n";
			
			data_err_SOR_Niter << "\n";
			data_dgamma_SOR_Niter << "\n";

			// remove the root scene node (contains walls & spheres but no camera no lights)
			// to reset and prepare for new scene at next for() loop.
			parent->remove();

			// Now the system should already have no bodies, because of full removal from Irrlicht scene.
			// Then, the following clearing should be unuseful...(do it anyway..)
			mphysicalSystem.Clear(); 
		}

	} // end test



	// Test convergence for varying omega 
	//
	// (solver:JACOBI)
	//
	if (false)
	{
		ChStreamOutAsciiFile data_err_JACOBI_Niter("data_err_JACOBI_Niter_L10_at500_ok.dat");
		ChStreamOutAsciiFile data_dgamma_JACOBI_Niter("data_dgamma_JACOBI_Niter_L10_at500_ok.dat");
		int plotframe = 500;
		int ntestspheres = 220;

		mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
		mphysicalSystem.SetIterLCPomega(0.8);
		mphysicalSystem.SetIterLCPmaxItersSpeed(80);
		mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 

		ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
		msolver->SetRecordViolation(true);

		for (double momega = 0.1; (momega <= 0.71 && application.GetDevice()->run()); momega +=0.1)
		{
			ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

			mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
			mphysicalSystem.SetIterLCPomega(0.8);
			mphysicalSystem.SetIterLCPmaxItersSpeed(80);
			mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 
			mphysicalSystem.SetIterLCPsharpnessLambda(1.0);

				// create spheres and walls, and insert into that scene node
			ChSetRandomSeed(123);
			create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, ntestspheres, 1.6, 10); 

			int totframes = 0;
										// ------- begin simulation loop -----
			while(application.GetDevice()->run())
			{
				totframes++;

				application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
				application.DrawAll();

				if (totframes==plotframe)
				{
					mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_JACOBI);
					ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
					msolver->SetRecordViolation(true);
					mphysicalSystem.SetIterLCPomega(momega);
					mphysicalSystem.SetIterLCPsharpnessLambda(1.0);
					mphysicalSystem.SetMaxPenetrationRecoverySpeed(0.0);
				}

				// integrate
				mphysicalSystem.DoStepDynamics(0.01);

				application.GetVideoDriver()->endScene(); 

				//***PLOT***
				if (totframes==plotframe)
				{
					GetLog()<< "Saving data\n";
					ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
					for (int k=0; k< msolver->GetViolationHistory().size(); k++)
					{
						data_err_JACOBI_Niter <<  msolver->GetViolationHistory()[k] << " ";
					}
					for (int j=0; j< msolver->GetDeltalambdaHistory().size(); j++)
					{
						data_dgamma_JACOBI_Niter <<  msolver->GetDeltalambdaHistory()[j] << " ";
					}
				}

				if(totframes>plotframe) break;

			}							// ------- end of simulation loop -----

			GetLog()<< "  num contacts " << mphysicalSystem.GetNcontacts() << "\n";
			
			data_err_JACOBI_Niter << "\n";
			data_dgamma_JACOBI_Niter << "\n";

			// remove the root scene node (contains walls & spheres but no camera no lights)
			// to reset and prepare for new scene at next for() loop.
			parent->remove();

			// Now the system should already have no bodies, because of full removal from Irrlicht scene.
			// Then, the following clearing should be unuseful...(do it anyway..)
			mphysicalSystem.Clear(); 
		}

	} // end test



	// Test lambda effect
	//
	// Velocity error  vs.  Num. velocity iterations  vs. Lambda
	// (solver:SOR)
	//
	if (false)
	{
		ChStreamOutAsciiFile data_err_SOR_Niter("data_err_SOR_Niter_om1.dat");
		ChStreamOutAsciiFile data_dgamma_SOR_Niter("data_dgamma_SOR_Niter_om1.dat");
		int plotframe = 500;
		int ntestspheres = 220;

		mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
		mphysicalSystem.SetIterLCPmaxItersSpeed(80);
		mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 

		ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
		msolver->SetRecordViolation(true);

		for (double mlambda = 0.2; (mlambda <= 1.01 && application.GetDevice()->run()); mlambda +=0.2)
		{
			ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

			mphysicalSystem.SetIterLCPomega(0.8);
			mphysicalSystem.SetIterLCPsharpnessLambda(1.0);
			mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0);

				// create spheres and walls, and insert into that scene node
			ChSetRandomSeed(123);
			create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, ntestspheres, 1.6, 10); 

			int totframes = 0;
										// ------- begin simulation loop -----
			while(application.GetDevice()->run())
			{
				totframes++;

				application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
				application.DrawAll();

				if (totframes==plotframe)
				{
					mphysicalSystem.SetIterLCPomega(1.0);
					mphysicalSystem.SetIterLCPsharpnessLambda(mlambda);
					mphysicalSystem.SetMaxPenetrationRecoverySpeed(0.0);
				}

				// integrate
				mphysicalSystem.DoStepDynamics(0.01);

				application.GetVideoDriver()->endScene(); 

				//***PLOT***
				if (totframes==plotframe)
				{
					GetLog()<< "Saving data\n";
					ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
					for (int k=0; k< msolver->GetViolationHistory().size(); k++)
					{
						data_err_SOR_Niter <<  msolver->GetViolationHistory()[k] << " ";
					}
					for (int j=0; j< msolver->GetDeltalambdaHistory().size(); j++)
					{
						data_dgamma_SOR_Niter <<  msolver->GetDeltalambdaHistory()[j] << " ";
					}
				}


				

				if(totframes>plotframe) break;

			}							// ------- end of simulation loop -----

			GetLog()<< "  num contacts " << mphysicalSystem.GetNcontacts() << "\n";
			
			data_err_SOR_Niter << "\n";
			data_dgamma_SOR_Niter << "\n";

			// remove the root scene node (contains walls & spheres but no camera no lights)
			// to reset and prepare for new scene at next for() loop.
			parent->remove();

			// Now the system should already have no bodies, because of full removal from Irrlicht scene.
			// Then, the following clearing should be unuseful...(do it anyway..)
			mphysicalSystem.Clear(); 
		}

	} // end test



	// Test stack aspect ratio
	//
	//
	if (false)
	{
		ChStreamOutAsciiFile data_err_SOR_Niter("data_err_aspectratio3.dat");
		int plotframe = 500;
		int ntestspheres = 220;

		mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
		mphysicalSystem.SetIterLCPmaxItersSpeed(30);
		mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 

		ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
		msolver->SetRecordViolation(true);

		for (double mspheres=10; (mspheres <= 330 && application.GetDevice()->run()); mspheres +=40)
		{
			for (int nviters = 20; (nviters <= 101 && application.GetDevice()->run()); nviters +=20)
			{
				ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

				mphysicalSystem.SetIterLCPomega(0.9);
				mphysicalSystem.SetIterLCPsharpnessLambda(1.0);
				mphysicalSystem.SetIterLCPmaxItersSpeed(30);
				mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0);
				
					// create spheres and walls, and insert into that scene node
				ChSetRandomSeed(13);
				create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, mspheres, 1.6, 10,20.1); 

				int totframes = 0;
											// ------- begin simulation loop -----
				while(application.GetDevice()->run())
				{
					totframes++;

					application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
					application.DrawAll();

					if (totframes==plotframe)
					{
						mphysicalSystem.SetIterLCPomega(0.9);
						mphysicalSystem.SetIterLCPmaxItersSpeed(nviters);
						mphysicalSystem.SetMaxPenetrationRecoverySpeed(0.0);
					}

					application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
					application.DrawAll();

					// integrate
					mphysicalSystem.DoStepDynamics(0.01);

					application.GetVideoDriver()->endScene(); 

					//***PLOT***
					if (totframes==plotframe)
					{
						GetLog()<< "Saving data\n";
						ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
						data_err_SOR_Niter <<  msolver->GetViolationHistory()[msolver->GetViolationHistory().size()-1] << " ";
					}

					if(totframes>plotframe) break;

				}							// ------- end of simulation loop -----

				
				// remove the root scene node (contains walls & spheres but no camera no lights)
				// to reset and prepare for new scene at next for() loop.
				parent->remove();

				// Now the system should already have no bodies, because of full removal from Irrlicht scene.
				// Then, the following clearing should be unuseful...(do it anyway..)
				mphysicalSystem.Clear(); 
			}

			data_err_SOR_Niter << "\n";
		}

	} // end test




	// Test pos error
	//
	//
	if (false)
	{
		ChStreamOutAsciiFile data_err_pos("data_err_pos.dat");
		int plotframe = 500;
		int ntestspheres = 120;
		double mystep= 0;

		for (double mdt=0.01; (mdt>0.00015 && application.GetDevice()->run()); mdt*=0.5)
		{
			GetLog() << "\n\nDT = " << mdt << "\n";

			for (int nviters = 20; (nviters <= 81 && application.GetDevice()->run()); nviters +=20)
			{
				GetLog() << "  nviters = " << nviters << "\n";

				ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

				mystep = 0.01;
				mphysicalSystem.SetChTime(0.0);
				mphysicalSystem.SetIterLCPsharpnessLambda(0.8);
				mphysicalSystem.SetIterLCPomega(0.8);
				mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
				mphysicalSystem.SetIterLCPmaxItersSpeed(30);
				mphysicalSystem.SetMaxPenetrationRecoverySpeed(2.0); 
				
					// create spheres and walls, and insert into that scene node
				ChSetRandomSeed(13);
				create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, ntestspheres, 1.6, 10); 

				int totframes = 0;
				int averagecnt = 0;
				double average = 0;
											// ------- begin simulation loop -----
				while(application.GetDevice()->run())
				{
					totframes++;

					application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
					application.DrawAll();

					// start mode
					if (mphysicalSystem.GetChTime()>2.4)
					{	
						mphysicalSystem.SetIterLCPmaxItersSpeed(nviters);
						mystep=mdt;
					}

					//start average
					if (mphysicalSystem.GetChTime()>2.6)
					{	

						class _label_reporter_class : public chrono::ChReportContactCallback 
						{
						public:
							virtual bool ReportContactCallback (
											const chrono::ChVector<>& pA,				
											const chrono::ChVector<>& pB,				
											const chrono::ChMatrix33<>& plane_coord,	
											const double& distance,				
											const float& mfriction,			  	
											const chrono::ChVector<>& react_forces,		
											const chrono::ChVector<>& react_torques,	
											chrono::collision::ChCollisionModel* modA,	
											chrono::collision::ChCollisionModel* modB) 
							{
								if (distance<maxpen)
									maxpen = distance;
								return true; // to continue scanning contacts
							}
							// Data 
							double maxpen;
						};

						_label_reporter_class my_label_rep;

						my_label_rep.maxpen = 0;

						// scan all contacts
						mphysicalSystem.GetContactContainer()->ReportAllContacts(&my_label_rep);
						//GetLog() << "        p: " << my_label_rep.maxpen << "\n";
						averagecnt++;
						average += my_label_rep.maxpen;
					}

					// stop average & loop
					if(mphysicalSystem.GetChTime()>2.8)
					{
						average /= (double)averagecnt;
						GetLog() << "     avg.err: " << average << "\n";
						data_err_pos <<  average << " ";
						break;
					}

					// integrate
					mphysicalSystem.DoStepDynamics(mystep);

					application.GetVideoDriver()->endScene(); 

				}							// ------- end of simulation loop -----

				
				// remove the root scene node (contains walls & spheres but no camera no lights)
				// to reset and prepare for new scene at next for() loop.
				parent->remove();

				// Now the system should already have no bodies, because of full removal from Irrlicht scene.
				// Then, the following clearing should be unuseful...(do it anyway..)
				mphysicalSystem.Clear(); 
			}

			data_err_pos << "\n";
		}

	} // end test



	// Test pos error with Tasora stabilization
	//
	//
	if (true)
	{
		ChStreamOutAsciiFile data_err_pos("data_err_tasora.dat");
		int ntestspheres = 120;

		for (int npiters = 20; (npiters <= 81 && application.GetDevice()->run()); npiters +=20)
		{
			GetLog() << "  npiters = " << npiters << "\n";

			for (int nviters = 20; (nviters <= 81 && application.GetDevice()->run()); nviters +=20)
			{
				GetLog() << "  nviters = " << nviters << "\n";

				ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

				mphysicalSystem.SetChTime(0.0);
				mphysicalSystem.SetIterLCPsharpnessLambda(0.8);
				mphysicalSystem.SetIterLCPomega(0.8);
				mphysicalSystem.SetLcpSolverType(ChSystem::LCP_ITERATIVE_SOR);
				mphysicalSystem.SetIntegrationType(ChSystem::INT_TASORA);
				mphysicalSystem.SetIterLCPmaxItersSpeed(30);
				mphysicalSystem.SetIterLCPmaxItersStab(30);
				mphysicalSystem.SetMaxPenetrationRecoverySpeed(0.0); 
				
					// create spheres and walls, and insert into that scene node
				ChSetRandomSeed(13);
				create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, ntestspheres, 1.6, 10); 

				int totframes = 0;
				int averagecnt = 0;
				double average = 0;
											// ------- begin simulation loop -----
				while(application.GetDevice()->run())
				{
					totframes++;

					application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
					application.DrawAll();

					// start mode
					if (mphysicalSystem.GetChTime()>3)
					{	
						mphysicalSystem.SetIterLCPmaxItersSpeed(nviters);
						mphysicalSystem.SetIterLCPmaxItersStab(npiters);
					}

					//start average
					if (mphysicalSystem.GetChTime()>4.2)
					{	

						class _label_reporter_class : public chrono::ChReportContactCallback 
						{
						public:
							virtual bool ReportContactCallback (
											const chrono::ChVector<>& pA,				
											const chrono::ChVector<>& pB,				
											const chrono::ChMatrix33<>& plane_coord,	
											const double& distance,				
											const float& mfriction,			  	
											const chrono::ChVector<>& react_forces,		
											const chrono::ChVector<>& react_torques,	
											chrono::collision::ChCollisionModel* modA,	
											chrono::collision::ChCollisionModel* modB) 
							{
								if (distance<maxpen)
									maxpen = distance;
								return true; // to continue scanning contacts
							}
							// Data 
							double maxpen;
						};

						_label_reporter_class my_label_rep;

						my_label_rep.maxpen = 0;

						// scan all contacts
						mphysicalSystem.GetContactContainer()->ReportAllContacts(&my_label_rep);
						averagecnt++;
						average += my_label_rep.maxpen;
					}

					// stop average & loop
					if(mphysicalSystem.GetChTime()>4.5)
					{
						average /= (double)averagecnt;
						GetLog() << "     avg.err: " << average << "\n";
						data_err_pos <<  average << " ";
						break;
					}

					// integrate
					mphysicalSystem.DoStepDynamics(0.01);

					application.GetVideoDriver()->endScene(); 

				}							// ------- end of simulation loop -----

				
				// remove the root scene node (contains walls & spheres but no camera no lights)
				// to reset and prepare for new scene at next for() loop.
				parent->remove();

				// Now the system should already have no bodies, because of full removal from Irrlicht scene.
				// Then, the following clearing should be unuseful...(do it anyway..)
				mphysicalSystem.Clear(); 
			}

			data_err_pos << "\n";
		}

	} // end test



	getchar();



	//
	// loop of tests:each time test more spheres!
	// 
	ChStreamOutAsciiFile data_spheres_times("data_spheres_times.dat");
	ChStreamOutAsciiFile data_contacts_times("data_contact_times.dat");
	ChStreamOutAsciiFile data_ncontacts("data_ncontacts.dat");
	ChStreamOutAsciiFile data_timexconstr("data_timexconstr.dat");

	for (int nspheres = 1; (nspheres <= 1 && application.GetDevice()->run()); nspheres +=1)
	{

		ChStreamOutAsciiFile data_timing("data_timing1k.dat");
		

		// 
		// Create all the  rigid bodies!!!! 
		//

			// the root scene node containing all dynamic objects
		ISceneNode* parent = application.GetSceneManager()->addEmptySceneNode();

			// create spheres and walls, and insert into that scene node
		create_some_falling_items(mphysicalSystem, application.GetSceneManager(), application.GetVideoDriver(), parent, SPHERE_NUM,SPHERE_RAD,SPHERE_MASS); 

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

		int mdelay=0;
		int lastFPS = -1;

		ChTimer<double>mtimer; 

		ChRealtimeStepTimer m_realtime_timer;

		//ChStreamOutAsciiFile data_deltares("data_pNviolation_i80.dat");


		int totframes = 0;
		while(application.GetDevice()->run())
		{
			totframes++;

			if (totframes == 400) mtimer.start();

			// Irrlicht must prepare frame to draw
			application.GetVideoDriver()->beginScene(true, true, SColor(255,140,161,192));
		
			// Irrlicht draws all 3D objects and all GUI items
			application.DrawAll();


			// HERE CHRONO INTEGRATION IS PERFORMED: THE  
			// TIME OF THE SIMULATION ADVANCES FOR A SINGLE
			// STEP:
			mphysicalSystem.DoStepDynamics(0.01);


			application.GetVideoDriver()->endScene(); 

			

			if (totframes > 600)
			data_timing << mphysicalSystem.GetChTime()-3.0 << " " \
						<< mphysicalSystem.GetTimerStep() << " " \
						<< mphysicalSystem.GetTimerLcp()+mphysicalSystem.GetTimerCollisionBroad() << " " \
						<< mphysicalSystem.GetTimerLcp() << "\n";


			/*
			//***PLOT*** plot max constr.normal violation
			if ((totframes<600)&&(totframes>300))
			{
				ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverStab();
				if (msolver->GetViolationHistory().size()>1)
					data_deltares <<  msolver->GetViolationHistory()[msolver->GetViolationHistory().size()-1] << "\n";
			}

			//***PLOT*** plot deltalambda corrections for varying omega
			if (totframes==999)
			{
				ChLcpIterativeSymmSOR* msolver = (ChLcpIterativeSymmSOR*)mphysicalSystem.GetLcpSolverSpeed();
				msolver->SetOmega(1.0);
			}
			if (totframes==1000)
			{
				GetLog()<< "Saving plot data\n";
				ChLcpIterativeSolver* msolver = (ChLcpIterativeSolver*)mphysicalSystem.GetLcpSolverSpeed();
				ChStreamOutAsciiFile data_deltalambda("data_deltalambda_om80.dat");
				for (int k=0; k< msolver->GetDeltalambdaHistory().size(); k++)
				{
					data_deltalambda <<  msolver->GetDeltalambdaHistory()[k] << "\n";
				}
			}
			*/

			if ((totframes>200)&&(totframes<=500))
			{
				//data_timexconstr << mphysicalSystem.GetTimerLcp()/(double)mphysicalSystem.GetNcontacts() << "\n";
				//GetLog()<< "  avg time/contacts " << mphysicalSystem.GetTimerLcp()/(double)mphysicalSystem.GetNcontacts() << "\n";
				//GetLog()<< "  ncontacts " << (double)mphysicalSystem.GetNcontacts() << "\n";
			}

			if(totframes>500) break;


		}  // ------- end of simulation loop -----



		mtimer.stop();
		GetLog()<< "Time used for simulating/viewing first 500 steps: " << mtimer() << "\n";
		GetLog()<< "  num contacts " << mphysicalSystem.GetNcontacts() << "\n";
		GetLog()<< "  avg time/contacts " << mtimer()/(double)mphysicalSystem.GetNcontacts() << "\n";
		data_spheres_times << nspheres << "  " << mtimer() << "\n";
		data_contacts_times << mphysicalSystem.GetNcontacts() << "  " << mtimer() << "\n";
		

		// remove the root scene node (contains walls & spheres but no camera no lights)
		// to reset and prepare for new scene at next for() loop.
		parent->remove();

		// Now the system should already have no bodies, because of full removal from Irrlicht scene.
		// Then, the following clearing should be unuseful...(do it anyway..)
		mphysicalSystem.Clear(); 
	}



	// Remember this at the end of the program, if you started
	// with DLL_CreateGlobals();
	DLL_DeleteGlobals();

	getchar();

	return 0;
}