Skip to content

Illustrative ex for viz #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
06398c4
Added a 3 link pendulum problem, with massless links. and
tarzzz Jun 18, 2013
11a0059
Added README
tarzzz Jun 18, 2013
d5f2d44
Update three_link_pendulum.py
tarzzz Jun 18, 2013
a61e602
Modified script for two dimensional joints
tarzzz Jun 19, 2013
e69d5cf
Merge branch '3-link-pendulum' of https://github.com/tarzzz/pydy_exam…
tarzzz Jun 19, 2013
89db91f
Added an illustrative example to demonstrate the workflow of
tarzzz Jun 19, 2013
b10d0e5
Updated to include code according to PEP8 style guide
tarzzz Jun 23, 2013
b1a923c
[WIP] Added some base classes for the illustrative example
Jul 9, 2013
aa6a338
[WIP] Some error in the numerical integration of the problem.
Jul 10, 2013
17f8f0b
WIP
Jul 12, 2013
5a79f75
[WIP] Python part nearly complete, some problems with json serialization
Jul 12, 2013
134bf88
WIP
Jul 12, 2013
f769203
[WIP] Completed Python side, although in a dirty way, with some hacks
Jul 13, 2013
31e7b65
WIP Added some javascript code
Jul 14, 2013
7c348e9
WIP Enabled visualizations of the shapes.
Jul 15, 2013
9c10bf6
Added server creating module
Jul 15, 2013
bcbca28
Added indents to JSON Output
Jul 15, 2013
f0aa71b
Added scene.display method in the run script
Jul 15, 2013
3c82531
Added README
Jul 15, 2013
8441d29
WIP
Jul 15, 2013
ae2a57b
Added static orientations to the shape
Jul 15, 2013
e60fe75
Fixed translation bug
Jul 18, 2013
f950c97
WIP Animation bug. I have kept output.json for ease in testing
Jul 19, 2013
cb5ba46
Working example now. Modified both python and Javascript code.
Jul 22, 2013
8314218
Changed time.
moorepants Aug 6, 2013
d11bd84
Modified according to new code for pydy_viz
Aug 12, 2013
5ef35c4
WIP
Aug 18, 2013
733f2ca
Removed white spaces
Aug 18, 2013
85b715e
Modified illustrative_example source
Sep 9, 2013
9fcf6bb
Merge branch 'illustrative-ex-for-viz' of github.com:tarzzz/pydy_exam…
moorepants Sep 9, 2013
4ea2488
Attempt to fix up the animation with correct link lengths and spheres…
moorepants Sep 9, 2013
0fec414
Removed comma.
moorepants Sep 9, 2013
18ad2b2
Removed extraneous line.
moorepants Sep 10, 2013
cde87c8
Modified README
Sep 22, 2013
53bddd4
Modified README
Sep 22, 2013
896a29f
Merge branch 'clean_conical' of https://github.com/PythonDynamics/pyd…
Sep 22, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added an illustrative example to demonstrate the workflow of
pydy_viz
  • Loading branch information
tarzzz committed Jun 19, 2013
commit 89db91f2b447be6b20ae622a15b1c759685b2d95
221 changes: 221 additions & 0 deletions illustrative_example_for_viz/illustrative_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#This program represents a hypothetical situation for a complete workflow
#for simulating a three link pendulum with links as rigid bodies
from sympy import symbols,sympify
from sympy.physics.mechanics import *

#Number of links = 3
N_links = 3

#Number of masses = 3
N_bobs = 3

#Defining Dynamic Symbols ................

#Generalized coordinates(angular) ...

alpha = dynamicsymbols('alpha1 alpha2 alpha3')
beta = dynamicsymbols('beta1 beta2 beta3')

#Generalized speeds(angular) ...
alphad = dynamicsymbols('alpha1 alpha2 alpha3',1)
betad = dynamicsymbols('beta1 beta2 beta3',1)

#Mass of each bob:
m = symbols('m:'+str(N_bobs))


#Length mass and radii of each link(assuming as rods) ..
l = symbols('l:' + str(N_links))
M = symbols('M:' + str(N_links))
radii = symbols('radii:' + str(N_links))

#For storing Inertia for each link :
Ixx = symbols('Ixx:'+str(N_links))
Iyy = symbols('Iyy:'+str(N_links))

#gravity and time ....
g, t = symbols('g t')


#Now defining an Inertial ReferenceFrame First ....

I = ReferenceFrame('I')

#And some other frames ...

A = ReferenceFrame('A')
A.orient(I,'Body',[alpha[0],beta[0],0],'ZXY')
B = ReferenceFrame('B')
B.orient(I,'Body',[alpha[1],beta[1],0],'ZXY')
C = ReferenceFrame('C')
C.orient(I,'Body',[alpha[2],beta[2],0],'ZXY')


