CONSTRAINED MULTIBODY DYNAMICS WITH PYTHON: FROM SYMBOLIC

EQUATION GENERATION TO PUBLICATION

Gilbert Gede∗

, Dale L. Peterson, Angadh S. Nanjangud, Jason K. Moore, Mont Hubbard

Sports Biomechanics Laboratory

Department of Mechanical and Aerospace Engineering

University of California

Davis, California 95616

Email: {ggede, dlpeterson, asnanjangud, jkmoor, mhubbard}@ucdavis.edu

ABSTRACT

Symbolic equations of motion (EOMs) for multibody systems

are desirable for simulation, stability analyses, control system

design, and parameter studies. Despite this, the majority of en-

gineering software designed to analyze multibody systems are

numeric in nature (or present a purely numeric user interface).

To our knowledge, none of the existing software packages are 1)

fully symbolic, 2) open source, and 3) implemented in a popular,

general, purpose high level programming language. In response,

we extended SymPy (an existing computer algebra system imple-

mented in Python) with functionality for derivation of symbolic

EOMs for constrained multibody systems with many degrees of

freedom. We present the design and implementation of the soft-

ware and cover the basic usage and workﬂow for solving and

analyzing problems. The intended audience is the academic re-

search community, graduate and advanced undergraduate stu-

dents, and those in industry analyzing multibody systems. We

demonstrate the software by deriving the EOMs of a N-link pen-

dulum, show its capabilities for L

A

T

E

X output, and how it inte-

grates with other Python scientiﬁc libraries - allowing for nu-

merical simulation, publication quality plotting, animation, and

online notebooks designed for sharing results. This software ﬁlls

a unique role in dynamics and is attractive to academics and

industry because of its BSD open source license which permits

open source or commercial use of the code.

∗Address all correspondence to this author

INTRODUCTION

There are many dynamic systems which can be better or

more effectively studied when their EOMs are accessible in a

symbolic form. For equations that may be visually inspected

(i.e., of reasonable length), symbolics are generally preferable

because the interrelations of the variables and constants can give

clear understanding to the nature of the problem without the need

for numerical simulation. Many classic problems ﬁt this cate-

gory, such as the mass-spring-damper, double pendulum, rolling

disc, rattleback, and tippy-top. The beneﬁts of symbolic equa-

tions of motion are not limited to these basic problems though.

Larger, more complicated multibody systems can also be stud-

ied more effectively when the equations of motion are available

symbolically. Advanced simpliﬁcation routines can sometimes

reduce the length of the equations such that they are human read-

able and the intermediate derivation steps are often short enough

that symbolic checks can be used to validate the correctness. Fur-

thermore, the symbolic form of the EOMs often evaluate much

faster than their numerical counterparts, which is a signiﬁcant

advantage for real time computations. Problems in biomechan-

ics, spacecraft dynamics, and single-track vehicles have all been

successfully studied using symbolic EOMs.

Having the symbolic equations of motion available permits

numerical simulation, but also allows for a more mathemati-

cal study of the system in question. System behavior can be

studied parametrically by examining coefﬁcients in the differ-

ential equations. This includes symbolic expressions for equi-

Proceedings of the ASME 2013 International Design Engineering Technical Conferences and

Computers and Information in Engineering Conference

IDETC/CIE 2013

August 4-7, 2013, Portland, Oregon, USA

DETC2013-13470

1

Copyright © 2013 by ASME

Downloaded From: http://proceedings.asmedigitalcollection.asme.org/ on 11/03/2014 Terms of Use: http://asme.org/terms

libria points and symbolic conditions for the stability of these

points. The symbolic form also allows for more complicated

tasks, such as analyzing how inﬁnitesimal changes in system pa-

rameters (masses, lengths, inertias) affect the dynamics, study-

ing lumped parameter discretization sizing, and analyzing how

coordinate choices affect problem complexity or conﬁguration

singularities. It also becomes possible to share the equations of

motion in a “written” form to other individuals for collaboration,

validation, or comparison reasons. This allows for the EOMs to

be used with other software packages, for multi-domain simu-

lation, hardware-in-the-loop testing, or for use in optimal con-

trol/optimization problems.

Before adequate computing technology was available, the

equations of motion for multibody dynamics problems were

formed by hand. There are many methodologies to obtain the

correct equations of motion (Newton-Euler, Lagrange, Kane,

Hamilton, etc). But all methods are tedious and error-prone when

derived by hand, which limits the size and complexity of systems

which can be studied. It only takes a handful of unique orienta-

tions between a small set of rigid bodies within the system to

reach this point of complexity. The introduction of computer al-

gebra systems (CAS) has reduced the difﬁculty involved in form-

ing the equations of motion, but it has not completely eliminated

these problems. However, the details of the symbolic algebra,

differentiation, and vector calculus can be handled by a reliable

CAS, eliminating the errors associated with those operations, al-

lowing the user to think more about the implications of the dy-

namic equations.

The software presented herein addresses some of the lim-

itations of hand derivations and allows for the symbolic study

of complex multibody dynamics problems. There already ex-

ist software packages which similarly meet these limited criteria

