Rolling and spinning friction example (demo_IRR_friction.cpp)

A benchmark that show the feature of spinning friction (aka 'drilling' friction) and rolling friction.

These types of frictions are useful for rolling objects like wheels, spheres etc. and can be optionally turned on.

This tutorial shows how to:

  • enable rolling and spinning friction.
  • impose initial velocity and angular velocity to objects.
// =============================================================================
// 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
// - using rolling friction (not only sliding and static friction, available in
// all objects by default)
// - optional sharing of some assets (visualization stuff)
//
// =============================================================================
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChBodyEasy.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 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
// Create a ChronoENGINE physical system
ChSystemNSC mphysicalSystem;
// Create the Irrlicht visualization (open the Irrlicht device,
// bind a simple user interface, etc. etc.)
ChIrrApp application(&mphysicalSystem, L"Contacts with rolling friction", 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, 14, -20));
// Create all the rigid bodies.
double mradius = 0.5;
double density = 1000;
// Create a texture asset. It can be shared between bodies.
auto textureasset = chrono_types::make_shared<ChTexture>(GetChronoDataFile("bluwhite.png"));
// Create some spheres that roll horizontally,
// with increasing rolling friction values
for (int bi = 0; bi < 10; bi++) {
double initial_angspeed = 10;
double initial_linspeed = initial_angspeed * mradius;
auto msphereBody = chrono_types::make_shared<ChBodyEasySphere>(mradius, // radius size
1000, // density
true, // collide enable?
true); // visualization?
// Set some properties
msphereBody->SetPos(ChVector<>(-7, mradius - 0.5, -5 + bi * mradius * 2.5));
msphereBody->GetMaterialSurfaceNSC()->SetFriction(0.4f);
msphereBody->AddAsset(textureasset); // assets can be shared
// Set initial speed: rolling in horizontal direction,
msphereBody->SetWvel_par(ChVector<>(0, 0, -initial_angspeed));
msphereBody->SetPos_dt(ChVector<>(initial_linspeed, 0, 0));
// Set a non zero value of rolling friction to have a rolling resisting torque:
msphereBody->GetMaterialSurfaceNSC()->SetRollingFriction(((float)bi / 10) * 0.05f);
// Add to the system
mphysicalSystem.Add(msphereBody);
}
// Create some spheres that spin on place, for a 'drilling friction' case,
// with increasing spinning friction values
for (int bi = 0; bi < 10; bi++) {
auto msphereBody = chrono_types::make_shared<ChBodyEasySphere>(mradius, // radius size
1000, // density
true, // collide enable?
true); // visualization?
// Set some properties
msphereBody->SetPos(ChVector<>(-8, 1 + mradius - 0.5, -5 + bi * mradius * 2.5));
msphereBody->GetMaterialSurfaceNSC()->SetFriction(0.4f);
msphereBody->AddAsset(textureasset); // assets can be shared
// Set initial speed: spinning in vertical direction
msphereBody->SetWvel_par(ChVector<>(0, 20, 0));
// Set a non zero value of spinning friction that brakes the spinning on vertical axis
// of the contact:
msphereBody->GetMaterialSurfaceNSC()->SetSpinningFriction(((float)bi / 10) * 0.02f);
// Add to the system
mphysicalSystem.Add(msphereBody);
// Notes:
// - setting nonzero spinning friction and/or setting nonzero rolling friction
// affects the speed of the solver (each contact eats 2x of CPU time repsect to the
// case of simple sliding/staic contact)
// - avoid using zero spinning friction with nonzero rolling friction.
}
// Create the five walls of the rectangular container, using
// fixed rigid bodies of 'box' type:
// floor:
auto mfloorBody = chrono_types::make_shared<ChBodyEasyBox>(20, 1, 20, // x,y,z size
2000, // density
true, // collide enable?
true); // visualization?
mfloorBody->SetPos(ChVector<>(0, -1, 0));
mfloorBody->SetBodyFixed(true);
mfloorBody->GetMaterialSurfaceNSC()->SetRollingFriction(
1); // the min. of the two coeff. of the two contact surfaces will be used
mfloorBody->GetMaterialSurfaceNSC()->SetSpinningFriction(
1); // the min. of the two coeff. of the two contact surfaces will be used
mfloorBody->AddAsset(chrono_types::make_shared<ChTexture>(GetChronoDataFile("blu.png")));
mphysicalSystem.Add(mfloorBody);
// four walls:
auto mwallBody1 = chrono_types::make_shared<ChBodyEasyBox>(1, 2, 20.99, // x,y,z size
2000, // density
true, // collide enable?
true); // visualization?
mwallBody1->SetPos(ChVector<>(-10, 0, 0));
mwallBody1->SetBodyFixed(true);
mwallBody1->AddAsset(chrono_types::make_shared<ChColorAsset>(0.6f, 0.3f, 0.0f));
mphysicalSystem.Add(mwallBody1);
auto mwallBody2 = chrono_types::make_shared<ChBodyEasyBox>(1, 2, 20.99, // x,y,z size
2000, // density
true, // collide enable?
true); // visualization?
mwallBody2->SetPos(ChVector<>(10, 0, 0));
mwallBody2->SetBodyFixed(true);
mwallBody2->AddAsset(chrono_types::make_shared<ChColorAsset>(0.6f, 0.3f, 0.0f));
mphysicalSystem.Add(mwallBody2);
auto mwallBody3 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 2, 1, // x,y,z size
2000, // density
true, // collide enable?
true); // visualization?
mwallBody3->SetPos(ChVector<>(0, 0, -10));
mwallBody3->SetBodyFixed(true);
mwallBody3->AddAsset(chrono_types::make_shared<ChColorAsset>(0.6f, 0.3f, 0.0f));
mphysicalSystem.Add(mwallBody3);
auto mwallBody4 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 2, 1, // x,y,z size
2000, // density
true, // collide enable?
true); // visualization?
mwallBody4->SetPos(ChVector<>(0, 0, 10));
mwallBody4->SetBodyFixed(true);
mwallBody4->AddAsset(chrono_types::make_shared<ChColorAsset>(0.6f, 0.3f, 0.0f));
mphysicalSystem.Add(mwallBody4);
// Use this function for adding a ChIrrNodeAsset to all already created items.
// Otherwise use application.AssetBind(myitem); on a per-item basis.
application.AssetBindAll();
application.AssetUpdateAll();
// Modify some setting of the physical system for the simulation
mphysicalSystem.SetSolverMaxIterations(100);
// Simulation loop
application.SetStepManage(true);
application.SetTimestep(0.01);
application.SetTryRealtime(true);
while (application.GetDevice()->run()) {
application.BeginScene(true, true, SColor(255, 140, 161, 192));
application.DrawAll();
application.DoStep();
application.EndScene();
}
return 0;
}
std::string GetChronoDataFile(const std::string &filename)
Obtain the complete path to the specified filename, given relative to the Chrono data directory (thre...
Definition: ChGlobal.cpp:95
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
ChLog & GetLog()
Global function to get the current ChLog object.
Definition: ChLog.cpp:39
void SetTimestep(double val)
Set/Get the time step for time integration.
Definition: ChIrrAppInterface.cpp:532
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
void SetStepManage(bool val)
If set to true, you can use DoStep() in the simulation loop to advance the simulation by one timestep...
Definition: ChIrrAppInterface.h:84
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
Class to add some GUI to Irrlicht+ChronoEngine applications.
Definition: ChIrrApp.h:29
virtual void EndScene()
Call this to end the scene draw at the end of each animation frame.
Definition: ChIrrAppInterface.cpp:578
Namespace with classes for the Irrlicht module.
Definition: ChApiIrr.h:48
Accelerated Projected Gradient Descent.
Definition of general purpose 3d vector variables, such as points in 3D.
Definition: ChVector.h:35
virtual void DoStep()
Call this important function inside a cycle like while(application.GetDevice()->run()) {....
Definition: ChIrrAppInterface.cpp:590
virtual void SetSolverType(ChSolver::Type type)
Choose the solver type, to be used for the simultaneous solution of the constraints in dynamical simu...
Definition: ChSystem.cpp:149
void Add(std::shared_ptr< ChPhysicsItem > item)
Attach an arbitrary ChPhysicsItem (e.g.
Definition: ChAssembly.cpp:190
void SetSolverMaxIterations(int max_iters)
Set the maximum number of iterations, if using an iterative solver.
Definition: ChSystem.cpp:123
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:559
Main namespace for the Chrono package.
Definition: ChAsset.cpp:18
virtual void DrawAll()
Call this important function inside a loop like while(application.GetDevice()->run()) {....
Definition: ChIrrAppInterface.cpp:699
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29
void SetTryRealtime(bool val)
If set to true, the function DoStep() will try to use a timestep that is the same as that used to ref...
Definition: ChIrrAppInterface.h:92