#Setting angular velocities of new frames ...
A.set_ang_vel(I, alphad[0] * I.z + betad[0] * I.x)
B.set_ang_vel(I, alphad[1] * I.z + betad[1] * I.x)
C.set_ang_vel(I, alphad[2] * I.z + betad[2] * I.x)



# An Origin point, with velocity = 0
O = Point('O')
O.set_vel(I,0)

#Three more points, for masses ..
P1 = O.locatenew('P1', l[0] * A.y)
P2 = O.locatenew('P2', l[1] * B.y)
P3 = O.locatenew('P3', l[2] * C.y)

#Setting velocities of points with v2pt theory ...
P1.v2pt_theory(O, I, A)
P2.v2pt_theory(P1, I, B)
P3.v2pt_theory(P2, I, C)
points = [P1,P2,P3]

Pa1 = Particle('Pa1', points[0], m[0])
Pa2 = Particle('Pa2', points[1], m[1])
Pa3 = Particle('Pa3', points[2], m[2])
particles = [Pa1,Pa2,Pa3]



#defining points for links(RigidBodies)
#Assuming CoM as l/2 ...
P_link1 = O.locatenew('P_link1', l[0]/2 * A.y)
P_link2 = O.locatenew('P_link1', l[1]/2 * B.y)
P_link3 = O.locatenew('P_link1', l[2]/2 * C.y)

#setting velocities of these points with v2pt theory ...
P_link1.v2pt_theory(O, I, A)
P_link2.v2pt_theory(P_link1, I, B)
P_link3.v2pt_theory(P_link2, I, C)

points_rigid_body = [P_link1,P_link2,P_link3]


#defining inertia tensors for links

inertia_link1 = inertia(A,Ixx[0],Iyy[0],0)
inertia_link2 = inertia(B,Ixx[1],Iyy[1],0)
inertia_link3 = inertia(C,Ixx[2],Iyy[2],0)

#Defining links as Rigid bodies ...

link1 = RigidBody('link1', P_link1, A, M[0], (inertia_link1, O))
link2 = RigidBody('link2', P_link2, B, M[1], (inertia_link2, P1))
link3 = RigidBody('link3', P_link3, C, M[2], (inertia_link3, P2))
links = [link1,link2,link3]


#Defining a basic shape for links ..
rod1 = Cylinder(length=l[0],radii=radii[0])
rod2 = Cylinder(length=l[1],radii=radii[1])
rod3 = Cylinder(length=l[2],radii=radii[2])

link1.shape(rod1)
link2.shape(rod2)
link3.shape(rod3)

#Applying forces on all particles , and adding all forces in a list..
forces = []
for particle in particles:

mass = particle.get_mass()
point = particle.get_point()
forces.append((point, -mass * g * I.y) )

#Applying forces on rigidbodies ..
for link in links:
mass = link.get_mass()
point = link.get_masscenter()
forces.append((point, -mass * g * I.y) )

kinetic_differentials = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a picky comment, but differentials are different from differential equations. Also are these kinematic or kinetic? The word kinetic is sometimes used to mean "dynamic" (that is, coming from F=ma).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are kinematic equations.

On 6/23/13, Christopher Dembia [email protected] wrote:

+#Applying forces on all particles , and adding all forces in a list..
+forces = []
+for particle in particles:
+

  • mass = particle.get_mass()
  • point = particle.get_point()
  • forces.append((point, -mass * g * I.y) )

+#Applying forces on rigidbodies ..
+for link in links:

  • mass = link.get_mass()
  • point = link.get_masscenter()
  • forces.append((point, -mass * g * I.y) )

+kinetic_differentials = []

This is a picky comment, but differentials are different from differential
equations. Also are these kinematic or kinetic? The word kinetic is
sometimes used to mean "dynamic" (that is, coming from F=ma).


Reply to this email directly or view it on GitHub:
https://github.com/PythonDynamics/pydy_examples/pull/11/files#r4833547

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the correct term is "kinematic differential equations"

for i in range(0,N_bobs):
kinetic_differentials.append(alphad[i] - alpha[i])
kinetic_differentials.append(betad[i] - beta[i])

#Adding particles and links in the same system ...
total_system = []
for particle in particles:
total_system.append(particle)

for link in links:
total_system.append(link)

q = []
for angle in alpha:
q.append(angle)
for angle in beta:
q.append(angle)
print q
u = []

for vel in alphad:
u.append(vel)
for vel in betad:
u.append(vel)

print u
kane = KanesMethod(I, q_ind=q, u_ind=u, kd_eqs=kinetic_differentials)
fr, frstar = kane.kanes_equations(forces, total_system)

print fr

#Now we have symbolic equations of motion. ..
# we integrate them numerically. ..

params = [g ,l1,l2,l3,m1,m2,m3,M1,M2,M3]