(e.g. Autolev/MotionGenesis, AutoSim/VehicleSim). But when

developing our software, we also included these unique require-

ments:

1. The software should be open source with a liberal li-

cense, encourage collaborative development, ensure contin-

ued project development, not be limited by or rely on any

individual or organization, and allow easy integration and

use by other projects.

2. The software should be written in a popular high level pro-

gramming language that balances efﬁcient execution speed

with efﬁcient programmer development time, and has a wide

selection of scientiﬁc libraries (or can conveniently interface

with libraries written in other languages).

3. The software should be built on top of an existing full-

featured symbolic CAS that is also open source.

4. The software should easily export the equations in formats

that are publication friendly (i.e., L

A

T

E

X) or are compatible

with other popular computing platforms and languages (i.e.,

Modelica, C/C++/Fortan, MATLAB).

To meet these criteria, we selected Python as the program-

ming language to implement our software. Python is interactive,

high level, easy to learn, widely available, widely used, cross

platform, open source, and has a large scientiﬁc user base.

Our software is distributed as a sub-package of SymPy [1],

which is a full featured CAS written in Python. SymPy is part of

the SciPy Stack [2] speciﬁcation and is included with all scien-

tiﬁc Python distributions including Enthought, Sage, Anaconda,

and Python(x,y). SymPy is one of the more actively developed

Python packages with a large number of maintainers, ensuring

a long future. The SymPy development model allows new func-

tionality to be easily added and allows for other users to view our

code, suggest additional features, and improve upon and add to

what we have already done, as well as ensure that the our code

is constantly tested against any changes or updates to the base

symbolic functionality offered by SymPy.

In this paper, we discuss two main topics: 1) The interface to

the EOM generation sub-package sympy.physics.mechanics, and

2) the workﬂow for studying multibody dynamic systems (from

derivation to simulation and visualization), which we call Python

Dynamics (PyDy). We will explore these two topics through an

explanation of the software design and by demonstrating a test

problem which displays software functionality and usage, how

our software is incorporated into a workﬂow for analyzing dy-

namic systems, and the results of these processes. We will then

discuss a number of other features, internal constructions within

our software, and veriﬁcation with benchmark examples.

DEMONSTRATION PROBLEM

We now demonstrate the value of PyDy through the deriva-

tion of the N-pendulum system shown in Figure 1. The system is

deﬁned by Nmassless links of length liwith particles of mass mi

ﬁxed at one end. We selected this problem because it illustrates

the power and utility of having EOM generation code available

within a full-featured programming language. The angular ve-

locity of each and every link must be found, as well as the veloc-

ity of each particle. The velocity of i-th particle is

¯vi=¯vi−1+¯

ωi×¯ri(i=1,...,N)

This nesting of velocities is best addressed with a loop,

something that a computer is well suited for (loop unrolling is

difﬁcult by hand when there are many steps and Nis large).

There are thirty-seven lines of source code required to derive the

dynamic equations of motion for the Npendulum, where Nis the

number of links, is shown in Figure 2.

The script ﬁrst imports necessary functions and classes, then

declares a number of symbolic variables that represent general-

ized coordinates, generalized speeds, constant parameters, refer-

ence frames, points and particles. A few empty lists are created

2

Copyright © 2013 by ASME

Downloaded From: http://proceedings.asmedigitalcollection.asme.org/ on 11/03/2014 Terms of Use: http://asme.org/terms

ˆ

ay

ˆ

ax

g

q0

l0

m0

q1

l1

m1

.

.

.

.

.

.

qN−1

lN−1

mN−1

FIGURE 1. N-pendulum system, a sequence of massive links con-

nected by revolute joints subjected to a gravitational ﬁeld.

before the for loop is entered; these lists are ﬁlled by the loop.

When the ﬁnal iteration of the for loop is complete, the kinemat-

ics and all active forces of the problem have been completely

speciﬁed. The last two lines of the script take this speciﬁca-

tion of kinematics and dynamics and generate Kane’s dynam-

ical equations of motion (Fr+F∗

r=0) in symbolic form. At

this point, these equations may be manipulated as fully symbolic

variables for a variety of purposes. For example, the command

mlatex(fr) generates L

A

T

E

X code for the generalized active

force Fr, which renders as:

gl0m0sin(q0)+gl0m1sin(q0)+gl0m2sin(q0)+gl0m3sin(q0)

gl1m1sin(q1)+gl1m2sin(q1)+gl1m3sin(q1)

gl2m2sin(q2)+gl2m3sin(q2)

gl3m3sin(q3)

(1)

with no further modiﬁcation from the user.

There are other options besides L

A

T

E

X output which are use-

ful. Within a console, commands to “pretty print” symbolic ex-

pressions can be performed with mpprint, which generates the

output formatted just like the L

A

T

E

X equation above, but within

the terminal.

FIGURE 4. Time history of generalized coordinates and speeds for a

4 link pendulum.

Another part of studying dynamic systems is simulation and

visualization of the results. SymPy can only analytically solve

simple ODEs, so the equations of motion generated for more

complex systems need to be passed to other numerical integra-

