Exemple #1
0
    def test_BasicShapes(self):
        """
        Create the basic shapes and verify their names. Furthermore, verify
        that scaling them works.
        """
        # Create the Collision Shape instances.
        cs_p = StaticPlaneShape(Vec3(0, 1, 2), 3)
        cs_s = SphereShape(3)
        cs_b = BoxShape(Vec3(1, 2, 3))
        cs_e = EmptyShape()

        # Verify the dimensions of the sphere and the box.
        assert cs_s.getRadius() == 3
        assert cs_b.getHalfExtentsWithMargin() == Vec3(1, 2, 3)

        # Put the collision shapes into a dictionary where the key is the
        # expected name.
        shapes = {b"STATICPLANE": cs_p, b"SPHERE": cs_s, b"Box": cs_b, b"Empty": cs_e}

        # Verify the name of each shape and modify its scale.
        scale = Vec3(1.5, 2.5, 3.5)
        for name, cs in shapes.items():
            cs.setLocalScaling(scale)
            assert cs.getLocalScaling() == scale
            assert cs.getName() == name
Exemple #2
0
 def test_calculateLocalInertia(self):
     """
     Create a sphere and let Bullet compute its inertia via the
     'calculateLocalInertia' method. Verify that the result is correct.
     """
     # Compute the inertia of the sphere. The inertia for a sphere is
     # I = 2 / 5 * mass * (R ** 2)
     mass, radius = 2, 3
     sphere = SphereShape(radius)
     inertia = sphere.calculateLocalInertia(mass)
     ref = 2 / 5 * mass * radius ** 2
     assert np.allclose(inertia.topy(), ref * np.ones(3))
Exemple #3
0
        def runSimulation(sim):
            # Create the collision shapes for the ball and ground.
            cs_ball = SphereShape(1)
            cs_ground = StaticPlaneShape(Vec3(0, 1, 0), 1)

            # Create a Rigid Body for the static (ie mass=0) Ground.
            q0 = Quaternion(0, 0, 0, 1)
            ms = DefaultMotionState(Transform(q0, Vec3(0, -1, 0)))
            ci = RigidBodyConstructionInfo(0, ms, cs_ground)
            rb_ground = RigidBody(ci, bodyID=1)
            del ms, ci

            # Create a Rigid body for the dynamic (ie mass > 0) Ball.
            ms = DefaultMotionState(Transform(q0, Vec3(0, 5, 0)))
            inertia = cs_ball.calculateLocalInertia(1)
            ci = RigidBodyConstructionInfo(1, ms, cs_ball, inertia)
            rb_ball = RigidBody(ci, bodyID=2)
            del ms, inertia, ci

            # Ensure that Bullet never deactivates the objects.
            rb_ground.forceActivationState(4)
            rb_ball.forceActivationState(4)

            # Add both bodies to the simulation.
            sim.addRigidBody(rb_ground)
            sim.addRigidBody(rb_ball)

            # Sanity check: the ball must be at position y=5
            pos = rb_ball.getMotionState().getWorldTransform().getOrigin()
            pos = pos.topy()
            assert pos[1] == 5

            # Step the simulation long enough for the ball to fall down and
            # come to rest on the plane.
            for ii in range(10):
                sim.stepSimulation(1, 100)

            # Verify that the y-position of the ball is such that the ball
            # rests on the plane.
            pos = rb_ball.getMotionState().getWorldTransform().getOrigin()
            return pos.topy()
Exemple #4
0
def getRB(pos=Vec3(0, 0, 0), cshape=SphereShape(1)):
    """
    Return a Rigid Body plus auxiliary information (do *not* delete; see
    note below).

    .. note:: Do not delete the tuple until the end of the test
    because it may lead to memory access violations. The reason is that a
    rigid body requires several indepenent structures that need to remain
    in memory.
    """
    t = Transform(Quaternion(0, 0, 0, 1), pos)
    ms = DefaultMotionState(t)
    mass = 1

    # Build construction info and instantiate the rigid body.
    ci = RigidBodyConstructionInfo(mass, ms, cshape)
    return RigidBody(ci)
Exemple #5
0
"""
Python version of Bullet's own 'Hello World' demo using 'azBullet' wrapper.
"""
import azBullet
from azBullet import Vec3, Quaternion
from azBullet import StaticPlaneShape, SphereShape
from azBullet import DefaultMotionState, Transform
from azBullet import RigidBody, RigidBodyConstructionInfo

sim = azBullet.BulletBase()
sim.setGravity(Vec3(0, -10, 0))

# Create a collision shape for the Ball and for the Ground.
ballShape = SphereShape(1)
groundShape = StaticPlaneShape(Vec3(0, 1, 0), 1)

# Create a Rigid Body for the Ground based on the collision shape.
mass = 0
groundRigidBodyState = DefaultMotionState(
    Transform(Quaternion(0, 0, 0, 1), Vec3(0, -1, 0)))
ci = RigidBodyConstructionInfo(mass, groundRigidBodyState, groundShape)
groundRigidBody = RigidBody(ci)
groundRigidBody.setRestitution(1.0)
sim.addRigidBody(groundRigidBody)
del mass, ci

# Create a Rigid body for the Ball based on its collision shape. Let Bullet do
# the heavy lifting and compute the mass and inertia for us.
fallRigidBodyState = DefaultMotionState(
    Transform(Quaternion(0, 0, 0, 1), Vec3(0, 20, 0)))
