Falling bricks example (demo_MBS_bricks.cpp)

A tutorial about collisions.

Create a stack of bricks and a wrecking ball that collides with them.

Learn about:

  • how to enable collisions
  • how to use the surface material
  • how to impose an initial speed to a body
// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// 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
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Alessandro Tasora
// =============================================================================
//
// Demo code about
// - collisions and contacts
// - sharing a ChContactMaterialNSC property between bodies
//
// =============================================================================
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/solver/ChSolverPSOR.h"
#include "chrono/assets/ChTexture.h"
#include "chrono/assets/ChVisualSystem.h"
#ifdef CHRONO_IRRLICHT
#include "chrono_irrlicht/ChVisualSystemIrrlicht.h"
using namespace chrono::irrlicht;
#endif
#ifdef CHRONO_VSG
#include "chrono_vsg/ChVisualSystemVSG.h"
using namespace chrono::vsg3d;
#endif
using namespace chrono;
// Create a bunch of rigid bodies that represent bricks in a large wall.
void create_wall_bodies(ChSystemNSC& sys) {
// Create a material that will be shared among all collision shapes
auto mat = chrono_types::make_shared<ChContactMaterialNSC>();
mat->SetFriction(0.4f);
mat->SetCompliance(0.0);
mat->SetComplianceT(0.0);
mat->SetDampingF(0.2f);
// Create bricks
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
auto mrigidBody = chrono_types::make_shared<ChBodyEasyBox>(3.96, 2, 4, // x,y,z size
100, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBody->SetPos(ChVector3d(-8 + ui * 4.0 + 2 * (bi % 2), 1.0 + bi * 2.0, ai * 9));
mrigidBody->GetVisualShape(0)->SetTexture(GetChronoDataFile("textures/cubetexture_borders.png"));
sys.Add(mrigidBody);
}
}
}
// Create the floor using fixed rigid body of 'box' type:
auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size
1000, // density
true, // visulization?
true, // collision?
mat); // contact material
mrigidFloor->SetPos(ChVector3d(0, -2, 0));
mrigidFloor->SetFixed(true);
sys.Add(mrigidFloor);
// Create a ball that will collide with wall
auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4, // radius
8000, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBall->SetPos(ChVector3d(0, -2, 0));
mrigidBall->SetPos(ChVector3d(0, 3, -8));
mrigidBall->SetPosDt(ChVector3d(0, 0, 16)); // set initial speed
mrigidBall->GetVisualShape(0)->SetTexture(GetChronoDataFile("textures/bluewhite.png"));
sys.Add(mrigidBall);
}
// Create a bunch of ChronoENGINE rigid bodies that represent bricks in a Jenga tower
void create_jengatower_bodies(ChSystemNSC& sys) {
// Create a material that will be shared among all collision shapes
auto mat = chrono_types::make_shared<ChContactMaterialNSC>();
mat->SetFriction(0.4f);
mat->SetCompliance(0.0);
mat->SetComplianceT(0.0);
mat->SetDampingF(0.2f);
// Create bricks
for (int bi = 0; bi < 12; bi += 2) {
auto mrigidBody1 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size
100, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBody1->SetPos(ChVector3d(-5, 1.0 + bi * 2.0, 0));
sys.Add(mrigidBody1);
auto mrigidBody2 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size
100, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBody2->SetPos(ChVector3d(5, 1.0 + bi * 2.0, 0));
sys.Add(mrigidBody2);
auto mrigidBody3 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size
100, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBody3->SetPos(ChVector3d(0, 3.0 + bi * 2.0, 5));
sys.Add(mrigidBody3);
auto mrigidBody4 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size
100, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBody4->SetPos(ChVector3d(0, 3.0 + bi * 2.0, -5));
sys.Add(mrigidBody4);
}
// Create the floor using fixed rigid body of 'box' type:
auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size
1000, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidFloor->SetPos(ChVector3d(0, -2, 0));
mrigidFloor->SetFixed(true);
sys.Add(mrigidFloor);
// Create a ball that will collide with tower
auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4, // radius
1000, // density
true, // visualization?
true, // collision?
mat); // contact material
mrigidBall->SetPos(ChVector3d(0, 3, -8));
mrigidBall->SetPosDt(ChVector3d(0, 0, 2)); // set initial speed
mrigidBall->GetVisualShape(0)->SetTexture(GetChronoDataFile("textures/bluewhite.png"));
sys.Add(mrigidBall);
}
int main(int argc, char* argv[]) {
std::cout << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << std::endl;
// Create the physical system
// Create all the rigid bodies.
create_wall_bodies(sys);
// Create the run-time visualization system
#ifndef CHRONO_IRRLICHT
#endif
#ifndef CHRONO_VSG
if (vis_type == ChVisualSystem::Type::VSG)
#endif
std::shared_ptr<ChVisualSystem> vis;
switch (vis_type) {
#ifdef CHRONO_IRRLICHT
auto vis_irr = chrono_types::make_shared<ChVisualSystemIrrlicht>();
vis_irr->AttachSystem(&sys);
vis_irr->SetWindowSize(800, 600);
vis_irr->SetWindowTitle("Bricks test");
vis_irr->Initialize();
vis_irr->AddLogo();
vis_irr->AddSkyBox();
vis_irr->AddLight(ChVector3d(70, 120, -90), 290, ChColor(0.7f, 0.7f, 0.7f));
vis_irr->AddLight(ChVector3d(30, 80, 60), 190, ChColor(0.7f, 0.8f, 0.8f));
vis_irr->AddCamera(ChVector3d(-15, 14, -30), ChVector3d(0, 5, 0));
vis = vis_irr;
#endif
break;
}
default:
#ifdef CHRONO_VSG
auto vis_vsg = chrono_types::make_shared<ChVisualSystemVSG>();
vis_vsg->AttachSystem(&sys);
vis_vsg->SetWindowSize(ChVector2i(800, 600));
vis_vsg->SetWindowPosition(ChVector2i(100, 100));
vis_vsg->SetWindowTitle("VSG Bricks Demo");
vis_vsg->SetClearColor(ChColor(0.8f, 0.85f, 0.9f));
vis_vsg->SetUseSkyBox(true);
vis_vsg->SetCameraVertical(CameraVerticalDir::Y);
vis_vsg->AddCamera(ChVector3d(-30, 28, -60), ChVector3d(0, 5, 0));
vis_vsg->SetCameraAngleDeg(40);
vis_vsg->SetLightDirection(1.5 * CH_PI_2, CH_PI_4);
vis_vsg->SetShadows(true);
vis_vsg->Initialize();
vis = vis_vsg;
#endif
break;
}
}
// Prepare the physical system for the simulation
auto solver = chrono_types::make_shared<ChSolverPSOR>();
solver->SetMaxIterations(40);
solver->EnableWarmStart(true);
sys.SetSolver(solver);
// sys.SetSleepingAllowed(true);
// Simulation loop
while (vis->Run()) {
vis->BeginScene();
vis->Render();
vis->EndScene();
sys.DoStepDynamics(0.02);
}
return 0;
}
std::string GetChronoDataFile(const std::string &filename)
Get the full path to the specified filename, given relative to the Chrono data directory (thread safe...
Definition: ChGlobal.cpp:37
void Add(std::shared_ptr< ChPhysicsItem > item)
Attach an arbitrary ChPhysicsItem (e.g.
Definition: ChSystem.cpp:196
void SetMaxPenetrationRecoverySpeed(double value)
Set the speed limit of exiting from penetration situations (default: 0.6).
Definition: ChSystem.h:115
Type
Supported run-time visualization systems.
Definition: ChVisualSystem.h:36
Namespace with classes for the Irrlicht module.
Definition: ChApiIrr.h:47
Definition of a visual color.
Definition: ChColor.h:30
int DoStepDynamics(double step_size)
Advance the dynamics simulation by a single time step of given length.
Definition: ChSystem.cpp:1632
Bullet-based collision detection system.
ChVector3< double > ChVector3d
Alias for double-precision vectors.
Definition: ChVector3.h:283
virtual void SetSolver(std::shared_ptr< ChSolver > newsolver)
Attach a solver (derived from ChSolver) for use by this system.
Definition: ChSystem.cpp:319
Main namespace for the Chrono package.
Definition: ChCamera.cpp:17
virtual void SetCollisionSystemType(ChCollisionSystem::Type type)
Set the collision detection system used by this Chrono system to the specified type.
Definition: ChSystem.cpp:324
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29
Namespace with classes for the VSG module.
Definition: ChApiVSG.h:51
ChVector2< int > ChVector2i
Alias for integer vectors.
Definition: ChVector2.h:227