Skip to content

Tutorial 1 python Bouncing Cube

Jacob Austin edited this page May 16, 2020 · 2 revisions

Goals

Now that the library/python module has been compilled, you can begin setting up your first project. We will be building a simple cube simulation with a global plane constraint (causing it to bounce).

Set up

Importing the pythonTitan module

In order to be able to import the pythonTitan module it must be located somewhere python can find it. If you haven't relocated it to your python library path, go ahead and move it there or, alternatively, move it to your project's root.

Once you make sure the module can be imported go ahead and begin writing your python script by importing the necessary modules.

import titan 
import numpy as np

Setting up the cube

We create the cube by adding individual masses. They are positioned at the corners of a cube spanning [0, 1] x [0, 1] x [0, 1].

    sim =  titan.Sim() # create the basic simulation object.
    m1 = sim.createMass(np.array([0,0,1]))
    m2 = sim.createMass(np.array([1,0,1]))
    m3 = sim.createMass(np.array([1,1,1]))
    m4 = sim.createMass(np.array([0,1,1]))
    m5 = sim.createMass(np.array([0,0,2]))
    m6 = sim.createMass(np.array([1,0,2]))
    m7 = sim.createMass(np.array([1,1,2]))
    m8 = sim.createMass(np.array([0,1,2]))

Then we add springs connecting the masses at the corners.

    s1 = sim.createSpring(m1,m2)
    s2 = sim.createSpring(m2,m3)
    s3 = sim.createSpring(m3,m4)
    s4 = sim.createSpring(m4,m1)
    s5 = sim.createSpring(m1,m5)
    s6 = sim.createSpring(m5,m8)
    s7 = sim.createSpring(m8,m4)
    s8 = sim.createSpring(m8,m7)
    s9 = sim.createSpring(m5,m6)
    s10 = sim.createSpring(m2,m6)
    s11 = sim.createSpring(m6,m7)
    s12 = sim.createSpring(m3,m7)

As expected, we have added 12 springs, one for each side of the cube. The library also includes a createCube function, which more or less performs this computation for you (with a fully connected spring).

Adding a plane constraint

Next, we'd like to constraint the plane to stay above the xy-plane, which we can do with the sim.createPlane command. The function takes two arguments, a numpy array (a, b, c) which specifies the normal vector to the plane, and a double d which specifies the offset (i.e. the plane is defined as ax + by + cz = d). All masses are then constrained to lie in the positive half-space defined by the plane and its orientation.

    sim.createPlane(np.array([0,0,1]), 0) # our plane has a unit normal in the z-direction, with 0 offset.

Starting the simulation

The simulation runs asynchronously, so the user can continue to run commands while it is running. In this case, we do not need to make modifications during the run, so we can just start the simulation and let it run until it is finished. The setBreakpoint command will stop the simulation at the specified time, but will not otherwise block the CPU.

    runtime = 10.0
    sim.setBreakpoint(runtime)
    sim.start()

The finished program:

The full program now looks like this:

import titan 
import numpy as np

sim =  titan.Sim() # create the basic simulation object.
    m1 = sim.createMass(np.array([0,0,1]))
    m2 = sim.createMass(np.array([1,0,1]))
    m3 = sim.createMass(np.array([1,1,1]))
    m4 = sim.createMass(np.array([0,1,1]))
    m5 = sim.createMass(np.array([0,0,2]))
    m6 = sim.createMass(np.array([1,0,2]))
    m7 = sim.createMass(np.array([1,1,2]))
    m8 = sim.createMass(np.array([0,1,2]))

    s1 = sim.createSpring(m1,m2)
    s2 = sim.createSpring(m2,m3)
    s3 = sim.createSpring(m3,m4)
    s4 = sim.createSpring(m4,m1)
    s5 = sim.createSpring(m1,m5)
    s6 = sim.createSpring(m5,m8)
    s7 = sim.createSpring(m8,m4)
    s8 = sim.createSpring(m8,m7)
    s9 = sim.createSpring(m5,m6)
    s10 = sim.createSpring(m2,m6)
    s11 = sim.createSpring(m6,m7)
    s12 = sim.createSpring(m3,m7)

    sim.createPlane(np.array([0,0,1]), 0) # our plane has a unit normal in the z-direction, with 0 offset.

    runtime = 10.0
    sim.setBreakpoint(runtime)
    sim.start()

The same thing can be achieved more or less with the built in sim.createCube(const Vec & center, const Vec & sides) method, i.e.

import titan 
import numpy as np

sim =  titan.Sim() # create the basic simulation object.
sim.createCube(np.array([0,0,1]),2)
sim.createPlane(np.array([0,0,1]), 0) # our plane has a unit normal in the z-direction, with 0 offset.

runtime = 10.0
sim.setBreakpoint(runtime)
sim.start()