Skip to content
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

Illustrative ex for viz #11

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
25 changes: 25 additions & 0 deletions illustrative_example_for_viz/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
To run and see this visualization working, you need to first install PyDyViz.

Install Instructions for PyDyViz
================================

1) Get the source code from repository::

$ git clone https://github.com/PythonDynamics/pydy-viz

2) Add the directory to the PYTHONPATH::
Copy link
Member

Choose a reason for hiding this comment

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

It would be better to instruct them to actually install it here:

cd pydy-viz
python setup.py install # use sudo if you want system wide install

Copy link
Member

Choose a reason for hiding this comment

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

You can do the python path trick addition as an option.

Copy link
Member

Choose a reason for hiding this comment

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

It'd be best if you showed how to run each file in this directory indenpendently. You have the derivation file, the simulation, and the visualization.

Ideally the user could type three commands to run things individually:

python derive.py
python simulate.py
python visualize.py

The results of the previous command could be pickled to file so that the subsequent file could load the data. If the data isn't available on disk, then it can run

try:
    open('simulate-data.p')
except IOError:
    import simulate # runs simulate.py if data doesn't exits

# do the simulation ...

# pickle the results
pickle.dump(simulation_results)


$ export PYTHONPATH=$PYTHONPATH:/path/to/directory/pydy-viz

3) Now you can run the example from this script::

$ python illustrative_example.py


In case there are any difficulties to get it working, Please feel free to contact our `mailing list`_.

.. _mailing list: http://groups.google.com/group/pydy




52 changes: 52 additions & 0 deletions illustrative_example_for_viz/code_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python

from sympy import Dummy, lambdify
from sympy.external import import_module

np = import_module('numpy')

def numeric_right_hand_side(kane, parameters):
"""Returns the right hand side of the first order ordinary differential
equations from a KanesMethod system which can be evaluated numerically.

This function probably only works for simple cases (no dependent speeds,
specified functions).

"""

dynamic = kane._q + kane._u
dummy_symbols = [Dummy() for i in dynamic]
dummy_dict = dict(zip(dynamic, dummy_symbols))
kindiff_dict = kane.kindiffdict()

M = kane.mass_matrix_full.subs(kindiff_dict).subs(dummy_dict)
F = kane.forcing_full.subs(kindiff_dict).subs(dummy_dict)

M_func = lambdify(dummy_symbols + parameters, M)
F_func = lambdify(dummy_symbols + parameters, F)

def right_hand_side(x, t, args):
"""Returns the derivatives of the states.

Parameters
----------
x : ndarray, shape(n)
The current state vector.
t : float
The current time.
args : ndarray
The constants.

Returns
-------
dx : ndarray, shape(2 * (n + 1))
The derivative of the state.

"""
arguments = np.hstack((x, args))
dx = np.array(np.linalg.solve(M_func(*arguments),
F_func(*arguments))).T[0]

return dx

return right_hand_side
32 changes: 32 additions & 0 deletions illustrative_example_for_viz/illustrative_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#Export method calls and namespace
# from three_link_pendulum example ..

from three_link_pendulum import I, O, links, particles, kane
from simulate import params, states, param_vals
from simulate import link_length, link_radius, particle_radius
from pydy_viz.shapes import Cylinder, Sphere
from pydy_viz.scene import Scene
from pydy_viz.visualization_frame import VisualizationFrame

viz_frames = []

for i, (link, particle) in enumerate(zip(links, particles)):

link_shape = Cylinder('cylinder{}'.format(i), radius=link_radius,
length=link_length, color='red')
viz_frames.append(VisualizationFrame('link_frame{}'.format(i), link,
link_shape))

particle_shape = Sphere('sphere{}'.format(i), radius=particle_radius,
color='blue')
viz_frames.append(VisualizationFrame('particle_frame{}'.format(i),
link.frame, particle,
particle_shape))

scene = Scene(I, O, *viz_frames)

print('Generating transform time histories.')
scene.generate_visualization_json(kane._q + kane._u, params, states,
param_vals)
print('Done.')
scene.display()
38 changes: 38 additions & 0 deletions illustrative_example_for_viz/simulate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#This script produces the numerical integration for the EoMs
#generated by three_link_pendulum.py

from three_link_pendulum import l, m, M, Ixx, Iyy, Izz, g, kane
from scipy.integrate import odeint
from code_gen import numeric_right_hand_side
from numpy import radians, linspace, hstack, zeros, ones