mass = 1
Exemple #6
0
def main():
    # Create two rigid bodies side by side (they *do* touch, but just).
    pos_a = Vec3(-10, 0, 0)
    pos_b = Vec3(10, 0, 0)
    r = 0.001
    rb_a = getRB(pos=pos_a, cshape=SphereShape(r))
    rb_b = getRB(pos=pos_b, cshape=SphereShape(r))
    del r

    # Create the constraint between the two bodies. The constraint applies
    # at (0, 0, 0) in world coordinates.
    frameInA = Transform(Quaternion(0, 1, 0, 0), Vec3(5, 0, 0))
    frameInB = Transform(Quaternion(0, -1, 0, 0), Vec3(-5, 0, 0))
    frameInA.setIdentity()
    frameInB.setIdentity()
    clsDof6 = Generic6DofSpring2Constraint
    dof = clsDof6(rb_a, rb_b, frameInA, frameInB)

    # We are now emulating a slider constraint with this 6DOF constraint.
    # For this purpose we need to specify the linear/angular limits.
    sliderLimitLo = -100
    sliderLimitHi = 100

    # Apply the linear/angular limits.
    dof.setLinearLowerLimit(Vec3(sliderLimitLo, sliderLimitLo, sliderLimitLo))
    dof.setLinearLowerLimit(Vec3(sliderLimitHi, sliderLimitHi, sliderLimitHi))
    tmp = 0 * np.pi / 12
    dof.setAngularLowerLimit(Vec3(-tmp, -tmp, -tmp))
    dof.setAngularUpperLimit(Vec3(tmp, tmp, tmp))

    # Activate the spring for all three translational axis and disable it
    # for the three angular axis.
    for ii in range(3):
        dof.enableSpring(ii, True)
        dof.enableSpring(3 + ii, False)
        dof.setStiffness(ii, 0.1)
        dof.setDamping(ii, 1)
        dof.setEquilibriumPoint(ii, 0)

    # Add both rigid bodies and the constraint to the Bullet simulation.
    bb = azBullet.BulletBase()
    bb.setGravity(Vec3(0, 0, 0))
    bb.addRigidBody(rb_a)
    bb.addRigidBody(rb_b)
    rb_a.forceActivationState(4)
    rb_b.forceActivationState(4)
    bb.addConstraint(dof)

    # Pull the right object to the right. Initially this must not affect
    # the object on the left until the slider is fully extended, at which
    # point the left object must begin to move as well.
#    rb_a.applyCentralForce(Vec3(0, -1, 0))
#    rb_b.applyCentralForce(Vec3(0, 1, 0))

    numIter = 1000
    out_a = np.zeros((numIter, 3))
    out_b = np.zeros_like(out_a)
    for ii in range(numIter):
        if ii == 1:
            rb_a.applyCentralForce(Vec3(0, 0, 0))
            rb_b.applyCentralForce(Vec3(0, 0, 0))

        # Step simulation.
        bb.stepSimulation(1 / 60, 60)

        # Query the position of the objects.
        p_a = rb_a.getCenterOfMassTransform().getOrigin().topy()
        p_b = rb_b.getCenterOfMassTransform().getOrigin().topy()

        out_a[ii, :] = p_a
        out_b[ii, :] = p_b
    animateMotion(out_a, out_b)
Exemple #7
0
Test behaviour of compound shapes in terms of their masses and inertia.
"""
import azBullet
from azBullet import Vec3, Quaternion
from azBullet import StaticPlaneShape, SphereShape, CompoundShape
from azBullet import DefaultMotionState, Transform
from azBullet import RigidBody, RigidBodyConstructionInfo

from IPython import embed as ipshell

# Instantiate the Bullet simulation.
sim = azBullet.BulletBase()
sim.setGravity(Vec3(0, 0, 0))

# Create the spherical collision shape and a compound shape.
csSphere = SphereShape(radius=1)
cs = azBullet.CompoundShape()

# Specify the mass and let Bullet compute the Inertia.
total_mass = 1
print('Inertia sphere: ', csSphere.calculateLocalInertia(total_mass))

# Add collision shapes to the compound. Its constituents are two spheres
# at different positions.
t1 = Transform(Quaternion(0, 0, 0, 1), Vec3(0, -5, 0))
t2 = Transform(Quaternion(0, 0, 0, 1), Vec3(0, 5, 0))
cs.addChildShape(t1, csSphere)
cs.addChildShape(t2, csSphere)

# The local inertia is only a crude approximation based on the AABBs. Do not
# use it. Use calculatePrincipalAxisTransform instead (see below).
Exemple #8
0
"""
Python version of Bullet's own 'Hello World' demo using 'azBullet' wrapper.
"""
import azBullet
from azBullet import Vec3, Quaternion
from azBullet import StaticPlaneShape, SphereShape
from azBullet import DefaultMotionState, Transform
from azBullet import RigidBody, RigidBodyConstructionInfo

# Instantiate the Bullet simulation.
sim = azBullet.BulletBase()
sim.setGravity(Vec3(0, -10, 0))

# Create the collision shape for Ball and Ground.
ballShape = SphereShape(1)
groundShape = StaticPlaneShape(Vec3(0, 1, 0), 1)

# Create the rigid body for the Ground. Since it is a static body its mass must
# be zero.
mass = 0
groundRigidBodyState = DefaultMotionState(
    Transform(Quaternion(0, 0, 0, 1), Vec3(0, -1, 0)))
ci = RigidBodyConstructionInfo(mass, groundRigidBodyState, groundShape)
groundRigidBody = RigidBody(ci)
groundRigidBody.setRestitution(1.0)
sim.addRigidBody(groundRigidBody)
del mass, ci

# Create the rigid body for the Ball. Since it is a dynamic body we need to
# specify mass and inertia. The former we need to do ourselves but Bullet can
# do the heavy lifting for the Inertia and compute it for us.