def create_hinge_scene(): size = [0.5, 0.25, 1] b1, b2 = create_bodies([0, 0, 0], [0, 0, -2.5], size) demoutils.sim().add(b1) demoutils.sim().add(b2) f1 = agx.Frame() f1.setLocalTranslate(0, 0, size[2]) f1.setLocalRotate(agx.EulerAngles(0, math.radians(90), 0)) hinge1 = agx.Hinge(b1, f1) demoutils.sim().add(hinge1) # Make the first motor swing back and forth speed_controller = AlternatingSpeedController(hinge1.getMotor1D(), 1, 2) demoutils.sim().add(speed_controller) distance = (b2.getPosition() - b1.getPosition()).length() f1 = agx.Frame() f1.setLocalTranslate(0, 0, -distance / 2) f1.setLocalRotate(agx.EulerAngles(0, math.radians(90), 0)) f2 = agx.Frame() f2.setLocalTranslate(0, 0, distance / 2) f2.setLocalRotate(agx.EulerAngles(0, math.radians(90), 0)) hinge2 = agx.Hinge(b1, f1, b2, f2) demoutils.sim().add(hinge2)
def seesaw(sim, root, pos, angle, h=0.08): d = 0.8 # Sides dims = [0.6*(width/14), 0.15*(width/14), h*3/2] pos_s = [pos[0]+(d/2+0.3)*np.cos(angle)*(width/14), pos[1]+(d/2+0.3)*np.sin(angle)*(width/14), pos[2]+h/2] sideP = addboxx(sim, root, dims, pos_s) dims = [0.6*(width/14), 0.15*(width/14), h*3/2] pos_s = [pos[0]-(d/2+0.3)*np.cos(angle)*(width/14), pos[1]-(d/2+0.3)*np.sin(angle)*(width/14), pos[2]+h/2] sideN = addboxx(sim, root, dims, pos_s) # Main board dims = [d*(width/14), 0.9*(width/14), 0.004] pos_s = [pos[0]+0.06*np.sin(angle)*(width/14), pos[1]-0.06*np.cos(angle)*(width/14), pos[2]+h] board = addboxx(sim, root, dims, pos_s, Fixed=False) sideP.setRotation(agx.Quat(angle, agx.Vec3(0,0,1))) sideN.setRotation(agx.Quat(angle, agx.Vec3(0,0,1))) board.setRotation(agx.Quat(angle, agx.Vec3(0,0,1))) #Some stops under bot_tilt = 0.17 dims = [d, 0.43, 0.004] dif = 0.215*np.cos(bot_tilt)*(width/14)-0.002*np.sin(bot_tilt)*(width/14) pos_s = [pos[0]+(0.06+dif)*np.sin(angle)*(width/14), pos[1]-(0.06+dif)*np.cos(angle)*(width/14), pos[2]+np.sin(bot_tilt)*dif] bottom1 = addboxx(sim, root, dims, pos_s, color=agxRender.Color.DarkGray()) pos_s = [pos[0]+(0.06-dif)*np.sin(angle)*(width/14), pos[1]-(0.06-dif)*np.cos(angle)*(width/14), pos[2]+np.sin(bot_tilt)*dif] bottom2 = addboxx(sim, root, dims, pos_s, color=agxRender.Color.DarkGray()) bottom1.setRotation(agx.Quat( bot_tilt, agx.Vec3(1,0,0))) bottom1.setRotation(bottom1.getRotation()*agx.Quat(angle, agx.Vec3(0,0,1))) bottom2.setRotation(agx.Quat(-bot_tilt, agx.Vec3(1,0,0))) bottom2.setRotation(bottom2.getRotation()*agx.Quat(angle, agx.Vec3(0,0,1))) hf = agx.HingeFrame() hf.setAxis(agx.Vec3( np.cos(angle),np.sin(angle),0)) hf.setCenter(agx.Vec3(pos[0]+(d/2)*np.cos(angle)*(width/14), pos[1]+(d/2)*np.sin(angle)*(width/14), pos[2]+h)) axleP = agx.Hinge(hf, board, sideP) sim.add(axleP) hf = agx.HingeFrame() hf.setAxis(agx.Vec3( np.cos(angle),np.sin(angle),0)) hf.setCenter(agx.Vec3(pos[0]*(width/14)-(d/2)*np.cos(angle)*(width/14), pos[1]*(width/14)-(d/2)*np.sin(angle)*(width/14), pos[2]+h)) axleN = agx.Hinge(hf, board, sideN) sim.add(axleN)
def LinkBodies_Hinge(body1, body2, link_position, link_direction, MiroSystem=False): hf = agx.HingeFrame() hf.setAxis(agxVecify(link_direction)) hf.setCenter(agxVecify(link_position)) link = agx.Hinge(hf, body1, body2) # The line below is disabled because it messes up the steering of the example bot. # link.setSolveType(agx.Constraint.DIRECT_AND_ITERATIVE) if MiroSystem: MiroSystem.Add(link) return link
def connect(self, simulation, body1, body2, pos, axis, hingeRange): assert (body1 and body2) f1 = agx.Frame() f2 = agx.Frame() agx.Constraint.calculateFramesFromWorld(pos, axis, body1, f1, body2, f2) hinge = agx.Hinge(body1, f1, body2, f2) if hingeRange: hinge.getRange1D().setEnable(True) hinge.getRange1D().setRange(hingeRange) simulation.add(hinge) return hinge
def buildScene1(self, app, sim, root): # Create the Terrain num_cells_x = 80 num_cells_y = 80 cell_size = 0.15 max_depth = 1.0 agx_heightField = agxCollide.HeightField(num_cells_x, num_cells_y, (num_cells_x - 1) * cell_size, (num_cells_y - 1) * cell_size) # Define the initial height field (random or fixed) depending on if if data collection or test if self.control_mode == "data_collection": np_heightField = self.createRandomHeightfield( num_cells_x, num_cells_y, cell_size) elif self.control_mode == "mpcc" or self.control_mode == "trajectory_control": np_heightField = self.createRandomHeightfield( num_cells_x, num_cells_y, cell_size) if self.set_height_from_previous: agx_heightField = self.agx_heightField_previous else: agx_heightField = self.setHeightField(agx_heightField, np_heightField) terrain = agxTerrain.Terrain.createFromHeightField( agx_heightField, 5.0) sim.add(terrain) # Define Gravity G = agx.Vec3(0, 0, -10.0) sim.setUniformGravity(G) # define the material terrain.loadLibraryMaterial("sand_1") terrainMaterial = terrain.getTerrainMaterial() terrainMaterial.getBulkProperties().setSwellFactor(1.00) compactionProperties = terrainMaterial.getCompactionProperties() compactionProperties.setAngleOfReposeCompactionRate(500.0) terrain.setCompaction(1.05) # The trenching will reach the bounds of the terrain so we simply remove particles out of bounds # to get rid of the mateiral in a practical way. terrain.getProperties().setDeleteSoilParticlesOutsideBounds(True) if app: # Setup a renderer for the terrain renderer = agxOSG.TerrainVoxelRenderer(terrain, root) renderer.setRenderHeightField(True) # We choose to render the compaction of the soil to visually denote excavated # soil from compacted ground # renderer.setRenderCompaction( True, agx.RangeReal( 1.0, 1.05 ) ) renderer.setRenderHeights(True, agx.RangeReal(-0.4, 0.1)) # renderer.setRenderHeights(True, agx.RangeReal(-0.5,0.5)) renderer.setRenderVoxelSolidMass(False) renderer.setRenderVoxelFluidMass(False) renderer.setRenderNodes(False) renderer.setRenderVoxelBoundingBox(False) renderer.setRenderSoilParticlesMesh(True) sim.add(renderer) # Set contact materials of the terrain and shovel # This contact material governs the resistance that the shovel will feel when digging into the terrain # [ Shovel - Terrain ] contact material shovelMaterial = agx.Material("shovel_material") terrainMaterial = terrain.getMaterial( agxTerrain.Terrain.MaterialType_TERRAIN) shovelTerrainContactMaterial = agx.ContactMaterial( shovelMaterial, terrainMaterial) shovelTerrainContactMaterial.setYoungsModulus(1e8) shovelTerrainContactMaterial.setRestitution(0.0) shovelTerrainContactMaterial.setFrictionCoefficient(0.4) sim.add(shovelTerrainContactMaterial) # Create the trenching shovel body creation, do setup in the Terrain object and # constrain it to a kinematic that will drive the motion # Create the bucket rigid body cuttingEdge, topEdge, forwardVector, bucket = self.createBucket( default) sim.add(bucket) # Create the Shovel object using the previously defined cutting and top edge shovel = agxTerrain.Shovel(bucket, topEdge, cuttingEdge, forwardVector) agxUtil.setBodyMaterial(bucket, shovelMaterial) # Set a margin around the bounding box of the shovel where particles are not to be merged shovel.setNoMergeExtensionDistance(0.1) # Add the shovel to the terrain terrain.add(shovel) if app: # and self.consecutive_scoop_i < 4: # Create visual representation of the shovel node = agxOSG.createVisual(bucket, root) agxOSG.setDiffuseColor(node, agxRender.Color.Gold()) agxOSG.setAlpha(node, 1.0) # Set initial bucket rotation if self.control_mode == "mpcc": angle_bucket_initial = -0.3 * np.pi else: angle_bucket_initial = np.random.uniform(low=-0.25 * np.pi, high=-0.35 * np.pi) bucket.setRotation(agx.EulerAngles(0.0, angle_bucket_initial, agx.PI)) # Get the offset of the bucket tip from the COM tip_offset = shovel.getCuttingEdgeWorld().p2 # inertia_tensor = bucket.getMassProperties().getInertiaTensor() mass = bucket.getMassProperties().getMass() h_offset_sqrd = tip_offset[0]**2 + tip_offset[2]**2 inertia_bucket = inertia_tensor.at(1, 1) + mass * h_offset_sqrd # Set initial bucket position (for consecutive scoops) if self.control_mode == "mpcc" or self.control_mode == "trajectory_control": if self.consecutive_scoop_i == 0: x_initial_tip = -4.0 elif self.consecutive_scoop_i == 1: x_initial_tip = -3.6 elif self.consecutive_scoop_i == 2: x_initial_tip = -3.3 else: x_initial_tip = -2.6 else: x_initial_tip = np.random.uniform(low=-4.5, high=-3.0) # find the soil height at the initial penetration location hf_grid_initial = terrain.getClosestGridPoint( agx.Vec3(x_initial_tip, 0.0, 0.0)) height_initial = terrain.getHeight(hf_grid_initial) - 0.05 # Set the initial bucket location such that it is just contacting the soil position = agx.Vec3(x_initial_tip - tip_offset[0], 0, height_initial - tip_offset[2]) bucket.setPosition(terrain.getTransform().transformPoint(position)) bucket.setVelocity(0.0, 0.0, 0.0) # bucket.setAngularVelocity(0.0, 0.05, 0.0) # Add a lockjoint between a kinematic sphere and the shovel # in order to have some compliance when moving the shovel # through the terrain offset = agx.Vec3(0.0, 0.0, 0.0) ## ADD ALL THE JOINTS TO CONTROL THE BUCKET (x,z,theta) sphere1 = agx.RigidBody(agxCollide.Geometry(agxCollide.Sphere(.1))) sphere2 = agx.RigidBody(agxCollide.Geometry(agxCollide.Sphere(.1))) sphere3 = agx.RigidBody(agxCollide.Geometry(agxCollide.Sphere(.1))) sphere1.setMotionControl(agx.RigidBody.DYNAMICS) sphere2.setMotionControl(agx.RigidBody.DYNAMICS) sphere3.setMotionControl(agx.RigidBody.DYNAMICS) sphere1.getGeometries()[0].setEnableCollisions(False) sphere2.getGeometries()[0].setEnableCollisions(False) sphere3.getGeometries()[0].setEnableCollisions(False) tip_position = shovel.getCuttingEdgeWorld().p2 tip_position[1] = bucket.getCmPosition()[1] sphere1.setPosition(tip_position) sphere2.setPosition(tip_position) sphere3.setPosition(tip_position) sphere1.getMassProperties().setMass(0.000001) sphere2.getMassProperties().setMass(0.000001) sphere3.getMassProperties().setMass(0.000001) # print('sphere mass: ', sphere1.getMassProperties().getMass()) sim.add(sphere1) sim.add(sphere2) sim.add(sphere3) # Set prismatic joint for x transalation world - sphere 1 f1 = agx.Frame() f1.setLocalRotate(agx.EulerAngles(0, math.radians(90), 0)) prismatic1 = agx.Prismatic(sphere1, f1) # Set prismatic joint for z transalation world - sphere 2 f1 = agx.Frame() f2 = agx.Frame() f1.setLocalRotate(agx.EulerAngles(0, math.radians(180), 0)) f2.setLocalRotate(agx.EulerAngles(0, math.radians(180), 0)) prismatic2 = agx.Prismatic(sphere1, f1, sphere2, f2) # # Set hinge joint for rotation of the bucket f1 = agx.Frame() f1.setLocalRotate(agx.EulerAngles(-math.radians(90), 0, 0)) f2 = agx.Frame() f2.setLocalRotate(agx.EulerAngles(-math.radians(90), 0, 0)) hinge2 = agx.Hinge(sphere2, f1, sphere3, f2) sim.add(prismatic1) sim.add(prismatic2) sim.add(hinge2) lock = agx.LockJoint(sphere3, bucket) sim.add(lock) # Uncomment to lock rotations # sim.add(agx.LockJoint(sphere2,bucket)) # constant force and torque operations = [agx.Vec3(0.0, 0.0, 0.0), agx.Vec3(0.0, 0.0, 0.0)] # Extract soil shape along the bucket excavation direction x_hf, z_hf = self.extractSoilSurface(terrain, sim) self.soilShapeEvaluator = SoilSurfaceEvaluator(x_hf, z_hf) setattr(self.dfl, "soilShapeEvaluator", self.soilShapeEvaluator) if self.control_mode == "data_collection": # create driver and add it to the simulation driver = ForceDriverPID(app, sphere3, lock, hinge2, prismatic1, prismatic2, terrain, shovel, operations, self.dt_control) # Add the current surface evaluator to the controller setattr(driver, "soilShapeEvaluator", self.soilShapeEvaluator) # Add the controller to the simulation sim.add(driver) elif self.control_mode == "trajectory_control": # create driver and add it to the simulation # create driver and add it to the simulation driver = ForceDriverTrajectory(app, sphere3, lock, hinge2, prismatic1, prismatic2, terrain, shovel, operations, self.dt_control) # Add the current surface evaluator to the controller setattr(driver, "soilShapeEvaluator", self.soilShapeEvaluator) setattr(driver, "dfl", self.dfl) x_path = x_initial_tip + np.array( [0., 0.5, 1.5, 2.0, 2.5, 3.0, 3.5]) y_soil, _, _, _ = self.soilShapeEvaluator.soil_surf_eval(x_path) y_path = y_soil + np.array( [-0.07, -0.25, -0.25, -0.25, -0.25, -0.25, -0.02]) spl_path = spline_path(x_path, y_path) setattr(driver, "path_eval", spl_path.path_eval) # Add the controller to the simulation sim.add(driver) elif self.control_mode == "mpcc": # create driver and add it to the simulation driver = ForceDriverDFL(app, sphere3, lock, hinge2, terrain, shovel, self.dt_control) ################ MPCC CONTROLLER ############################ # Add the current surface evaluator to the controller setattr(driver, "soilShapeEvaluator", self.soilShapeEvaluator) setattr(driver, "dfl", self.dfl) setattr(driver, "scaling", self.scaling) x_path = x_initial_tip + np.array([ 0., 0.5, 1.5, 2.0, 2.5, 3.0, ]) y_soil, _, _, _ = self.soilShapeEvaluator.soil_surf_eval(x_path) y_path = y_soil + np.array( [-0.07, -0.25, -0.25, -0.25, -0.25, -0.02]) # Set the state constraints if self.observable_type == "dfl": x_min = np.array([ x_initial_tip - 0.1, -3., 0.5, -0.5, -2.5, -2.5, -80000 * self.scaling, -80000 * self.scaling, 0.0, -70000 * self.scaling, -70000 * self.scaling, -70000 * self.scaling, -70000 * self.scaling ]) x_max = np.array([ 2., 5.0, 2.5, 2.5, 2.5, 2.5, 80000 * self.scaling, 80000 * self.scaling, 3000. * self.scaling, 70000 * self.scaling, 70000 * self.scaling, 70000 * self.scaling, 70000 * self.scaling ]) n_dyn = self.dfl.plant.n elif self.observable_type == "x": x_min = np.array( [x_initial_tip - 0.1, -3., 0.5, -0.5, -2.5, -2.5]) x_max = np.array([2., 5.0, 2.5, 2.5, 2.5, 2.5]) n_dyn = self.dfl.plant.n_x # Set the input constraints u_min = np.array([ -100. * self.scaling, -70000 * self.scaling, -70000 * self.scaling ]) u_max = np.array([ 75000. * self.scaling, 70000 * self.scaling, 70000 * self.scaling ]) if self.set_height_from_previous: pass else: self.spl_path = spline_path(x_path, y_path) # instantiate the MPCC object mpcc = MPCC(np.zeros((n_dyn, n_dyn)), np.zeros((n_dyn, self.dfl.plant.n_u)), x_min, x_max, u_min, u_max, dt=self.dt_data, N=50) # set the observation function, path object and linearization function setattr(mpcc, "path_eval", self.spl_path.path_eval) setattr(mpcc, "get_soil_surface", self.soilShapeEvaluator.soil_surf_eval) if self.model_has_surface_shape: print('Linearizing with soil shape') setattr(mpcc, "get_linearized_model", self.dfl.linearize_soil_dynamics_koop) else: setattr(mpcc, "get_linearized_model", self.dfl.linearize_soil_dynamics_no_surface) self.mpcc = copy.copy(mpcc) pos_tip, vel_tip, acl_tip, ang_tip, omega, alpha = measureBucketState( sphere3, shovel) x_i = np.array([ pos_tip[0], pos_tip[2], ang_tip, vel_tip[0], vel_tip[2], omega[1] ]) eta_i = np.array( [acl_tip[0], acl_tip[2], alpha[1], 0., 0., 0., 0.]) # Choose the initial path arcposition based on a close initial x tip position theta_array = np.linspace(-10, 0, num=1000) for i in range(len(theta_array)): x_path, y_path = self.spl_path.path_eval(theta_array[i], d=0) if x_path > pos_tip[0]: path_initial = theta_array[i] break # set initial input (since input cost is differential) x_0_mpcc = np.concatenate( (self.dfl.g_Koop(x_i, eta_i, _), np.array([path_initial]))) u_minus_mpcc = np.array([0.0, 0.0, 0.0, 0.0]) driver.last_x_opt = x_0_mpcc # sets up the new mpcc problem _mpcc mpcc.setup_new_problem(self.Q_mpcc, self.R_mpcc, self.q_theta_mpcc, x_0_mpcc, u_minus_mpcc) setattr(driver, "mpcc", mpcc) ##################################################################################### # Add the controller to the simulation sim.add(driver) # Limit core usage to number of physical cores. Assume that HT/SMT is active # and divide max threads with 2. agx.setNumThreads(0) n = int(agx.getNumThreads() / 2 - 1) agx.setNumThreads(n) # Setup initial camera view if app: createHelpText(sim, app) return terrain, shovel, driver, sphere3
def create_gripper_peg_in_hole(sim=None, name="", material=None, position=agx.Vec3(0.0, 0.0, 0.0), geometry_transform=agx.AffineMatrix4x4(), geometry_scaling=agx.Matrix3x3(agx.Vec3(0.045)), joint_ranges=None, force_ranges=None): # Create gripper object gripper_mesh = agxUtil.createTrimeshFromWavefrontOBJ( MESH_GRIPPER_FILE, agxCollide.Trimesh.NO_WARNINGS, geometry_scaling) gripper_geom = agxCollide.Geometry( gripper_mesh, agx.AffineMatrix4x4.rotate(agx.Vec3(0, 1, 0), agx.Vec3(0, 0, 1))) gripper_body = agx.RigidBody(name + "_body") gripper_body.add(gripper_geom) gripper_body.setMotionControl(agx.RigidBody.DYNAMICS) gripper_body.setPosition(position) gripper_body.setCmRotation(agx.EulerAngles(0.0, np.pi, 0.0)) if material is not None: gripper_geom.setMaterial(material) sim.add(gripper_body) # Add kinematic structure rotation_y_to_z = agx.OrthoMatrix3x3() rotation_y_to_z.setRotate(agx.Vec3.Y_AXIS(), agx.Vec3.Z_AXIS()) rotation_y_to_x = agx.OrthoMatrix3x3() rotation_y_to_x.setRotate(agx.Vec3.Y_AXIS(), agx.Vec3.X_AXIS()) base_z = create_body(name=name + "_base_z", shape=agxCollide.Cylinder(0.005, 0.025), position=position, rotation=rotation_y_to_z, motion_control=agx.RigidBody.DYNAMICS, disable_collisions=True) sim.add(base_z) base_y = create_body(name=name + "_base_y", shape=agxCollide.Cylinder(0.005, 0.025), position=position, motion_control=agx.RigidBody.DYNAMICS, disable_collisions=True) sim.add(base_y) base_x = create_body(name=name + "_base_x", shape=agxCollide.Cylinder(0.005, 0.025), position=position, rotation=rotation_y_to_x, motion_control=agx.RigidBody.DYNAMICS, disable_collisions=True) sim.add(base_x) base_x_body = base_x.getRigidBody("gripper_base_x") base_y_body = base_y.getRigidBody("gripper_base_y") base_z_body = base_z.getRigidBody("gripper_base_z") base_x_body.getGeometry("gripper_base_x").setEnableCollisions(False) base_y_body.getGeometry("gripper_base_y").setEnableCollisions(False) base_z_body.getGeometry("gripper_base_z").setEnableCollisions(False) # Add prismatic joints between bases joint_base_x = agx.Prismatic(agx.Vec3(1, 0, 0), base_x_body) joint_base_x.setEnableComputeForces(True) joint_base_x.setEnable(True) joint_base_x.setName(name + "_joint_base_x") sim.add(joint_base_x) joint_base_y = agx.Prismatic(agx.Vec3(0, 1, 0), base_x_body, base_y_body) joint_base_y.setEnableComputeForces(True) joint_base_y.setEnable(True) joint_base_y.setName(name + "_joint_base_y") sim.add(joint_base_y) joint_base_z = agx.Prismatic(agx.Vec3(0, 0, -1), base_y_body, base_z_body) joint_base_z.setEnableComputeForces(True) joint_base_z.setEnable(True) joint_base_z.setName(name + "_joint_base_z") sim.add(joint_base_z) # Hinge joint to rotate gripper around y axis hf = agx.HingeFrame() hf.setCenter(position) hf.setAxis(agx.Vec3(0, 1, 0)) joint_rot_y = agx.Hinge(hf, base_z_body, gripper_body) joint_rot_y.setEnableComputeForces(True) joint_rot_y.setName(name + "_joint_rot_y") sim.add(joint_rot_y) # Set joint ranges if joint_ranges is not None: # x range joint_base_x_range_controller = joint_base_x.getRange1D() joint_base_x_range_controller.setRange(joint_ranges["t_x"][0], joint_ranges["t_x"][1]) joint_base_x_range_controller.setEnable(True) # y range joint_base_y_range_controller = joint_base_y.getRange1D() joint_base_y_range_controller.setRange(joint_ranges["t_y"][0], joint_ranges["t_y"][1]) joint_base_y_range_controller.setEnable(True) # z range joint_base_z_range_controller = joint_base_z.getRange1D() joint_base_z_range_controller.setRange(joint_ranges["t_z"][0], joint_ranges["t_z"][1]) joint_base_z_range_controller.setEnable(True) # rot y joint_rot_y_range_controller = joint_rot_y.getRange1D() joint_rot_y_range_controller.setRange(joint_ranges["r_y"][0], joint_ranges["r_y"][1]) joint_rot_y_range_controller.setEnable(True) # Enable motors joint_base_x_motor = joint_base_x.getMotor1D() joint_base_x_motor.setEnable(True) joint_base_x_motor.setLockedAtZeroSpeed(False) joint_base_y_motor = joint_base_y.getMotor1D() joint_base_y_motor.setEnable(True) joint_base_y_motor.setLockedAtZeroSpeed(False) joint_base_z_motor = joint_base_z.getMotor1D() joint_base_z_motor.setEnable(True) joint_base_z_motor.setLockedAtZeroSpeed(False) joint_rot_y_motor = joint_rot_y.getMotor1D() joint_rot_y_motor.setEnable(True) joint_rot_y_motor.setLockedAtZeroSpeed(False) # Set max forces in motors if force_ranges is not None: # force x joint_base_x_motor.setForceRange(force_ranges['t_x'][0], force_ranges['t_x'][1]) # force y joint_base_y_motor.setForceRange(force_ranges['t_y'][0], force_ranges['t_y'][1]) # force z joint_base_z_motor.setForceRange(force_ranges['t_z'][0], force_ranges['t_z'][1]) # force rotation around y joint_rot_y_motor.setForceRange(force_ranges['r_y'][0], force_ranges['r_y'][1])
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
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
def buildBot(sim, root, bot_pos, controller='Arrows', drivetrain = 'FWD', color=False): body_wid = 0.32 body_len = 0.6 body_hei = 0.16 wheel_rad = 0.07 wheel_wid = 0.02 wheel_dmp = -0.02 body = agx.RigidBody( agxCollide.Geometry( agxCollide.Box(body_wid/2, body_len/2, body_hei/2))) body.setPosition(bot_pos[0], bot_pos[1], bot_pos[2] + body_hei/2 + wheel_rad + wheel_dmp ) # body.setMotionControl(1) body.setRotation(agx.Quat(np.pi, agx.Vec3(0,0,1))) sim.add(body) vis_body = agxOSG.createVisual(body, root) if color: agxOSG.setDiffuseColor(vis_body, color) else: agxOSG.setTexture(vis_body, 'flames.png', True, agxOSG.DIFFUSE_TEXTURE, 1.0, 1.0) wheelLF = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(wheel_rad, wheel_wid))) wheelLF.setPosition(bot_pos[0]-(body_wid/2+wheel_wid/2), bot_pos[1]+(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad) # wheelLF.setMotionControl(1) wheelLF.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(wheelLF) # agxOSG.setDiffuseColor(agxOSG.createVisual(wheelLF, root), agxRender.Color.Red()) wheelRF = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(wheel_rad, wheel_wid))) wheelRF.setPosition(bot_pos[0]+(body_wid/2+wheel_wid/2), bot_pos[1]+(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad) # wheelRF.setMotionControl(1) wheelRF.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(wheelRF) # agxOSG.setDiffuseColor(agxOSG.createVisual(wheelRF, root), agxRender.Color.Red()) wheelLB = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(wheel_rad, wheel_wid))) wheelLB.setPosition(bot_pos[0]-(body_wid/2+wheel_wid/2), bot_pos[1]-(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad) # wheelLB.setMotionControl(1) wheelLB.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(wheelLB) # agxOSG.setDiffuseColor(agxOSG.createVisual(wheelLB, root), agxRender.Color.Red()) wheelRB = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(wheel_rad, wheel_wid))) wheelRB.setPosition(bot_pos[0]+(body_wid/2+wheel_wid/2), bot_pos[1]-(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad) # wheelRB.setMotionControl(1) wheelRB.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(wheelRB) # agxOSG.setDiffuseColor(agxOSG.createVisual(wheelRB, root), agxRender.Color.Red()) for wheel in [wheelLB, wheelLF, wheelRB, wheelRF]: vis_body = agxOSG.createVisual(wheel, root) agxOSG.setTexture(vis_body, 'tire.png', True, agxOSG.DIFFUSE_TEXTURE, 1.0, 1.0) light_rad = 0.02 light_dep = 0.01 headlightL = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(light_rad, light_dep))) headlightL.setPosition( bot_pos[0] + 0.79*body_wid/2, bot_pos[1] + body_len/2+light_dep/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp) # headlightL.setMotionControl(1) # headlightL.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(headlightL) agxOSG.setTexture(agxOSG.createVisual(headlightL, root), 'light.png', True, agxOSG.DIFFUSE_TEXTURE, 1.0, 1.0) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3( bot_pos[0] + 0.79*body_wid/2, bot_pos[1] + body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp )) HLL = agx.Hinge(hf, body, headlightL) sim.add(HLL) headlightR = agx.RigidBody(agxCollide.Geometry( agxCollide.Cylinder(light_rad, light_dep))) headlightR.setPosition(bot_pos[0] -0.79*body_wid/2, bot_pos[1] + body_len/2+light_dep/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp ) # headlightR.setMotionControl(1) # headlightL.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(headlightR) agxOSG.setTexture(agxOSG.createVisual(headlightR, root), 'light.png', True, agxOSG.DIFFUSE_TEXTURE, 1.0, 1.0) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3(bot_pos[0] -0.79*body_wid/2, bot_pos[1] + body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp )) HLR = agx.Hinge(hf, body, headlightR) sim.add(HLR) light_wid = 0.012 light_hei = 0.02 light_dep = 0.003 taillightL = agx.RigidBody(agxCollide.Geometry( agxCollide.Box(light_wid, light_dep, light_hei))) taillightL.setPosition(bot_pos[0] -0.79*body_wid/2,bot_pos[1] -(body_len/2+light_dep/2), bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp) # taillightL.setMotionControl(1) # headlightL.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(taillightL) agxOSG.setDiffuseColor(agxOSG.createVisual(taillightL, root), agxRender.Color.Red()) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3(bot_pos[0] -0.79*body_wid/2, bot_pos[1] -body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp + light_hei/3)) TLL_hi = agx.Hinge(hf, body, taillightL) sim.add(TLL_hi) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3(bot_pos[0] -0.79*body_wid/2, bot_pos[1] -body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp - light_hei/3)) TLL_low = agx.Hinge(hf, body, taillightL) sim.add(TLL_low) taillightR = agx.RigidBody(agxCollide.Geometry( agxCollide.Box(light_wid, light_dep, light_hei))) taillightR.setPosition( bot_pos[0] + 0.79*body_wid/2,bot_pos[1] -(body_len/2+light_dep/2), bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp) # taillightR.setMotionControl(1) # headlightL.setRotation(agx.Quat(np.pi/2, agx.Vec3(0,0,1))) sim.add(taillightR) agxOSG.setDiffuseColor(agxOSG.createVisual(taillightR, root), agxRender.Color.Red()) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3( bot_pos[0] + 0.79*body_wid/2,bot_pos[1]-body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp + light_hei/3)) TLR = agx.Hinge(hf, body, taillightR) sim.add(TLR) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,1,0)) hf.setCenter(agx.Vec3( bot_pos[0] + 0.79*body_wid/2,bot_pos[1]-body_len/2, bot_pos[2] + 0.7*body_hei + wheel_rad + wheel_dmp - light_hei/3)) TLR = agx.Hinge(hf, body, taillightR) sim.add(TLR) windangle = np.pi/4 windshield = agx.RigidBody( agxCollide.Geometry( agxCollide.Box(0.9*body_wid/2, 0.005, body_hei/3))) windshield.setPosition(bot_pos[0], bot_pos[1]+body_len/5, bot_pos[2] + body_hei + wheel_rad + wheel_dmp + np.cos(windangle)*body_hei/3) # windshield.setTorque(0,0,100) # windshield.setMotionControl(2) windshield.setRotation(agx.Quat(windangle, agx.Vec3(1,0,0))) sim.add(windshield) agxOSG.setTexture(agxOSG.createVisual(windshield, root), 'windshield.jpg', True, agxOSG.DIFFUSE_TEXTURE, 1.0, 1.0) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,0,1)) hf.setCenter(agx.Vec3(-body_wid/3, body_len/5, bot_pos[2] + body_hei + wheel_rad + wheel_dmp)) windh1 = agx.Hinge(hf, body, windshield) sim.add(windh1) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(0,0,1)) hf.setCenter(agx.Vec3(body_wid/3, body_len/5, bot_pos[2] + body_hei + wheel_rad + wheel_dmp)) windh2 = agx.Hinge(hf, body, windshield) sim.add(windh2) x_ax = agx.Vec3(1,0,0) y_ax = agx.Vec3(0,1,0) z_ax = agx.Vec3(0,0,1) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(-1,0,0)) hf.setCenter(agx.Vec3(bot_pos[0]-body_wid/2, bot_pos[1]+(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad)) axleLF = agx.Hinge(hf, body, wheelLF) sim.add(axleLF) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(-1,0,0)) hf.setCenter(agx.Vec3(bot_pos[0]-body_wid/2, bot_pos[1]-(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad)) axleLB = agx.Hinge(hf, body, wheelLB) sim.add(axleLB) hf = agx.HingeFrame() hf.setAxis(agx.Vec3( 1,0,0)) hf.setCenter(agx.Vec3(bot_pos[0]+body_wid/2, bot_pos[1]-(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad)) axleRB = agx.Hinge(hf, body, wheelRB) sim.add(axleRB) hf = agx.HingeFrame() hf.setAxis(agx.Vec3( 1,0,0)) hf.setCenter(agx.Vec3(bot_pos[0]+body_wid/2, bot_pos[1]+(body_len/2-wheel_rad*1.8), bot_pos[2]+wheel_rad)) axleRF = agx.Hinge(hf, body, wheelRF) sim.add(axleRF) wheels = [wheelLF, wheelRF] # default FWD if drivetrain == 'FWD': wheels = [wheelLF, wheelRF] elif drivetrain == 'RWD': wheels = [wheelLB, wheelRB] elif drivetrain == 'AWD': wheels = [wheelLF, wheelRF, wheelLB, wheelRB] if controller == 'Numpad': sim.add(WheelControllerNumpad(wheels)) sim.add(Fjoink(body).setHopper(agxSDK.GuiEventListener.KEY_KP_Subtract)) else: sim.add(WheelControllerArrows(wheels)) sim.add(Fjoink(body)) # return a pointer to the body return body
def obstacles(sim, root, h): #start plattform dims = [1.5, 1.5, 0.06] pos = [-6, 0, h + dims[2] / 2] startbox = addboxx(sim, root, dims, pos) #timer timer = Timer(startbox) sim.add(timer) dims = [0.1, 1.5, 0.3] pos = [-6.75, 0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.1, 1.5, 0.3] pos = [-5.25, 0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [1.6, 0.1, 0.3] pos = [-6, -0.75, h + dims[2] / 2] addboxx(sim, root, dims, pos) # wall dims = [4.0, 0.1, 0.22] pos = [-3.3, -0.6, h + dims[2] / 2] addboxx(sim, root, dims, pos) # Random stuff in the first quarter dims = [0.2, 0.2, 0.8] pos = [-4, 0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.4, 0.25, 0.2] pos = [-3, 1.5, h + dims[2] / 2] addboxx(sim, root, dims, pos) for i in range(30): x = -0.5 - random.random() * 4.75 y = -0.5 + random.random() * 6 dims = [ random.random() * 0.6, random.random() * 0.6, random.random() * 0.6 ] pos = agx.Vec3(x, y, 0) if pos.length() < 1.5: pos.setLength(1.5 + random.random() * 3.75) if pos.length() > 7.0: pos.setLength(1.5 + random.random() * 5.5) pos.set(h + dims[2] / 2, 2) addboxx(sim, root, dims, pos) # Pole in the middle with walls around dims = [0.28, 1.4] pos = [0, 0, h + dims[1] / 2] can = addcylinder(sim, root, dims, pos, texture='schrodbull.png') can.setRotation(agx.Quat(np.pi / 2, agx.Vec3(1, 0, 0))) pos = [0, 0, h + dims[1]] dims = [0.28, 0.025] pos[2] = pos[2] + dims[1] / 2 lid = addcylinder(sim, root, dims, pos, texture='sodacan_lid.png') lid.setRotation(agx.Quat(np.pi / 2, agx.Vec3(1, 0, 0))) dims = [0.3, 2.0, 0.4] pos = [-1.15, 0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [2.6, 0.3, 0.4] pos = [0, -1.15, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.3, 2.0, 0.4] pos = [1.15, 0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.3, 7.0, 0.4] pos = [0, 3.5, h + dims[2] / 2] addboxx(sim, root, dims, pos) # Seesaw board dims = [2.1, 0.25, 0.3] pos = [2.1, 0.4, h + dims[2] / 2] addboxx(sim, root, dims, pos) seesaw(sim, root, [3.75, 0.9, h], -0.85 * np.pi, h=0.1) dims = [0.5, 3.8, 0.18] pos = [4.8, 3.15, h + dims[2] / 2] addboxx(sim, root, dims, pos) # Ballroom walls dims = [0.25, 4.3, 0.3] pos = [6.0, 0.0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.25, 1.0, 0.3] pos = [2.1, -1.0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.25, 1.4, 0.3] pos = [3.0, -0.4, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.25, 2.4, 0.3] pos = [2.5, -3.0, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [1.1, 0.25, 0.3] pos = [3.1, -3.1, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [0.66, 0.25, 0.3] pos = [2.3, -1.65, h + dims[2] / 2] wall_1 = addboxx(sim, root, dims, pos) dims = [2.8, 0.25, 0.3] pos = [3.95, -2.0, h + dims[2] / 2] wall_2 = addboxx(sim, root, dims, pos) dims = [3.91, 0.25, 0.3] pos = [4.65, -3.45, h + dims[2] / 2] wall_3 = addboxx(sim, root, dims, pos) wall_1.setRotation(agx.Quat(-np.pi / 4, agx.Vec3(0, 0, 1))) wall_2.setRotation(agx.Quat(-np.pi / 4, agx.Vec3(0, 0, 1))) wall_3.setRotation(agx.Quat(np.pi / 4, agx.Vec3(0, 0, 1))) # Ballroom balls for i in range(200): x = 4.0 + random.random() * 2.8 y = 0.75 - random.random() * 2.5 rad = 0.025 + random.random() * 0.075 pos = agx.Vec3(x, y, h + rad + 3 * random.random() * rad) addball(sim, root, rad, pos, Fixed=False) # Climbing ramp dx = 0.8 bot_tilt = 0.0445 dims = [dx, 2.5, 0.6] bot_tilt = np.arcsin(0.45 / (2.5 * 4)) dif = dims[1] / 2 * np.cos(bot_tilt) - 0.002 * np.sin(bot_tilt) dh = 2 * np.sin(bot_tilt) * dif for i in range(4): angle = (i + 1) * np.pi pos = [2 - dx * i, -4.7 - 0.015 * (-1)**i, -0.3 + h + (i + 1 / 2) * dh] hip = addboxx(sim, root, dims, pos) hip.setRotation(agx.Quat(bot_tilt, agx.Vec3(1, 0, 0))) hip.setRotation(hip.getRotation() * agx.Quat(angle, agx.Vec3(0, 0, 1))) addboxx(sim, root, [2 * dx, 1.1, dims[2]], [ 2 - dx * (i + 1 / 2), -4.7 - 1.8 * ((-1)**i), -0.3 + h + (i + 1) * dh ]) # Bridge boxes dims = [1.5, 1.8, 0.45] pos = [-1.5, -3.25, h + dims[2] / 2] addboxx(sim, root, dims, pos) dims = [1.5, 1.8, 0.45] pos = [-4.5, -3.25, h + dims[2] / 2] addboxx(sim, root, dims, pos) # Bridge part bridge = addboxx(sim, root, [1.5, 0.5, 0.08], [-3.0, -3.25, h + 0.45 - 0.04]) timer.addCheckpoint(bridge) # Swinging ball over bridge rad = 0.4 pendulum = addball(sim, root, rad, [-3.0, -3.25, h + 0.45 + rad + 0.01], Fixed=False) pendulum.setVelocity(agx.Vec3(0, 5, 0)) hf = agx.HingeFrame() hf.setAxis(agx.Vec3(1, 0, 0)) hf.setCenter(agx.Vec3(-3.0, -3.25, 3.0 + h + 0.45 + rad + 0.01)) axleP = agx.Hinge(hf, pendulum) sim.add(axleP) # addboxx(sim, root, [1.5, 0.5, 0.08], ) # final ramp addboxx(sim, root, [0.1, 2.5, 0.5], [-6.5, -2.05, h + 0.5 / 2]) addboxx(sim, root, [0.1, 2.5, 0.5], [-5.5, -2.05, h + 0.5 / 2]) hip = addboxx(sim, root, [0.9, 1.5, 0.1], [-6.0, -1.53, h + 0.026 + np.sin(0.15) * 1.5 / 2]) hip.setRotation(agx.Quat(0.15, agx.Vec3(1, 0, 0))) addboxx(sim, root, [0.9, 2.0, 0.2], [-6.0, -2.25, h + 0.075]) addboxx(sim, root, [1.4, 0.8, 0.2], [-5.8, -3.7, h + 0.45 - 0.1]) hip = addboxx(sim, root, [0.9, 1.5, 0.1], [-6.0, -3.0, h + 0.026 + np.sin(0.15) * 1.5 / 2]) hip.setRotation(agx.Quat(-0.15, agx.Vec3(1, 0, 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