NVlabs / curobo

CUDA Accelerated Robot Library
https://curobo.org
Other
732 stars 109 forks source link

Time cost of python example #101

Closed im-renpei closed 8 months ago

im-renpei commented 8 months ago

If it’s not a bug, please use discussions: https://github.com/NVlabs/curobo/discussions

Please provide the below information in addition to your issue:

  1. cuRobo installation mode (choose from [python, isaac sim, docker python, docker isaac sim]): python
  2. python version: 3.8.10
  3. Isaac Sim version (if using): N/A
  4. GPU: RTX 4090
  5. CUDA: 11.8

Hi @balakumar-s , I just execute the example. But the time cost for franka IK example is strange and does not math the time mentioned in the paper.

Result

➜  curobo git:(main) ✗ python3 examples/ik_example_franka.py
--------------------------------------------------
Running demo_basic_ik
Success, Solve Time(s), Total Time(s)  1.0 1.0106189250946045 0.7667928535113149 tensor(0.0008, device='cuda:0') tensor(0.0066, device='cuda:0')
--------------------------------------------------
Running demo_full_config_collision_free_ik
Success, Solve Time(s), Total Time(s) 1.0 0.15874934196472168 0.4029872417449951 2.481468136980839 tensor(0.0005, device='cuda:0') tensor(0.0034, device='cuda:0')
--------------------------------------------------
Running demo_full_config_batch_env_collision_free_ik
Success, Solve Time(s), Total Time(s) 1.0 0.48165225982666016 0.5924277305603027
Running Batch Env Goalset IK
Success, Solve Time(s), Total Time(s) 1.0 0.18120265007019043 0.39771509170532227
➜  curobo git:(main) ✗

Code

# Standard Library
import time

# Third Party
import torch

# CuRobo
from curobo.geom.types import WorldConfig
from curobo.types.base import TensorDeviceType
from curobo.types.math import Pose
from curobo.types.robot import RobotConfig
from curobo.util_file import get_robot_configs_path, get_world_configs_path, join_path, load_yaml
from curobo.wrap.reacher.ik_solver import IKSolver, IKSolverConfig

torch.backends.cudnn.benchmark = True

torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True

def demo_basic_ik():
    tensor_args = TensorDeviceType()

    config_file = load_yaml(join_path(get_robot_configs_path(), "franka.yml"))
    urdf_file = config_file["robot_cfg"]["kinematics"][
        "urdf_path"
    ]  # Send global path starting with "/"
    base_link = config_file["robot_cfg"]["kinematics"]["base_link"]
    ee_link = config_file["robot_cfg"]["kinematics"]["ee_link"]
    robot_cfg = RobotConfig.from_basic(urdf_file, base_link, ee_link, tensor_args)

    ik_config = IKSolverConfig.load_from_robot_config(
        robot_cfg,
        None,
        rotation_threshold=0.05,
        position_threshold=0.005,
        num_seeds=20,
        self_collision_check=False,
        self_collision_opt=False,
        tensor_args=tensor_args,
        use_cuda_graph=False,
    )
    ik_solver = IKSolver(ik_config)

    print("Running demo_basic_ik")
    for _ in range(1):
        q_sample = ik_solver.sample_configs(1)
        kin_state = ik_solver.fk(q_sample)
        goal = Pose(kin_state.ee_position, kin_state.ee_quaternion)

        st_time = time.time()
        result = ik_solver.solve_batch(goal)
        torch.cuda.synchronize()
        print(
            "Success, Solve Time(s), Total Time(s) ",
            torch.count_nonzero(result.success).item() / len(q_sample),
            result.solve_time,
            q_sample.shape[0] / (time.time() - st_time),
            torch.mean(result.position_error) * 100.0,
            torch.mean(result.rotation_error) * 100.0,
        )