tors. Currently, sympy.physics.mechanics can make use of exist-

ing SymPy translation functions, but more advanced options to

generate compiled code are being developed and guided by user

demands. The SymPy translation function lambdify can con-

vert symbolic expressions to a NumPy compatible function. The

code in Figure 3 (which is executed after the previously written

code) shows this method.

NumPy is an integral part of the larger Scientiﬁc Python

ecosystem, focusing primarily on numerical arrays and matrices

and operations on these arrays and matrices. SciPy is another

part of this ecosystem that provides quick and simple Python

wrappers to a large library of legacy scientiﬁc code. The third

necessary component of this ecosystem is matplotlib, a Python

plotting library for visualization of the large datasets generated

by NumPy and SciPy code. Using these three Python packages,

we can numerically integrate ODEs and plot the results, which

are shown in Figure 4.

Using other Python packages, such as MayaVi, 3D anima-

tions can be created. Use of human-interface-devices (with a suf-

ﬁciently fast computer) allows for real-time interaction between

a user and a visualized simulation.

3

Copyright © 2013 by ASME

Downloaded From: http://proceedings.asmedigitalcollection.asme.org/ on 11/03/2014 Terms of Use: http://asme.org/terms

from sympy import symbols # Import the symbols function

from sympy.physics.mechanics import *# Import mechanics classes

n = 4 # Number of links in N-pendulum

q = dynamicsymbols(’q:’ + str(n)) # Generalized coordinates

u = dynamicsymbols(’u:’ + str(n)) # Generalized speeds

m = symbols(’m:’ + str(n)) # Mass of each link

l = symbols(’l:’ + str(n)) # Length of each link

g, t = symbols(’g t’) # gravity and time symbols

A = ReferenceFrame(’A’) # Inertial reference frame

frames = [] # List to hold n link frames

P = Point(’P’) # Hinge point of top link

P.set_vel(A, 0) # Set velocity of P in A to be 0

particles = [] # List to hold N particles

forces = [] # List to hold N applied forces

kin_odes = [] # List to hold kinematic ODE’s

for i in range(n):

Ai = A.orientnew(’A’ + str(i), ’Axis’, [q[i], A.z]) # Create a new frame

Ai.set_ang_vel(A, u[i] *A.z) # Set angular velocity

frames.append(Ai) # Add it to Frames list

Pi = P.locatenew(’P’ + str(i), l[i] *Ai.x) # Create a new point Pi

Pi.v2pt_theory(P, A, Ai) # Set velocity of Pi

Pai = Particle(’Pa’ + str(i), Pi, m[i]) # Create a new particle

particles.append(Pai) # Add Pai to Particles list

forces.append((Pi, m[i] *g*A.x)) # Set force applied at i-th Point

P = Pi # P is now the lowest Point

kin_odes.append(q[i].diff(t) - u[i]) # Kinematic ODE: dq_i/dt-u_i=0

kane = KanesMethod(A, q_ind=q, u_ind=u, kd_eqs=kin_odes)# Generate EoM’s:

fr, frstar = kane.kanes_equations(forces, particles) # fr + frstar = 0

FIGURE 2. User Python script to derive equations of motion for N-pendulum

SOFTWARE VALIDATION

Anytime new software is developed to generate equations

of motion, the validity and accuracy of the software comes into

question. We have addressed these concerns in three ways to en-

sure that our code does generate correct equations of motion for

arbitrarily complex systems. Firstly, the code is open source and

well documented. This allows anyone to review the code and

check for bugs. Linus’s Law “given enough eyeballs, all bugs

are shallow” [3] applies, if true. Secondly, the code functionality

is thoroughly checked with unit testing; each piece of indepen-

dent functionality in the code has a test (known input/output) in

place that guarantees correct functioning of each unit. This en-

sures that not only the current code works as expected, but also

that future versions are automatically checked against the same

expected behavior. Thirdly, there are built in tests for well bench-

marked problems in mutlibody dynamics. There are many prob-

lems, both simple and complex, that have well known symbolic

solutions. We have chosen several benchmark problems that in-

clude sequential rotations, conﬁguration and motion constraints,

and examination of noncontributing forces. These problems are

4

Copyright © 2013 by ASME

from pylab import *

from sympy import Dummy, lambdify

from scipy.integrate import odeint

parameters = [g] # Parameter Definitions

parameter_vals = [9.81] # First we define gravity

for i in range(n):

parameters += [l[i], m[i]] # Then each mass

parameter_vals += [1. / n, 0.01 / n] # and length

dummy_symbols = [Dummy() for i in q + u] # Necessary to translate

dummy_dict = dict(zip(q + u, dummy_symbols)) # out of functions of time

kds = kane.kindiffdict() # Need to eliminate qdots

mm_sym = kane.mass_matrix_full.subs(kds).subs(dummy_dict) # Substituting away qdots

fo_sym = kane.forcing_full.subs(kds).subs(dummy_dict) # and in dummy symbols

mm = lambdify(dummy_symbols + parameters, mm_sym) # The actual call that gets

fo = lambdify(dummy_symbols + parameters, fo_sym) # us to a NumPy function

