def init(visual, timestep):
    """ Initialize ROS2 and various other things common to all agx simulations """
    try:
        rclpy.init()
    except Exception:
        if not rclpy.ok():
            print("Init error, not because of multiple init")
    if visual:
        app = agxPython.getContext().environment.getApplication()
        sim = agxPython.getContext().environment.getSimulation()
        root = agxPython.getContext().environment.getSceneRoot()
    else:
        app = []
        sim = agxSDK.Simulation()
        root = []

    sim.setTimeStep(timestep)
    if visual:
        setup_camera(app)
        sim.add(GuiListener(app, timestep))
        sim.getRenderManager().setScaleFactor(0.03)
        app.getSceneDecorator().setBackgroundColor(agxRender.Color.SkyBlue(), agxRender.Color.DodgerBlue())

    agx.setNumThreads(2)

    return sim, root
Esempio n. 2
0
    def __init__(self, **kwargs):
        """
        Construct given optional arguments.

        Arguments:
            model_path: str - path to model.
            driveline_settings: Struct - driveline settings.
            tire_settings: Struct - tire settings.
            keyboard_controls: Struct - keyboard controls (optional)
            gamepad_controls: Struct - gamepad controls (optional)
        """
        super().__init__()

        temp_simulation = agxSDK.Simulation()

        data = SimulationFile(simulation=temp_simulation, root=root())
        if not data.load(filename=kwargs['model_path'], parent=self):
            raise FileNotFoundError(
                'Unable to load wheel loader model: {}'.format(
                    kwargs['model_path']))

        states = {}
        for rb in self.getRigidBodies():
            states[rb.getUuid()] = rb.getEnable()

        disabled_collisions = DisabledCollisionsStateHandler(temp_simulation)
        for disabled in disabled_collisions:
            disabled1 = disabled[0]
            disabled2 = disabled[1] if len(disabled) > 1 else disabled[0]
            if isinstance(disabled1, agxCollide.Geometry):
                continue
            global_simulation().getSpace().setEnablePair(
                disabled1, disabled2, False)

        self._initialize(data, **kwargs)

        del disabled_collisions
        del data
        del temp_simulation

        for rb in self.getRigidBodies():
            if not rb.getUuid() in states:
                continue
            rb.setEnable(states[rb.getUuid()])

        from . import BucketTiltController
        self.bucket_tilt_controller = kwargs.get('bucket_tilt_controller',
                                                 BucketTiltController(self))

        assert self.tire( Tire.Location.FRONT_LEFT ).material == self.tire( Tire.Location.FRONT_RIGHT ).material,\
               'Front left and right tire materials expected to be the same.'
        assert self.tire( Tire.Location.REAR_LEFT ).material == self.tire( Tire.Location.REAR_RIGHT ).material,\
               'Rear left and right tire materials expected to be the same.'
        assert self.tire( Tire.Location.FRONT_LEFT ).material != self.tire( Tire.Location.REAR_LEFT ).material,\
               'Front and rear tire materials not expected to be the same.'
Esempio n. 3
0
    def __init__(self, scene_path, n_substeps, n_actions, observation_type, image_size, camera_pose, no_graphics, args):
        """Initializes a AgxEnv object
        :param scene_path: path to binary file containing serialized simulation defined in sim/ folder
        :param n_substeps: number os simulation steps per call to step()
        :param n_actions: number of actions (DoF)
        :param camera_pose: dictionary containing EYE, CENTER, UP information for rendering
        :param args: arguments for agxViewer
        """
        self.scene_path = scene_path
        self.n_substeps = n_substeps
        self.render_to_image = []
        self.image_size = image_size
        self.no_graphics = no_graphics

        # Initialize AGX simulation
        self.gravity = None
        self.time_step = None
        self.init = agx.AutoInit()
        self.sim = agxSDK.Simulation()
        self._build_simulation()

        # Initialize OSG ExampleApplication
        self.app = agxOSG.ExampleApplication(self.sim)
        self.args = args
        self.root = None
        self.camera_pose = camera_pose
        if not no_graphics:
            self._add_rendering(mode='osg')

        # TODO: Is this needed?
        self.fps = int(np.round(1.0 / self.dt))

        self.np_random = None
        self.seed()

        self.n_actions = n_actions
        self.observation_type = observation_type
        if not no_graphics:
            self._render_callback()

        obs = self._get_observation()
        self.observation_space = spaces.Box(low=-1, high=1, shape=(obs.shape), dtype=np.float32)
        self.action_space = spaces.Box(-1., 1., shape=(self.n_actions,), dtype='float32')
Esempio n. 4
0
    def createSimulation(self, no_graphics=True):

        ap = argparse.ArgumentParser()

        # the --noApp will run this without a graphics window
        ap.add_argument('--noApp', action='store_true')
        args1, args2 = ap.parse_known_args()
        args1 = vars(args1)

        if no_graphics:
            app = None
        else:
            # Creates an Example Application
            app = agxOSG.ExampleApplication()
            app.init(agxIO.ArgumentParser([sys.executable] + args2))

        # Create a simulation
        sim = agxSDK.Simulation()

        return sim, app
Esempio n. 5
0
    def __init__(self, **kwargs):
        """
        Construct given optional arguments.

        Arguments:
            driveline_settings: Struct - driveline settings, ExcavatorCAT365.default_driveline_settings() is used if not given.
            track_settings: Struct - track settings, ExcavatorCAT365.default_track_settings() is used if not given.
            keyboard_controls: Struct - keyboard controls (e.g., ExcavatorCAT365.default_keyboard_settings())
            gamepad_controls: Struct - gamepad controls (e.g., ExcavatorCAT365.default_gamepad_controls())
        """
        super().__init__()

        temp_simulation = agxSDK.Simulation()

        data = SimulationFile( simulation = temp_simulation, root = root() )
        if not data.load( filename = self.model_path, parent = self ):
            raise FileNotFoundError( 'Unable to load excavator model: {}'.format( self.model_path ) )

        states = []
        for rb in self.getRigidBodies():
            states.append( rb.getEnable() )

        disabled_collisions = DisabledCollisionsStateHandler( temp_simulation )
        for disabled in disabled_collisions:
            disabled1 = disabled[ 0 ]
            disabled2 = disabled[ 1 ] if len( disabled ) > 1 else disabled[ 0 ]
            if isinstance( disabled1, agxCollide.Geometry ):
                continue
            global_simulation().getSpace().setEnablePair( disabled1, disabled2, False )

        self._initialize( data, **kwargs )

        del disabled_collisions
        del data
        del temp_simulation

        for i, rb in enumerate( self.getRigidBodies() ):
            rb.setEnable( states[ i ] )
