시뮬레이션이니까 world 위의 모든 object의 위치를 파악할 수 있다.
말 그대로 일을 주는 것이다. 로봇팔이라면 pick&place가 될 것이고, 주행로봇이면 A2B의 일을 하는 것이다. 이러한 명령들이 모여모여 하나의 시스템이 될 터이니, 가장 간단한 Task를 이해하며 늘려가보자.
삽입된 객체는 scene을 통해서 확인할 수 있다. 실제 움직이는 것은 world의 add_physics_callback 함수를 통해서 움직여야 함으로,
필요한 데이터를 습득했으면, 그곳으로 이동하는 함수를 사용하여 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
안녕하세요!
Omniverse Isaac sim 사용하시는 블로그를 올려주시다니 굉장히 흥미롭네요!
Omniverse Isaac sim관련하여 현재는 커뮤니티가 거의 없다보니
같이 대화 나누면서 지식을 공유하고 싶은데..
혹시 개인톡을 드려도 괜찮을까요?