1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 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 // Demo code (advanced), about
13 //
14 // - using the SCM semi-empirical model for deformable soil
15 // - using a deformable tire
16 // =============================================================================
17
18 #include "chrono/geometry/ChTriangleMeshConnected.h"
19 #include "chrono/physics/ChLinkMotorRotationAngle.h"
20 #include "chrono/physics/ChLoadContainer.h"
21 #include "chrono/physics/ChSystemSMC.h"
22
23 #include "chrono_irrlicht/ChIrrApp.h"
24 #include "chrono_pardisomkl/ChSolverPardisoMKL.h"
25
26 #include "chrono_vehicle/ChVehicleModelData.h"
27 #include "chrono_vehicle/terrain/SCMDeformableTerrain.h"
28 #include "chrono_vehicle/wheeled_vehicle/wheel/Wheel.h"
29 #include "chrono_vehicle/wheeled_vehicle/tire/ReissnerTire.h"
30
31 using namespace chrono;
32 using namespace chrono::irrlicht;
33 using namespace chrono::vehicle;
34
35 using namespace irr;
36
main(int argc,char * argv[])37 int main(int argc, char* argv[]) {
38 GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
39
40 // Global parameter for tire:
41 double tire_rad = 0.5;
42 ChVector<> tire_center(0, tire_rad, 0);
43
44 // Create a Chrono physical system
45 ChSystemSMC my_system;
46
47 // Create the Irrlicht visualization (open the Irrlicht device,
48 // bind a simple user interface, etc. etc.)
49 ChIrrApp application(&my_system, L"Deformable soil and deformable tire", core::dimension2d<u32>(1280, 720),
50 VerticalDir::Y, false, true);
51
52 // Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene:
53 application.AddTypicalLogo();
54 application.AddTypicalSky();
55 application.AddTypicalLights();
56 application.AddTypicalCamera(core::vector3df(1.0f, 1.4f, -1.2f), core::vector3df(0, (f32)tire_rad, 0));
57 application.AddLightWithShadow(core::vector3df(1.5f, 5.5f, -2.5f), core::vector3df(0, 0, 0), 3, 2.2, 7.2, 40, 512,
58 video::SColorf(0.8f, 0.8f, 1.0f));
59
60 std::shared_ptr<ChBody> mtruss (new ChBody);
61 mtruss->SetBodyFixed(true);
62 my_system.Add(mtruss);
63
64
65 //
66 // CREATE A DEFORMABLE TIRE
67 //
68
69 // The rim body:
70 auto mrim = chrono_types::make_shared<ChBody>();
71 my_system.Add(mrim);
72 mrim->SetMass(80);
73 mrim->SetInertiaXX(ChVector<>(1,1,1));
74 mrim->SetPos(tire_center + ChVector<>(0,0.2,0));
75 mrim->SetRot(Q_from_AngAxis(CH_C_PI_2, VECT_Z));
76
77 // The wheel object:
78 auto wheel = chrono_types::make_shared<Wheel>(vehicle::GetDataFile("hmmwv/wheel/HMMWV_Wheel.json"));
79 wheel->Initialize(mrim, LEFT);
80
81 // The tire:
82 auto tire_reissner = chrono_types::make_shared<ReissnerTire>(vehicle::GetDataFile("hmmwv/tire/HMMWV_ReissnerTire.json"));
83 tire_reissner->EnablePressure(false);
84 tire_reissner->EnableContact(true);
85 tire_reissner->SetContactSurfaceType(ChDeformableTire::ContactSurfaceType::TRIANGLE_MESH);
86 tire_reissner->EnableRimConnection(true);
87 std::static_pointer_cast<ChTire>(tire_reissner)->Initialize(wheel);
88 tire_reissner->SetVisualizationType(VisualizationType::MESH);
89
90 // Attach tire to wheel
91 wheel->GetTire() = tire_reissner;
92
93 // The motor that rotates the rim:
94 auto motor = chrono_types::make_shared<ChLinkMotorRotationAngle>();
95 motor->SetSpindleConstraint(ChLinkMotorRotation::SpindleConstraint::OLDHAM);
96 motor->SetAngleFunction(chrono_types::make_shared<ChFunction_Ramp>(0, CH_C_PI / 4.0));
97 motor->Initialize(mrim, mtruss, ChFrame<>(tire_center, Q_from_AngAxis(CH_C_PI_2, VECT_Y)));
98 my_system.Add(motor);
99
100
101 //
102 // THE DEFORMABLE TERRAIN
103 //
104
105 // Create the 'deformable terrain' object
106 vehicle::SCMDeformableTerrain mterrain(&my_system);
107
108 // Displace/rotate the terrain reference plane.
109 // Note that SCMDeformableTerrain uses a default ISO reference frame (Z up). Since the mechanism is modeled here in
110 // a Y-up global frame, we rotate the terrain plane by -90 degrees about the X axis.
111 mterrain.SetPlane(ChCoordsys<>(ChVector<>(0, 0.2, 0.3), Q_from_AngX(-CH_C_PI_2)));
112
113 // Initialize the geometry of the soil: use either a regular grid:
114 mterrain.Initialize(1.5, 6, 0.075);
115
116 // Set the soil terramechanical parameters:
117 mterrain.SetSoilParameters(1.2e6, // Bekker Kphi
118 0, // Bekker Kc
119 1.1, // Bekker n exponent
120 0, // Mohr cohesive limit (Pa)
121 30, // Mohr friction limit (degrees)
122 0.01, // Janosi shear coefficient (m)
123 5e7, // Elastic stiffness (Pa/m), before plastic yield, must be > Kphi
124 2e4 // Damping (Pa s/m), proportional to negative vertical speed (optional)
125 );
126 mterrain.EnableBulldozing(true); // inflate soil at the border of the rut
127 mterrain.SetBulldozingParameters(
128 55, // angle of friction for erosion of displaced material at the border of the rut
129 0.8, // displaced material vs downward pressed material.
130 5, // number of erosion refinements per timestep
131 10); // number of concentric vertex selections subject to erosion
132
133 // Set some visualization parameters: either with a texture, or with falsecolor plot, etc.
134 //mterrain.SetTexture(vehicle::GetDataFile("terrain/textures/grass.jpg"), 16, 16);
135 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_PRESSURE, 0, 30000.2);
136 mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_PRESSURE_YELD, 0, 30000.2);
137 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_SINKAGE, 0, 0.15);
138 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_SINKAGE_PLASTIC, 0, 0.15);
139 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_SINKAGE_ELASTIC, 0, 0.05);
140 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_STEP_PLASTIC_FLOW, 0, 0.0001);
141 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_ISLAND_ID, 0, 8);
142 //mterrain.SetPlotType(vehicle::SCMDeformableTerrain::PLOT_IS_TOUCHED, 0, 8);
143 mterrain.GetMesh()->SetWireframe(true);
144
145
146
147 // ==IMPORTANT!== Use this function for adding a ChIrrNodeAsset to all items
148 application.AssetBindAll();
149
150 // ==IMPORTANT!== Use this function for 'converting' into Irrlicht meshes the assets
151 application.AssetUpdateAll();
152
153 // Use shadows in realtime view
154 application.AddShadowAll();
155
156
157 //
158 // THE SOFT-REAL-TIME CYCLE
159 //
160
161 // change the solver to PardisoMKL:
162 GetLog() << "Using PardisoMKL solver\n";
163 auto mkl_solver = chrono_types::make_shared<ChSolverPardisoMKL>();
164 mkl_solver->LockSparsityPattern(true);
165 my_system.SetSolver(mkl_solver);
166
167
168 // Change the timestepper to HHT:
169 my_system.SetTimestepperType(ChTimestepper::Type::HHT);
170 auto integrator = std::static_pointer_cast<ChTimestepperHHT>(my_system.GetTimestepper());
171 integrator->SetAlpha(-0.2);
172 integrator->SetMaxiters(8);
173 integrator->SetAbsTolerances(5e-05, 1.8e00);
174 integrator->SetMode(ChTimestepperHHT::POSITION);
175 integrator->SetModifiedNewton(false);
176 integrator->SetScaling(true);
177 integrator->SetVerbose(true);
178
179
180
181
182 application.SetTimestep(0.002);
183
184 while (application.GetDevice()->run()) {
185 application.BeginScene();
186
187 application.DrawAll();
188
189 application.DoStep();
190
191 tools::drawColorbar(0,30000, "Pressure yield [Pa]", application.GetDevice(), 1180);
192
193 application.EndScene();
194 }
195
196 return 0;
197 }
198