def test_newtons_first_law_motion(): # When no external force acts, a body with constant velocity # continues to move with that velocity. cube_verts = torch.FloatTensor( [ [1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, -1.0, -1.0], [-1.0, 1.0, -1.0], ] ) cube = RigidBody(cube_verts) # Give the cube a linear momentum of `(8, 8, 8)` (it's mass is `8`), # so, the velocity becomes `1` meter per second. Our frame rate by # default, is 30 Hz, i.e., 0.033 meters per frame. cube.linear_momentum = torch.ones(3, dtype=torch.float32) * 8 sim = Simulator([cube]) sim.step() assert torch.allclose(cube.position, 0.0333 * torch.ones(3), atol=1e-4) sim.step() assert torch.allclose(cube.position, 0.0667 * torch.ones(3), atol=1e-4) sim.step() assert torch.allclose(cube.position, 0.1 * torch.ones(3), atol=1e-4)
def test_cube_with_gravity(): # Add gravity to the cube. cube_verts = torch.FloatTensor( [ [1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, -1.0, -1.0], [-1.0, 1.0, -1.0], ] ) cube = RigidBody(cube_verts) gravity = Gravity() direction = torch.tensor([0.0, 0.0, -1.0]) cube.add_external_force(gravity) sim = Simulator([cube]) sim.step() assert torch.allclose(cube.linear_velocity, 0.3333333 * direction) assert torch.allclose(cube.position, 0.0111111 * direction) sim.step() assert torch.allclose(cube.linear_velocity, 0.66666667 * direction) assert torch.allclose(cube.position, 0.0333333 * direction) sim.step() assert torch.allclose(cube.linear_velocity, 1.0 * direction) assert torch.allclose(cube.position, 0.0666667 * direction)
def test_create_body(): cube_verts = torch.FloatTensor([ [1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, -1.0, -1.0], [-1.0, 1.0, -1.0], ]) cube = RigidBody(cube_verts)
def make_rigid_body(sample, init_pos, orientation, linear_velocity, angular_velocity, device, target_vertices=None): # Load a triangle mesh obj file if target_vertices is not None: tmp_obj_file = '/tmp/obj.obj' from blender_process import Process p = Process(sample.obj, target_vertices, tmp_obj_file) mesh = TriangleMesh.from_obj(tmp_obj_file) else: mesh = TriangleMesh.from_obj(sample.obj) vertices = (meshutils.normalize_vertices( mesh.vertices).unsqueeze(0).to(device)) faces = mesh.faces.unsqueeze(0).to(device) textures = torch.cat( ( sample.color[0] / 255 * torch.ones( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), sample.color[1] / 255 * torch.ones( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), sample.color[2] / 255 * torch.ones( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), ), dim=-1, ) # (Uniform) Masses masses = (sample.mass / vertices.shape[-2]) * torch.nn.Parameter( torch.ones(vertices.shape[-2], dtype=vertices.dtype, device=device), requires_grad=True, ) # Body body = RigidBody( vertices[0], position=torch.tensor(init_pos, dtype=torch.float32, device=device), masses=masses, orientation=torch.tensor(orientation).type(torch.float32).to(device), friction_coefficient=sample.fric, # linear_velocity=torch.tensor(linear_velocity).type(torch.float32).to(device) # angular_veloctiy=torch.tensor(angular_velocity).type(torch.float32).to(device) ) return body, vertices, faces, textures
def test_newtons_first_law_rest(): # When no external force acts, bodies at rest remain at rest. cube_verts = torch.FloatTensor( [ [1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, -1.0, -1.0], [-1.0, 1.0, -1.0], ] ) cube = RigidBody(cube_verts) sim = Simulator([cube]) sim.step() assert torch.allclose(cube.position, torch.zeros(3)) sim.step() assert torch.allclose(cube.position, torch.zeros(3))
# print("GT mass:", mass[0], mass[0] * vertices.shape[-2]) true_masses.append(mass[0]) # (Uniform) Masses masses_gt = (float(mass[0])) * torch.nn.Parameter( torch.ones(vertices.shape[-2], dtype=vertices.dtype, device=device), requires_grad=True, ) # Body body_gt = RigidBody( vertices[0], masses=masses_gt, # position=torch.from_numpy(init_pos[i]).float().to(device), orientation=torch.from_numpy(orientation[0]).float().to(device), friction_coefficient=float(fric[0]), restitution=float(elas[0]), # linear_velocity=torch.tensor(linear_velocity[i], device=device), # angular_velocity=torch.tensor(angular_velocity[i], device=device), ) # inds = body_gt.vertices.argmin(1) # application_points = list(inds.view(-1).detach().cpu().numpy()) # print("Est app points:", application_points) application_points = [force_application_points[0]] # print("True app points:", application_points) # Add a force force = ConstantForce( magnitude=force_magnitude[0], direction=torch.from_numpy(force_direction[0]).float().to(device), starttime=0.0,
torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.zeros(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), ), dim=-1, ) masses = torch.nn.Parameter( 0.1 * torch.ones(vertices.shape[1], dtype=vertices.dtype, device=device), requires_grad=True, ) position = torch.tensor([0.0, 4.0, 0.0], dtype=torch.float32, device=device) orientation = torch.tensor([1.0, 0.0, 0.0, 0.0], dtype=torch.float32, device=device) body = RigidBody( vertices[0], position=position, orientation=orientation, masses=masses, restitution=0.5, ) # Create a force that applies gravity (g = 10 metres / second^2). # gravity = Gravity(device=device) force_magnitude = 10.0 # / vertices.shape[-2] gravity = ConstantForce( magnitude=force_magnitude, direction=torch.tensor([0.0, -1.0, 0.0]), device=device, ) # Add this force to the body. body.add_external_force(gravity)
if __name__ == "__main__": cube_verts = torch.FloatTensor([ [1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, -1.0, -1.0], [1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, -1.0, -1.0], [-1.0, 1.0, -1.0], ]) position = torch.tensor([2.0, 2.0, 2.0]) orientation = torch.tensor([1.0, 0.0, 0.0, 0.0]) cube = RigidBody(cube_verts + 1, position=position, orientation=orientation) force_magnitude = 10.0 # / cube_verts.shape[0] force_direction = torch.tensor([0.0, -1.0, 0.0]) gravity = ConstantForce(magnitude=force_magnitude, direction=force_direction) cube.add_external_force(gravity) # sim = Simulator([cube], engine=EulerIntegratorWithContacts()) sim_substeps = 32 dtime = (1 / 30) / sim_substeps sim = Simulator([cube], engine=SemiImplicitEulerWithContacts(), dtime=dtime)
( torch.ones( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.ones( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.zeros( 1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), ), dim=-1, ) masses = torch.nn.Parameter( 0.1 * torch.ones(vertices.shape[1], dtype=vertices.dtype, device=device), requires_grad=True, ) body = RigidBody(vertices[0], masses=masses) # Create a force that applies gravity (g = 10 metres / second^2). # gravity = Gravity(device=device) gravity = ConstantForce(direction=torch.tensor([0.0, -1.0, 0.0]), device=device) # Add this force to the body. body.add_external_force(gravity, application_points=[0, 1]) # Initialize the simulator with the body at the origin. sim = Simulator([body]) # Initialize the renderer. renderer = SoftRenderer(camera_mode="look_at", device=device) camera_distance = 8.0
# (Uniform) Masses masses_gt = (float(mass[0])) * torch.nn.Parameter( torch.ones(vertices.shape[-2], dtype=vertices.dtype, device=device), requires_grad=True, ) restitution_gt = torch.nn.Parameter( torch.tensor([float(elas[0])], dtype=vertices.dtype, device=device), ) # Body body_gt = RigidBody( vertices[0], masses=masses_gt, position=torch.from_numpy(init_pos[0]).float().to(device), orientation=torch.from_numpy(orientation[0]).float().to(device), friction_coefficient=float(fric[0]), restitution=restitution_gt, # linear_velocity=torch.tensor(linear_velocity[i], device=device), # angular_velocity=torch.tensor(angular_velocity[i], device=device), ) # application_points = [force_application_points[0]] # # Add a force # force = ConstantForce( # magnitude=force_magnitude[0], # direction=torch.from_numpy(force_direction[0]).float().to(device), # starttime=0.0, # endtime=0.1, # device=device, # ) # body_gt.add_external_force(force, application_points=application_points)
( torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.zeros(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), ), dim=-1, ) # masses_gt = torch.nn.Parameter( # 1 * torch.ones(vertices.shape[1], dtype=vertices.dtype, device=device), # requires_grad=False, # ) masses_gt = torch.nn.Parameter( torch.ones(vertices.shape[1], dtype=vertices.dtype, device=device), requires_grad=False, ) body_gt = RigidBody(vertices[0], masses=masses_gt) # Create a force that applies gravity (g = 10 metres / second^2). gravity = ConstantForce( direction=torch.tensor([0.0, -1.0, 0.0]), magnitude=args.force_magnitude, device=device, ) # Add this force to the body. body_gt.add_external_force(gravity, application_points=[0, 1]) # Initialize the simulator with the body at the origin. sim_gt = Simulator([body_gt]) # Initialize the renderer.
) masses_gt = torch.nn.Parameter( torch.ones(vertices.shape[1], dtype=vertices.dtype, device=device), requires_grad=True, ) position = torch.tensor([0.0, 4.0, 0.0], dtype=torch.float32, device=device) orientation = torch.tensor([1.0, 0.0, 0.0, 0.0], dtype=torch.float32, device=device) restitution_gt = 0.8 body = RigidBody( vertices[0], position=position, orientation=orientation, masses=masses_gt, restitution=restitution_gt, ) # Create a force that applies gravity (g = 10 metres / second^2). # gravity = Gravity(device=device) force_magnitude = 10.0 # / vertices.shape[-2] gravity = ConstantForce( magnitude=force_magnitude, direction=torch.tensor([0.0, -1.0, 0.0]), device=device, ) # Add this force to the body. body.add_external_force(gravity)
dtype=torch.float32, device=device) orientation_gt = torch.tensor([1.0, 0.0, 0.0, 0.0], dtype=torch.float32, device=device) # mass_per_vertex = 1.0 / vertices_gt.shape[1] mass_per_vertex = 1.0 masses_gt = torch.nn.Parameter( mass_per_vertex * torch.ones( vertices_gt.shape[1], dtype=vertices_gt.dtype, device=device), requires_grad=False, ) body_gt = RigidBody( vertices_gt[0], masses=masses_gt, position=position_gt, orientation=orientation_gt, ) # Create a force that applies gravity (g = 10 metres / second^2). # normalized_magnitude_gt = args.force_magnitude / vertices_gt.shape[-2] gravity_gt = ConstantForce( direction=torch.tensor([0.0, -1.0, 0.0]), magnitude=args.force_magnitude, device=device, ) # Add this force to the body. inds = vertices_gt.argmin(-2)[0] application_points = list(inds.view(-1).detach().cpu().numpy()) body_gt.add_external_force(gravity_gt,
# Output (gif) file path outfile = cache / "hellogradsim.gif" # Load a body (from a triangle mesh obj file). mesh = TriangleMesh.from_obj(Path("sampledata/banana.obj")) vertices = meshutils.normalize_vertices(mesh.vertices.unsqueeze(0)).to(device) faces = mesh.faces.to(device).unsqueeze(0) textures = torch.cat( ( torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.ones(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), torch.zeros(1, faces.shape[1], 2, 1, dtype=torch.float32, device=device), ), dim=-1, ) body = RigidBody(vertices[0]) # Create a force that applies gravity (g = 10 metres / second^2). # gravity = Gravity(device=device) gravity = ConstantForce(direction=torch.tensor([0.0, -1.0, 0.0]), device=device) # Add this force to the body. body.add_external_force(gravity) # Initialize the simulator with the body at the origin. sim = Simulator([body]) # Initialize the renderer. renderer = SoftRenderer(camera_mode="look_at", device=device) camera_distance = 8.0 elevation = 30.0