def rhs(y, t, args): # Creating the rhs function

vals = hstack((y, args)) # States and parameters

sol = linalg.solve(mm_sym(*vals), fo_sym(*vals)) # Solving for the udots

return array(sol).T[0]

y0 = hstack((arange(n) *0.01, arange(n) *0)) # Initial conditions, q & u

t = linspace(0, 10, 1000) # Time vector

y = odeint(rhs, y0, t, args=(parameter_vals,)) # Actual integration

FIGURE 3. User input Python script to perform numerical integration

built into the test suite for the package.

Built in tests which validate the equations of motion that

are generated include: varying degrees of freedom spring-

mass-damper systems, various pendulums, multiple rolling

disc examples testing auxiliary and dependent speeds, and an

inverted-pendulum cart. These are all compared to results

found by hand (checked multiple times). The other parts of

sympy.physics.mechanics include hundreds of tests on other

pieces of the overall functionality.

There are also some external (non-automated) tests which

are more advanced. Currently, the most complicated test vali-

dates the formulation of the equations of motion for a bicycle

(a system with conﬁguration and velocity constraints), symboli-

cally linearizes it, and compares it (successfully) to benchmark

values presented in [4].

USAGE

This section deals with obtaining the software demonstrated

in this paper and the available resources for learning to use it.

All of the software demonstrated in this paper can be readily ob-

tained for free and installed on virtually any platform. Also, all

of the packages are liberally licensed with a BSD or compatible

license and either stable releases or development branches can be

downloaded.

To obtain and use the core mechanics package for sym-

bolic equation of motion generation, one must simply down-

load and install Python version 2.5+ and SymPy version 0.7.2+1.

Download and installation instructions for each can be found

on the softwares’ respective web sites, www.python.org and

www.sympy.org.

To run a full PyDy example from equation of motion gener-

ation to simulation and visualization, Python and at least the Sci-

entiﬁc Python stack (SciPy) [2] must be obtained. SciPy provides

more comprehensive installation instructions than space permits

1One of the major requirements for code added to SymPy is that every func-

tion and object has to be thoroughly tested and documented. SymPy has over 88%

of its code tested by the automated unit-tests. This ensures that no update causes

regressions or breaks current functionality. Generally, the SymPy development

branch is more stable and contains fewer bugs than the numbered releases.

5

Copyright © 2013 by ASME

here, but we make use of these packages in the SciPy stack in the

previous demo problem:

SymPy: http://sympy.org/

NumPy: http://www.numpy.org/

SciPy: http://www.scipy.org/

matplotlib: http://matplotlib.org/

Download and installation instructions for various platforms

are available on their respective web sites. But it is worth noting

that these packages are part of most of the widely used scientiﬁc

Python distributions. Downloading a distribution binary is gen-

erally the easiest method of installing all of the needed software

for a user unfamiliar with Python. Popular scientiﬁc distributions

that provide the needed software are listed below:

Enthought: http://www.enthought.com/

Sage: http://www.sagemath.org/

Anaconda: http://continuum.io/

Python(x,y): http://www.pythonxy.com

The ﬁrst step in doing multibody dynamics with Python is

to get familiar using mechanics2. The ﬁrst stop is the SymPy

documentation which is available online [5]. The documentation

provides detailed instructions on installation, has introductory tu-

torials, lists common mistakes, details development procedures

and the internal architecture, and contains detailed documenta-

tion for all of the subpackages and modules. In particular, the

mechanics documentation contains over 60 pages that aim to

provide an overview of using the package and a brief introduction

to the fundamentals dynamics. Several example classic dynamics

problems are included in the documentation and there are even

more in the mechanics.tests package. Working through

the material in the mechanics documentation will provide the

basics of generating the symbolic equations of motion of multi-

body systems.

Additionally, a wiki for PyDy is maintained at

www.pydy.org. This is a user-editable guide to solving dy-

namics problems in Python, and contains numerous introductory

examples that demonstrate the process from system deﬁni-

tion to simulation and visualization, examples of interfacing

mechanics with various compiled languages, and more

advanced use cases to demonstrate capabilities. As the PyDy

workﬂow is integrated into more university courses, the goal is

to allow professors, teaching assistants, and students to utilize,

reﬁne, and expand the wiki.

Finally, each of the software packages listed above main-

tains email lists and IRC channels for “live” help and the com-

munities supporting the software are quite amicable to beginners.

The PyDy Google Group is a good place to start if you have ques-

tions [6].

2Some may prefer to learn Python and the SciPy Stack ﬁrst, but the authors

do not think this is such a necessity. It boils down to preference and learning

style.

SOFTWARE DESIGN

The software design for mechanics is inﬂuenced by

Python’s object oriented nature, the underlying SymPy data

types, Kane’s method for generating equations of motion [7] for

multibody systems, and the proprietary (now defunct) software,

Autolev [8], which also implemented Kane’s method in a sym-

bolic fashion.

Kane’s method powers many of the dynamic system soft-

ware packages available [9, 10] due to its detailed bookkeeping

design and ease of mapping to programming languages. Kane’s