def demo_full_config_collision_free_ik():
    tensor_args = TensorDeviceType()
    world_file = "collision_cage.yml"

    robot_file = "franka.yml"
    robot_cfg = RobotConfig.from_dict(
        load_yaml(join_path(get_robot_configs_path(), robot_file))["robot_cfg"]
    )
    world_cfg = WorldConfig.from_dict(load_yaml(join_path(get_world_configs_path(), world_file)))
    ik_config = IKSolverConfig.load_from_robot_config(
        robot_cfg,
        world_cfg,
        rotation_threshold=0.05,
        position_threshold=0.005,
        num_seeds=20,
        self_collision_check=True,
        self_collision_opt=True,
        tensor_args=tensor_args,
        use_cuda_graph=True,
        # use_fixed_samples=True,
    )
    ik_solver = IKSolver(ik_config)

    # print(kin_state)
    print("Running demo_full_config_collision_free_ik")
    for _ in range(1):
        q_sample = ik_solver.sample_configs(1)
        kin_state = ik_solver.fk(q_sample)
        goal = Pose(kin_state.ee_position, kin_state.ee_quaternion)

        st_time = time.time()
        result = ik_solver.solve_batch(goal)
        torch.cuda.synchronize()
        total_time = (time.time() - st_time) / q_sample.shape[0]
        print(
            "Success, Solve Time(s), Total Time(s)",
            torch.count_nonzero(result.success).item() / len(q_sample),
            result.solve_time,
            total_time,
            1.0 / total_time,
            torch.mean(result.position_error) * 100.0,
            torch.mean(result.rotation_error) * 100.0,
        )

def demo_full_config_batch_env_collision_free_ik():
    tensor_args = TensorDeviceType()
    world_file = ["collision_test.yml", "collision_cubby.yml"]

    robot_file = "franka.yml"
    robot_cfg = RobotConfig.from_dict(
        load_yaml(join_path(get_robot_configs_path(), robot_file))["robot_cfg"]
    )
    world_cfg = [
        WorldConfig.from_dict(load_yaml(join_path(get_world_configs_path(), x))) for x in world_file
    ]
    ik_config = IKSolverConfig.load_from_robot_config(
        robot_cfg,
        world_cfg,
        rotation_threshold=0.05,
        position_threshold=0.005,
        num_seeds=100,
        self_collision_check=True,
        self_collision_opt=True,
        tensor_args=tensor_args,
        use_cuda_graph=False,
        # use_fixed_samples=True,
    )
    ik_solver = IKSolver(ik_config)
    q_sample = ik_solver.sample_configs(len(world_file))
    kin_state = ik_solver.fk(q_sample)
    goal = Pose(kin_state.ee_position, kin_state.ee_quaternion)

    print("Running demo_full_config_batch_env_collision_free_ik")
    for _ in range(1):
        st_time = time.time()
        result = ik_solver.solve_batch_env(goal)
        # print(result.success)
        torch.cuda.synchronize()
        print(
            "Success, Solve Time(s), Total Time(s)",
            torch.count_nonzero(result.success).item() / len(q_sample),
            result.solve_time,
            time.time() - st_time,
        )

    q_sample = ik_solver.sample_configs(10 * len(world_file))
    kin_state = ik_solver.fk(q_sample)
    goal = Pose(
        kin_state.ee_position.view(len(world_file), 10, 3),
        kin_state.ee_quaternion.view(len(world_file), 10, 4),
    )

    print("Running Batch Env Goalset IK")
    for _ in range(1):
        st_time = time.time()
        result = ik_solver.solve_batch_env_goalset(goal)
        torch.cuda.synchronize()
        print(
            "Success, Solve Time(s), Total Time(s)",
            torch.count_nonzero(result.success).item() / len(result.success.view(-1)),
            result.solve_time,
            time.time() - st_time,
        )

if __name__ == "__main__":
    print("-"*50)
    demo_basic_ik()
    print("-"*50)
    demo_full_config_collision_free_ik()
    print("-"*50)
    demo_full_config_batch_env_collision_free_ik()
balakumar-s commented 8 months ago

To get numbers from the paper, run the benchmark script following: https://curobo.org/source/getting_started/4_benchmarks.html#inverse-kinematics

balakumar-s commented 8 months ago

I also noticed that you changed the example to only run the for loop once. You need to warmup the ik solver on the gpu by running a few times (3) before timing. We hence use a for loop of 10.

im-renpei commented 8 months ago

I also noticed that you changed the example to only run the for loop once. You need to warmup the ik solver on the gpu by running a few times (3) before timing. We hence use a for loop of 10.

Hi Balakumar, the time consumption did change after adding warm up.

As we implement our own robotic arm example, what else should we pay attention to? For example, warm up the process as you just mentioned

By the way, if we want to share our robot as an example with you, what do we need to provide?

balakumar-s commented 8 months ago

You need to provide the urdf, meshes and the robot configuration file.