当前位置: 首页 > news >正文

5. isaac sim4.2 教程-Core API-操作机械臂

本教程将向仿真场景中引入第二个机器人——Franka Panda机械臂,详细讲解如何将其添加到场景中,并演示如何使用其PickAndPlaceController(抓放控制器)。通过本教程的学习,您将积累更多在Omniverse Isaac Sim中使用不同机器人及控制器类的实践经验。

1. 创建场景

# 机械臂
from omni.isaac.examples.base_sample import BaseSample
# This extension has franka related tasks and controllers as well
from omni.isaac.franka import Franka
from omni.isaac.core.objects import DynamicCuboid
import numpy as npclass MyHelloWorld(BaseSample): # 继承自basesampledef __init__(self) -> None:super().__init__()returndef setup_scene(self):world = self.get_world()world.scene.add_default_ground_plane()# adding a Franka robot franka = world.scene.add(Franka(prim_path="/World/Fancy_Franka", name="fancy_franka"))world.scene.add(DynamicCuboid(prim_path="/World/random_cube",name="fancy_cube",position=np.array([0.3, 0.3, 0.3]),scale=np.array([0.0515, 0.0515, 0.0515]),color=np.array([0, 0, 1.0]),))return

2. Using the PickAndPlace Controller

可以看到franka带了3个控制器,我们这里用第一个

# 机械臂
from omni.isaac.examples.base_sample import BaseSample
# This extension has franka related tasks and controllers as well
from omni.isaac.franka import Franka
from omni.isaac.core.objects import DynamicCuboid
from omni.isaac.franka.controllers import PickPlaceController
import numpy as npclass MyHelloWorld(BaseSample): # 继承自basesampledef __init__(self) -> None:super().__init__()returndef setup_scene(self):world = self.get_world()world.scene.add_default_ground_plane()# adding a Franka robot franka = world.scene.add(Franka(prim_path="/World/Fancy_Franka", name="fancy_franka"))world.scene.add(DynamicCuboid(prim_path="/World/random_cube",name="fancy_cube",position=np.array([0.3, 0.3, 0.3]),scale=np.array([0.0515, 0.0515, 0.0515]),color=np.array([0, 0, 1.0]),))returnasync def setup_post_load(self):self._world = self.get_world()self._franka = self._world.scene.get_object("fancy_franka")self._fancy_cube = self._world.scene.get_object("fancy_cube")# 初始化自己的控制器self._controller = PickPlaceController(name="pick_place_controller",gripper=self._franka.gripper,robot_articulation=self._franka,)# 设置自动执行的任务--通过回调函数self._world.add_physics_callback("sim_step", callback_fn=self.physics_step)# load之后要设置夹爪初始位置,确定仿真启动之后机器人从同一个已知状态开始self._franka.gripper.set_joint_positions(self._franka.gripper.joint_opened_positions)await self._world.play_async()return# 重置之后要做的事情async def setup_post_reset(self):self._controller.reset()# 重启之后也要重置夹爪位置/打开夹爪self._franka.gripper.set_joint_positions(self._franka.gripper.joint_opened_positions)await self._world.play_async()returndef physics_step(self, step_size):cube_position, _ = self._fancy_cube.get_world_pose()goal_position = np.array([-0.3, -0.3, 0.0515 / 2.0])current_joint_positions = self._franka.get_joint_positions()# 生成actionactions = self._controller.forward(picking_position=cube_position,placing_position=goal_position,current_joint_positions=current_joint_positions,)self._franka.apply_action(actions)if self._controller.is_done():self._world.pause()returndef world_cleanup(self):# 释放内存等return

3. 什么是task

在 Omniverse Isaac Sim 中,Task 类提供了一种模块化的方式,用于管理场景创建、信息检索和指标计算。它适用于构建具有高级逻辑的更复杂场景。在本教程中,你将需要基于 Task 类重构之前的代码。

3.1 定义自己的task