Esempio n. 6
0
def build_simulation():
    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Create a ground plane for reference
    ground = create_body(name="ground",
                         shape=agxCollide.Box(CYLINDER_LENGTH * 2,
                                              CYLINDER_LENGTH * 2,
                                              GROUND_WIDTH),
                         position=agx.Vec3(0, 0, 0),
                         motion_control=agx.RigidBody.STATIC)
    sim.add(ground)

    rotation_cylinder = agx.OrthoMatrix3x3()
    rotation_cylinder.setRotate(agx.Vec3.Y_AXIS(), agx.Vec3.Z_AXIS())

    material_cylinder = agx.Material("Aluminum")
    bulk_material_cylinder = material_cylinder.getBulkMaterial()
    bulk_material_cylinder.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    bulk_material_cylinder.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)

    # Create cylinders
    bottom_cylinder = create_body(
        name="bottom_cylinder",
        shape=agxCollide.Cylinder(CYLINDER_RADIUS, 3 / 4 * CYLINDER_LENGTH),
        position=agx.Vec3(0, 0, GROUND_WIDTH + (3 / 4 * CYLINDER_LENGTH) / 2),
        rotation=rotation_cylinder,
        motion_control=agx.RigidBody.STATIC,
        material=material_cylinder)
    sim.add(bottom_cylinder)

    middle_cylinder = create_body(
        name="middle_cylinder",
        shape=agxCollide.Cylinder(CYLINDER_RADIUS - GROOVE_DEPTH,
                                  GROOVE_WIDTH),
        position=agx.Vec3(
            0, 0, GROUND_WIDTH + (3 / 4 * CYLINDER_LENGTH) + GROOVE_WIDTH / 2),
        rotation=rotation_cylinder,
        motion_control=agx.RigidBody.STATIC,
        material=material_cylinder)
    sim.add(middle_cylinder)

    top_cylinder = create_body(
        name="top_cylinder",
        shape=agxCollide.Cylinder(CYLINDER_RADIUS, 1 / 4 * CYLINDER_LENGTH),
        position=agx.Vec3(
            0, 0, GROUND_WIDTH + (3 / 4 * CYLINDER_LENGTH) + GROOVE_WIDTH +
            (1 / 4 * CYLINDER_LENGTH) / 2),
        rotation=rotation_cylinder,
        motion_control=agx.RigidBody.STATIC,
        material=material_cylinder)
    sim.add(top_cylinder)

    material_ring = agx.Material("Rubber")
    bulk_material_ring = material_ring.getBulkMaterial()
    bulk_material_ring.setPoissonsRatio(RUBBER_POISSON_RATIO)
    bulk_material_ring.setYoungsModulus(RUBBER_YOUNG_MODULUS)

    ring = create_ring(name="ring",
                       radius=RING_RADIUS,
                       element_shape=agxCollide.Capsule(
                           RING_CROSS_SECTION, RING_SEGMENT_LENGTH),
                       num_elements=NUM_RING_ELEMENTS,
                       constraint_type=agx.LockJoint,
                       rotation_shift=math.pi / 2,
                       translation_shift=RING_SEGMENT_LENGTH / 2,
                       compliance=RING_COMPLIANCE,
                       center=agx.Vec3(0, 0, CYLINDER_LENGTH + RING_RADIUS),
                       material=material_ring)
    sim.add(ring)

    left_ring_element = sim.getRigidBody(LEFT_ELEMENT)
    right_ring_element = sim.getRigidBody(RIGHT_ELEMENT)

    gripper_left = create_body(
        name="gripper_left",
        shape=agxCollide.Box(SIZE_GRIPPER, SIZE_GRIPPER, SIZE_GRIPPER),
        position=left_ring_element.getPosition(),
        rotation=agx.OrthoMatrix3x3(left_ring_element.getRotation()),
        motion_control=agx.RigidBody.DYNAMICS)
    sim.add(gripper_left)

    gripper_right = create_body(
        name="gripper_right",
        shape=agxCollide.Box(SIZE_GRIPPER, SIZE_GRIPPER, SIZE_GRIPPER),
        position=right_ring_element.getPosition(),
        rotation=agx.OrthoMatrix3x3(right_ring_element.getRotation()),
        motion_control=agx.RigidBody.DYNAMICS)
    sim.add(gripper_right)

    # Disable collisions for grippers
    gripper_left_body = sim.getRigidBody("gripper_left")
    gripper_left_body.getGeometry("gripper_left").setEnableCollisions(False)
    gripper_right_body = sim.getRigidBody("gripper_right")
    gripper_right_body.getGeometry("gripper_right").setEnableCollisions(False)

    frame_element = agx.Frame()
    frame_gripper = agx.Frame()

    result = agx.Constraint.calculateFramesFromBody(
        agx.Vec3(RING_CROSS_SECTION, 0, 0), agx.Vec3(1, 0, 0),
        left_ring_element, frame_element, gripper_left_body, frame_gripper)
    print(result)

    lock_joint_left = agx.LockJoint(gripper_left_body, frame_gripper,
                                    left_ring_element, frame_element)
    lock_joint_left.setName('lock_joint_left')
    lock_joint_left.setCompliance(GRIPPER_COMPLIANCE)
    sim.add(lock_joint_left)

    frame_gripper = agx.Frame()

    result = agx.Constraint.calculateFramesFromBody(
        agx.Vec3(RING_CROSS_SECTION, 0, 0), agx.Vec3(1, 0, 0),
        right_ring_element, frame_element, gripper_right_body, frame_gripper)
    print(result)

    lock_joint_right = agx.LockJoint(gripper_right_body, frame_gripper,
                                     right_ring_element, frame_element)
    lock_joint_right.setName('lock_joint_right')
    lock_joint_right.setCompliance(GRIPPER_COMPLIANCE)
    sim.add(lock_joint_right)

    # Create contact materials
    contact_material = sim.getMaterialManager().getOrCreateContactMaterial(
        material_cylinder, material_ring)
    contact_material.setYoungsModulus(CONTACT_YOUNG_MODULUS)

    # Create friction model, DIRECT is more accurate, but slower
    # fm = agx.IterativeProjectedConeFriction()
    # fm.setSolveType(agx.FrictionModel.DIRECT)
    # contact_material.setFrictionModel(fm)

    # Create bases for gripper motors
    prismatic_base_left = create_hinge_prismatic_base(
        "gripper_left",
        gripper_left_body,
        position_ranges=[(-CYLINDER_RADIUS, CYLINDER_RADIUS),
                         (-CYLINDER_RADIUS, CYLINDER_RADIUS),
                         (-(CYLINDER_LENGTH + 2 * RING_RADIUS), RING_RADIUS),
                         (-math.pi / 4, math.pi / 4)])
    sim.add(prismatic_base_left)

    prismatic_base_right = create_hinge_prismatic_base(
        "gripper_right",
        gripper_right_body,
        position_ranges=[(-CYLINDER_RADIUS, CYLINDER_RADIUS),
                         (-CYLINDER_RADIUS, CYLINDER_RADIUS),
                         (-CYLINDER_LENGTH - RING_RADIUS, RING_RADIUS),
                         (-math.pi / 4, math.pi / 4)])
    sim.add(prismatic_base_right)

    # Add keyboard listener
    left_motor_x = sim.getConstraint1DOF(
        "gripper_left_joint_base_x").getMotor1D()
    left_motor_y = sim.getConstraint1DOF(
        "gripper_left_joint_base_y").getMotor1D()
    left_motor_z = sim.getConstraint1DOF(
        "gripper_left_joint_base_z").getMotor1D()
    left_motor_rb = sim.getConstraint1DOF("gripper_left_joint_rb").getMotor1D()
    right_motor_x = sim.getConstraint1DOF(
        "gripper_right_joint_base_x").getMotor1D()
    right_motor_y = sim.getConstraint1DOF(
        "gripper_right_joint_base_y").getMotor1D()
    right_motor_z = sim.getConstraint1DOF(
        "gripper_right_joint_base_z").getMotor1D()
    right_motor_rb = sim.getConstraint1DOF(
        "gripper_right_joint_rb").getMotor1D()
    key_motor_map = {
        agxSDK.GuiEventListener.KEY_Right: (right_motor_x, 0.1),
        agxSDK.GuiEventListener.KEY_Left: (right_motor_x, -0.1),
        agxSDK.GuiEventListener.KEY_Up: (right_motor_y, 0.1),
        agxSDK.GuiEventListener.KEY_Down: (right_motor_y, -0.1),
        65365: (right_motor_z, 0.1),
        65366: (right_motor_z, -0.1),
        0x64: (left_motor_x, 0.1),
        0x61: (left_motor_x, -0.1),
        0x32: (left_motor_y,
               0.1),  # 0x77 W is replaced with 2, due to prior shortcut
        0x73: (left_motor_y, -0.1),
        0x71: (left_motor_z, 0.1),
        0x65: (left_motor_z, -0.1),
        0x72: (left_motor_rb, 0.1),  # R
        0x74: (left_motor_rb, -0.1),  # T
        0x6f: (right_motor_rb, 0.1),  # O
        0x70: (right_motor_rb, -0.1)
    }  # P
    sim.add(KeyboardMotorHandler(key_motor_map))

    return sim
