Tutorial: demo_buildsystem.cpp
Tutorial which teaches the basic approach to build and simulate mechanical systems using the Chrono::Engine library.
Learn how to:
- create a physical system (a slider-crank)
- add/remove rigid bodies
- create mechanical joints between bodies
- perform a simulation
Note: no GUI: only text output in this demo.

Theorical background
Chrono::Engine uses an object of class ChSystem to collect the database of all simulated items.
Therefore, bodies and constraints must be added to a ChSystem in order to work. 
Bodies are objects of class ChBody, while 'constraints' are represented by many kinds of mechanical joints: these are inherited from the ChLink class.
Also, each ChBody may optionally contain ChForce objects (to apply torque or forces) and ChMarker objects (these are auxiliary coordinate systems which move together with the rigid body, and are used as references for the ChLink joints.
For example, consider a double pendulum as depicted in the following figure:

Note that the revolute joints are two ChLink objects, referencing pairs of ChMarker objects belonging to the ChBody rigid bodies. Also the truss (i.e. the 'absolute reference frame') is a ChBody.
In Chrono::Engine, this concept is used to build mechanisms of whatever complexity: in this tutorial we will build a slider-crank mechanism, for example.

Let's start C++ coding..
First of all, include some headers needed for this example, use required namespaces, initialize the library, etc:
   
#include "physics/CHapidll.h" 
#include "physics/CHsystem.h"

using namespace chrono;

int main(int argc, char* argv[])
{
	// The DLL_CreateGlobals() - DLL_DeleteGlobals(); pair is needed if
	// global functions are needed.
	ChGlobals* GLOBAL_Vars = DLL_CreateGlobals();

Example 1: manage the hierarchy of rigid bodies
The following few statements teach how to dreate a ChSystem, how to add rigid bodies to it, and how to remove rigid bodies. Also, see how ChMarker objects are added/removed from rigid bodies.


	{
				// The physical system: it contains all physical objects.
		ChSystem my_system;      
  
				// Create a bunch of rigid bodies..
				// Note that we use shared pointers, so you don't 
				// have to care about the deletion (never use delete.. for
				// objects managed with shared pointers! it will be automatic!)
		ChSharedBodyPtr  my_body_A(new ChBody);   
		ChSharedBodyPtr  my_body_B(new ChBody); 
		ChSharedBodyPtr  my_body_C(new ChBody); 

				// Create some markers.. 
				// Markers are 'auxiliary coordinate systems' to be added
				// to rigid bodies.
				// Again, note that they are managed by shared pointers.
		ChSharedMarkerPtr my_marker_a1(new ChMarker);
		ChSharedMarkerPtr my_marker_a2(new ChMarker);
		ChSharedMarkerPtr my_marker_b1(new ChMarker);
		ChSharedMarkerPtr my_marker_b2(new ChMarker);

				// You can create some forces too...
		ChSharedForcePtr my_force_a1(new ChForce);
		ChSharedForcePtr my_force_a2(new ChForce);	

				// Here you will add forces and markers to rigid
				// bodies. 
				// Note: the same marker shouldn't be added to multiple bodies.
		my_body_A->AddMarker(my_marker_a1);
		my_body_A->AddMarker(my_marker_a2);
		my_body_A->AddForce (my_force_a1);
		my_body_A->AddForce (my_force_a2);
		my_body_B->AddMarker(my_marker_b1);
		my_body_B->AddMarker(my_marker_b2);

				// Ok, remember that rigid bodies must be added to 
				// the physical system.
		my_system.AddBody(my_body_A);
		my_system.AddBody(my_body_B);
		my_system.AddBody(my_body_C);

				// Show the hierarchy in the shell window...
		GetLog() << "Here's the system hierarchy which you built: \n\n ";
		my_system.ShowHierarchy( GetLog() ); 
		

				// Do you want to remove items? Use the 
				// Remove...() functions. 
		my_body_A->RemoveAllForces();

				// Remove a single body..
		my_system.RemoveBody(my_body_A);

				// Add markers to another body...
		my_body_B->AddMarker(my_marker_a1);
		my_body_B->AddMarker(my_marker_a2);
		my_body_B->AddForce(my_force_a1);
		my_body_B->AddForce(my_force_a2);

		GetLog() << "\n\n\nHere's the system hierarchy after modifications: \n\n ";
		my_system.ShowHierarchy( GetLog());
	}

Example 2: now that you have learned how to manage the database of rigid bodies, you can easily understand the following block of code, which is used to create a meaningful mechanism: the SLIDER-CRANK mechanism.
A slider-crank is made of a rotating crank (or a flywheel) and a rod, like in pumps, piston engines, etc.
In our simple example there is no piston: we have only 3 rigid bodies:
- the truss (fixed, as an absolute reference),
- the crank
- the rod.
Also, there are three 3D mechanical constraints, represented by objects of classes inherited from ChLink:
- the engine, between the truss and the crank,
- the revolute joint between the crank and the rod,
- the sliding joint between the other end of the rod and the truss.
We assume that the sliding motion of the rod is on the horizontal plane.


	{
		//
		// EXAMPLE 2: 
		//

		GetLog() << " Example: create a slider-crank system: \n";

				// The physical system: it contains all physical objects.
		ChSystem my_system; 

				// Create three rigid bodies and add them to the system:
		ChSharedBodyPtr  my_body_A(new ChBody);   // truss
		ChSharedBodyPtr  my_body_B(new ChBody);	  // crank
		ChSharedBodyPtr  my_body_C(new ChBody);	  // rod
		my_system.AddBody(my_body_A);
		my_system.AddBody(my_body_B);
		my_system.AddBody(my_body_C);

				// Set initial position of the bodies (center of mass)
		my_body_A->SetBodyFixed(true);			// truss does not move!
		my_body_B->SetPos(ChVector<>(1,0,0));
		my_body_C->SetPos(ChVector<>(4,0,0));


				// Create two markers and add them to two bodies:
				// they will be used as references for 'rod-crank'link.
		ChSharedMarkerPtr my_marker_b(new ChMarker);
		ChSharedMarkerPtr my_marker_c(new ChMarker);
		my_body_B->AddMarker(my_marker_b); 
		my_body_C->AddMarker(my_marker_c);
 
				// Set absolute position of the two markers, 
				// for the initial position of the 'rod-crank' link:
		my_marker_b->Impose_Abs_Coord(ChCoordsys<>(ChVector<>(2,0,0)));
		my_marker_c->Impose_Abs_Coord(ChCoordsys<>(ChVector<>(2,0,0)));
    
				// Now create a mechanical link (a revolute joint) 
				// between these two markers, and insert in system:
		ChSharedPtr<ChLinkLockRevolute>  my_link_BC(new ChLinkLockRevolute);
		my_link_BC->Initialize(my_marker_b, my_marker_c);
		my_system.AddLink(my_link_BC);

				// Phew! All this 'marker' stuff is boring!
				// Note that there's an easier way to create a link,
				// without needing the two markers (they will be
				// automatically created and added to the two bodies)
				// i.e. is using two bodies and a position as arguments..
				// For example, to create the rod-truss constraint:
		ChSharedPtr<ChLinkLockPointLine> my_link_CA(new ChLinkLockPointLine);
		my_link_CA->Initialize(my_body_C, my_body_A, ChCoordsys<>(ChVector<>(6,0,0)));
		my_system.AddLink(my_link_CA);

				// Now create a 'motor' link between crank and truss,
				// in 'imposed speed' mode:
		ChSharedPtr<ChLinkEngine> my_link_AB(new ChLinkEngine);
		my_link_AB->Initialize(my_body_A, my_body_B, ChCoordsys<>(ChVector<>(0,0,0)));
		my_link_AB->Set_eng_mode(ChLinkEngine::ENG_MODE_SPEED);
		my_link_AB->Get_spe_funct()->Set_yconst(CH_C_PI); // speed w=3.145 rad/sec
		my_system.AddLink(my_link_AB);


		GetLog() << "\n\n\nHere's the system hierarchy for slider-crank: \n\n ";
		my_system.ShowHierarchy( GetLog()); 


		// OK! NOW GET READY FOR THE DYNAMICAL SIMULATION!

		my_system.Setup();		// Allocate and resize auxiliary system data
		my_system.Update_B2Y();	// Current body positions -> initial system state

		// A very simple simulation loop..
		double chronoTime = 0;
		while(chronoTime<2.5)
		{
			chronoTime +=0.01; 

				// PERFORM SIMULATION UP TO chronoTime
			my_system.FrameDynamics(chronoTime);
	
				// Print something on the console..
			GetLog() << "Time: "
					 << chronoTime
					 << "  Slider X position: " 
					 << my_link_CA->GetMarker1()->GetAbsCoord().pos.x 
					 << "  Engine torque: " 
					 << my_link_AB->Get_mot_retorque()
					 << "\n";
		}

	}
 

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

	return 0;
}