Slider crank example (demo_IRR_crank.cpp)

The simpliest way to integrate Chrono::Engine in the Irrlicht 3D visualization library: in fact the coordinates of the joints are simply used as end-points of simple polygonal lines which are drawn in the 3D space for each frame redraw, to show a very simplified 'skeleton' of a slider-crank mechanism. The demo also teaches how to:

  • create constraints and 'engine' objects
  • make a real-time application, where Chrono::Engine adapts the integration step to the speed of the CPU.
// =============================================================================
// Copyright (c) 2014
// All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// =============================================================================
// Authors: Alessandro Tasora
// =============================================================================
// Demo code about
// - constraints and 'motor' objects
// - using IRRLICHT as a realtime 3D viewer of a slider-crank mechanism
// simulated with Chrono::Engine.
// - using the real-time step.
// This is just a possible method of integration of Chrono::Engine + Irrlicht;
// many others are possible.
// =============================================================================
#include "chrono/core/ChRealtimeStep.h"
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChLinkMotorRotationSpeed.h"
#include "chrono_irrlicht/ChIrrApp.h"
// Use the namespaces of Chrono
using namespace chrono;
using namespace chrono::irrlicht;
// Use the main namespaces of Irrlicht
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
using namespace irr::video;
using namespace irr::io;
using namespace irr::gui;
int main(int argc, char* argv[]) {
GetLog() << "Copyright (c) 2017\nChrono version: " << CHRONO_VERSION << "\n\n";
// 1- Create a Chrono physical system: all bodies and constraints
// will be handled by this ChSystemNSC object.
ChSystemNSC my_system;
// 2- Create the rigid bodies of the slider-crank mechanical system
// (a crank, a rod, a truss), maybe setting position/mass/inertias of
// their center of mass (COG) etc.
// ..the truss
auto my_body_A = chrono_types::make_shared<ChBody>();
my_body_A->SetBodyFixed(true); // truss does not move!
// ..the crank
auto my_body_B = chrono_types::make_shared<ChBody>();
my_body_B->SetPos(ChVector<>(1, 0, 0)); // position of COG of crank
// ..the rod
auto my_body_C = chrono_types::make_shared<ChBody>();
my_body_C->SetPos(ChVector<>(4, 0, 0)); // position of COG of rod
// 3- Create constraints: the mechanical joints between the rigid bodies.
// .. a revolute joint between crank and rod
auto my_link_BC = chrono_types::make_shared<ChLinkLockRevolute>();
my_link_BC->Initialize(my_body_B, my_body_C, ChCoordsys<>(ChVector<>(2, 0, 0)));
// .. a slider joint between rod and truss
auto my_link_CA = chrono_types::make_shared<ChLinkLockPointLine>();
my_link_CA->Initialize(my_body_C, my_body_A, ChCoordsys<>(ChVector<>(6, 0, 0)));
// .. a motor between crank and truss
auto my_link_AB = chrono_types::make_shared<ChLinkMotorRotationSpeed>();
my_link_AB->Initialize(my_body_A, my_body_B, ChFrame<>(ChVector<>(0, 0, 0)));
auto my_speed_function = chrono_types::make_shared<ChFunction_Const>(CH_C_PI); // speed w=3.145 rad/sec
// 4- Create the Irrlicht visualization
ChIrrApp application(&my_system, L"Simple slider-crank example", core::dimension2d<u32>(800, 600), false);
// Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene:
ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(0, 0, -6));
// Bind assets
// Timer for enforcing soft real-time
ChRealtimeStepTimer realtime_timer;
double time_step = 0.01;
bool removed = false;
while (application.GetDevice()->run()) {
// Irrlicht must prepare frame to draw
application.BeginScene(true, true, SColor(255, 140, 161, 192));
// Irrlicht now draws simple lines in 3D world representing a
// skeleton of the mechanism, in this instant:
// .. draw items belonging to Irrlicht scene, if any
// .. draw a grid
ChIrrTools::drawGrid(application.GetVideoDriver(), 0.5, 0.5);
// .. draw GUI items belonging to Irrlicht screen, if any
// .. draw the rod (from joint BC to joint CA)
ChIrrTools::drawSegment(application.GetVideoDriver(), my_link_BC->GetMarker1()->GetAbsCoord().pos,
my_link_CA->GetMarker1()->GetAbsCoord().pos, video::SColor(255, 0, 255, 0));
// .. draw the crank (from joint AB to joint BC)
ChIrrTools::drawSegment(application.GetVideoDriver(), my_link_AB->GetLinkAbsoluteCoords().pos,
my_link_BC->GetMarker1()->GetAbsCoord().pos, video::SColor(255, 255, 0, 0));
// .. draw a small circle at crank origin
ChIrrTools::drawCircle(application.GetVideoDriver(), 0.1, ChCoordsys<>(ChVector<>(0, 0, 0), QUNIT));
/* test: delete a link after 10 seconds
if (my_system.GetChTime() >10 && (!removed))
removed = true;
// Enforce soft real-time
// Irrlicht must finish drawing the frame
return 0;
static void drawGrid(irr::video::IVideoDriver *driver, double ustep=0.1, double vstep=0.1, int nu=20, int nv=20, ChCoordsys<> mpos=CSYSNORM, irr::video::SColor mcol=irr::video::SColor(50, 80, 110, 110), bool use_Zbuffer=false)
Easy-to-use function to draw grids in 3D space, with given orientation, color and spacing.
Definition: ChIrrTools.cpp:695
static void add_typical_Camera(irr::IrrlichtDevice *device, irr::core::vector3df mpos=irr::core::vector3df(0, 0, -8), irr::core::vector3df mtarg=irr::core::vector3df(0, 0, 0))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:53
Definition: ChCoordsys.h:38
ChLog & GetLog()
Global function to get the current ChLog object.
Definition: ChLog.cpp:39
virtual void AddLink(std::shared_ptr< ChLinkBase > link)
Attach a link to the underlying assembly.
Definition: ChSystem.h:245
static void add_typical_Logo(irr::IrrlichtDevice *device, const std::string &mlogofilename=GetChronoDataFile("logo_chronoengine_alpha.png"))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:20
static void add_typical_Sky(irr::IrrlichtDevice *device, const std::string &mtexturedir=GetChronoDataFile("skybox/"))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:40
static void add_typical_Lights(irr::IrrlichtDevice *device, irr::core::vector3df pos1=irr::core::vector3df(30.f, 100.f, 30.f), irr::core::vector3df pos2=irr::core::vector3df(30.f, 80.f, -30.f), double rad1=290, double rad2=190, irr::video::SColorf col1=irr::video::SColorf(0.7f, 0.7f, 0.7f, 1.0f), irr::video::SColorf col2=irr::video::SColorf(0.7f, 0.8f, 0.8f, 1.0f))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:25
static void drawCircle(irr::video::IVideoDriver *driver, double radius, ChCoordsys<> mpos=CSYSNORM, irr::video::SColor mcol=irr::video::SColor(255, 0, 0, 0), int mresolution=36, bool use_Zbuffer=false)
Easy-to-use function to draw a circle line in 3D space, with given color.
Definition: ChIrrTools.cpp:625
ChFrame: a class for coordinate systems in 3D space.
Definition: ChFrame.h:42
Class to add some GUI to Irrlicht+ChronoEngine applications.
Definition: ChIrrApp.h:29
const ChApi ChQuaternion< double > QUNIT
Constant unit quaternion: {1, 0, 0, 0} , corresponds to no rotation (diagonal rotation matrix)
virtual void EndScene()
Call this to end the scene draw at the end of each animation frame.
Definition: ChIrrAppInterface.cpp:562
Namespace with classes for the Irrlicht module.
Definition: ChApiIrr.h:48
Class for a timer which attempts to enforce soft real-time.
Definition: ChRealtimeStep.h:25
static void drawSegment(irr::video::IVideoDriver *driver, ChVector<> mstart, ChVector<> mend, irr::video::SColor mcol=irr::video::SColor(255, 0, 0, 0), bool use_Zbuffer=false)
Easy-to-use function to draw segment lines in 3D space, with given color.
Definition: ChIrrTools.cpp:594
void Spin(double step)
Call this function INSIDE the simulation loop, just ONCE per loop (preferably as the last call in the...
Definition: ChRealtimeStep.h:34
Definition of general purpose 3d vector variables, such as points in 3D.
Definition: ChVector.h:35
int DoStepDynamics(double step_size)
Advances the dynamical simulation for a single step, of length step_size.
Definition: ChSystem.cpp:1274
virtual void AddBody(std::shared_ptr< ChBody > body)
Attach a body to the underlying assembly.
Definition: ChSystem.h:242
virtual void BeginScene(bool backBuffer=true, bool zBuffer=true, irr::video::SColor color=irr::video::SColor(255, 0, 0, 0))
Call this to clean the canvas at the beginning of each animation frame.
Definition: ChIrrAppInterface.cpp:545
Main namespace for the Chrono package.
Definition: ChAsset.cpp:18
virtual void DrawAll()
Call this function inside a loop such as.
Definition: ChIrrAppInterface.cpp:676
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29