Skip to content

Commit

Permalink
Merge pull request #81 from pydy/system
Browse files Browse the repository at this point in the history
Prototype System class.
  • Loading branch information
chrisdembia committed Aug 7, 2014
2 parents f7399f4 + f6c03a3 commit 64732fd
Show file tree
Hide file tree
Showing 15 changed files with 1,148 additions and 181 deletions.
171 changes: 86 additions & 85 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ PyDy
PyDy_, short for Python Dynamics, is a tool kit written in and accessed through
the Python programming language that utilizes an array of scientific tools to
study multibody dynamics. The goal is to have a modular framework and
eventually a physics abstraction layer which utilizes a variety of backend that
can provide the user with their desired workflow, including:
eventually a physics abstraction layer which utilizes a variety of backends
that can provide the user with their desired workflow, including:

- Model specification
- Equation of motion generation
Expand All @@ -29,7 +29,7 @@ visualization.
Installation
============

The PyDy workflow has hard dependecies on these Python packages:
The PyDy workflow has hard dependencies on these Python packages:

- Python >= 2.7
- setuptools
Expand Down Expand Up @@ -85,11 +85,11 @@ Tests require nose:

- nose: 1.3.0

Isolated Virtual Environment Installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Isolated Environments
~~~~~~~~~~~~~~~~~~~~~

The following installation assumes you have virtualenvwrapper_ and all the
dependencies needed to build the packages::
dependencies needed to build the various packages::

$ mkvirtualenv pydy-dev
(pydy-dev)$ pip install numpy scipy cython nose theano sympy
Expand All @@ -100,6 +100,16 @@ dependencies needed to build the packages::

.. _virtualenvwrapper: https://pypi.python.org/pypi/virtualenvwrappe://pypi.python.org/pypi/virtualenvwrapper

Or with conda_::

$ conda create -n pydy-dev numpy scipy cython nose theano sympy matplotlib
$ source activate pydy-dev
(pydy-dev)$ git clone git@github.com:pydy/pydy.git
(pydy-dev)$ cd pydy
(pydy-dev)$ python setup.py develop

.. _conda: https://github.com/conda/conda

Run the tests::

(pydy-dev)$ nosetests
Expand All @@ -124,61 +134,6 @@ Run the benchmark to test the n-link pendulum problem.::
Usage
=====

Simply import the modules and functions when in a Python interpreter::

>>> from sympy import symbols
>>> from sympy.physics import mechanics
>>> from pydy import codegen, viz

Documentation
=============

The documentation is hosted at http://pydy-viz.readthedocs.org but you can also
build them from source using the following instructions:

Requires:

- Sphinx
- numpydoc

::

pip install sphinx numpydoc

To build the HTML docs::

$ sphinx-build -b html docs/src docs/build

View::

$ firefox docs/build/index.html

Code Generation
===============

This package provides code generation facilities for PyDy_. For now, it
generates functions that can evaluate the right hand side of the ordinary
differential equations generated with sympy.physics.mechanics_ with three
different backends: SymPy's lambdify_, Theano_, and Cython_.

.. _PyDy: http://pydy.org
.. _sympy.physics.mechanics: http://docs.sympy.org/latest/modules/physics/mechanics
.. _lambdify: http://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify
.. _Theano: http://deeplearning.net/software/theano/
.. _Cython: http://cython.org/

Optional Dependencies
---------------------

To enable different code generation backends, you can install the various
optional dependencies:

- Cython: >=0.15.1
- Theano: >=0.6.0

Usage
-----

This is an example of a simple 1 degree of freedom system: a mass, spring,
damper system under the influence of gravity and a force::

Expand Down Expand Up @@ -224,39 +179,31 @@ Derive the system::
particles = [block]

kane = me.KanesMethod(ceiling, q_ind=[position], u_ind=[speed],
kd_eqs=kinematic_equations)
kd_eqs=kinematic_equations)
kane.kanes_equations(forces, particles)

Store the expressions and symbols in sequences for the code generation::
Create a system to manage integration. Specify numerical values for the
constants and specified quantities. Here, we specify sinusoidal forcing::

mass_matrix = kane.mass_matrix_full
forcing_vector = kane.forcing_full
constants = (mass, stiffness, damping, gravity)
coordinates = (position,)
speeds = (speed,)
specified = (force,)
from numpy import array, linspace, sin
from pydy.system import System

Now generate the function needed for numerical evaluation of the ODEs. The
generator can use various back ends: ``lambdify``, ``theano``, or ``cython``::
sys = System(kane,
constants={mass: 1.0, stiffness: 1.0,
damping: 0.2, gravity: 9.8},
specified={'symbols': [force],
'values': lambda x, t: sin(t)},
initial_conditions=array([0.1, -1.0]))

from pydy.codegen.code import generate_ode_function
Now generate the function needed for numerical evaluation of the ODEs::

evaluate_ode = generate_ode_function(mass_matrix, forcing_vector, constants,
coordinates, speeds, specified,
generator='lambdify')
sys.generate_ode_function()

Integrate the equations of motion under the influence of a specified sinusoidal
force::

from numpy import array, linspace, sin
from scipy.integrate import odeint

x0 = array([0.1, -1.0])
args = {'constants': array([1.0, 1.0, 0.2, 9.8]),
'specified': lambda x, t: sin(t)}
t = linspace(0.0, 10.0, 1000)

y = odeint(evaluate_ode, x0, t, args=(args,))
y = sys.integrate(t)

