Create a stack of bricks

Create a small stack of bricks, move the floor like an earthquake, and see the bricks falling. Uses PyChrono.

Learn how:

  • use Irrlicht 3D realtime visualization in PyChrono
  • impose a motion law to an object (the shaking platform)
  • add soft shadows to the realtime simulation
1 #------------------------------------------------------------------------------
2 # Name: pychrono example
3 # Purpose:
4 #
5 # Author: Alessandro Tasora
6 #
7 # Created: 1/01/2019
8 # Copyright: (c) ProjectChrono 2019
9 #
10 #
11 # This file shows how to
12 # - create a small stack of bricks,
13 # - create a support that shakes like an earthquake, with motion function
14 # - simulate the bricks that fall
15 #-------------------------------------------------------------------------------
16 
17 
18 import pychrono.core as chrono
19 import pychrono.irrlicht as chronoirr
20 
21 
22 # Change this path to asset path, if running from other working dir.
23 # It must point to the data folder, containing GUI assets (textures, fonts, meshes, etc.)
24 chrono.SetChronoDataPath("../../../data/")
25 
26 # ---------------------------------------------------------------------
27 #
28 # Create the simulation system and add items
29 #
30 
31 my_system = chrono.ChSystemNSC()
32 
33 
34 # Set the default outward/inward shape margins for collision detection,
35 # this is epecially important for very large or very small objects.
36 chrono.ChCollisionModel.SetDefaultSuggestedEnvelope(0.001)
37 chrono.ChCollisionModel.SetDefaultSuggestedMargin(0.001)
38 
39 # Maybe you want to change some settings for the solver. For example you
40 # might want to use SetMaxItersSolverSpeed to set the number of iterations
41 # per timestep, etc.
42 
43 #my_system.SetSolverType(chrono.ChSolver.Type_BARZILAIBORWEIN) # precise, more slow
44 my_system.SetMaxItersSolverSpeed(70)
45 
46 
47 
48 # Create a contact material (surface property)to share between all objects.
49 # The rolling and spinning parameters are optional - if enabled they double
50 # the computational time.
51 brick_material = chrono.ChMaterialSurfaceNSC()
52 brick_material.SetFriction(0.5)
53 brick_material.SetDampingF(0.2)
54 brick_material.SetCompliance (0.0000001)
55 brick_material.SetComplianceT(0.0000001)
56 # brick_material.SetRollingFriction(rollfrict_param)
57 # brick_material.SetSpinningFriction(0)
58 # brick_material.SetComplianceRolling(0.0000001)
59 # brick_material.SetComplianceSpinning(0.0000001)
60 
61 
62 
63 # Create the set of bricks in a vertical stack, along Y axis
64 
65 nbricks_on_x = 1
66 nbricks_on_y = 6
67 
68 size_brick_x = 0.25
69 size_brick_y = 0.12
70 size_brick_z = 0.12
71 density_brick = 1000; # kg/m^3
72 mass_brick = density_brick * size_brick_x * size_brick_y * size_brick_z;
73 inertia_brick = 2/5*(pow(size_brick_x,2))*mass_brick; # to do: compute separate xx,yy,zz inertias
74 
75 for ix in range(0,nbricks_on_x):
76  for iy in range(0,nbricks_on_y):
77  # create it
78  body_brick = chrono.ChBody()
79  # set initial position
80  body_brick.SetPos(chrono.ChVectorD(ix*size_brick_x, (iy+0.5)*size_brick_y, 0 ))
81  # set mass properties
82  body_brick.SetMass(mass_brick)
83  body_brick.SetInertiaXX(chrono.ChVectorD(inertia_brick,inertia_brick,inertia_brick))
84  # set collision surface properties
85  body_brick.SetMaterialSurface(brick_material)
86 
87  # Collision shape
88  body_brick.GetCollisionModel().ClearModel()
89  body_brick.GetCollisionModel().AddBox(size_brick_x/2, size_brick_y/2, size_brick_z/2) # must set half sizes
90  body_brick.GetCollisionModel().BuildModel()
91  body_brick.SetCollide(True)
92 
93  # Visualization shape, for rendering animation
94  body_brick_shape = chrono.ChBoxShape()
95  body_brick_shape.GetBoxGeometry().Size = chrono.ChVectorD(size_brick_x/2, size_brick_y/2, size_brick_z/2)
96  if iy%2==0 :
97  body_brick_shape.SetColor(chrono.ChColor(0.65, 0.65, 0.6)) # set gray color only for odd bricks
98  body_brick.GetAssets().push_back(body_brick_shape)
99 
100  my_system.Add(body_brick)
101 
102 
103 # Create the room floor: a simple fixed rigid body with a collision shape
104 # and a visualization shape
105 
106 body_floor = chrono.ChBody()
107 body_floor.SetBodyFixed(True)
108 body_floor.SetPos(chrono.ChVectorD(0, -2, 0 ))
109 body_floor.SetMaterialSurface(brick_material)
110 
111 # Collision shape
112 body_floor.GetCollisionModel().ClearModel()
113 body_floor.GetCollisionModel().AddBox(3, 1, 3) # hemi sizes
114 body_floor.GetCollisionModel().BuildModel()
115 body_floor.SetCollide(True)
116 
117 # Visualization shape
118 body_floor_shape = chrono.ChBoxShape()
119 body_floor_shape.GetBoxGeometry().Size = chrono.ChVectorD(3, 1, 3)
120 body_floor.GetAssets().push_back(body_floor_shape)
121 
122 body_floor_texture = chrono.ChTexture()
123 body_floor_texture.SetTextureFilename(chrono.GetChronoDataPath() + 'concrete.jpg')
124 body_floor.GetAssets().push_back(body_floor_texture)
125 
126 my_system.Add(body_floor)
127 
128 
129 
130 # Create the shaking table, as a box
131 
132 size_table_x = 1;
133 size_table_y = 0.2;
134 size_table_z = 1;
135 
136 body_table = chrono.ChBody()
137 body_table.SetPos(chrono.ChVectorD(0, -size_table_y/2, 0 ))
138 body_table.SetMaterialSurface(brick_material)
139 
140 # Collision shape
141 body_table.GetCollisionModel().ClearModel()
142 body_table.GetCollisionModel().AddBox(size_table_x/2, size_table_y/2, size_table_z/2) # hemi sizes
143 body_table.GetCollisionModel().BuildModel()
144 body_table.SetCollide(True)
145 
146 # Visualization shape
147 body_table_shape = chrono.ChBoxShape()
148 body_table_shape.GetBoxGeometry().Size = chrono.ChVectorD(size_table_x/2, size_table_y/2, size_table_z/2)
149 body_table_shape.SetColor(chrono.ChColor(0.4,0.4,0.5))
150 body_table.GetAssets().push_back(body_table_shape)
151 
152 body_table_texture = chrono.ChTexture()
153 body_table_texture.SetTextureFilename(chrono.GetChronoDataPath() + 'concrete.jpg')
154 body_table.GetAssets().push_back(body_table_texture)
155 
156 my_system.Add(body_table)
157 
158 
159 # Create a constraint that blocks free 3 x y z translations and 3 rx ry rz rotations
160 # of the table respect to the floor, and impose that the relative imposed position
161 # depends on a specified motion law.
162 
163 link_shaker = chrono.ChLinkLockLock()
164 link_shaker.Initialize(body_table, body_floor, chrono.CSYSNORM)
165 my_system.Add(link_shaker)
166 
167 # ..create the function for imposed x horizontal motion, etc.
168 mfunY = chrono.ChFunction_Sine(0,1.5,0.001) # phase, frequency, amplitude
169 link_shaker.SetMotion_Y(mfunY)
170 
171 # ..create the function for imposed y vertical motion, etc.
172 mfunZ = chrono.ChFunction_Sine(0,1.5,0.12) # phase, frequency, amplitude
173 link_shaker.SetMotion_Z(mfunZ)
174 
175 # Note that you could use other types of ChFunction_ objects, or create
176 # your custom function by class inheritance (see demo_python.py), or also
177 # set a function for table rotation , etc.
178 
179 
180 
181 
182 # ---------------------------------------------------------------------
183 #
184 # Create an Irrlicht application to visualize the system
185 #
186 
187 myapplication = chronoirr.ChIrrApp(my_system, 'PyChrono example', chronoirr.dimension2du(1024,768))
188 
189 myapplication.AddTypicalSky()
190 myapplication.AddTypicalLogo(chrono.GetChronoDataPath() + 'logo_pychrono_alpha.png')
191 myapplication.AddTypicalCamera(chronoirr.vector3df(0.5,0.5,1.0))
192 myapplication.AddLightWithShadow(chronoirr.vector3df(2,4,2), # point
193  chronoirr.vector3df(0,0,0), # aimpoint
194  9, # radius (power)
195  1,9, # near, far
196  30) # angle of FOV
197 
198  # ==IMPORTANT!== Use this function for adding a ChIrrNodeAsset to all items
199  # in the system. These ChIrrNodeAsset assets are 'proxies' to the Irrlicht meshes.
200  # If you need a finer control on which item really needs a visualization proxy in
201  # Irrlicht, just use application.AssetBind(myitem); on a per-item basis.
202 
203 myapplication.AssetBindAll();
204 
205  # ==IMPORTANT!== Use this function for 'converting' into Irrlicht meshes the assets
206  # that you added to the bodies into 3D shapes, they can be visualized by Irrlicht!
207 
208 myapplication.AssetUpdateAll();
209 
210  # If you want to show shadows because you used "AddLightWithShadow()'
211  # you must remember this:
212 myapplication.AddShadowAll();
213 
214 # ---------------------------------------------------------------------
215 #
216 # Run the simulation
217 #
218 
219 myapplication.SetTimestep(0.001)
220 myapplication.SetTryRealtime(True)
221 
222 while(myapplication.GetDevice().run()):
223  myapplication.BeginScene()
224  myapplication.DrawAll()
225  for substep in range(0,5):
226  myapplication.DoStep()
227  myapplication.EndScene()
228 
229