Esempio n. 7
0
def build_simulation():
    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Define materials
    material_hard = agx.Material("Aluminum")
    material_hard_bulk = material_hard.getBulkMaterial()
    material_hard_bulk.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    material_hard_bulk.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)

    # Create gripper
    create_gripper_peg_in_hole(sim=sim,
                               name="gripper",
                               material=material_hard,
                               position=agx.Vec3(0.0, 0.0, 0.35),
                               geometry_transform=agx.AffineMatrix4x4(),
                               joint_ranges=JOINT_RANGES,
                               force_ranges=FORCE_RANGES)

    # Create hollow cylinde with hole
    scaling_cylinder = agx.Matrix3x3(agx.Vec3(0.0275))
    hullMesh = agxUtil.createTrimeshFromWavefrontOBJ(MESH_HOLLOW_CYLINDER_FILE,
                                                     0, scaling_cylinder)
    hullGeom = agxCollide.Geometry(
        hullMesh,
        agx.AffineMatrix4x4.rotate(agx.Vec3(0, 1, 0), agx.Vec3(0, 0, 1)))
    hollow_cylinder = agx.RigidBody("hollow_cylinder")
    hollow_cylinder.add(hullGeom)
    hollow_cylinder.setMotionControl(agx.RigidBody.STATIC)
    hullGeom.setMaterial(material_hard)
    sim.add(hollow_cylinder)

    # Create rope and set name + properties
    peg = agxCable.Cable(RADIUS, RESOLUTION)
    peg.setName("DLO")
    material_peg = peg.getMaterial()
    peg_material = material_peg.getBulkMaterial()
    peg_material.setPoissonsRatio(PEG_POISSON_RATIO)
    properties = peg.getCableProperties()
    properties.setYoungsModulus(YOUNG_MODULUS_BEND, agxCable.BEND)
    properties.setYoungsModulus(YOUNG_MODULUS_TWIST, agxCable.TWIST)
    properties.setYoungsModulus(YOUNG_MODULUS_STRETCH, agxCable.STRETCH)

    # Add connection between cable and gripper
    tf_0 = agx.AffineMatrix4x4()
    tf_0.setTranslate(0.0, 0, 0.075)
    peg.add(agxCable.BodyFixedNode(sim.getRigidBody("gripper_body"), tf_0))
    peg.add(agxCable.FreeNode(0.0, 0.0, 0.1))

    sim.add(peg)

    segment_iterator = peg.begin()
    n_segments = peg.getNumSegments()
    for i in range(n_segments):
        if not segment_iterator.isEnd():
            seg = segment_iterator.getRigidBody()
            seg.setAngularVelocityDamping(1e3)
            segment_iterator.inc()

    # Try to initialize rope
    report = peg.tryInitialize()
    if report.successful():
        print("Successful rope initialization.")
    else:
        print(report.getActualError())

    # Add rope to simulation
    sim.add(peg)

    # Set rope material
    material_peg = peg.getMaterial()
    material_peg.setName("rope_material")

    contactMaterial = sim.getMaterialManager().getOrCreateContactMaterial(
        material_hard, material_peg)
    contactMaterial.setYoungsModulus(1e12)
    fm = agx.IterativeProjectedConeFriction()
    fm.setSolveType(agx.FrictionModel.DIRECT)
    contactMaterial.setFrictionModel(fm)

    # Add keyboard listener
    motor_x = sim.getConstraint1DOF("gripper_joint_base_x").getMotor1D()
    motor_y = sim.getConstraint1DOF("gripper_joint_base_y").getMotor1D()
    motor_z = sim.getConstraint1DOF("gripper_joint_base_z").getMotor1D()
    motor_rot_y = sim.getConstraint1DOF("gripper_joint_rot_y").getMotor1D()
    key_motor_map = {
        agxSDK.GuiEventListener.KEY_Up: (motor_y, 0.5),
        agxSDK.GuiEventListener.KEY_Down: (motor_y, -0.5),
        agxSDK.GuiEventListener.KEY_Right: (motor_x, 0.5),
        agxSDK.GuiEventListener.KEY_Left: (motor_x, -0.5),
        65365: (motor_z, 0.5),
        65366: (motor_z, -0.5),
        120: (motor_rot_y, 5),
        121: (motor_rot_y, -5)
    }
    sim.add(KeyboardMotorHandler(key_motor_map))

    rbs = peg.getRigidBodies()
    for i in range(len(rbs)):
        rbs[i].setName('dlo_' + str(i + 1))

    return sim
Esempio n. 8
0
def build_simulation(goal=False):
    """Builds simulations for both start and goal configurations
    :param bool goal: toggles between simulation definition of start and goal configurations
    :return agxSDK.Simulation: simulation object
    """
    assembly_name = "start_"
    goal_string = ""
    if goal:
        assembly_name = "goal_"
        goal_string = "_goal"

    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default, the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Create a new empty Assembly
    scene = agxSDK.Assembly()
    scene.setName(assembly_name + "assembly")

    # Add start assembly to simulation
    sim.add(scene)

    # Create a ground plane for reference
    if not goal:
        ground = create_body(name="ground", shape=agxCollide.Box(LENGTH, LENGTH, GROUND_WIDTH),
                             position=agx.Vec3(LENGTH / 2, 0, -(GROUND_WIDTH + SIZE_GRIPPER / 2 + LENGTH)),
                             motion_control=agx.RigidBody.STATIC)
        scene.add(ground)

    # Create cable
    cable = agxCable.Cable(RADIUS, RESOLUTION)
    cable.setName("DLO" + goal_string)

    gripper_left = create_body(name="gripper_left" + goal_string,
                               shape=agxCollide.Box(SIZE_GRIPPER, SIZE_GRIPPER, SIZE_GRIPPER),
                               position=agx.Vec3(0, 0, 0), motion_control=agx.RigidBody.DYNAMICS)
    scene.add(gripper_left)

    gripper_right = create_body(name="gripper_right" + goal_string,
                                shape=agxCollide.Box(SIZE_GRIPPER, SIZE_GRIPPER, SIZE_GRIPPER),
                                position=agx.Vec3(LENGTH, 0, 0),
                                motion_control=agx.RigidBody.DYNAMICS)
    scene.add(gripper_right)

    # Disable collisions for grippers
    gripper_left_body = scene.getRigidBody("gripper_left" + goal_string)
    gripper_left_body.getGeometry("gripper_left" + goal_string).setEnableCollisions(False)
    gripper_right_body = scene.getRigidBody("gripper_right" + goal_string)
    gripper_right_body.getGeometry("gripper_right" + goal_string).setEnableCollisions(False)

    logger.info("Mass of grippers: {}".format(scene.getRigidBody("gripper_right" + goal_string).calculateMass()))

    # Create Frames for each gripper:
    # Cables are attached passing through the attachment point along the Z axis of the body's coordinate frame.
    # The translation specified in the transformation is relative to the body and not the world
    left_transform = agx.AffineMatrix4x4()
    left_transform.setTranslate(SIZE_GRIPPER + RADIUS, 0, 0)
    left_transform.setRotate(agx.Vec3.Z_AXIS(), agx.Vec3.Y_AXIS())  # Rotation matrix which switches Z with Y
    frame_left = agx.Frame(left_transform)

    right_transform = agx.AffineMatrix4x4()
    right_transform.setTranslate(- SIZE_GRIPPER - RADIUS, 0, 0)
    right_transform.setRotate(agx.Vec3.Z_AXIS(), -agx.Vec3.Y_AXIS())  # Rotation matrix which switches Z with -Y
    frame_right = agx.Frame(right_transform)

    cable.add(agxCable.FreeNode(agx.Vec3(SIZE_GRIPPER + RADIUS, 0, 0)))  # Fix cable to gripper_left
    cable.add(agxCable.FreeNode(agx.Vec3(LENGTH - SIZE_GRIPPER - RADIUS, 0, 0)))  # Fix cable to gripper_right

    # Try to initialize cable
    report = cable.tryInitialize()
    if report.successful():
        logger.debug("Successful cable initialization.")
    else:
        logger.error(report.getActualError())

    actual_length = report.getLength()
    logger.info("Actual length: " + str(actual_length))

    # Add cable plasticity
    plasticity = agxCable.CablePlasticity()
    plasticity.setYieldPoint(YIELD_POINT, agxCable.BEND)  # set torque required for permanent deformation
    cable.addComponent(plasticity)  # NOTE: Stretch direction is always elastic

    # Define material
    material = agx.Material("Aluminum")
    bulk_material = material.getBulkMaterial()
    bulk_material.setPoissonsRatio(POISSON_RATIO)
    bulk_material.setYoungsModulus(YOUNG_MODULUS)
    cable.setMaterial(material)

    # Add cable to simulation
    scene.add(cable)

    # Add segment names and get first and last segment
    count = 1
    iterator = cable.begin()
    segment_left = iterator.getRigidBody()
    segment_left.setName('dlo_' + str(count) + goal_string)
    while not iterator.isEnd():
        count += 1
        segment_right = iterator.getRigidBody()
        segment_right.setName('dlo_' + str(count) + goal_string)
        iterator.inc()

    # Add hinge constraints
    hinge_joint_left = agx.Hinge(scene.getRigidBody("gripper_left" + goal_string), frame_left, segment_left)
    hinge_joint_left.setName('hinge_joint_left' + goal_string)
    motor_left = hinge_joint_left.getMotor1D()
    motor_left.setEnable(True)
    motor_left_param = motor_left.getRegularizationParameters()
    motor_left_param.setCompliance(1e12)
    motor_left.setLockedAtZeroSpeed(False)
    lock_left = hinge_joint_left.getLock1D()
    lock_left.setEnable(False)
    # Set range of hinge joint
    # range_left = hinge_joint_left.getRange1D()
    # range_left.setEnable(True)
    # range_left.setRange(agx.RangeReal(-math.pi / 2, math.pi / 2))
    scene.add(hinge_joint_left)

    hinge_joint_right = agx.Hinge(scene.getRigidBody("gripper_right" + goal_string), frame_right, segment_right)
    hinge_joint_right.setName('hinge_joint_right' + goal_string)
    motor_right = hinge_joint_right.getMotor1D()
    motor_right.setEnable(True)
    motor_right_param = motor_right.getRegularizationParameters()
    motor_right_param.setCompliance(1e12)
    motor_right.setLockedAtZeroSpeed(False)
    lock_right = hinge_joint_right.getLock1D()
    lock_right.setEnable(False)
    # Set range of hinge joint
    # range_right = hinge_joint_right.getRange1D()
    # range_right.setEnable(True)
    # range_right.setRange(agx.RangeReal(-math.pi / 2, math.pi / 2))
    scene.add(hinge_joint_right)

    # Create base for gripper motors
    prismatic_base_right = create_locked_prismatic_base("gripper_right" + goal_string, gripper_right_body, compliance=0,
                                                        motor_ranges=[(-FORCE_RANGE, FORCE_RANGE),
                                                                      (-FORCE_RANGE, FORCE_RANGE),
                                                                      (-FORCE_RANGE, FORCE_RANGE)],
                                                        position_ranges=[
                                                            (-LENGTH + 2 * (2 * RADIUS + SIZE_GRIPPER),
                                                             0),
                                                            (-LENGTH, LENGTH),
                                                            (-LENGTH, LENGTH)],
                                                        compute_forces=True,
                                                        lock_status=[False, False, False])
    scene.add(prismatic_base_right)
    prismatic_base_left = create_locked_prismatic_base("gripper_left" + goal_string, gripper_left_body, compliance=0,
                                                       lock_status=[True, True, True])
    scene.add(prismatic_base_left)

    return sim