params = list(l) + list(m) + list(M) + list(Ixx) + list(Iyy) + list(Izz) + [g]
Copy link
Member

Choose a reason for hiding this comment

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

this is messy, there's got to be a nicer way to do this


link_length = 10.0 # meters
link_mass = 10.0 # kg
link_radius = 0.5 # meters
link_ixx = 1.0 / 12.0 * link_mass * \
(3 * link_radius ** 2 + link_length ** 2)
link_iyy = link_mass * link_radius ** 2
link_izz = link_ixx

particle_mass = 5.0 # kg
particle_radius = 1.0 # meters

param_vals = [link_length for x in l] + \
[particle_mass for x in m] + \
[link_mass for x in M] + \
[link_ixx for x in list(Ixx)] + \
[link_iyy for x in list(Iyy)] + \
[link_izz for x in list(Izz)] + \
[9.8]

print("Generating numeric right hand side.")
right_hand_side = numeric_right_hand_side(kane, params)

t = linspace(0.0, 60.0, num=6000)
x0 = hstack((ones(6) * radians(10.0), zeros(6)))

print("Integrating equations of motion.")
states = odeint(right_hand_side, x0, t, args=(param_vals,))
print("Integration done.")
129 changes: 129 additions & 0 deletions illustrative_example_for_viz/three_link_pendulum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#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
import sympy.physics.mechanics as me

print("Defining the problem.")
#Number of links = 3
N_links = 3

#Number of masses = 3
N_bobs = 3

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

#Generalized coordinates(angular) ...

alpha = me.dynamicsymbols('alpha:{}'.format(N_links))
beta = me.dynamicsymbols('beta:{}'.format(N_links))

#Generalized speeds(angular) ...
omega = me.dynamicsymbols('omega:{}'.format(N_links))
delta = me.dynamicsymbols('delta:{}'.format(N_links))

#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))
Iyy = symbols('Iyy:' + str(N_links))
Izz = symbols('Izz:' + str(N_links))

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

#Now defining an Inertial ReferenceFrame First ....

I = me.ReferenceFrame('I')

#And some other frames ...

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

#Setting angular velocities of new frames ...
A.set_ang_vel(I, omega[0] * I.z + delta[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 angular velocity definitions are not consistent with your Body fixed rotations. These should be:

A.set_ang_vel(I, omega[0] * I.z + delta[0] * (cos(alpha[0]) * I.x + sin(alpha[0[) * I.y))

Or you can change your orientations to Space fixed and leave these definitions as is.

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

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

#Three more points, for masses ..
P1 = O.locatenew('P1', -l[0] * A.y)
P2 = P1.locatenew('P2', -l[1] * B.y)
P3 = P2.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 = me.Particle('Pa1', points[0], m[0])
Pa2 = me.Particle('Pa2', points[1], m[1])
Pa3 = me.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 = P1.locatenew('P_link2', -l[1] / 2 * B.y)
P_link3 = P2.locatenew('P_link3', -l[2] / 2 * C.y)

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

points_rigid_body = [P_link1, P_link2, P_link3]

#defining inertia tensors for links

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

#Defining links as Rigid bodies ...

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

#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))

kinematic_differentials = []
for i in range(0, N_bobs):
kinematic_differentials.append(omega[i] - alpha[i].diff(t))
kinematic_differentials.append(delta[i] - beta[i].diff(t))

#Adding particles and links in the same system ...
total_system = links + particles

q = alpha + beta

u = omega + delta

print("Generating equations of motion.")
kane = me.KanesMethod(I, q_ind=q, u_ind=u, kd_eqs=kinematic_differentials)
fr, frstar = kane.kanes_equations(forces, total_system)
print("Derivation complete.")
Empty file modified mass_spring/code_gen.py
100755 → 100644
Empty file.
2 changes: 2 additions & 0 deletions mass_spring/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
def visualize(coordinate_time):
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?

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 was trying to make the example work with IPython too, but ran into some trouble.
This is remniscient of that. Will remove it now.

Copy link
Member

Choose a reason for hiding this comment

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

ok

Copy link
Member

Choose a reason for hiding this comment

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

Doesn't this still need to be removed?

#we will replace the data in the js_data file
js_data = re.sub("#\(coordinates_time\)", str(coordinate_time), js)
f = open('output.js','w')
f.write(js_data)
display(Javascript(js_data))
2 changes: 2 additions & 0 deletions three_link_pendulum/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This is a 3 link pendulum problem, assuming links as RigidBodies ..
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 will add a fig soon ..
Loading