method has inﬂuenced the design of mechanics a great deal,

but the code is structured so that any method for deriving the

equations can be used. This is possible because we separated the

kinematic code from the equations of motion generation code.

We have recently included Lagrange’s method to demonstrate

that unique ability.

SymPy’s symbolic manipulation library provides the core

functionality for the mechanics package. The majority of ob-

jects that are created when using SymPy are expression objects,

Expr. Other symbolic objects in SymPy, such as symbols, adds

and muls, or exponentials are inherited from the Expr class. The

mechanics package is dependent on these objects, but not via

inheritance. mechanics is made up of a number of classes and

functions spread out over several modules which are explained

in the following list:

essential.py contains the basic building blocks for working with

vector calculus and dynamic systems and includes the fol-

lowing classes and functions:

ReferenceFrame is a class that represent a rotational refer-

ence frame in a dynamic system. ReferenceFrame

has three orthonormal basis unit vectors and man-

ages information about the frame’s orientation, an-

gular velocity, and angular acceleration relative to

other reference frames through a direction cosine

matrix and velocity and acceleration vectors. It

is closely interlinked to the Vector class, i.e.

Vectors have associated ReferenceFrames and

ReferenceFramess have associated Vectors.

Vector is a class that represents a generic three dimensional

vector built from components in multiple frames of ref-

erence. Vectors support all of the common operations

as one would expect such as addition, subtraction, mul-

tiplication, division, dot products, cross products, outer

products, re-expression into different reference frames,

and frame dependent differentiation.

Dyadic is a class that represents a generic Dyadic. Dyadics

are used in this software as a basis independent method

of deﬁning an inertia tensor. Dyadics support all of the

common operations, similar to the Vector class.

dynamicsymbols is a function that is used to facilitate

the generation of time dependent quantities and their

6

Copyright © 2013 by ASME

derivatives. These variables are created as SymPy

Functions of time, where the default time is the

symbols t.

point.py contains the Point class. This class manages and

tracks the location, velocity, and acceleration of a point in

space relative to another point. It also provides some con-

venience methods to set velocities and accelerations via the

one point and two point theories [7].

functions.py contains an assortment of convenience functions.

For example there is a function for generating inertia dyadics

from tensor notation, a function that outputs kinematical dif-

ferential equations for various body or spaced ﬁxed coordi-

nates and speeds, functions to generate linear and angular

momenta or kinetic and potential energies for a general sys-

tem of particles and bodies, among others.

particle.py contains the Particle class which functions as a

container class for a point and an associated mass. It also

has methods for computing momentum and energy.

rigidbody.py contains the RigidBody is analogous to the

Particle class but for rigid bodies and contains mass,

mass center, inertia, and a reference frame associated with

the rigid body. It also has methods for momentum and en-

ergy.

kane.py contains the KanesMethod class which automates

the generation of a system’s non-linear equations of motion

using Kane’s method [7] and linear equations of motion us-

ing the method presented in [11]. A KanesMethod object

is initialized with an inertial reference frame, set of particles

and/or rigid bodies, a set of forces and torques acting on the

system, the desired kinematical differential equations, the

desired independent and dependent generalized speeds, any

conﬁguration constraints, any velocity constraints, and any

auxiliary speeds needed to compute non-contributing forces.

lagrange.py contains the LagrangesMethod class which au-

tomates the generation of a system’s non-linear equations of

motion via the methods of Lagrangian mechanics [12]. To

derive the equations of motion of a constrained system using

Lagrange’s equations, one requires the conﬁguration and ve-

locity constraint equations, if any, before proceeding to de-

rive a complete set of dynamical equations that describe said

system. The LagrangesMethod object is initialized with

a Lagrangian and the desired generalized coordinates and

optionally forces acting on the system, velocity constraints,

and an inertial reference frame. If velocity constraints are

supplied, Lagrange multipliers are generated to account for

them and non-conservative forces are appropriately handled

if they affect the system.

ESSENTIAL

As previously mentioned, the submodule essen-

tial.py (which is the core of sympy.physics.mechanics)

includes ReferenceFrame,Vector,Dyadic, and

dynamicsymbols, as well as some output functions. These

classes will be explained in some detail, to allow for a greater

understanding of how our software was written and how it

functions.

Firstly, dynamicsymbols will be explained - it is merely

a shortcut to producing quantities which are functions of time. It

is included for two reasons: speciﬁcs relating to Python import-

ing requirements, and because dynamicsymbols deﬁnes the

symbol used to represent time (default “t”). All of the vector

calculus methods assume that functions of time deﬁne rotations

between ReferenceFrames; if basic symbols or expressions

which are not functions of time are supplied, they will be treated

as constants when differentiating with respect to time.

The relationship between ReferenceFrame and

Vector is very complex. Upon initialization, a

ReferenceFrame has three vectors representing the or-

thonormal basis vectors of that reference frame. A Vector

is made up of a list of segments per associated frame. For

each unique ReferenceFrame involved in the deﬁnition of

a vector, one element in this list exists. Each element in the list

contains the associated ReferenceFrame and a 3 ×1 SymPy

