Use paths as constraints

Create two pendulums following paths (i.e. parametric lines). Uses PyChrono.

Learn how to:

  • create piecewise paths built from sub-lines, and visualize them
  • add a constraint of 'curvilinear glyph' type (the body can freely move with one of its points being constrained to slide along a path)
  • add a constraint of 'imposed trajectory' type (the body must with one of its points being constrained to walk along a path as a parametric line with motion function)
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 
12 import pychrono.core as chrono
13 import pychrono.irrlicht as chronoirr
14 
15 print ("Example: create a system and visualize it in realtime 3D");
16 
17 # Change this path to asset path, if running from other working dir.
18 # It must point to the data folder, containing GUI assets (textures, fonts, meshes, etc.)
19 chrono.SetChronoDataPath("../../../data/")
20 
21 # ---------------------------------------------------------------------
22 #
23 # Create the simulation system and add items
24 #
25 
26 mysystem = chrono.ChSystemNSC()
27 
28 mfloor = chrono.ChBodyEasyBox(3, 0.2, 3, 1000)
29 mfloor.SetBodyFixed(True)
30 mysystem.Add(mfloor)
31 
32 #
33 # EXAMPLE1
34 #
35 
36 # Create a ChLinePath geometry, and insert sub-paths:
37 mpath = chrono.ChLinePath()
38 mseg1 = chrono.ChLineSegment(chrono.ChVectorD(1, 2, 0), chrono.ChVectorD(2, 2, 0))
39 mpath.AddSubLine(mseg1)
40 marc1 = chrono.ChLineArc(chrono.ChCoordsysD(chrono.ChVectorD(2, 2.5, 0)), 0.5, -chrono.CH_C_PI_2, chrono.CH_C_PI_2, True)
41 mpath.AddSubLine(marc1)
42 mseg2 = chrono.ChLineSegment(chrono.ChVectorD(2, 3, 0), chrono.ChVectorD(1, 3, 0))
43 mpath.AddSubLine(mseg2)
44 marc2 = chrono.ChLineArc(chrono.ChCoordsysD(chrono.ChVectorD(1, 2.5, 0)), 0.5, chrono.CH_C_PI_2, -chrono.CH_C_PI_2, True);
45 mpath.AddSubLine(marc2)
46 mpath.Set_closed(True)
47 
48 # Create a ChLineShape, a visualization asset for lines.
49 # The ChLinePath is a special type of ChLine and it can be visualized.
50 mpathasset = chrono.ChLineShape()
51 mpathasset.SetLineGeometry(mpath)
52 mfloor.AddAsset(mpathasset)
53 
54 # Create a body that will follow the trajectory
55 
56 mpendulum = chrono.ChBodyEasyBox(0.1, 1, 0.1, 1000)
57 mpendulum.SetPos(chrono.ChVectorD(1, 1.5, 0))
58 mysystem.Add(mpendulum)
59 
60 # The trajectory constraint:
61 
62 mtrajectory = chrono.ChLinkTrajectory()
63 
64 # Define which parts are connected (the trajectory is considered in the 2nd body).
65 mtrajectory.Initialize(mpendulum, # body1 that follows the trajectory
66  mfloor, # body2 that 'owns' the trajectory
67  chrono.ChVectorD(0, 0.5, 0), # point on body1 that will follow the trajectory
68  mpath # the trajectory (reuse the one already added to body2 as asset)
69  )
70 
71 # Optionally, set a function that gets the curvilinear
72 # abscyssa s of the line, as a function of time s(t).
73 # By default it was simply s=t.
74 mspacefx = chrono.ChFunction_Ramp(0, 0.5)
75 mtrajectory.Set_space_fx(mspacefx)
76 
77 mysystem.Add(mtrajectory)
78 
79 #
80 # EXAMPLE 2:
81 #
82 
83 # Create a ChBody that contains the trajectory
84 
85 mwheel = chrono.ChBody()
86 mwheel.SetPos(chrono.ChVectorD(-3, 2, 0))
87 mysystem.Add(mwheel)
88 
89 # Create a motor that spins the wheel
91 my_motor.Initialize(mwheel, mfloor, chrono.ChFrameD(chrono.ChVectorD(-3, 2, 0)))
92 my_angularspeed = chrono.ChFunction_Const(chrono.CH_C_PI / 4.0)
93 my_motor.SetMotorFunction(my_angularspeed)
94 mysystem.Add(my_motor)
95 
96 # Create a ChLinePath geometry, and insert sub-paths:
97 mglyph = chrono.ChLinePath()
98 ms1 = chrono.ChLineSegment(chrono.ChVectorD(-0.5, -0.5, 0), chrono.ChVectorD(0.5, -0.5, 0))
99 mglyph.AddSubLine(ms1)
100 ma1 = chrono.ChLineArc(chrono.ChCoordsysD(chrono.ChVectorD(0.5, 0, 0)), 0.5, -chrono.CH_C_PI_2, chrono.CH_C_PI_2, True)
101 mglyph.AddSubLine(ma1)
102 ms2 = chrono.ChLineSegment(chrono.ChVectorD(0.5, 0.5, 0), chrono.ChVectorD(-0.5, 0.5, 0))
103 mglyph.AddSubLine(ms2)
104 ma2 = chrono.ChLineArc(chrono.ChCoordsysD(chrono.ChVectorD(-0.5, 0, 0)), 0.5, chrono.CH_C_PI_2, -chrono.CH_C_PI_2, True);
105 mglyph.AddSubLine(ma2)
106 mglyph.SetPathDuration(1)
107 mglyph.Set_closed(True)
108 
109 # Create a ChLineShape, a visualization asset for lines.
110 # The ChLinePath is a special type of ChLine and it can be visualized.
111 mglyphasset = chrono.ChLineShape()
112 mglyphasset.SetLineGeometry(mglyph)
113 mwheel.AddAsset(mglyphasset)
114 
115 # Create a body that will slide on the glyph
116 
117 mpendulum2 = chrono.ChBodyEasyBox(0.1, 1, 0.1, 1000)
118 mpendulum2.SetPos(chrono.ChVectorD(-3, 1, 0))
119 mysystem.Add(mpendulum2)
120 
121 # The glyph constraint:
122 
123 mglyphconstraint = chrono.ChLinkPointSpline()
124 
125 # Define which parts are connected (the trajectory is considered in the 2nd body).
126 mglyphconstraint.Initialize(mpendulum2, # body1 that follows the trajectory
127  mwheel, # body2 that 'owns' the trajectory
128  True,
129  chrono.ChCoordsysD(chrono.ChVectorD(0, 0.5, 0)), # point on body1 that will follow the trajectory
130  chrono.ChCoordsysD())
131 
132 mglyphconstraint.Set_trajectory_line(mglyph)
133 
134 mysystem.Add(mglyphconstraint)
135 
136 
137 # ---------------------------------------------------------------------
138 #
139 # Create an Irrlicht application to visualize the system
140 #
141 
142 myapplication = chronoirr.ChIrrApp(mysystem, 'PyChrono example', chronoirr.dimension2du(1024,768))
143 
144 myapplication.AddTypicalSky()
145 myapplication.AddTypicalLogo(chrono.GetChronoDataPath() + 'logo_pychrono_alpha.png')
146 myapplication.AddTypicalCamera(chronoirr.vector3df(1,4,5), chronoirr.vector3df(0,2,0))
147 myapplication.AddTypicalLights()
148 
149  # ==IMPORTANT!== Use this function for adding a ChIrrNodeAsset to all items
150  # in the system. These ChIrrNodeAsset assets are 'proxies' to the Irrlicht meshes.
151  # If you need a finer control on which item really needs a visualization proxy in
152  # Irrlicht, just use application.AssetBind(myitem); on a per-item basis.
153 
154 myapplication.AssetBindAll();
155 
156  # ==IMPORTANT!== Use this function for 'converting' into Irrlicht meshes the assets
157  # that you added to the bodies into 3D shapes, they can be visualized by Irrlicht!
158 
159 myapplication.AssetUpdateAll();
160 
161 
162 # ---------------------------------------------------------------------
163 #
164 # Run the simulation
165 #
166 
167 
168 myapplication.SetTimestep(0.005)
169 
170 
171 while(myapplication.GetDevice().run()):
172  myapplication.BeginScene()
173  myapplication.DrawAll()
174  myapplication.DoStep()
175  myapplication.EndScene()
176 
177 
178 
179 
180