# 自己定义task
from omni.isaac.examples.base_sample import BaseSample
from omni.isaac.franka import Franka
from omni.isaac.core.objects import DynamicCuboid
from omni.isaac.franka.controllers import PickPlaceController
from omni.isaac.core.tasks import BaseTask # 任务基类
import numpy as np# FrankaPlaying 任务子类
class FrankaPlaying(BaseTask):#NOTE: 这里只有basetask任务类中的一部分,还有更多可以查看原本实现def __init__(self, name):super().__init__(name=name, offset=None)self._goal_position = np.array([-0.3, -0.3, 0.0515 / 2.0]) # 立方体目标位置self._task_achieved = False # 任务完成标志return# setup all 在任务中的 assetsdef 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([0.3, 0.3, 0.3]),scale=np.array([0.0515, 0.0515, 0.0515]),color=np.array([0, 0, 1.0])))# 添加Franka机械臂self._franka = scene.add(Franka(prim_path="/World/Fancy_Franka",name="fancy_franka"))return# 任务中需要的信息通过 get_observationsdef 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# 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()# 检查立方体是否到达目标位置(误差<2cm)if not self._task_achieved and np.mean(np.abs(self._goal_position - cube_position)) < 0.02:# 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# 每次重置后调用def post_reset(self):self._franka.gripper.set_joint_positions(self._franka.gripper.joint_opened_positions) # 打开夹爪self._cube.get_applied_visual_material().set_color(color=np.array([0, 0, 1.0])) # 重置为蓝色self._task_achieved = False # 重置任务状态returnclass MyHelloWorld(BaseSample): # 继承自basesampledef __init__(self) -> None:super().__init__()returndef setup_scene(self):world = self.get_world()world.add_task(FrankaPlaying(name="my_first_task"))  # 添加自定义任务returnasync def setup_post_load(self):self._world = self.get_world()self._franka = self._world.scene.get_object("fancy_franka")  # 获取机械臂对象# 初始化抓放控制器self._controller = PickPlaceController(name="pick_place_controller",gripper=self._franka.gripper,  # 夹爪对象robot_articulation=self._franka  # 机械臂对象)# 注册物理步进回调self._world.add_physics_callback("sim_step", callback_fn=self.physics_step)await self._world.play_async()  # 开始仿真# 重置之后要做的事情async def setup_post_reset(self):self._controller.reset()# 重启之后也要重置夹爪位置/打开夹爪self._franka.gripper.set_joint_positions(self._franka.gripper.joint_opened_positions)await self._world.play_async()returndef physics_step(self, step_size):# 1. 获取当前观察值(立方体位置/目标位置/关节角度)current_observations = self._world.get_observations()# 2. 控制器计算动作指令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"])# 3. 应用动作到机械臂self._franka.apply_action(actions)# 4. 检查任务完成状态if self._controller.is_done():self._world.pause()  # 暂停仿真returndef world_cleanup(self):# 释放内存等return

最后成功了cube就有蓝变绿.

3.2 使用Pick and Place Task

Omniverse Isaac Sim 也提供了不同的任务类在许多的机器人扩展中,我们这里重写提供的pickplace

# Use the Pick and Place Task
from omni.isaac.examples.base_sample import BaseSample
from omni.isaac.franka.controllers import PickPlaceController
from omni.isaac.franka.tasks import PickPlace
import numpy as npclass MyHelloWorld(BaseSample): # 继承自basesampledef __init__(self) -> None:super().__init__()returndef setup_scene(self):world = self.get_world()world.add_task(PickPlace(name="awesome_task"))  # 添加自带的任务,包含了机械臂方块等returnasync def setup_post_load(self):self._world = self.get_world()# 每个被定义好的任务都有一个 get_params()和set_params()方法# 通过 get_params() 获取任务参数task_params = self._world.get_task("awesome_task").get_params()self._franka = self._world.scene.get_object(task_params["robot_name"]["value"])self._cube_name = task_params["cube_name"]["value"]self._controller = PickPlaceController(name="pick_place_controller",gripper=self._franka.gripper,robot_articulation=self._franka,)# 注册物理步进回调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()# 重启之后也要重置夹爪位置/打开夹爪self._franka.gripper.set_joint_positions(self._franka.gripper.joint_opened_positions)await self._world.play_async()returndef physics_step(self, step_size):# 1. 获取当前观察值(立方体位置/目标位置/关节角度)current_observations = self._world.get_observations()# 2. 控制器计算动作指令actions = self._controller.forward(picking_position=current_observations[self._cube_name]["position"],placing_position=current_observations[self._cube_name]["target_position"],current_joint_positions=current_observations[self._franka.name]["joint_positions"],)# 3. 应用动作到机械臂self._franka.apply_action(actions)# 4. 检查任务完成状态if self._controller.is_done():self._world.pause()  # 暂停仿真return

整体来说更简单,直接调用人家封装好的就可以,不用我们自己设置各种各样的东西。

http://www.dtcms.com/a/273370.html

相关文章:

  • 用黑盒测试与白盒测试,读懂专利审查的 “双重关卡”​​
  • K8S的CNI之calico插件升级至3.30.2
  • 深度学习中的 Seq2Seq 模型与注意力机制
  • 解释sync.WaitGroup的用途和工作原理。在什么情况下应该使用它?
  • 时间显示 蓝桥云课Java
  • Android ViewBinding 使用与封装教程​​
  • Netron的基本使用介绍
  • UNet改进(20):融合通道-空间稀疏注意力的医学图像分割模型
  • 客户频繁问询项目进度,如何提高响应效率
  • Java 中的多线程实现方式
  • Spring AI 系列之八 - MCP Server
  • NFS文件存储及部署论坛(小白的“升级打怪”成长之路)
  • (鱼书)深度学习入门2:手搓感知机
  • PostgreSQL创建新实例并指定目录
  • 下一代防火墙混合模式部署
  • Jupyter介绍
  • MySQL事务实现原理
  • SpringCloud系列 - 分布式锁(八)
  • html页面,当鼠标移开A字标就隐藏颜色框
  • Spring Boot项目中大文件上传的优化策略与实践
  • 华为鸿蒙3.0 4.0完全关闭纯净模式的方法以及临时绕过纯净模式检测的方法
  • 接口(上篇)
  • 基于深度学习的自动调制识别网络(持续更新)
  • 亚洲牧原:活跃行业交流,延伸公益版图,市场拓展再结硕果
  • 布隆过滤器原理
  • 我的世界模组开发——机械动力的渲染(4)
  • java-io流
  • 对象序列化与反序列化
  • 【PyTorch】PyTorch 自动微分与完整手动实现对比
  • vue3 element plus table 使用固定列,滑动滚动会错位、固定列层级异常、滑动后固定列的内容看不到了