Hi all,
I am currently trying to simulate magnets in Isaac gym. I created and tested the magnet computation code using Isaac gym Spheres, which works fine. You can see what I mean through this YouTube video link: Isaac gym magnet calculation success using spheres - YouTube.
However, the end goal is to add this “magnetic” feature to the tip of a rigid body that I upload to Isaac gym using a URDF file. Unfortunately, when applying the same magnetic computation code to an external URDF file, magnet computation “explodes”… I am not sure why this happens. For reference, this is what happens: Isaac gym servo links magnet force "explosion" - YouTube
My system configurations:
- OS: Ubuntu 18.04.6 LTS
- CUDA: v11.7
- Python: 3.7
- Environment: conda rlgpu
I am currently running the simulation on the GPU with the following parameters:
- sim_params.up_axis = gymapi.UP_AXIS_Z
- sim_params.dt = 1.0 / 60.0
- sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.81)
- sim_params.substeps = 4
- sim_params.physx.solver_type = 1
- sim_params.physx.num_position_iterations = 4
- sim_params.physx.num_velocity_iterations = 1
- sim_params.physx.contact_offset = 0.02
- sim_params.physx.rest_offset = 0.001
- sim_params.physx.friction_correlation_distance = 0.0005
- sim_params.physx.friction_offset_threshold = 0.04
- sim_params.physx.max_depenetration_velocity = 0.1
To explain a little more regarding the URDF file:
- 9 rigid bodies (body, Shaft0, Cone0, Tip0, Magnet0, Shaft1, Cone1, Tip1, Magnet1)
- 2 prismatic joints.
- 6 fixed joints
The two ball-looking things at the object’s tip (Magent0 and Magent1) are what I want to behave as a magnet. It is connected to the rigid body named Tip0 and Tip1, respectively through a fixed joint. For every frame, I calculate the magnetic force based on the location of Magent0 and Magent1 and apply a force tensor using apply_rigid_body_force_tensor()
Here is my code for clarity:
# simulation runner
def run_crawl_magnets(Sim, Env, Asset, vectorize):
if Asset.dof_count > 0:
tensor = torch.tensor([0.0, 0.0], dtype=torch.float32, device=Sim.args.sim_device)
base_state = torch.flatten(tensor.repeat(Asset.n, 2)).view(-1, 2)
was_successful = Sim.gym.set_dof_state_tensor(Sim.sim, gymtorch.unwrap_tensor(base_state))
print(was_successful)
frame_count = 0
while not Sim.gym.query_viewer_has_closed(Env.viewer):
Sim.gym.simulate(Sim.sim)
Sim.gym.fetch_results(Sim.sim, True)
if frame_count > 100:
mag_status = apply_servo_magnet_force(Sim, Asset, frame_count, vectorize = vectorize)
crawl_status = apply_crawl(Sim, Asset)
# refresh the state tensors (from tensor api)
Sim.gym.refresh_actor_root_state_tensor(Sim.sim)
# update the viewer
Sim.gym.step_graphics(Sim.sim)
Sim.gym.draw_viewer(Env.viewer, Sim.sim, True)
Sim.gym.sync_frame_time(Sim.sim)
frame_count += 1
Sim.gym.destroy_viewer(Env.viewer)
Sim.gym.destroy_sim(Sim.sim)
# applying magnetic force on Magnet0 and Magent1
def apply_servo_magnet_force(Sim, Asset, frame, vectorize = False):
force_mat = torch.zeros((Asset.n*Asset.num_bodies, 3), device=Sim.device, dtype=torch.float)
torques = torch.zeros((Asset.n*Asset.num_bodies, 3), device=Sim.device, dtype=torch.float)
mag_mat = get_servo_magnet_mat(Sim, Asset)
tmp = 0
for n in range(Asset.n):
force_mat[n*Asset.num_bodies+4,:] = mag_mat[tmp,:]
force_mat[n*Asset.num_bodies+8,:] = mag_mat[tmp+1,:]
tmp += 2
status = Sim.gym.apply_rigid_body_force_tensors(Sim.sim, gymtorch.unwrap_tensor(force_mat.type(torch.float32)), gymtorch.unwrap_tensor(torques), gymapi.ENV_SPACE)
return status
# magnet calculation code
def calculate_mag_force(Sim, v1, v2):
dir_vector = v1 - v2
magnitude = torch.tensor([torch.linalg.norm(dir_vector)], device=Sim.device, dtype=torch.float)
direction = dir_vector/magnitude
tmp = torch.tensor([1e-12], device=Sim.device, dtype=torch.float)
if torch.isnan(magnitude):
print("ERROR: magnets ARE NAN")
elif magnitude**2 < 1e-9:
print("ERROR: magnets are too close")
force = (MAX_MAGNETIC_FORCE/torch.maximum(magnitude**2, tmp))*direction
return force
def get_servo_magnet_mat(Sim, Asset):
mag_mat = torch.zeros((Asset.n*2, 3), device=Sim.device, dtype=torch.float)
tensor = Sim.gym.acquire_rigid_body_state_tensor(Sim.sim)
states = gymtorch.wrap_tensor(tensor).type(torch.float64)
positions = states[:, 0:3]
mask = Asset.magnet_mask*Asset.n
positions = positions[mask]
# calculate magnet force
for i in range(positions.shape[0]):
total_force = torch.zeros((1, 3), device=Sim.device, dtype=torch.float)
for j in range(positions.shape[0]):
if i == j:
continue
else:
v1 = positions[i, :]; v2 = positions[j, :]
total_force -= calculate_mag_force(Sim, v1, v2)
mag_mat[i] = total_force
return mag_mat
I have tried changing AssetOptions, RigidShapeProperties, and SImulation parameters, and nothing is working…
Please let me know if there is anything I need to do differently. Thank you!