Nvidia Omniverse (Isaac SIM)

최준혁·2022년 2월 11일
0

시뮬레이션이니까 world 위의 모든 object의 위치를 파악할 수 있다.

Task 이해하기

말 그대로 일을 주는 것이다. 로봇팔이라면 pick&place가 될 것이고, 주행로봇이면 A2B의 일을 하는 것이다. 이러한 명령들이 모여모여 하나의 시스템이 될 터이니, 가장 간단한 Task를 이해하며 늘려가보자.

1. Task Class 이해하기

[task]

  • set_up_scene(): World에서 로봇이나 world를 추가하듯이, 여기서도 동일하게 작동할 수 있다. 즉 이 함수 안에서 객체 삽입하라는 것.
  • get_observations(): 삽입된 객체의 정보들을 관찰할 수 있다. return 이 존재하며, dictionary형태로 돌려주어야 한다.
  • pre_step(): 각각의 물리스텝 전에 실행이 되는 함수이다. 이곳에서 일의 성공 유무를 파악하면 되겠다.

2. World Class에서 task 활용하기.

삽입된 객체는 scene을 통해서 확인할 수 있다. 실제 움직이는 것은 world의 add_physics_callback 함수를 통해서 움직여야 함으로,

  • world.add_task(Task(name="task1")): 해야할 task를 삽입할 수 있다.
  • get_observations() 함수를 사용하여 필요한 관찰 데이터 획득.

필요한 데이터를 습득했으면, 그곳으로 이동하는 함수를 사용하여 task를 진행하면 되겠다.

from omni.isaac.examples.base_sample import BaseSample
from omni.isaac.franka import Franka
from omni.isaac.jetbot import Jetbot
from omni.isaac.core.objects import DynamicCuboid
from omni.isaac.core.controllers import BaseController
from omni.isaac.franka.controllers import PickPlaceController
from omni.isaac.core.utils.types import ArticulationAction
from omni.isaac.core.tasks import BaseTask

import numpy as np


class FrankaPlaying(BaseTask):
    def __init__(self, name):
        super().__init__(name=name, offset=None)
        self._goal_position=np.array([-30, -30, 5.15/2.])
        self._task_achieved  = False

    # Here we setup all the assets that we care about in this task.
    def set_up_scene(self, scene):
        super().set_up_scene(scene)
        scene.add_default_ground_plane()
        self._cube = scene.add(
            DynamicCuboid(
                prim_path="/World/random_cube",
                name="fancy_cube",
                position=np.array([30, 30, 30]),
                size=np.array([5.15, 5.15, 5.15]),
                color=np.array([1., 0, 0])
            )
        )
        self._franka = scene.add(
            Franka(
                prim_path="/World/Fancy_Franka",
                name="fancy_franka"
            )
        )
        return

    # Information exposed to solve the task is returned from the task through get_observations
    def get_observations(self):
        cube_position, _ = self._cube.get_world_pose()
        current_joint_positions = self._franka.get_joint_positions()
        observations = {
            self._franka.name: {
                "joint_positions": current_joint_positions,
            },
            self._cube.name: {
                "position": cube_position,
                "goal_position": self._goal_position
            }
        }
        return observations

    # Called before each physics step,
    # for instance we can check here if the task was accomplished by
    # changing the color of the cube once its accomplished
    def pre_step(self, control_index, simulation_time):
        cube_position, _ = self._cube.get_world_pose()
        if not self._task_achieved and np.mean(np.abs(self._goal_position - cube_position)) < 2:
            # Visual Materials are applied by default to the cube
            # in this case the cube has a visual material of type
            # PreviewSurface, we can set its color once the target is reached.
            self._cube.get_applied_visual_material().set_color(color=np.array([0, 1.0, 0]))
            self._task_achieved = True
        return

class HelloWorld(BaseSample):
    def __init__(self) -> None:
        super().__init__()
        return

    def setup_scene(self):
        world = self.get_world()
        # We add the task to the world here
        world.add_task(FrankaPlaying(name="my_first_task"))
        return

    async def setup_post_load(self):
        self._world = self.get_world()
        # The world already called the setup_scene from the task (with first reset of the world)
        # so we can retrieve the task objects
        self._franka = self._world.scene.get_object("fancy_franka")
        self._controller = PickPlaceController(
            name="pick_place_controller",
            gripper_dof_indices=self._franka.gripper.dof_indices,
            robot_prim_path=self._franka.prim_path,
        )
        self._world.add_physics_callback("sim_step", callback_fn=self.physics_step)
        await self._world.play_async()
        return

    async def setup_post_reset(self):
        self._controller.reset()
        await self._world.play_async()
        return

    def physics_step(self, step_size):
        # Gets all the tasks observations
        current_observations = self._world.get_observations()
        actions = self._controller.forward(
            picking_position=current_observations["fancy_cube"]["position"],
            placing_position=current_observations["fancy_cube"]["goal_position"],
            current_joint_positions=current_observations["fancy_franka"]["joint_positions"],
        )
        self._franka.apply_action(actions)
        if self._controller.is_done():
            self._world.pause()
        return
profile
3D Vision, VSLAM, Robotics, Deep_Learning

1개의 댓글

comment-user-thumbnail
2022년 6월 14일

안녕하세요!
Omniverse Isaac sim 사용하시는 블로그를 올려주시다니 굉장히 흥미롭네요!
Omniverse Isaac sim관련하여 현재는 커뮤니티가 거의 없다보니
같이 대화 나누면서 지식을 공유하고 싶은데..
혹시 개인톡을 드려도 괜찮을까요?

답글 달기