param_vals = [9.8 ,1.0,1.0,1.0,2,2,2,5,5,5]

right_hand_side = code_generator(kane,params)

#setting initial conditions ..
init_conditions = [radians(45),radians(45),radians(30),\
radians(30),radians(15),radians(15),\
0, 0, 0,\
0, 0, 0]
t = [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]

numerical_vals = odeint(right_hand_side,init_conditions,t)

#Now for each t, we have numerical vals of coordinates ..
#Now we set up a visualization frame,

frame1 = VisualizationFrame('frame1',I,O)

frame1.add_rigidbodies(links)

frame1.add_particles(particles)

param_vals_for_viz = {'g':9.8 ,'l1':1.0,'l2':1.0,'l3':1.0,'m1':2,'m2':2,'m3':2,'M1':5,'M1':5,'M1':5]

json = frame1.generate_json(initial_conditions,q)
#Here we can replace initial_conditions with the conditions at any
#specific time interval ....

##This line does following things ...
##calls RigidBody.transform_matrix() on all rigidbodies,
#so that we have info of rigidbodies(CoM,rotation,translation)
# w.r.t VisualizationFrame('I' in this case)
##Even if they are defined in any other frame ....
##calls point.set_pos() for all particles with arg
##as Point in VisualizationFrame(O here) ..
##With these and init_conditions, we have a starting point of visualization ..

scene = Scene()
Scene.view(json) # Just visualize/view the system at initial_conditions,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lower-case scene

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it should be scene ...

my bad ....

On 6/23/13, Christopher Dembia [email protected] wrote:

+json = frame1.generate_json(initial_conditions, q)
+#Here we can replace initial_conditions with the conditions at any
+#specific time interval ....
+
+##This line does following things ...
+##calls RigidBody.transform_matrix() on all rigidbodies,
+#so that we have info of rigidbodies(CoM,rotation,translation)
+# w.r.t VisualizationFrame('I' in this case)
+##Even if they are defined in any other frame ....
+##calls point.set_pos() for all particles with arg
+##as Point in VisualizationFrame(O here) ..
+##With these and init_conditions, we have a starting point of
visualization ..
+
+scene = Scene()
+Scene.view(json) # Just visualize/view the system at
initial_conditions,

lower-case scene


Reply to this email directly or view it on GitHub:
https://github.com/PythonDynamics/pydy_examples/pull/11/files#r4833824

#w.r.t VIsualizationFrame(I in this case)
# No simulation here. ..

Scene.simulate(json,numerical_vals) # modify the input json,
#Add the values at different times from numerical_vals,
#To the json, which is then passed to
#javascript
#
#(alpha1,alpha2,alpha3,beta1,beta2,beta3) at time=t



157 changes: 157 additions & 0 deletions illustrative_example_for_viz/three_link_pendulum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#For this one we assume RigidBody links
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this file here? I though you have this in another pull request. Do not include it in both PR's.

from sympy import symbols,sympify
from sympy.physics.mechanics import *

#Number of links = 3
N_links = 3

#Number of masses = 3
N_bobs = 3

#Defining Dynamic Symbols ................

#Generalized coordinates(angular) ...

alpha = dynamicsymbols('alpha1 alpha2 alpha3')
beta = dynamicsymbols('beta1 beta2 beta3')