matrix representing the measure numbers for each frame. The

basis vectors, which are created upon ReferenceFrame

initialization, have a list of length 1 and are made up of the

ReferenceFrame they are created in and a matrix that deﬁnes

one of the standard basis vectors (e.g. [1,0,0]).

As objects, both these basis vectors and other general vec-

tors are instances of the same Vector class. More complicated

Vectors just consist of longer lists and matrices. More frames

can be introduced by adding vectors together or performing more

advanced vector and vector calculus operations.

The ﬁnal two parts of Vector’s design are in the users in-

teraction with these objects, i.e. creating and displaying them.

Direct initialization of a Vector object by a user should never

take place; more complicated vectors will be formed out of basis

vectors from the ReferenceFrames and operations between

Vectors. When displaying a Vector object to the user, the

complex implementation details of each instance are masked. In-

stead, the user only sees something along the following lines:

3*A.x + 5*A.y + sin(theta)*C.z

Each measure number and accompanying basis vector are printed

out in a way that the output can be copied and reentered to form

the Vector again. This leaves our Vector class as a symbolic

object (although, not a subclass of the main SymPy Expr class)

which users will interact with on a symbolic/mathematical level.

The complex initialization should never have to be done by hand,

thus making use of this class is easy for people not intimately

familiar with Python and SymPy.

In order to allow interactions between vectors deﬁned in

different reference frames, information is stored which relates

7

Copyright © 2013 by ASME

each reference frame to others. The user deﬁnes how one frame

is oriented to another, using a simple rotation around an arbi-

trary axis, standard body- or space-ﬁxed angles, quaternions, or

Euler parameters. Once this is deﬁned, each of the involved

ReferenceFrames sets its internal dictionary, where a pointer

to the other frame and the generated direction cosine matrix

are stored together (transposing happens for one of the frames).

When the orientation matrix between two frames is requested, if

it has not already been deﬁned, the code will search through all

possible branches to ﬁnd the other frame, and then multiply all of

the orientation matrices in order to generate the direction cosine

matrix between the two frames. After doing so, it will be saved

so future searching does not have to happen again.

Angular velocities between frames are set in a similar way.

When the user orients one frame relative to another, the angu-

lar velocity is generated by taking the time derivative of the di-

rection cosine matrix. This is usually not desirable though, so

the user is free to overwrite the angular velocity vector between

frames. Again, setting this in one frame will set an equal and op-

posite vector in the other frame, to ensure consistency. Also, the

same tree search occurs for angular velocities, except it involves

adding angular velocity vectors instead of multiplying direction

cosine matrices.

One potential pitfall is the possibility of a user closing a loop

of ReferenceFrames. In doing so, it is possible for the user

to create internally inconsistent rotations or angular velocities; in

other terms, if they don’t use the correct value when closing the

loop, the code does not detect this and incorrect results might be

generated. Users are instructed to avoid doing this, and we feel

it is an unlikely scenario, as it requires extra, unneeded work on

the user’s part.

The Point class functions in a similar manner to

ReferenceFrame, in that it has a tree which links the posi-

tion of this point to other points and is searchable to ﬁnd the

position between two points which have not been directly as-

signed. However, the Point class does not extend this func-

tionality to velocities; it only works for positions. This limitation

is due to the complexities of identifying bound/unbound vectors

within reference frames. It has been more reliable to ask the user

to ﬁnd these velocities themselves rather than attempting to do it

automatically (and frequently incorrectly). In order to help with

this task, the Point class has a number of methods using the

one point and two point theorems [7] to make this step easier.

The Dyadic object has a similar construction approach as

Vector, i.e. it is made up of a list of components. However,

for a dyadic, there are three parts of each list entry: a measure

number, the ﬁrst basis vector, and the second basis vector. The

lists which compose a Dyadic object look like:

[(J, A.x, A.x), (I, A.x, B.y)]

which in turn is printed as:

J*(A.x|A.x) + I*(A.x|B.y)

which again follows the SymPy convention that the displayed

version of this object can be copied and pasted in order to re-

make the object. The vector math and calculus associated with

Dyadic is similar to that in Vector. The ﬁrst or second basis

vector is operated upon, depending on whether pre or post dot

and cross products are used.

For a user, once all kinematics and system parameters have

been deﬁned, the next step is generating the equations of motion.

There are two included methods for generating EOM: Kane’s and

Lagrange’s. Both of these objects require the system’s deﬁni-

tion to be passed in using the container classes Particle and

RigidBody. These objects (as described above) store the min-

imum amount of information for a body that is needed to create

the equations of motion.

KanesMethod Class

Upon initialization, it takes in a number of properties which

describe the system: the inertial reference frame; independent

and constrained generalized coordinates; independent, auxiliary,

and constrained (dependent) generalized speeds; and conﬁgura-

tion, velocity, and (optionally) acceleration constraint equations.

At this point, the relationships between the independent and con-

strained speeds are found as in Kane’s Method [7]; this is shown

in equation (7), where fv(q,u,t)is the list of constraint equations

and uis the list of independent and dependent speeds.

0=fv(q,u,t)(2)