Esempio n. 9
0
def build_simulation(goal=False):
    """Builds simulations for both start and goal configurations
    :param bool goal: toggles between simulation definition of start and goal configurations
    :return agxSDK.Simulation: simulation object
    """
    assembly_name = "start_"
    goal_string = ""
    if goal:
        assembly_name = "goal_"
        goal_string = "_goal"

    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default, the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Create a new empty Assembly
    scene = agxSDK.Assembly()
    scene.setName(assembly_name + "assembly")

    # Add start assembly to simulation
    sim.add(scene)

    # Create a ground plane for reference and obstacle
    if not goal:
        ground = create_body(name="ground",
                             shape=agxCollide.Box(LENGTH, LENGTH,
                                                  GROUND_WIDTH),
                             position=agx.Vec3(
                                 0, 0,
                                 -(GROUND_WIDTH + SIZE_GRIPPER / 2 + LENGTH)),
                             motion_control=agx.RigidBody.STATIC)
        sim.add(ground)

    # Create two grippers
    gripper_left = create_body(name="gripper_left" + goal_string,
                               shape=agxCollide.Box(SIZE_GRIPPER, SIZE_GRIPPER,
                                                    SIZE_GRIPPER),
                               position=agx.Vec3(-LENGTH / 2, 0, 0),
                               motion_control=agx.RigidBody.DYNAMICS)
    scene.add(gripper_left)

    gripper_right = create_body(name="gripper_right" + goal_string,
                                shape=agxCollide.Box(SIZE_GRIPPER,
                                                     SIZE_GRIPPER,
                                                     SIZE_GRIPPER),
                                position=agx.Vec3(LENGTH / 2, 0, 0),
                                motion_control=agx.RigidBody.DYNAMICS)
    scene.add(gripper_right)

    gripper_left_body = gripper_left.getRigidBody("gripper_left" + goal_string)
    gripper_right_body = gripper_right.getRigidBody("gripper_right" +
                                                    goal_string)

    # Create material
    material_cylinder = agx.Material("cylinder_material")
    bulk_material_cylinder = material_cylinder.getBulkMaterial()
    bulk_material_cylinder.setPoissonsRatio(POISSON_RATIO)
    bulk_material_cylinder.setYoungsModulus(YOUNG_MODULUS)

    cylinder = create_body(name="obstacle" + goal_string,
                           shape=agxCollide.Cylinder(CYLINDER_RADIUS,
                                                     CYLINDER_LENGTH),
                           position=agx.Vec3(0, 0, -2 * CYLINDER_RADIUS),
                           motion_control=agx.RigidBody.STATIC,
                           material=material_cylinder)
    scene.add(cylinder)

    # Create cable
    cable = agxCable.Cable(RADIUS, RESOLUTION)

    # Create Frames for each gripper:
    # Cables are attached passing through the attachment point along the Z axis of the body's coordinate frame.
    # The translation specified in the transformation is relative to the body and not the world
    left_transform = agx.AffineMatrix4x4()
    left_transform.setTranslate(SIZE_GRIPPER + RADIUS, 0, 0)
    left_transform.setRotate(
        agx.Vec3.Z_AXIS(),
        agx.Vec3.Y_AXIS())  # Rotation matrix which switches Z with Y
    frame_left = agx.Frame(left_transform)

    right_transform = agx.AffineMatrix4x4()
    right_transform.setTranslate(-SIZE_GRIPPER - RADIUS, 0, 0)
    right_transform.setRotate(
        agx.Vec3.Z_AXIS(),
        -agx.Vec3.Y_AXIS())  # Rotation matrix which switches Z with -Y
    frame_right = agx.Frame(right_transform)

    cable.add(
        agxCable.FreeNode(agx.Vec3(-LENGTH / 2 + SIZE_GRIPPER + RADIUS, 0,
                                   0)))  # Fix cable to gripper_left
    cable.add(
        agxCable.FreeNode(agx.Vec3(LENGTH / 2 - SIZE_GRIPPER - RADIUS, 0,
                                   0)))  # Fix cable to gripper_right

    # Set cable name and properties
    cable.setName("DLO" + goal_string)
    properties = cable.getCableProperties()
    properties.setYoungsModulus(YOUNG_MODULUS, agxCable.BEND)
    properties.setYoungsModulus(YOUNG_MODULUS, agxCable.TWIST)
    properties.setYoungsModulus(YOUNG_MODULUS, agxCable.STRETCH)

    material_wire = cable.getMaterial()
    wire_material = material_wire.getBulkMaterial()
    wire_material.setPoissonsRatio(POISSON_RATIO)
    wire_material.setYoungsModulus(YOUNG_MODULUS)
    cable.setMaterial(material_wire)

    # Add cable plasticity
    plasticity = agxCable.CablePlasticity()
    plasticity.setYieldPoint(
        YIELD_POINT,
        agxCable.BEND)  # set torque required for permanent deformation
    plasticity.setYieldPoint(
        YIELD_POINT,
        agxCable.STRETCH)  # set torque required for permanent deformation
    cable.addComponent(plasticity)  # NOTE: Stretch direction is always elastic

    # Tell MaterialManager to create and return a contact material which will be used
    # when two geometries both with this material is in contact
    contact_material = sim.getMaterialManager().getOrCreateContactMaterial(
        material_cylinder, material_wire)
    contact_material.setYoungsModulus(CONTACT_YOUNG_MODULUS)

    # Create a Friction model, which we tell the solver to solve ITERATIVELY (faster)
    fm = agx.IterativeProjectedConeFriction()
    fm.setSolveType(agx.FrictionModel.DIRECT)
    contact_material.setFrictionModel(fm)

    # Try to initialize cable
    report = cable.tryInitialize()
    if report.successful():
        logger.debug("Successful cable initialization.")
    else:
        logger.error(report.getActualError())

    # Add cable to simulation
    sim.add(cable)

    # Add segment names and get first and last segment
    segment_count = 0
    iterator = cable.begin()
    segment_left = iterator.getRigidBody()
    segment_left.setName('dlo_' + str(segment_count + 1) + goal_string)
    segment_right = None

    while not iterator.isEnd():
        segment_count += 1
        segment_right = iterator.getRigidBody()
        segment_right.setName('dlo_' + str(segment_count + 1) + goal_string)
        iterator.inc()

    # Add hinge constraints
    hinge_joint_left = agx.Hinge(
        sim.getRigidBody("gripper_left" + goal_string), frame_left,
        segment_left)
    hinge_joint_left.setName('hinge_joint_left' + goal_string)
    motor_left = hinge_joint_left.getMotor1D()
    motor_left.setEnable(False)
    motor_left_param = motor_left.getRegularizationParameters()
    motor_left_param.setCompliance(1e12)
    motor_left.setLockedAtZeroSpeed(False)
    lock_left = hinge_joint_left.getLock1D()
    lock_left.setEnable(False)
    range_left = hinge_joint_left.getRange1D()
    range_left.setEnable(True)
    range_left.setRange(agx.RangeReal(-math.pi / 2, math.pi / 2))
    sim.add(hinge_joint_left)

    hinge_joint_right = agx.Hinge(
        sim.getRigidBody("gripper_right" + goal_string), frame_right,
        segment_right)
    hinge_joint_right.setName('hinge_joint_right' + goal_string)
    motor_right = hinge_joint_right.getMotor1D()
    motor_right.setEnable(False)
    motor_right_param = motor_right.getRegularizationParameters()
    motor_right_param.setCompliance(1e12)
    motor_right.setLockedAtZeroSpeed(False)
    lock_right = hinge_joint_right.getLock1D()
    lock_right.setEnable(False)
    range_right = hinge_joint_right.getRange1D()
    range_right.setEnable(True)
    range_right.setRange(agx.RangeReal(-math.pi / 2, math.pi / 2))
    sim.add(hinge_joint_right)

    # Create bases for gripper motors
    prismatic_base_left = create_locked_prismatic_base(
        "gripper_left" + goal_string,
        gripper_left_body,
        compliance=0,
        motor_ranges=[(-FORCE_RANGE, FORCE_RANGE), (-FORCE_RANGE, FORCE_RANGE),
                      (-FORCE_RANGE, FORCE_RANGE)],
        position_ranges=[(-LENGTH / 2 + CYLINDER_RADIUS,
                          LENGTH / 2 - CYLINDER_RADIUS),
                         (-CYLINDER_LENGTH / 3, CYLINDER_LENGTH / 3),
                         (-(GROUND_WIDTH + SIZE_GRIPPER / 2 + LENGTH), 0)],
        lock_status=[False, False, False])
    sim.add(prismatic_base_left)
    prismatic_base_right = create_locked_prismatic_base(
        "gripper_right" + goal_string,
        gripper_right_body,
        compliance=0,
        motor_ranges=[(-FORCE_RANGE, FORCE_RANGE), (-FORCE_RANGE, FORCE_RANGE),
                      (-FORCE_RANGE, FORCE_RANGE)],
        position_ranges=[(-LENGTH / 2 + CYLINDER_RADIUS,
                          LENGTH / 2 - CYLINDER_RADIUS),
                         (-CYLINDER_LENGTH / 3, CYLINDER_LENGTH / 3),
                         (-(GROUND_WIDTH + SIZE_GRIPPER / 2 + LENGTH), 0)],
        lock_status=[False, False, False])
    sim.add(prismatic_base_right)

    return sim
