hello, I want to use isaacgym to build different scenes, where multiple objects are layed randomly on the table. But when I load objects into the environment, initializing their position as random x,y above the table and incremental z, I notice lots of objects fly to the sky and begin to span out of no reason in the air. And when I don’t set their max_linear_velocity, some even shoot away like explosion when hit with other objects. It’s obviously against physics laws. what’s more, I can also see objects "drop into the table (a box) " even if I checked their collision group is set correctly. I don’t think it’s the bug of my code, but I’ll still paste here.:
import os
from isaacgym import gymapi, gymutil
import random
import math
import numpy as np
import transforms3d
import torch
import trimesh
import argparse
import tqdm
import time
np.random.seed(543)
random.seed(53)
acquire gym interface
gym = gymapi.acquire_gym()
Add custom arguments
custom_parameters = [
{“name”: “–controller”, “type”: str, “default”: “ik”,
“help”: “Controller to use for Franka. Options are {ik, osc}”},
{“name”: “–num_envs”, “type”: int, “default”: 256, “help”: “Number of environments to create”},
]
args = gymutil.parse_arguments(
description=“Franka Jacobian Inverse Kinematics (IK) + Operational Space Control (OSC) Example”,
custom_parameters=custom_parameters,
)
set torch device
device = ‘cuda:0’#args.sim_device if args.use_gpu_pipeline else ‘cpu’
configure sim
sim_params = gymapi.SimParams()
sim_params.up_axis = gymapi.UP_AXIS_Z
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
sim_params.dt = 1.0 / 60.0
# sim_params.substeps = 2
sim_params.use_gpu_pipeline = False # args.use_gpu_pipeline
sim_params.physx.solver_type = 1
sim_params.physx.num_position_iterations = 8
sim_params.physx.num_velocity_iterations = 1
sim_params.physx.rest_offset = 0.0
sim_params.physx.contact_offset = 0.001
sim_params.physx.friction_offset_threshold = 0.001
sim_params.physx.friction_correlation_distance = 0.0005
sim_params.physx.num_threads = args.num_threads
sim_params.physx.use_gpu = args.use_gpu
sim_params = gymapi.SimParams()
set common parameters
sim_params.dt = 1 / 60
sim_params.substeps = 2
sim_params.up_axis = gymapi.UP_AXIS_Z
sim_params.gravity = gymapi.Vec3(0.0, 0., -9.8)
set PhysX-specific parameters
sim_params.physx.use_gpu = True
sim_params.physx.solver_type = 1
sim_params.physx.num_position_iterations = 8
sim_params.physx.num_velocity_iterations = 0
sim_params.physx.contact_offset = 0.01
sim_params.physx.rest_offset = 0.0
sim_params.use_gpu_pipeline = False
set ground plane parameters
plane_params = gymapi.PlaneParams()
plane_params.normal = gymapi.Vec3(0, 0, 1) # z-up!
plane_params.distance = 0
plane_params.static_friction = 1
plane_params.dynamic_friction = 1
plane_params.restitution = 0
get all object codes
obj_code = os.listdir(“DexGraspNet/grasp_generation/meshdata_new”)
get all object grasp dicts
grasp_dict_dict = {}
for code in obj_code:
grasp_dict_dict[code]=np.load(f"isaacgym_simu/dataset/{code}.npy",allow_pickle=True)
options for loading 8 object assets
obj_asset_root = “isaacgym_simu/meshdata”
obj_asset_files = [f"{code}/coacd/coacd.urdf" for code in obj_code]
obj_asset_options = gymapi.AssetOptions()
obj_asset_options.override_com = True
obj_asset_options.override_inertia = True
obj_asset_options.density = 10000
obj_asset_options.vhacd_enabled = True
obj_asset_options.max_angular_velocity = 2.0
obj_asset_options.max_linear_velocity = 10
obj_asset_options.armature = 50000.
obj_asset_options.thickness = 1.0
options for loading hand asset
hand_asset_root = “isaacgym_simu/open_ai_assets”
hand_asset_file = “hand/shadow_hand.xml”
hand_asset_options = gymapi.AssetOptions()
hand_asset_options.disable_gravity = True
hand_asset_options.fix_base_link = True
hand_asset_options.collapse_fixed_joints = True
options for loading table asset
table_size = gymapi.Vec3(12,12,3)
table_asset_options = gymapi.AssetOptions()
table_asset_options.fix_base_link = True
options for loading assisting box boundary
w = table_size.x / 3.8
t = w/20
h = 3
bound_asset_options = gymapi.AssetOptions()
bound_asset_options.fix_base_link = True
select one to grasp
grasp_obj_index = random.randint(0,obj_num-1)
grasp_obj_index = 0
grasp_dict = grasp_dict_dict[scene_objs[grasp_obj_index]]
set up the env grid
total_batch = 36 # grasp_dict.shape[0]
batch_size = 36
num_per_row = 6
spacing = 8
env_lower = gymapi.Vec3(-spacing, -spacing, 0.0)
env_upper = gymapi.Vec3(spacing, spacing, 4* spacing)
safe_gap = 3
sample_num = 8
def _create_sim():
# create sim
args.compute_device_id = 0
sim = gym.create_sim(args.compute_device_id, args.graphics_device_id, args.physics_engine, sim_params)
if sim is None:
print("*** Failed to create sim")
quit()
gym.add_ground(sim, plane_params)
# create viewer
viewer = gym.create_viewer(sim, gymapi.CameraProperties())
if viewer is None:
print("*** Failed to create viewer")
quit()
# position the camera
cam_pos = gymapi.Vec3(14.0, 6.0, 4.0)
cam_target = gymapi.Vec3(0.0, 6.0, 0.0)
gym.viewer_camera_look_at(viewer, None, cam_pos, cam_target)
obj_assets_all = [gym.load_asset(sim, obj_asset_root, file, obj_asset_options) for file in obj_asset_files]
hand_asset = gym.load_asset(sim, hand_asset_root, hand_asset_file, hand_asset_options)
table_asset = gym.create_box(sim, table_size.x, table_size.y, table_size.z, table_asset_options)
bound_assets = [gym.create_box(sim, 2*w, t, h, bound_asset_options),
gym.create_box(sim, 2*w, t, h, bound_asset_options),
gym.create_box(sim, t, 2*w, h, bound_asset_options),
gym.create_box(sim, t, 2*w, h, bound_asset_options),
gym.create_box(sim, 2*w, 2*w, t, bound_asset_options)]
return sim,viewer,obj_assets_all,hand_asset,table_asset,bound_assets
view in batches
offset = 0
for batch in [0]:#range(total_batch//batch_size):
offset_ = min(offset + batch_size, total_batch)
print(f"batch {batch+1} : adding {offset_-offset} envs to sim")
# cache useful handles
envs = []
obj_idxs = []
hand_idxs = []
hand_handles = []
bound_handles = []
sim,viewer,obj_assets_all,hand_asset,table_asset,bound_assets=_create_sim()
# add a batch of envs
for index in range(offset, offset_):
# randomly sample 8 objects for scene building and one object for grasping
scene_objs_idx = random.sample(range(len(obj_code)),k=sample_num)
scene_objs_code = [obj_code[idx]for idx in scene_objs_idx]
grasp_obj_idx = random.choice(scene_objs_idx)
grasp_obj_code = obj_code[grasp_obj_idx]
grasp_dict = grasp_dict_dict[grasp_obj_code]
obj_assets = [obj_assets_all[idx]for idx in scene_objs_idx]
# create env
env = gym.create_env(sim, env_lower, env_upper, num_per_row)
envs.append(env)
# add table
table_pose = gymapi.Transform()
table_pose.p = gymapi.Vec3(0.0, 0.0, 0.5 * table_size.z)
table_handle = gym.create_actor(env, table_asset, table_pose, "table", index, 0)
# set table restitution
shape_props = gym.get_actor_rigid_shape_properties(env, table_handle)
shape_props[0].restitution = 0
gym.set_actor_rigid_shape_properties(env, table_handle, shape_props)
# # add bound
# box_pose = gymapi.Transform()
# box_pose.p = gymapi.Vec3(0.0, w+t/2, h/2)
# bound_handles.append(gym.create_actor(env, bound_assets[0], box_pose, "bound_1", index, 0))
# box_pose.p = gymapi.Vec3(0.0, -w-t/2, h/2)
# bound_handles.append(gym.create_actor(env, bound_assets[1], box_pose, "bound_2", index, 0))
# box_pose.p = gymapi.Vec3(w+t/2, 0.0, h/2)
# bound_handles.append(gym.create_actor(env, bound_assets[2], box_pose, "bound_3", index, 0))
# box_pose.p = gymapi.Vec3(-w-t/2, 0.0, h/2)
# bound_handles.append(gym.create_actor(env, bound_assets[3], box_pose, "bound_4", index, 0))
# box_pose.p = gymapi.Vec3(0.0, 0.0, h+t/2)
# bound_handles.append(gym.create_actor(env, bound_assets[4], box_pose, "bound_5", index, 0))
# add actor(all objects)
obj_handles = []
pose = gymapi.Transform()
for idx in range(sample_num):
pose.p = gymapi.Vec3(random.uniform(-w/2,w/2), random.uniform(-w/2,w/2), table_size.z+(2+idx)*safe_gap)
pose.r = gymapi.Quat.from_axis_angle(gymapi.Vec3(0, 0, 1), np.random.uniform(-math.pi, math.pi))
obj_handle = gym.create_actor(env, obj_assets[idx], pose, f"env_{index}_obj_{idx}_{scene_objs_code[idx][9:12]}", index, 0)
color = gymapi.Vec3(np.random.uniform(0, 1), np.random.uniform(0, 1), np.random.uniform(0, 1))
gym.set_rigid_body_color(env, obj_handle, 0, gymapi.MESH_VISUAL_AND_COLLISION, color)
obj_shape_props = gym.get_actor_rigid_shape_properties(
env, obj_handle)
for i in range(len(obj_shape_props)):
obj_shape_props[i].friction = 3.
gym.set_actor_rigid_shape_properties(env, obj_handle,
obj_shape_props)
# set coefficience of restitution
shape_props = gym.get_actor_rigid_shape_properties(env, obj_handle)
for sp_prop in shape_props:
sp_prop.restitution = 0
gym.set_actor_rigid_shape_properties(env, obj_handle, shape_props)
# set mass
rb_props = gym.get_actor_rigid_body_properties(env, obj_handle)
for rb_prop in rb_props:
rb_prop.mass = 0.1
gym.set_actor_rigid_body_properties(env, obj_handle, rb_props)
# get global index of object in rigid body state tensor
obj_idx = gym.get_actor_rigid_body_index(env, obj_handle, 0, gymapi.DOMAIN_SIM)
obj_idxs.append(obj_idx)
obj_handles.append(obj_handle)
# add hand TODO set hand DOF value
hand_pose = gymapi.Transform()
hand_pose.p = gymapi.Vec3(0,0,4)
hand_handle = gym.create_actor(env, hand_asset, hand_pose, "shand", index, -1)
hand_handles.append(hand_handle)
# simulate a batch of envs
thred = 0.1
start_time = time.time()
while not gym.query_viewer_has_closed(viewer):
# step the physics
gym.simulate(sim)
gym.fetch_results(sim, True)
# refresh tensors
gym.refresh_rigid_body_state_tensor(sim)
# obj_pos = rb
# update the viewer
gym.step_graphics(sim)
gym.draw_viewer(viewer, sim, True)
# Wait for dt to elapse in real time.
# This synchronizes the physics simulation with the rendering rate.
gym.sync_frame_time(sim)
body_states = gym.get_sim_rigid_body_states(sim, gymapi.STATE_ALL)
vels = [list(state[1][0]) for state in body_states]
vels_sum = sum([1 if sum(lst)<thred else 0 for lst in vels])
if time.time()-start_time > 5:
if vels_sum == body_states.shape[0]:
print(">>>> all static")
time.sleep(100)
break
# body_states = gym.get_sim_rigid_body_states(sim, gymapi.STATE_ALL)
# data_dict = {}
# data_dict['scene_objects']={}
# for code in scene_objs_code:
# data_dict['scene_objects'][code] =
gym.destroy_viewer(viewer)
gym.destroy_sim(sim)
offset = offset_
print("Done")