PyOMD Falling Ball Tutorial
Introduction
This example shows how to build a body falling under the influence of gravity. Steps by step instructions are given with the actual python command is italics . I have also included the final product, just for clarity and to show the indents necessary in python.
Step by Step
- Install Python
- Download PyOMD and unzip it and create an empty text file called "fallingball.py" in the directory: _____. The pyomd module is in this same directory which should allow python to find it.
-
Open the fallingball.py and add the following:
from pyomd import *
This make all the functionality of pyomd available.
-
First create a couple of variables to be used when building bodies and forces. Add this text:
g = 9.81
ballmass = 1
g is the acceleration due to gravity (in meters per second squared) and ballmass will be used to define the mass of the ball we will be creating. -
Matrices are used to define inertia and orientation of bodies, so we will define a couple matrices, which are components of the PyOMD library:
eye = Matrix3(1,0,0,0,1,0,0,0,1);
zero = Matrix3(0,0,0,0,0,0,0,0,0);
eye is a 3x2 identity matrix and zero is a 3x3 full of zeros. -
The PyOMD library comes with a Vector3 class.
Vector3s are required to specify relative positions durring the creation of components of the model.
The following line will create a vector which will define the initial location of the ball of x=0, y=0 and z=1:
initialLocation=Vector3(0,0,1)
-
Now define a couple Python arrays which will specify the initial translational and rotational velocity of the body we will soon create.
transVel=[0,0,0]
rotVel=[0,0,0]
-
In this step we will add a body and give it six degrees of freedom.
ball = make6DOF(mymodel,'ball',initialLocation,eye,ballmass,eye,transVel,rotVel)
There are 8 arguments to the make6DOF command, they are:- The model
- The name of the body.
- Initial location of the body relative to 0,0,0 in the form of a Vector3
- Initial orientation in the form of a Matrix3 (3x3 Matrix)
- Mass of the body
- Mass of the body
- Inertia of the body in the form of a Matrix3 (3x3 Matrix)
- Initial velocity of the body in the form of a Python array
- Initial angular velocity of the body in the form of a Python array
Note: The make6DOF command might be thought of as a macro. It actually creates several bodies and several joints. PyOMD adds one degree of freedom per joint. Because of this making a body with 6 degrees of freedom requires 5 other bodies. The make6DOF command does all that for you, if you are interested you can look at the file: __init__.py in the pyomd directory. -
All the joints have been made (the make6DOF command makes creates joints).
After that is done and before the model is solved the following command must be given:
mymodel.buildTree()
-
The model would solve but the ball would not do anything because it does not have any initial velocity and no forces are acting on it.
So, we will define a force representing gravity:
ballgrav = mymodel.addForce1Body('ballgrav',ball,frc)
This method has three arguments which are:
- name
- Body to which the force is applied
- Force vector
-
Everything in the model has been defined.
An integrator is required to integrate the model through time:
integrator = IntegRK4(mymodel)
-
These variable will be used as arguments in the upcomming steps:
time = 0. dt = 0.0005 endtime = 2
-
Now a loop is required to move from time 0 to the end time:
while time < endtime:
-
Have the integrator integrate for each time step, do not forget to indent as this is part of the while loop:
integrator.integrate(time,time+dt)
The integrate method has two arguements:
- The beginning time
- The end time of 1 time step
-
Increment time up for the next time through the loop (don't forget to indent):
time = time + dt;
-
Finally call the getBodyPostion method to get the ball's position and print out the x, y, and z values (indenting each line):
ballpos = mymodel.getBodyPosition('ball') print [ballpos.x, ballpos.y, ballpos.z]
- close the model and run it by typing "python fallingball.py".
Summary
The output should be the position of the ball through time as it falls. Thanks for trying it out, hope it went smoothly.
Falling Ball code:
# ball dropping under gravity
# just prints out position
from pyomd import *
# create Identity Matrix
eye = Matrix3(1,0,0,0,1,0,0,0,1);
# create zero Matrix
zero = Matrix3(0,0,0,0,0,0,0,0,0);
# define g as the gravitational constant
g = 9.81
# define ball mass
ballmass = 1
# the model which contains all OMD stuff
mymodel = Model1()
# add inertial reference frame body to model
# last argument (True) specifies that is is fixed to ground
irf = mymodel.addBody('irf',0,eye,eye,True)
initialLocation=Vector3(0,0,1)
# give the ball initial translational velocity
transVel=[0,0,0]
# give the ball initial rotational velocity
rotVel=[0,0,0]
ball = make6DOF(mymodel,'ball',initialLocation,eye,ballmass,eye,transVel,rotVel)
mymodel.buildTree()
# all the bodies are assembled into the joint tree
# now add forces
# define a force vector
frc = Vector3(0,0,-g*ballmass);
# gravity on ball
ballgrav = mymodel.addForce1Body('ballgrav',ball,frc)
# make the integrator
integrator = IntegRK4(mymodel)
# we have built our simple model so step forward in time
time = 0. # start time at 0
dt = 0.0005 # time step
endtime = 2 # time at which simulation stops
while time < endtime:
    integrator.integrate(time,time+dt)
    time = time + dt;
    #get ball position
    #ballpos = ball.getPosition()
    ballpos = mymodel.getBodyPosition('ball')
    print [ballpos.x, ballpos.y, ballpos.z]