Esempio n. 10
0
def build_simulation():
    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Define materials
    material_hard = agx.Material("Aluminum")
    material_hard_bulk = material_hard.getBulkMaterial()
    material_hard_bulk.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    material_hard_bulk.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)

    # Create a ground plane
    ground = create_body(name="ground",
                         shape=agxCollide.Box(GROUND_LENGTH_X, GROUND_LENGTH_Y,
                                              GROUND_HEIGHT),
                         position=agx.Vec3(0, 0, -0.005),
                         motion_control=agx.RigidBody.STATIC)
    sim.add(ground)

    # Creates poles
    for i, position in enumerate(POLE_POSITION_OFFSETS):
        create_pole(id=i, sim=sim, position=position, material=material_hard)

    # Create gripper
    gripper = create_body(name="gripper",
                          shape=agxCollide.Sphere(0.002),
                          position=agx.Vec3(0.0, 0.0,
                                            GRIPPER_HEIGHT + DIAMETER / 2.0),
                          motion_control=agx.RigidBody.DYNAMICS,
                          material=material_hard)
    gripper.getRigidBody("gripper").getGeometry("gripper").setEnableCollisions(
        False)

    sim.add(gripper)

    # Create base for pusher motors
    prismatic_base = create_locked_prismatic_base(
        "gripper",
        gripper.getRigidBody("gripper"),
        position_ranges=[(-GRIPPER_MAX_X, GRIPPER_MAX_X),
                         (-GRIPPER_MAX_Y, GRIPPER_MAX_Y),
                         (GRIPPER_MIN_Z, GRIPPER_MAX_Z)],
        motor_ranges=[(-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                      (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                      (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE)])
    sim.add(prismatic_base)

    # Create rope and set name + properties
    rubber_band = agxCable.Cable(RADIUS, RESOLUTION)
    rubber_band.setName("DLO")
    material_rubber_band = rubber_band.getMaterial()
    rubber_band_material = material_rubber_band.getBulkMaterial()
    rubber_band_material.setPoissonsRatio(PEG_POISSON_RATIO)
    properties = rubber_band.getCableProperties()
    properties.setYoungsModulus(YOUNG_MODULUS_BEND, agxCable.BEND)
    properties.setYoungsModulus(YOUNG_MODULUS_TWIST, agxCable.TWIST)
    properties.setYoungsModulus(YOUNG_MODULUS_STRETCH, agxCable.STRETCH)

    # Initialize dlo on circle
    steps = DLO_CIRCLE_STEPS
    for a in np.linspace(-np.pi / 2, (3.0 / 2.0) * np.pi - 2 * np.pi / steps,
                         steps):
        x = np.cos(a) * DIAMETER / 2.0
        z = np.sin(a) * DIAMETER / 2.0
        rubber_band.add(agxCable.FreeNode(x, 0, GRIPPER_HEIGHT + z))

    sim.add(rubber_band)

    segments_cable = list()
    cable = agxCable.Cable.find(sim, "DLO")
    segment_iterator = cable.begin()
    n_segments = cable.getNumSegments()
    for i in range(n_segments):
        if not segment_iterator.isEnd():
            seg = segment_iterator.getRigidBody()
            seg.setAngularVelocityDamping(1e4)
            mass_props = seg.getMassProperties()
            mass_props.setMass(1.25 * mass_props.getMass())
            segments_cable.append(seg)
            segment_iterator.inc()

    # Get segments at ends and middle
    s0 = segments_cable[0]
    s1 = segments_cable[int(n_segments / 2)]
    s2 = segments_cable[-1]

    # Add ball joint between gripper and rubber band
    f0 = agx.Frame()
    f1 = agx.Frame()
    ball_joint = agx.BallJoint(gripper.getRigidBody("gripper"), f0, s1, f1)
    sim.add(ball_joint)

    # Connect ends of rubber band
    f0 = agx.Frame()
    f0.setLocalTranslate(0.0, 0.0,
                         -1 * np.pi * DIAMETER / cable.getNumSegments())
    f1 = agx.Frame()
    lock = agx.LockJoint(s0, f0, s2, f1)
    lock.setCompliance(1.0e-4)
    sim.add(lock)

    # Try to initialize dlo
    report = rubber_band.tryInitialize()
    if report.successful():
        print("Successful dlo initialization.")
    else:
        print(report.getActualError())

    # Add rope to simulation
    sim.add(rubber_band)

    # Set rope material
    material_rubber_band = rubber_band.getMaterial()
    material_rubber_band.setName("rope_material")

    contactMaterial = sim.getMaterialManager().getOrCreateContactMaterial(
        material_hard, material_rubber_band)
    contactMaterial.setYoungsModulus(1e12)
    fm = agx.IterativeProjectedConeFriction()
    fm.setSolveType(agx.FrictionModel.DIRECT)
    contactMaterial.setFrictionModel(fm)

    # Add keyboard listener
    motor_x = sim.getConstraint1DOF("gripper_joint_base_x").getMotor1D()
    motor_y = sim.getConstraint1DOF("gripper_joint_base_y").getMotor1D()
    motor_z = sim.getConstraint1DOF("gripper_joint_base_z").getMotor1D()
    key_motor_map = {
        agxSDK.GuiEventListener.KEY_Up: (motor_y, 0.2),
        agxSDK.GuiEventListener.KEY_Down: (motor_y, -0.2),
        agxSDK.GuiEventListener.KEY_Right: (motor_x, 0.2),
        agxSDK.GuiEventListener.KEY_Left: (motor_x, -0.2),
        65365: (motor_z, 0.2),
        65366: (motor_z, -0.2)
    }
    sim.add(KeyboardMotorHandler(key_motor_map))

    rbs = rubber_band.getRigidBodies()
    for i in range(len(rbs)):
        rbs[i].setName('dlo_' + str(i + 1))

    return sim
def main():
    ap = argparse.ArgumentParser()
    ap.add_argument(
        "input",
        type=str,
        help=
        ".agx file whos particleEmitters will be replaced with rigidBodyEmitters."
    )
    ap.add_argument("-o",
                    "--output",
                    default="output.agx",
                    type=str,
                    help="Path for the resulting .agx file.")
    ap.add_argument("--shapeLibrary",
                    type=str,
                    default="",
                    help="Path to the shape library.")
    args = vars(ap.parse_args())

    input_path = args["input"]
    output_path = args["output"]
    shape_library_path = args["shapeLibrary"]

    if os.path.isfile(input_path):
        print("The serialized simulation to load:", input_path)
    else:
        sys.exit("Could not find input path:", input_path)
    print("The path where the new simulation is saved:",
          os.path.abspath(output_path))

    # check that the shape library path exists
    if not shape_library_path:
        if os.environ.get("AGX_DATA_DIR"):
            shape_library_path = os.path.join(os.environ.get("AGX_DATA_DIR"),
                                              "models\\convex_stones")
        else:
            sys.exit("No shape library found or given.")

    if os.path.isdir(shape_library_path):
        print("The path to the shape library is:", shape_library_path)
    else:
        sys.exit("Shape library path do not exist, or is not a directory:",
                 shape_library_path)
    print(
        "------------------------------------------------------------------------------"
    )
    shape_paths = find_shapes(shape_library_path)
    if len(shape_paths) < 1:
        sys.exit("Did not find any shapes in ", shape_library_path)

    sim = agxSDK.Simulation()
    sim.read(input_path, None, agxSDK.Simulation.READ_NONE)

    print(
        "------------------------------------------------------------------------------"
    )
    particle_emitters = sim.getParticleEmitters()
    if particle_emitters is None:
        sys.exit("Did not find any particle emitters in simulation.")
    else:
        print(
            "Found %d particle emitters. Replacing with rigidbody emitters ..."
            % len(particle_emitters))

    existing_materials = {}
    geoms = sim.getGeometries()
    for g in geoms:
        m = g.getMaterial()
        if m not in existing_materials.values():
            existing_materials[m.getName()] = m

    # Replace each of the particle emitters with rigid body emitters
    particle_model_materials = []
    rb_model_materials = []
    for pe in particle_emitters:
        dt = pe.getDistributionTable()
        # get emitter geometry
        geom = pe.getGeometry()
        geom.setSensor(True)
        # get the size, material and probability weight of all particle models
        weights = []
        sizes = []
        models = dt.getModels()
        for pm in models:
            m = pm.asParticleEmitterDistributionModel()
            sizes.append(m.getParticleRadius() * 2.0)
            weights.append(m.getProbabilityWeight())
            material = m.getParticleMaterial()

        if len(sizes) < 1:
            sys.exit("No particle models set on particle emitter",
                     geom.getName())

        # create a new material to use for the rigidbodies
        particle_model_materials.append(material)
        rb_mat = create_rigid_body_material_from_particle_material(material)
        rb_model_materials.append(rb_mat)
        # create rigid body distribution table from shape library
        dt_rb = create_distribution_table(shape_paths, sizes, weights, rb_mat)
        dt_rb.setProbabilityQuantity(dt.getProbabilityQuantity())

        # create rigidbody emitter
        rbe = agx.RigidBodyEmitter()
        rbe.setQuantity(pe.getQuantity())
        rbe.setRate(pe.getRate())
        rbe.setMaximumEmittedQuantity(pe.getMaximumEmittedQuantity())
        rbe.setGeometry(geom)
        rbe.setDistributionTable(dt_rb)

        # switch the emitter type in the simulation
        sim.add(rbe)
        sim.remove(pe)
        print("Replaced particle emitter on geometry: %s" % geom.getName())

    print(
        "------------------------------------------------------------------------------"
    )
    print(
        "Copying contact material properties from old particle material to the new rb material "
    )
    mm = sim.getMaterialManager()
    iterative_projected_cone_friction = agx.IterativeProjectedConeFriction()
    iterative_projected_cone_friction.setSolveType(agx.FrictionModel.ITERATIVE)

    # Copy material properties from the old particle material to the new rigidbody material
    def copy_cm_properties(old_pair, new_pair):
        cm0 = mm.getContactMaterial(old_pair[0], old_pair[1])
        restitution = cm0.getRestitution()
        friction = cm0.getFrictionCoefficient()
        cm1 = mm.getOrCreateContactMaterial(new_pair[0], new_pair[1])
        cm1.setRestitution(restitution)
        cm1.setFrictionCoefficient(friction)
        return cm1

    i = 0
    for particle_material, rb_material in zip(particle_model_materials,
                                              rb_model_materials):
        for k, v in existing_materials.items():
            cm1 = copy_cm_properties((particle_material, v), (v, rb_material))
            print("Material properties for contact material: %s-%s" %
                  (k, rb_material.getName()))
            print("... friction coefficient is: ",
                  cm1.getFrictionCoefficient())
            print("... restitution is: ", cm1.getRestitution())
        for particle_material2, rb_material2 in zip(
                particle_model_materials[i:], rb_model_materials[i:]):
            cm1 = copy_cm_properties((particle_material, particle_material2),
                                     (rb_material, rb_material2))
            cm1.setFrictionModel(iterative_projected_cone_friction)
            print("Material properties for contact material: %s-%s" %
                  (rb_material.getName(), rb_material2.getName()))
            print("... friction coefficient is: ",
                  cm1.getFrictionCoefficient())
            print("... restitution is: ", cm1.getRestitution())
        i += 1

    print(
        "------------------------------------------------------------------------------"
    )
    print("Removing all the particle materials...")
    # Remove all the old particle materials
    for pmat in particle_model_materials:
        print("... removing material \'%s\'" % pmat.getName())
        sim.getMaterialManager().remove(pmat)

    print(
        "------------------------------------------------------------------------------"
    )
    print("Finding particle sinks and making them rigidBody sinks...")
    # Find all the rigidbodies that are named "Sinki" for i=0...n where n+1 returns None.
    # and set a sensoroperation to remove rigidBodies.
    i = 0
    while True:
        rb = sim.getRigidBody("Sink%d" % i)
        if rb is not None:
            for g in rb.getGeometries():
                if g.isSensor():
                    print(
                        "... Found sink geometry \'%s\'. Is now rigidBody sink aswell."
                        % g.getName())
                    event_sensor = agxControl.EventSensor(g)
                    sensor_op = agxControl.RemoveRigidBody()
                    event_sensor.addSensorEvent(sensor_op)
                    sim.add(event_sensor)
        else:
            break
        i += 1

    print(
        "------------------------------------------------------------------------------"
    )
    sim.write(os.path.abspath(output_path))
    print("Saved simulation as:", os.path.abspath(output_path))
    print("You can run the simulation with the command agxviewer %s" %
          os.path.abspath(output_path))
    print(
        "Use the flags --journalRecord --journalIncrementalStructure to record a journal."
    )
Esempio n. 12
0
    def __init__(self, scene_path, n_substeps, n_actions, observation_config,
                 camera_pose, osg_window, agx_only, args):
        """Initializes a AgxEnv object
        :param str scene_path: path to binary file containing serialized simulation defined in sim/ folder
        :param int n_substeps: number os simulation steps per call to step()
        :param int n_actions: number of actions (DoF)
        :param gym_agx.rl.observation.ObservationConfig observation_config: observation configuration object
        :param dict camera_pose: dictionary containing EYE, CENTER, UP information for rendering
        :param bool osg_window: enables/disables window rendering (useful for training)
        :param bool agx_only: enables/disables all rendering (useful for training which does not use images)
        :param list args: arguments for agxViewer
        """
        self.render_mode = 'osg'
        self.scene_path = scene_path
        self.n_substeps = n_substeps

        self.gravity = None
        self.time_step = None
        self.init = agx.AutoInit()
        self.sim = agxSDK.Simulation()
        self._build_simulation()

        self.app = None
        self.root = None
        self.camera_pose = camera_pose
        self.osg_window = osg_window
        self.agx_only = agx_only

        self.n_actions = n_actions
        self.observation_config = observation_config

        self.args = args
        if not self.agx_only:
            self.app = agxOSG.ExampleApplication(self.sim)
            self.args = self.args + [
                '--window', 2 * observation_config.image_size[1],
                2 * observation_config.image_size[0]
            ]
            if self.osg_window:
                if self.observation_config.depth_in_obs or self.observation_config.rgb_in_obs:
                    warnings.warn((
                        "OSG window is enabled! \n"
                        "=======> Observations contain image data (OSG rendering cannot be disabled). \n"
                        "=======> Rendering is done inside step(). No need to call render()."
                    ))
                else:
                    warnings.warn((
                        "OSG window is enabled! \n"
                        "=======> Observations do not contain image data. \n"
                        "=======> Rendering is done inside render(), do not use 'human' or 'depth' mode."
                    ))
            else:
                self.args = self.args + ['--osgWindow', '0']
                if self.observation_config.depth_in_obs or self.observation_config.rgb_in_obs:
                    warnings.warn((
                        "OSG window is disabled! \n"
                        "=======> Observations contain image data (OSG rendering cannot be enabled). \n"
                        "=======> Rendering is done inside step(), "
                        "only 'human' or 'depth' modes available."))
                else:
                    warnings.warn(
                        ("OSG window is disabled! \n"
                         "=======> Observations do not contain image data. \n"
                         "=======> Rendering is done inside render(), "
                         "only 'human' or 'depth' modes available."))

        self.render_to_image = []
        self.img_object = None

        # TODO: Is this needed?
        self.fps = int(np.round(1.0 / self.dt))
        self.np_random = None
        self.seed()

        self.goal = self._sample_goal()
        obs = self._get_observation()

        self.obs_space = construct_space(obs['observation'])
        self.goal_space = construct_space(obs['desired_goal'])

        self.action_space = spaces.Box(-1.,
                                       1.,
                                       shape=(self.n_actions, ),
                                       dtype='float32')
        self.observation_space = spaces.Dict(
            dict(desired_goal=self.goal_space,
                 achieved_goal=self.goal_space,
                 observation=self.obs_space))
Esempio n. 13
0
def build_simulation():
    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Define materials
    material_hard = agx.Material("Aluminum")
    material_hard_bulk = material_hard.getBulkMaterial()
    material_hard_bulk.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    material_hard_bulk.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)

    # Create box with pocket
    side_length = 0.15
    thickness_outer_wall = 0.01
    body = create_body(name="ground", shape=agxCollide.Box(side_length, side_length, 0.01),
                       position=agx.Vec3(0, 0, -0.005),
                       motion_control=agx.RigidBody.STATIC,
                       material=material_hard)

    sim.add(body)

    body = create_body(name="walls", shape=agxCollide.Box(thickness_outer_wall, side_length, 0.04),
                       position=agx.Vec3(side_length + thickness_outer_wall, 0, 0.0),
                       motion_control=agx.RigidBody.STATIC,
                       material=material_hard)
    sim.add(body)

    body = create_body(name="walls", shape=agxCollide.Box(thickness_outer_wall, side_length, 0.04),
                       position=agx.Vec3(-(side_length + thickness_outer_wall), 0, 0.0),
                       motion_control=agx.RigidBody.STATIC,
                       material=material_hard)
    sim.add(body)

    body = create_body(name="walls",
                       shape=agxCollide.Box(side_length + 2 * thickness_outer_wall, thickness_outer_wall, 0.04),
                       position=agx.Vec3(0, -(side_length + thickness_outer_wall), 0.0),
                       motion_control=agx.RigidBody.STATIC,
                       material=material_hard)
    sim.add(body)

    body = create_body(name="walls",
                       shape=agxCollide.Box(side_length + 2 * thickness_outer_wall, thickness_outer_wall, 0.04),
                       position=agx.Vec3(0, side_length + thickness_outer_wall, 0.0),
                       motion_control=agx.RigidBody.STATIC,
                       material=material_hard)
    sim.add(body)

    # Create gripper 0
    gripper_0 = create_body(name="gripper_0",
                            shape=agxCollide.Sphere(0.005),
                            position=agx.Vec3(-(LENGTH/2), OFFSET_Y, 0.0025),
                            motion_control=agx.RigidBody.DYNAMICS,
                            material=material_hard)
    gripper_0.getRigidBody("gripper_0").getGeometry("gripper_0").setEnableCollisions(False)
    sim.add(gripper_0)

    # Create base for gripper motors
    prismatic_base_0 = create_locked_prismatic_base("gripper_0", gripper_0.getRigidBody("gripper_0"),
                                                    position_ranges=[(-side_length*2, side_length*2),
                                                                     (-side_length*2, side_length*2),
                                                                     (-0.1, 0.01)],
                                                    motor_ranges=[(-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                  (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                  (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE)],
                                                    lock_status=[False, False, False])

    sim.add(prismatic_base_0)

    # Create gripper
    gripper_1 = create_body(name="gripper_1",
                            shape=agxCollide.Sphere(0.005),
                            position=agx.Vec3((LENGTH/2), OFFSET_Y, 0.0025),
                            motion_control=agx.RigidBody.DYNAMICS,
                            material=material_hard)
    gripper_1.getRigidBody("gripper_1").getGeometry("gripper_1").setEnableCollisions(False)
    sim.add(gripper_1)

    # Create base for gripper motors
    prismatic_base_0 = create_locked_prismatic_base("gripper_1", gripper_1.getRigidBody("gripper_1"),
                                                    position_ranges=[(-side_length*2, side_length*2),
                                                                     (-side_length*2, side_length*2),
                                                                     (-0.1, 0.01)],
                                                    motor_ranges=[(-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                  (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                  (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE)],
                                                    lock_status=[False, False, False])
    sim.add(prismatic_base_0)
    
    # Create goal obstacle
    goal_obstacle = create_body(name="obstacle_goal",
                           shape=agxCollide.Cylinder(2 * R_GOAL_OBSTACLE, 0.1),
                           position=agx.Vec3(0.0,0.-0.075, 0.005),
                           motion_control=agx.RigidBody.STATIC,
                           material=material_hard)
    sim.add(goal_obstacle)
    rotation_cylinder = agx.OrthoMatrix3x3()
    rotation_cylinder.setRotate(agx.Vec3.Y_AXIS(), agx.Vec3.Z_AXIS())
    goal_obstacle.setRotation(rotation_cylinder)

    # Create obstacles
    obs_pos = OBSTACLE_POSITIONS
    for i in range(0, len(obs_pos)):
        obstacle = create_body(name="obstacle",
                               shape=agxCollide.Box(0.01, 0.015, 0.05),
                               position=agx.Vec3(obs_pos[i][0], obs_pos[i][1], 0.005),
                               motion_control=agx.RigidBody.STATIC,
                               material=material_hard)
        sim.add(obstacle)

    # Create rope and set name + properties
    dlo = agxCable.Cable(RADIUS, RESOLUTION)
    dlo.setName("DLO")
    material_rubber_band= dlo.getMaterial()
    rubber_band_material = material_rubber_band.getBulkMaterial()
    rubber_band_material.setPoissonsRatio(PEG_POISSON_RATIO)
    properties = dlo.getCableProperties()
    properties.setYoungsModulus(YOUNG_MODULUS_BEND, agxCable.BEND)
    properties.setYoungsModulus(YOUNG_MODULUS_TWIST, agxCable.TWIST)
    properties.setYoungsModulus(YOUNG_MODULUS_STRETCH, agxCable.STRETCH)

    dlo.add(agxCable.FreeNode(gripper_0.getRigidBody("gripper_0").getPosition()))
    dlo.add(agxCable.FreeNode(gripper_1.getRigidBody("gripper_1").getPosition()))
    #
    # hf = agx.HingeFrame()
    # hf.setCenter(gripper_0.getRigidBody("gripper_0").getPosition())
    # hf.setAxis(agx.Vec3(0,1,0))
    # hinge_0 = agx.Hinge(hf, base_z, rot_y)
    # agx.Hinge()


    # dlo.add(agxCable.BodyFixedNode(gripper_0.getRigidBody("gripper_0"), agx.Vec3()))
    # dlo.add(agxCable.BodyFixedNode(gripper_1.getRigidBody("gripper_1"),  agx.Vec3()))

    # Set angular damping for segments
    sim.add(dlo)
    segment_iterator = dlo.begin()
    n_segments = dlo.getNumSegments()
    segments = []
    for i in range(n_segments):
        if not segment_iterator.isEnd():
            seg = segment_iterator.getRigidBody()
            segments.append(seg)
            seg.setAngularVelocityDamping(2e4)
            segment_iterator.inc()
            mass_props = seg.getMassProperties()
            mass_props.setMass(1.25*mass_props.getMass())


    s0 = segments[0]
    s1 = segments[-1]

    h0 = agx.HingeFrame()
    h0.setCenter(gripper_0.getRigidBody("gripper_0").getPosition())
    h0.setAxis(agx.Vec3(0,0,1))
    l0 = agx.Hinge(h0, s0, gripper_0.getRigidBody("gripper_0") )
    sim.add(l0)

    h1 = agx.HingeFrame()
    h1.setCenter(gripper_1.getRigidBody("gripper_1").getPosition())
    h1.setAxis(agx.Vec3(0,0,1))
    l1 = agx.Hinge(h1, s1, gripper_1.getRigidBody("gripper_1") )
    sim.add(l1)

    # f0 = agx.Frame()
    # f1 = agx.Frame()
    # l0 = agx.LockJoint(s0, f0, gripper_0.getRigidBody("gripper_0"), f1)
    # l1 = agx.LockJoint(s1, f0, gripper_1.getRigidBody("gripper_1"), f1)
    # sim.add(l0)
    # sim.add(l1)

    # Try to initialize dlo
    report = dlo.tryInitialize()
    if report.successful():
        print("Successful dlo initialization.")
    else:
        print(report.getActualError())

    # Add rope to simulation
    sim.add(dlo)

    # Set rope material
    material_rubber_band = dlo.getMaterial()
    material_rubber_band.setName("rope_material")

    contactMaterial = sim.getMaterialManager().getOrCreateContactMaterial(material_hard, material_rubber_band)
    contactMaterial.setYoungsModulus(1e12)
    fm = agx.IterativeProjectedConeFriction()
    fm.setSolveType(agx.FrictionModel.DIRECT)
    contactMaterial.setFrictionModel(fm)

    # Add keyboard listener
    motor_x_0 = sim.getConstraint1DOF("gripper_0_joint_base_x").getMotor1D()
    motor_y_0 = sim.getConstraint1DOF("gripper_0_joint_base_y").getMotor1D()
    motor_x_1 = sim.getConstraint1DOF("gripper_1_joint_base_x").getMotor1D()
    motor_y_1 = sim.getConstraint1DOF("gripper_1_joint_base_y").getMotor1D()
    key_motor_map = {agxSDK.GuiEventListener.KEY_Up: (motor_y_0, 0.5),
                     agxSDK.GuiEventListener.KEY_Down: (motor_y_0, -0.5),
                     agxSDK.GuiEventListener.KEY_Right: (motor_x_0, 0.5),
                     agxSDK.GuiEventListener.KEY_Left: (motor_x_0, -0.5),
                     120: (motor_x_1, 0.5),
                     60: (motor_x_1, -0.5),
                     97: (motor_y_1, 0.5),
                     121: (motor_y_1, -0.5)}
    sim.add(KeyboardMotorHandler(key_motor_map))

    rbs = dlo.getRigidBodies()
    for i in range(len(rbs)):
        rbs[i].setName('dlo_' + str(i+1))

    return sim
Esempio n. 14
0
def build_simulation(goal=False, rope=True):
    """Builds simulations for both start and goal configurations
    :param bool goal: toggles between simulation definition of start and goal configurations
    :param bool rope: add rope to the scene or not
    :return agxSDK.Simulation: simulation object
    """
    assembly_name = "start_"
    goal_string = ""
    if goal:
        assembly_name = "goal_"
        goal_string = "_goal"

    # Instantiate a simulation
    sim = agxSDK.Simulation()

    # By default, the gravity vector is 0,0,-9.81 with a uniform gravity field. (we CAN change that
    # too by creating an agx.PointGravityField for example).
    # AGX uses a right-hand coordinate system (That is Z defines UP. X is right, and Y is into the screen)
    if not GRAVITY:
        logger.info("Gravity off.")
        g = agx.Vec3(0, 0, 0)  # remove gravity
        sim.setUniformGravity(g)

    # Get current delta-t (timestep) that is used in the simulation?
    dt = sim.getTimeStep()
    logger.debug("default dt = {}".format(dt))

    # Change the timestep
    sim.setTimeStep(TIMESTEP)

    # Confirm timestep changed
    dt = sim.getTimeStep()
    logger.debug("new dt = {}".format(dt))

    # Create a new empty Assembly
    scene = agxSDK.Assembly()
    scene.setName(assembly_name + "assembly")

    # Add start assembly to simulation
    sim.add(scene)

    # Define materials
    material_ground = agx.Material("Aluminum")
    bulk_material = material_ground.getBulkMaterial()
    bulk_material.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    bulk_material.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)
    surface_material = material_ground.getSurfaceMaterial()
    surface_material.setRoughness(GROUND_ROUGHNESS)
    surface_material.setAdhesion(GROUND_ADHESION, GROUND_ADHESION_OVERLAP)

    material_pusher = agx.Material("Aluminum")
    bulk_material = material_pusher.getBulkMaterial()
    bulk_material.setPoissonsRatio(ALUMINUM_POISSON_RATIO)
    bulk_material.setYoungsModulus(ALUMINUM_YOUNG_MODULUS)
    surface_material = material_pusher.getSurfaceMaterial()
    surface_material.setRoughness(PUSHER_ROUGHNESS)
    surface_material.setAdhesion(PUSHER_ADHESION, PUSHER_ADHESION_OVERLAP)

    # Create a ground plane and bounding box to prevent falls
    ground = create_body(name="ground" + goal_string, shape=agxCollide.Box(GROUND_LENGTH_X, GROUND_LENGTH_Y,
                                                                           GROUND_WIDTH),
                         position=agx.Vec3(0, 0, -GROUND_WIDTH / 2),
                         motion_control=agx.RigidBody.STATIC,
                         material=material_ground)
    scene.add(ground)

    bounding_box = create_body(name="bounding_box_1" + goal_string, shape=agxCollide.Box(GROUND_LENGTH_X, GROUND_WIDTH,
                                                                                         RADIUS * 4),
                               position=agx.Vec3(0, GROUND_LENGTH_Y - GROUND_WIDTH, RADIUS * 4 - GROUND_WIDTH),
                               motion_control=agx.RigidBody.STATIC,
                               material=material_ground)
    scene.add(bounding_box)
    bounding_box = create_body(name="bounding_box_2" + goal_string, shape=agxCollide.Box(GROUND_LENGTH_X, GROUND_WIDTH,
                                                                                         RADIUS * 4),
                               position=agx.Vec3(0, - GROUND_LENGTH_Y + GROUND_WIDTH, RADIUS * 4 - GROUND_WIDTH),
                               motion_control=agx.RigidBody.STATIC,
                               material=material_ground)
    scene.add(bounding_box)
    bounding_box = create_body(name="bounding_box_3" + goal_string, shape=agxCollide.Box(GROUND_WIDTH, GROUND_LENGTH_Y,
                                                                                         RADIUS * 4),
                               position=agx.Vec3(GROUND_LENGTH_X - GROUND_WIDTH, 0, RADIUS * 4 - GROUND_WIDTH),
                               motion_control=agx.RigidBody.STATIC,
                               material=material_ground)
    scene.add(bounding_box)
    bounding_box = create_body(name="bounding_box_4" + goal_string, shape=agxCollide.Box(GROUND_WIDTH, GROUND_LENGTH_Y,
                                                                                         RADIUS * 4),
                               position=agx.Vec3(- GROUND_LENGTH_X + GROUND_WIDTH, 0, RADIUS * 4 - GROUND_WIDTH),
                               motion_control=agx.RigidBody.STATIC,
                               material=material_ground)
    scene.add(bounding_box)

    if rope:
        # Create rope
        rope = agxCable.Cable(RADIUS, RESOLUTION)
        rope.add(agxCable.FreeNode(GROUND_LENGTH_X / 2 - RADIUS * 2, GROUND_LENGTH_Y / 2 - RADIUS * 2, RADIUS * 2))
        rope.add(agxCable.FreeNode(GROUND_LENGTH_X / 2 - RADIUS * 2, GROUND_LENGTH_Y / 2 - LENGTH - RADIUS * 2,
                                   RADIUS * 2))

        # Set rope name and properties
        rope.setName("DLO" + goal_string)
        properties = rope.getCableProperties()
        properties.setYoungsModulus(YOUNG_MODULUS_BEND, agxCable.BEND)
        properties.setYoungsModulus(YOUNG_MODULUS_TWIST, agxCable.TWIST)
        properties.setYoungsModulus(YOUNG_MODULUS_STRETCH, agxCable.STRETCH)

        # Try to initialize rope
        report = rope.tryInitialize()
        if report.successful():
            print("Successful rope initialization.")
        else:
            print(report.getActualError())

        # Add rope to simulation
        scene.add(rope)

        rbs = rope.getRigidBodies()
        for i in range(len(rbs)):
            rbs[i].setName('dlo_' + str(i+1) + goal_string)

        # Set rope material
        material_rope = rope.getMaterial()
        material_rope.setName("rope_material")
        bulk_material = material_rope.getBulkMaterial()
        bulk_material.setDensity(ROPE_DENSITY)
        surface_material = material_rope.getSurfaceMaterial()
        surface_material.setRoughness(ROPE_ROUGHNESS)
        surface_material.setAdhesion(ROPE_ADHESION, 0)

        # Check mass
        rope_mass = rope.getMass()
        print("Rope mass: {}".format(rope_mass))

        # Create contact materials
        contact_material_ground_rope = sim.getMaterialManager().getOrCreateContactMaterial(material_ground,
                                                                                           material_rope)
        contact_material_pusher_rope = sim.getMaterialManager().getOrCreateContactMaterial(material_pusher,
                                                                                           material_rope)
        contact_material_ground_rope.setUseContactAreaApproach(True)
        sim.add(contact_material_ground_rope)
        sim.add(contact_material_pusher_rope)

    rotation_cylinder = agx.OrthoMatrix3x3()
    rotation_cylinder.setRotate(agx.Vec3.Y_AXIS(), agx.Vec3.Z_AXIS())

    pusher = create_body(name="pusher" + goal_string,
                         shape=agxCollide.Cylinder(PUSHER_RADIUS, PUSHER_HEIGHT),
                         position=agx.Vec3(0.0, 0.0, PUSHER_HEIGHT / 2),
                         rotation=rotation_cylinder,
                         motion_control=agx.RigidBody.DYNAMICS,
                         material=material_pusher)
    scene.add(pusher)

    # Create base for pusher motors
    prismatic_base = create_locked_prismatic_base("pusher" + goal_string, pusher.getRigidBody("pusher" + goal_string),
                                                  position_ranges=[(-GROUND_LENGTH_X, GROUND_LENGTH_X),
                                                                   (-GROUND_LENGTH_Y, GROUND_LENGTH_Y),
                                                                   (0., 3 * RADIUS)],
                                                  motor_ranges=[(-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE),
                                                                (-MAX_MOTOR_FORCE, MAX_MOTOR_FORCE)])

    scene.add(prismatic_base)

    return sim