IK with CollisionΒΆ

Basic Inverse Kinematics with Collision Avoidance using PyRoKi.

All examples can be run by first cloning the PyRoki repository, which includes the pyroki_snippets implementation details.

 1import time
 2import viser
 3import numpy as np
 4from robot_descriptions.loaders.yourdfpy import load_robot_description
 5
 6import pyroki as pk
 7from pyroki.collision import HalfSpace, RobotCollision, Sphere
 8from viser.extras import ViserUrdf
 9import pyroki_snippets as pks
10
11
12def main():
13    """Main function for basic IK with collision."""
14    urdf = load_robot_description("panda_description")
15    target_link_name = "panda_hand"
16    robot = pk.Robot.from_urdf(urdf)
17
18    robot_coll = RobotCollision.from_urdf(urdf)
19    plane_coll = HalfSpace.from_point_and_normal(
20        np.array([0.0, 0.0, 0.0]), np.array([0.0, 0.0, 1.0])
21    )
22    sphere_coll = Sphere.from_center_and_radius(
23        np.array([0.0, 0.0, 0.0]), np.array([0.05])
24    )
25
26    # Set up visualizer.
27    server = viser.ViserServer()
28    server.scene.add_grid("/ground", width=2, height=2, cell_size=0.1)
29    urdf_vis = ViserUrdf(server, urdf, root_node_name="/robot")
30
31    # Create interactive controller for IK target.
32    ik_target_handle = server.scene.add_transform_controls(
33        "/ik_target", scale=0.2, position=(0.5, 0.0, 0.5), wxyz=(0, 0, 1, 0)
34    )
35
36    # Create interactive controller and mesh for the sphere obstacle.
37    sphere_handle = server.scene.add_transform_controls(
38        "/obstacle", scale=0.2, position=(0.4, 0.3, 0.4)
39    )
40    server.scene.add_mesh_trimesh("/obstacle/mesh", mesh=sphere_coll.to_trimesh())
41
42    timing_handle = server.gui.add_number("Elapsed (ms)", 0.001, disabled=True)
43
44    while True:
45        start_time = time.time()
46
47        sphere_coll_world_current = sphere_coll.transform_from_pos_wxyz(
48            position=np.array(sphere_handle.position),
49            wxyz=np.array(sphere_handle.wxyz),
50        )
51
52        world_coll_list = [plane_coll, sphere_coll_world_current]
53        solution = pks.solve_ik_with_collision(
54            robot=robot,
55            coll=robot_coll,
56            world_coll_list=world_coll_list,
57            target_link_name=target_link_name,
58            target_position=np.array(ik_target_handle.position),
59            target_wxyz=np.array(ik_target_handle.wxyz),
60        )
61
62        # Update timing handle.
63        timing_handle.value = (time.time() - start_time) * 1000
64
65        # Update visualizer.
66        urdf_vis.update_cfg(solution)
67
68
69if __name__ == "__main__":
70    main()