Plot the results::

Expand All @@ -266,14 +213,62 @@ Plot the results::
plt.legend((str(position), str(speed)))
plt.show()

Documentation
=============

The documentation is hosted at http://pydy.readthedocs.org but you can also
build them from source using the following instructions:

Requires:

- Sphinx
- numpydoc

::

pip install sphinx numpydoc

To build the HTML docs::

$ sphinx-build -b html docs/src docs/build

View::

$ firefox docs/build/index.html

Packages
========

Code Generation
---------------

This package provides code generation facilities for PyDy_. For now, it
generates functions that can evaluate the right hand side of the ordinary
differential equations generated with sympy.physics.mechanics_ with three
different backends: SymPy's lambdify_, Theano_, and Cython_.

.. _PyDy: http://pydy.org
.. _sympy.physics.mechanics: http://docs.sympy.org/latest/modules/physics/mechanics
.. _lambdify: http://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify
.. _Theano: http://deeplearning.net/software/theano/
.. _Cython: http://cython.org/

To enable different code generation backends, you can install the various
optional dependencies:

- Cython: >=0.15.1
- Theano: >=0.6.0

Visualization (viz)
===================
-------------------

Visualization of multibody systems generated with PyDy.

Related Packages
================

These are various related Python packages that have similar functionality.

- https://github.com/cdsousa/sympybotics
- https://pypi.python.org/pypi/Hamilton
- https://pypi.python.org/pypi/arboris
Expand All @@ -296,10 +291,16 @@ Related Packages
Release Notes
=============

0.3.0
-----

- Added a new System class and module to more seamlessly manage integrating the
equations of motion.

0.2.1
-----

- Unbundled unecessary files from tar ball.
- Unbundled unnecessary files from tar ball.

0.2.0
-----
Expand Down
2 changes: 1 addition & 1 deletion bin/benchmark_pydy_code_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def run_benchmark(max_num_links, num_time_steps=1000):
# odeint arguments
x0 = hstack((0, pi / 2 * ones(len(results[3]) - 1), 1e-3 *
ones(len(results[4]))))
args = {'constants': array(parameter_vals)}
args = {'constants': dict(zip(results[2], array(parameter_vals)))}
t = linspace(0, 10, num_time_steps)

for k, method in enumerate(methods):
Expand Down
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ codegen package

codegen/api.rst

System class
------------

.. toctree::
:maxdepth: 1

system.rst

viz package
-----------

Expand Down
7 changes: 7 additions & 0 deletions docs/system.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
System class
============

.. automodule:: pydy.system

.. autoclass:: pydy.system.System
:members:
16 changes: 8 additions & 8 deletions examples/double_pendulum/double_pendulum.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
KM = KanesMethod(N, q_ind=[q1, q2], u_ind=[u1, u2], kd_eqs=kd)


(fr, frstar) = KM.kanes_equations(FL, BL)
kdd = KM.kindiffdict()
mass_matrix = KM.mass_matrix_full
forcing_vector = KM.forcing_full
qudots = mass_matrix.inv() * forcing_vector
qudots = qudots.subs(kdd)
qudots.simplify()

KM.kanes_equations(FL, BL)
#kdd = KM.kindiffdict()
#mass_matrix = KM.mass_matrix_full
#forcing_vector = KM.forcing_full
#qudots = mass_matrix.inv() * forcing_vector
#qudots = qudots.subs(kdd)
#qudots.simplify()
#
43 changes: 8 additions & 35 deletions examples/double_pendulum/simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,22 @@
"""

from numpy import concatenate, array, linspace
from pydy.codegen.code import generate_ode_function
from pydy.system import System
from scipy.integrate import odeint

from double_pendulum import *

# List the symbolic arguments
# ===========================

# Constants
# ---------

constants = {l: 10.0, m: 10.0, g: 9.81}

# Time-varying
# ------------

coordinates = [q1, q2]

speeds = [u1, u2]


# Generate function that returns state derivatives
# ================================================

xdot_function = generate_ode_function(mass_matrix, forcing_vector,
constants.keys(), coordinates, speeds)
initial_conditions = {q1: 1.0, q2: 0.0, u1: 0.0, u2: 0.0}


# Specify numerical quantities
# ============================

initial_coordinates = [1.0, 0.0]
initial_speeds = [0.0, 0.0]
x0 = concatenate((initial_coordinates, initial_speeds), axis=1)

args = {'constants': constants.values()}


# Simulate
# ========
sys = System(KM, constants=constants,
initial_conditions=initial_conditions)

frames_per_sec = 60
final_time = 5.0

t = linspace(0.0, final_time, final_time * frames_per_sec)
x = odeint(xdot_function, x0, t, args=(args,))
times = linspace(0.0, final_time, final_time * frames_per_sec)

x = sys.integrate(times)

2 changes: 1 addition & 1 deletion examples/double_pendulum/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
# Create the visualization
# ========================

scene.generate_visualization_json(coordinates + speeds, constants.keys(), x,
scene.generate_visualization_json(sys.states, constants.keys(), x,
constants.values())

scene.display()
2 changes: 1 addition & 1 deletion examples/three_link_conical_pendulum/simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@

print("Integrating equations of motion.")
state_trajectories = odeint(right_hand_side, x0, t,
args=({'constants': param_vals},))
args=({'constants': dict(zip(param_syms, param_vals))},))
print("Integration done.")
Loading

0 comments on commit 64732fd

Please sign in to comment.