Post

NVIDIA Isaac Sim - WMR code

JetBot

jetbot

이번 포스팅에서는 JetBot이라는 소형 로봇을 기준으로 작성된 jetbot_move.py라는 코드를 리뷰할 예정이다. 참고로 JetBot은 2축 모바일 로봇 (2-wheeled Mobile Robot)이다.

처음으로는 간단히 jetbot이 움직이는 코드에 대해서 간략하게 리뷰를 해보겠다.

전체 코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import argparse
from omni.isaac.kit import SimulationApp

parser = argparse.ArgumentParser()
parser.add_argument("--test", default=False, action="store_true", help="Run in test mode")
args, unknown = parser.parse_known_args()

simulation_app = SimulationApp({"headless": False})

import carb
import numpy as np
from omni.isaac.core import World
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.wheeled_robots.controllers.differential_controller import DifferentialController
from omni.isaac.wheeled_robots.robots import WheeledRobot

my_world = World(stage_units_in_meters=1.0)
assets_root_path = get_assets_root_path()
if assets_root_path is None:
    carb.log_error("Could not find Isaac Sim assets folder")
jetbot_asset_path = assets_root_path + "/Isaac/Robots/Jetbot/jetbot.usd"
my_jetbot = my_world.scene.add(
    WheeledRobot(
        prim_path="/World/Jetbot",
        name="my_jetbot",
        wheel_dof_names=["left_wheel_joint", "right_wheel_joint"],
        create_robot=True,
        usd_path=jetbot_asset_path,
        position=np.array([0, 0.0, 2.0]),
    )
)
my_world.scene.add_default_ground_plane()
my_controller = DifferentialController(name="simple_control", wheel_radius=0.03, wheel_base=0.1125)
my_world.reset()

i = 0
while simulation_app.is_running():
    my_world.step(render=True)
    if my_world.is_playing():
        if my_world.current_time_step_index == 0:
            my_world.reset()
            my_controller.reset()
        if i >= 0 and i < 1000:
            # forward
            my_jetbot.apply_wheel_actions(my_controller.forward(command=[0.05, 0]))
            print(my_jetbot.get_linear_velocity())
        elif i >= 1000 and i < 1300:
            # rotate
            my_jetbot.apply_wheel_actions(my_controller.forward(command=[0.0, np.pi / 12]))
            print(my_jetbot.get_angular_velocity())
        elif i >= 1300 and i < 2000:
            # forward
            my_jetbot.apply_wheel_actions(my_controller.forward(command=[0.05, 0]))
        elif i == 2000:
            i = 0
        i += 1
    if args.test is True:
        break

simulation_app.close()

코드 줄만 보고 코드가 되게 어렵다 생각할 수도 있지만 전혀 어려운 구조는 아니다. 나중에 본인의 환경을 짜다 보면 2천줄 가까이 되는 코드를 짜고 있는 당신을 발견하고 있을테니까.

코드 리뷰에 앞서 이 포스팅은 시뮬레이션 코드에 대한 리뷰이지 python에 대한 리뷰는 아니기 때문에 argparse와 같이 Isaac Sim 코드가 아닌 것은 과감히 뛰어넘도록 하겠다.

그렇다면, 지금부터 코드를 한줄 한줄 뜯어보면서 해당 코드가 어떤 의미이고 어떻게 쓰이는지 알아보겠다.

코드를 실행시키면 아래와 같은 결과를 얻을 수 있다.

jetbot_move

1
2
from omni.isaac.kit import SimulationApp
simulation_app = SimulationApp({"headless": False})

코드를 이용하여 Isaac Sim을 실행하려면 omni.isaac.kit 디렉토리에 있는 SimulationApp이라는 클래스를 가져와서 선언해야한다.

SimulationApp 클래스에서는 시뮬레이션 설정에 필요한 config값들을 지정해 줄 수 있다 우리가 config값에 넣을 수 있는 변수들은 아래와 같다.

1
2
3
4
5
6
7
8
DEFAULT_LAUNCHER_CONFIG = {'active_gpu': None, 'anti_aliasing': 3, 'denoiser': True, 
                           'display_options': 3094, 'fast_shutdown': True, 'headless': True, 
                           'height': 720, 'livesync_usd': None, 'max_bounces': 4, 
                           'max_specular_transmission_bounces': 6, 'max_volume_bounces': 4, 
                           'multi_gpu': True, 'open_usd': None, 'physics_gpu': 0, 
                           'renderer': 'RayTracedLighting', 'samples_per_pixel_per_frame': 64, 
                           'subdiv_refinement_level': 0, 'sync_loads': True, 'width': 1280, 
                           'window_height': 900, 'window_width': 1440}
  • headless (bool): 시뮬레이션 UI를 실행할 것인지에 대한 파라미터이다. 기본값은 True로 되어 있다. 혼동하면 안되는 것은 headless=False가 UI를 실행시키는 것이다. Isaac Sim은 컴퓨터에서 차지하는 용량이 어마무시하기 때문에, 만약 본인의 컴퓨터가 UI를 감당하지 못한다면 headless=True로 설정하는 것을 잊으면 안된다.
  • active_gpu (int): 시뮬레이션을 실행할 때 어떤 GPU를 사용할 것인지를 지정하는 파라미터. 만약 컴퓨터에 GPU가 한개만 꽂혀 있다면 None값을 그대로 나두면 된다.
  • physics_gpu (int): 물리 시뮬레이션을 실행할 때 사용한 GPU를 지정하는 파라미터. 이것 또한 첫번째 GPU인 0으로 기본값이 설정되어 있다.
This post is licensed under CC BY 4.0 by the author.