1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2019 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Radu Serban
13 // =============================================================================
14 //
15 // Benchmark test for contact simulation using NSC contact.
16 //
17 // =============================================================================
18 
19 #include "chrono/ChConfig.h"
20 #include "chrono/utils/ChBenchmark.h"
21 
22 #include "chrono/physics/ChSystemNSC.h"
23 #include "chrono/physics/ChBodyEasy.h"
24 #include "chrono/physics/ChLinkMotorRotationSpeed.h"
25 
26 #include "chrono/assets/ChColorAsset.h"
27 
28 #ifdef CHRONO_IRRLICHT
29 #include "chrono_irrlicht/ChIrrApp.h"
30 #endif
31 
32 using namespace chrono;
33 
34 // =============================================================================
35 
36 template <int N>
37 class MixerTestNSC : public utils::ChBenchmarkTest {
38   public:
39     MixerTestNSC();
~MixerTestNSC()40     ~MixerTestNSC() { delete m_system; }
41 
GetSystem()42     ChSystem* GetSystem() override { return m_system; }
ExecuteStep()43     void ExecuteStep() override { m_system->DoStepDynamics(m_step); }
44 
45     void SimulateVis();
46 
47   private:
48     ChSystemNSC* m_system;
49     double m_step;
50 };
51 
52 template <int N>
MixerTestNSC()53 MixerTestNSC<N>::MixerTestNSC() : m_system(new ChSystemNSC()), m_step(0.02) {
54     auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
55 
56     for (int bi = 0; bi < N; bi++) {
57         auto sphereBody = chrono_types::make_shared<ChBodyEasySphere>(1.0, 1000, true, true, mat);
58         sphereBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
59         sphereBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.4f, 0.0f, 0.0f));
60         m_system->Add(sphereBody);
61 
62         auto boxBody = chrono_types::make_shared<ChBodyEasyBox>(1.25, 1.25, 1.25, 1000, true, true, mat);
63         boxBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
64         boxBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.4f, 0.0f));
65         m_system->Add(boxBody);
66 
67         auto cylBody = chrono_types::make_shared<ChBodyEasyCylinder>(0.8, 1.0, 1000, true, true, mat);
68         cylBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
69         cylBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.0f, 0.4f));
70         m_system->Add(cylBody);
71     }
72 
73     auto floorBody = chrono_types::make_shared<ChBodyEasyBox>(20, 1, 20, 1000, true, true, mat);
74     floorBody->SetPos(ChVector<>(0, -5, 0));
75     floorBody->SetBodyFixed(true);
76     m_system->Add(floorBody);
77 
78     auto wallBody1 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
79     wallBody1->SetPos(ChVector<>(-10, 0, 0));
80     wallBody1->SetBodyFixed(true);
81     m_system->Add(wallBody1);
82 
83     auto wallBody2 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
84     wallBody2->SetPos(ChVector<>(10, 0, 0));
85     wallBody2->SetBodyFixed(true);
86     m_system->Add(wallBody2);
87 
88     auto wallBody3 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
89     wallBody3->SetPos(ChVector<>(0, 0, -10));
90     wallBody3->SetBodyFixed(true);
91     m_system->Add(wallBody3);
92 
93     auto wallBody4 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
94     wallBody4->SetPos(ChVector<>(0, 0, 10));
95     wallBody4->SetBodyFixed(true);
96     m_system->Add(wallBody4);
97 
98     auto rotatingBody = chrono_types::make_shared<ChBodyEasyBox>(10, 5, 1, 4000, true, true, mat);
99     rotatingBody->SetPos(ChVector<>(0, -1.6, 0));
100     m_system->Add(rotatingBody);
101 
102     auto motor = chrono_types::make_shared<ChLinkMotorRotationSpeed>();
103     motor->Initialize(rotatingBody, floorBody, ChFrame<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X)));
104     auto fun = chrono_types::make_shared<ChFunction_Const>(CH_C_PI / 3.0);
105     motor->SetSpeedFunction(fun);
106     m_system->AddLink(motor);
107 }
108 
109 template <int N>
SimulateVis()110 void MixerTestNSC<N>::SimulateVis() {
111 #ifdef CHRONO_IRRLICHT
112     irrlicht::ChIrrApp application(m_system, L"Rigid contacts", irr::core::dimension2d<irr::u32>(800, 600));
113     application.AddTypicalLogo();
114     application.AddTypicalSky();
115     application.AddTypicalLights();
116     application.AddTypicalCamera(irr::core::vector3df(0, 14, -20));
117 
118     application.AssetBindAll();
119     application.AssetUpdateAll();
120 
121     while (application.GetDevice()->run()) {
122         application.BeginScene();
123         application.DrawAll();
124         ExecuteStep();
125         application.EndScene();
126     }
127 #endif
128 }
129 
130 // =============================================================================
131 
132 #define NUM_SKIP_STEPS 2000  // number of steps for hot start
133 #define NUM_SIM_STEPS 1000   // number of simulation steps for each benchmark
134 
135 CH_BM_SIMULATION_LOOP(MixerNSC032, MixerTestNSC<32>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
136 CH_BM_SIMULATION_LOOP(MixerNSC064, MixerTestNSC<64>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
137 
138 // =============================================================================
139 
main(int argc,char * argv[])140 int main(int argc, char* argv[]) {
141     ::benchmark::Initialize(&argc, argv);
142 
143 #ifdef CHRONO_IRRLICHT
144     if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
145         MixerTestNSC<64> test;
146         test.SimulateVis();
147         return 0;
148     }
149 #endif
150 
151     ::benchmark::RunSpecifiedBenchmarks();
152 }
153