=∇ufv(q,u,t)u(3)

=Bu (4)

=Bind uind +Bde pude p (5)

=⇒udep =−B−1

de pBind uind (6)

=Auind (7)

The conﬁguration constraints are used directly when forming the

equations of motion, but they do need to be supplied if the system

is going to be linearized [11].

From here, the formulation of the term Frfollows what Kane

presented, with the advantage that all of the vector addition and

multiplication is carried out symbolically. If necessary, the un-

constrained generalized active forces can be transformed into the

constrained generalized active forces, where nis the total num-

ber of generalized speeds, pis the number of independent speeds,

leaving mas the number of constrained speeds; this is shown in

equation (8).

˜

Find =Find +ATFde p (8)

8

Copyright © 2013 by ASME

The formulation of the generalized inertia forces is more

complicated. First, we deﬁned F∗

rdifferently, as in equation (9).

F∗

r=Mm˙

u+Mn(9)

Mmis the mass matrix of the system and Mnis all the terms in F∗

r

which are not part of the mass matrix. The construction of these

terms will be shown for a particle, but the procedure for rigid

bodies is almost the same, albeit for the rotational components.

If we start by deﬁning the velocity of a particle Pin the inertial

frame Aas:

A¯vP=

n

∑

i=1

A¯vP

r(10)

the inertial force R∗for that particle can be written as:

¯

R∗=−

Ad

dt (mA¯vP)(11)

=−m

Ad

dt

A

¯vP−˙mA¯vP(12)

=−˙mA¯vP−m

Ad

dt n

∑

i=1

A¯vP

iui!(13)

=−˙mA¯vP−m

n

∑

i=1A¯vP

i

d

dt ui+ui

Ad

dt

A¯vP

i(14)

(15)

We can then write:

F∗r=A¯vP

r¯

R∗(16)

F∗r=−"A¯vP

r˙mA¯vP+A¯vP

rm

n

∑

i=1˙uA

i¯vP

i+ui

Ad

dt

A¯vP

i#(17)

From this equation, we can see that only the mass and partial ve-

locity terms multiply ˙uterms, or that the mass matrix coefﬁcients

are made up of the product of mass and the dot product between

two partial velocities. In fact, the location of the element in the

mass matrix corresponds to the index of each partial velocity (the

order is not important as long as it is consistent). If we wanted

to deﬁne this another way, we could write a vertical vector of the

partial velocities of particle P,[A¯vP

r], and then the mass matrix

would be:

Mm=−mA¯vP

rA¯vP

rT(18)

In either case, the non-mass matrix terms (which make up

Mn) are the collection of terms that do not involve ˙u’s. As in

Kane’s method, the rotational and translational inertia forces and

torques are multiplied by the angular and translational partial ve-

locities, for each body/particle, summed across all bodies and

particles. To transform this for systems with nonholonomic con-

straints, we again use equation (8), substituting F∗for F.

Using auxiliary speeds to bring noncontributing forces into

evidence is important to fully utilize Kane’s method. Upon ini-

tialization of a KanesMethod object the user needs to supply

auxiliary speeds. Assuming the auxiliary speeds were used cor-

rectly when forming velocities, the user does not have to worry

about these speeds again, and they will not show up in any out-

put equations. When there are velocity constraints and auxil-

iary speeds, the relationship between auxiliary speeds and con-

strained speeds needs to be found and used in forming the equa-

tions. To accomplish this, a second, internal KanesMethod

object is created which has the same constraints and constrained

speeds, but auxiliary speeds are supplied as both independent and

auxiliary speeds, leaving the rest of the math the same.

More plainly, for any instance of KanesMethod, auxiliary

speeds are removed from (set to 0) the accelerations and veloci-

ties that form ¯

R,¯

T,¯

R∗, and ¯

T∗. The only difference between the

user’s and the internal instance is which generalized speeds are

used to form the partial velocities: independent or auxiliary. The

relationship between auxiliary speeds and constrained speeds is

found the same way as the relationship between the indepen-

dent speeds and constrained speeds, i.e. the matrix Ais found

to relate auxiliary and constrained speeds. The transformation

from unconstrained auxiliary equations to the constrained auxil-