#Generalized speeds(angular) ...
alphad = dynamicsymbols('alpha1 alpha2 alpha3',1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not technically the generalized speeds. The generalized speeds should be defined as:

omega = alpha'

You need to define some generalized speeds, not just the derivatives of the coordinates.

so:

omega1, omega2, omega3 = dynamicsymbols('omega1 omega2 omega3')

And similarly for beta.

betad = dynamicsymbols('beta1 beta2 beta3',1)

#Mass of each bob:
m = symbols('m:'+str(N_bobs))


#Length and mass of each link ..
l = symbols('l:' + str(N_links))
M = symbols('M:' + str(N_links))
#For storing Inertia for each link :
Ixx = symbols('Ixx:'+str(N_links))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8: spaces around operators

Iyy = symbols('Iyy:'+str(N_links))

#gravity and time ....
g, t = symbols('g t')


#Now defining an Inertial ReferenceFrame First ....

I = ReferenceFrame('I')

#And some other frames ...

A = ReferenceFrame('A')
A.orient(I,'Body',[alpha[0],beta[0],0],'ZXY')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8: space after comma

B = ReferenceFrame('B')
B.orient(I,'Body',[alpha[1],beta[1],0],'ZXY')
C = ReferenceFrame('C')
C.orient(I,'Body',[alpha[2],beta[2],0],'ZXY')


#Setting angular velocities of new frames ...
A.set_ang_vel(I, alphad[0] * I.z + betad[0] * I.x)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be

A.set_ang_vel(I, omega1 * I.z + gamma1 * I.x)

B.set_ang_vel(I, alphad[1] * I.z + betad[1] * I.x)
C.set_ang_vel(I, alphad[2] * I.z + betad[2] * I.x)



# An Origin point, with velocity = 0
O = Point('O')
O.set_vel(I,0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8, space after comma


#Three more points, for masses ..
P1 = O.locatenew('P1', l[0] * A.y)
P2 = O.locatenew('P2', l[1] * B.y)
P3 = O.locatenew('P3', l[2] * C.y)

#Setting velocities of points with v2pt theory ...
P1.v2pt_theory(O, I, A)
P2.v2pt_theory(P1, I, B)
P3.v2pt_theory(P2, I, C)
points = [P1,P2,P3]

Pa1 = Particle('Pa1', points[0], m[0])
Pa2 = Particle('Pa2', points[1], m[1])
Pa3 = Particle('Pa3', points[2], m[2])
particles = [Pa1,Pa2,Pa3]



#defining points for links(RigidBodies)
#Assuming CoM as l/2 ...
P_link1 = O.locatenew('P_link1', l[0]/2 * A.y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8: Space around operators.

P_link2 = O.locatenew('P_link1', l[1]/2 * B.y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be:

P_link2 = P1.locatenew('P_link1', l[1] / 2 * B.y)

P_link3 = O.locatenew('P_link1', l[2]/2 * C.y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

P_link3 = P2.locatenew('P_link1', l[2] / 2 * C.y)

#setting velocities of these points with v2pt theory ...
P_link1.v2pt_theory(O, I, A)
P_link2.v2pt_theory(P_link1, I, B)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P_link1 and P_link2 do not exist on the same rigid body so this is incorrect. It should be:

P_link2.v2pt_theory(P1, I, B) 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you meant do not exist on same referenceframe?
because P1 represents a Particle point, not exactly on the rigidbody.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rigid body and reference frame are synonymous in this case. The point should be the one that is at the joints.

P_link3.v2pt_theory(P_link2, I, C)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.


points_rigid_body = [P_link1,P_link2,P_link3]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8: Spaces after commas.



#defining inertia tensors for links

inertia_link1 = inertia(A,Ixx[0],Iyy[0],0)
inertia_link2 = inertia(B,Ixx[1],Iyy[1],0)
inertia_link3 = inertia(C,Ixx[2],Iyy[2],0)

#Defining links as Rigid bodies ...

link1 = RigidBody('link1', P_link1, A, M[0], (inertia_link1, O))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you define your inertia about the origin? Isn't the better way to define your inertia about the center of mass of each link.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I defined on the rotation axis of each rigidbody,
link1 will rotate about O, link2 about P1 etc. Isnt this the correct way>?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "clean" way to define your inertia tensor is about the body's reference frame and the center of mass. (at least in this case). Other times it may be useful to define inertia about other points, depending on the problem.

link2 = RigidBody('link2', P_link2, B, M[1], (inertia_link2, P1))
link3 = RigidBody('link3', P_link3, C, M[2], (inertia_link3, P2))
links = [link1,link2,link3]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8



#Applying forces on all particles , and adding all forces in a list..
forces = []
for particle in particles:

mass = particle.get_mass()
point = particle.get_point()
forces.append((point, -mass * g * I.y) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A one liner:

forces = [(p.get_point(), -p.get_mass() * g * I.y) for p in particles]


#Applying forces on rigidbodies ..
for link in links:
mass = link.get_mass()
point = link.get_masscenter()
forces.append((point, -mass * g * I.y) )
kinetic_differentials = []
for i in range(0,N_bobs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

range(N_bobs) does the same thing.

kinetic_differentials.append(alphad[i] - alpha[i])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be

kinetic_differentials.append(omega1 - alphad[i]) 

omega = alpha'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it really should be kinematic_differential_equations. Kinetic means "involving forces", kinda. And Differentials are like dt; here, we really mean differential equations.

kinetic_differentials.append(betad[i] - beta[i])

#Adding particles and links in the same system ...
total_system = []
for particle in particles:
total_system.append(particle)

for link in links:
total_system.append(link)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be a one liner:

total_system = particles + links


q = []
for angle in alpha:
q.append(angle)
for angle in beta:
q.append(angle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q = alpha + beta

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may have to do:

q = list(q) + list(beta)

print q
u = []

for vel in alphad:
u.append(vel)
for vel in betad:
u.append(vel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u = omega + delta


print u
kane = KanesMethod(I, q_ind=q, u_ind=u, kd_eqs=kinetic_differentials)
fr, frstar = kane.kanes_equations(forces, total_system)

print fr







7 changes: 0 additions & 7 deletions three_link_pendulum/three_link_pendulum.py
Original file line number Diff line number Diff line change
@@ -148,10 +148,3 @@
fr, frstar = kane.kanes_equations(forces, total_system)

print fr