iary equations (F+F∗=0 to ˜

F+˜

F∗=0 is performed exactly the

same way, just using the matrix Athat relates the auxiliary and

constrained speeds. The entire process is transparent to the user.

As the constrained generalized speeds are not substituted out

of the equations generated, we will have fewer equations than

independent and dependent speeds. If we have ntotal generalized

speeds and pindependent speeds, we are left with m=n−p

constrained speeds. This means that we will have pequations

containing time derivatives of nspeeds, or not enough equations

to solve for the ˙u’s. We instead use the mvelocity constraint

equations to generate the needed equations. When the velocity

constraint equations are differentiated with respect to time, we

get mequations (the additional number we needed) containing

up to n˙u’s, giving the required information to solve for the time

derivatives of the generalized speeds.

We will only brieﬂy discuss linearization here, as a more

detailed description of the linearization procedure used within

KanesMethod can be found elsewhere [11]. The only com-

plications that arise are when the user has a constrained system,

in which case relationships between dependent and independent

coordinates needs to be considered, as well as the relationship

between dependent speeds and independent speeds, independent

9

Copyright © 2013 by ASME

coordinates, and dependent coordinates. The important message

for the user is conﬁguration constraints are not considered when

forming the equations of motion, but if they exist and are not

supplied, the linear equations generated will be incorrect.

LangrangesMethod Class

In sympy.physics.mechanics, we assume that three basic sets

of equations are necessary to completely describe a system and

obtain the symbolic equations using LagrangesMethod:

0=mc(q,t)˙q+fc(q,t)(19)

0=mdc(˙q,q,t)¨q+fdc(˙q,q,t)(20)

0=md(˙q,q,t)¨q+Λc(q,t)λ+fd(˙q,q,t)(21)

where qrepresents a vector of generalized coordinates, ˙qand ¨q

are vectors of the ﬁrst and second time derivatives of the gener-

alized coordinates, λis a vector of the Lagrange multipliers. mc,

mdc,mdand Λcare coefﬁcient matrices. Equation (19) shows

the constraint equations, (20) shows the ﬁrst derivative of the

constraint equations, and (21) shows the dynamical equations us-

ing Lagrange’s equations. The LagrangesMethod class rear-

ranges the equations of motion into the following form:

M(q,t)x=f(q,˙q,t)(22)

where Mis the ’mass matrix’, and xis a vector of the states,

namely the ¨q’s and λ’s, if any.

The LagrangesMethod class is initialized by suppliy-

ing properties that describe a system: the Lagrangian, a list

of the generalized coordinates, holonomic and non-holonomic

constraint equations (if any), the forces and/or moments act-

ing on the system, and the inertial reference frame. The

LagrangesMethod class requires that holonomic constraint

equation be supplied after taking its ﬁrst time derivative. The

forces supplied upon initialization are primarily to account for

the non-conservative forces acting on the system as the conser-

vative forces are accounted for in the computation of the La-

grangian. Instead of the system’s Lagrangian, the user may sup-

ply the system’s kinetic energy, and account for any conservative

and/or non-conservative forces in the force list.

Usage of the LagrangesMethod class does not allow for

bringing non-contributing forces into evidence, or linearization

functionality. Otherwise, it provides mass matrix/forcing func-

tion outputs as in the KanesMethod class.

CONCLUSIONS

We have presented a set of tools, PyDy, for forming the

equations of motion of a constrained dynamic system in an auto-

mated fashion. The core of PyDy, the mechanics package within

SymPy, is written in a high-level programming language on top

of a fully function computer algebra system. We have demon-

strated the use of our software, as well as how it ﬁts into the larger

scientiﬁc Python ecosystem. We also detailed how our software

has been validated, why design decisions were made, and how its

internal architecture functions. All of the source code, including

extra code which generates a two dimensional animation of the

N-link pendulum, are available online [13].

ACKNOWLEDGEMENTS

Three Google Summer of Code grants (2009, 2011, 2012)

supported most of the software development. This material is

also partially based upon work supported by the National Science

Foundation under Grant No. 0928339. Any opinions, ﬁndings,

and conclusions or recommendations expressed in this material

are those of the author(s) and do not necessarily reﬂect the views

of the National Science Foundation.

REFERENCES

[1] Team, S. D., 2012. SymPy: Python library for symbolic

mathematics.

[2] SciPy stack. http://scipy.github.com/stackspec.html.

[3] Raymond, E., 1999. The Cathedral and the Bazaar.

[4] Meijaard, J. P., Papadopoulos, J. M., Ruina, A., and

Schwab, A. L., 2007. “Linearized dynamics equations for

the balance and steer of a bicycle: A benchmark and re-

view”. Proceedings of the Royal Society A: Mathematical,

Physical and Engineering Sciences, 463(2084), August,

pp. 1955–1982.

[5] Sympy documentation. https://docs.sympy.org.

[6] PyDy mailing list. https://groups.google.com/groups/pydy.

[7] Kane, T. R., and Levinson, D. A., 1985. Dynamics: Theory

and Applications. McGraw Hill, New York, NY.

[8] Kane, T. R., and Levinson, D. A., 2000. Dynamics On-

line: Theory and Implementation with AUTOLEV. Online

Dynamics, Inc., Sunnyvale, CA.

[9] Sayers, M. W., 1990. “Symbolic computer methods to auto-

matically formulate vehicle simulation codes”. PhD thesis,

The University of Michigan.

[10] Engineering, E., 2013. OMD: Opensource multibody dy-

namics.

[11] Dale L. Peterson, Gilbert Gede, M. H., submitted Oct.

2012. “Linearization procedure for constrained multibody

systems”. Multibody System Dynamics.

[12] Crandall, S. H., Karnopp, D. C., Edward F. Kurtz, J., and

Pridmore-Brown, D. C., 1968. Dynamics of mechanical

and electromechanical systems. Krieger Publishing Com-

pany, Malabar, Florida.

[13] Source code for this paper.

https://github.com/gilbertgede/idetc-2013-paper.

10

Copyright © 2013 by ASME