目录
API链接:
Dynamic Control [omni.isaac.dynamic_control] — isaac_sim 2022.2.1-beta.29 documentation
使用示例:
Dynamic Control — Omniverse Robotics documentation
1. 导入模型
1.1 从过去保存的stage导入
这一节中,各操作使用Sim内置的Python Script运行调试。
从文件系统可以看到,已经有一个stage1.usd保存在EnvFrank里,直接拖到界面中。
在Dynamic Control — Omniverse Robotics documentation给出了基本的读取,控制关节操作。但是,其对应的操作是默认Franka机器人在World下。控制stage1中的Franka机器人,需要修改引用为:
articulation = dc.get_articulation("/World/stage1/Franka")
注意运行前需要启动环境仿真。
测试代码为:
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
print(dc)
articulation = dc.get_articulation("/World/stage1/Franka")
dc.wake_up_articulation(articulation)
joint_angles = [np.random.rand(9) * 2 - 1]
dc.set_articulation_dof_position_targets(articulation, joint_angles)
该代码给Franka的9个自由度进行了随机的一次运动。
1.2 使用代码导入单个Franka机器人
首先清除界面,File->New 或者 New From Stage Template。(或者重启Sim,不然可能会加载不出ground plane)
参考示例 standalone_examples\api\omni.isaac.core\add_frankas.py
from omni.isaac.core import World
from omni.isaac.core.robots import Robot
from omni.isaac.core.utils.stage import add_reference_to_stage
from omni.isaac.core.utils.nucleus import get_assets_root_path
my_world = World(stage_units_in_meters=1.0)
my_world.scene.add_default_ground_plane()
assets_root_path = get_assets_root_path()
asset_path = assets_root_path + "/Isaac/Robots/Franka/franka_alt_fingers.usd"
add_reference_to_stage(usd_path=asset_path, prim_path="/World/Franka_1")
articulated_system_1 = my_world.scene.add(Robot(prim_path="/World/Franka_1", name="my_franka_1"))
运行结果:
1.3 使用代码导入多个Franka机器人
参考示例:standalone_examples\api\omni.isaac.cloner\clone_ants.py
注意,如果在Sim内运行示例代码时ants掉落,可能default ground plane没有加载,建议重启Sim。
将Ant替换为Franka后的代码:
import numpy as np
import omni
from omni.isaac.core import World
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.utils.stage import add_reference_to_stage, get_stage_units
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.cloner import GridCloner
my_world = World(stage_units_in_meters=1.0)
my_world.scene.add_ground_plane()
assets_root_path = get_assets_root_path()
# create initial robot
asset_path = assets_root_path + "/Isaac/Robots/Franka/franka_alt_fingers.usd"
add_reference_to_stage(usd_path=asset_path, prim_path="/World/Franka/Franka_0")
# create GridCloner instance
cloner = GridCloner(spacing=2)
# generate paths for clones
target_paths = cloner.generate_paths("/World/Franka/Franka",8)
# clone
position_offsets = np.array([[0, 0, 0]] * 8)
cloner.clone(
source_prim_path="/World/Franka/Franka_0",
prim_paths=target_paths,
position_offsets=position_offsets,
replicate_physics=True,
base_env_path="/World/Franka",
)
# create ArticulationView
ants = ArticulationView(prim_paths_expr="/World/Franka/.*/torso", name="Franka_view")
my_world.scene.add(ants)
my_world.reset()
for i in range(1000):
print(ants.get_world_poses())
my_world.step()
运行结果:
其中prim_paths_expr="/World/Franka/.*/torso"的错误暂时没管,不清楚影响。
2. 控制单个Franka机械臂
Dynamic Control — Omniverse Robotics documentation
2.1 位置控制
导入和控制指令在Sim中运行时,Script中的指令会被Franka的初始化覆盖,所以在这里使用另一种调试。
(1)将Python Script模式修改 Option->Clear after excute,代码在运行后会自动清除。
(2)输入并运行代码,导入Franka机器人。
from omni.isaac.core import World
from omni.isaac.core.robots import Robot
from omni.isaac.core.utils.stage import add_reference_to_stage
from omni.isaac.core.utils.nucleus import get_assets_root_path
my_world = World(stage_units_in_meters=1.0)
my_world.scene.add_default_ground_plane()
assets_root_path = get_assets_root_path()
asset_path = assets_root_path + "/Isaac/Robots/Franka/franka_alt_fingers.usd"
add_reference_to_stage(usd_path=asset_path, prim_path="/World/Franka_1")
articulated_system_1 = my_world.scene.add(Robot(prim_path="/World/Franka_1", name="my_franka_1"))
(3) 启动仿真
(4)输入并运行控制代码
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/World/Franka_1")
dc.wake_up_articulation(articulation)
joint_angles = [np.random.rand(9) * 2 - 1]
dc.set_articulation_dof_position_targets(articulation, joint_angles)
运行结果:
2.2 单自由度位置控制
接下来的控制调试都可以在(2)导入Franka机器人 的基础上继续。
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/World/Franka_1")
dc.wake_up_articulation(articulation)
dof_ptr = dc.find_articulation_dof(articulation, "panda_joint2")
dc.set_dof_position_target(dof_ptr, -1.5)
2.2 速度控制
from pxr import UsdPhysics
stage = omni.usd.get_context().get_stage()
for prim in stage.TraverseAll():
prim_type = prim.GetTypeName()
if prim_type in ["PhysicsRevoluteJoint" , "PhysicsPrismaticJoint"]:
if prim_type == "PhysicsRevoluteJoint":
drive = UsdPhysics.DriveAPI.Get(prim, "angular")
else:
drive = UsdPhysics.DriveAPI.Get(prim, "linear")
drive.GetStiffnessAttr().Set(0)
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
#Note: getting the articulation has to happen after changing the drive stiffness
articulation = dc.get_articulation("/World/Franka_1")
dc.wake_up_articulation(articulation)
joint_vels = [-np.random.rand(9)*10]
dc.set_articulation_dof_velocity_targets(articulation, joint_vels)
2.3 单自由度速度控制
from pxr import UsdPhysics
stage = omni.usd.get_context().get_stage()
panda_joint2_drive = UsdPhysics.DriveAPI.Get(stage.GetPrimAtPath("/Franka/panda_link1/panda_joint2"), "angular")
panda_joint2_drive.GetStiffnessAttr().Set(0)
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
#Note: getting the articulation has to happen after changing the drive stiffness
articulation = dc.get_articulation("/World/Franka_1")
dc.wake_up_articulation(articulation)
dof_ptr = dc.find_articulation_dof(articulation, "panda_joint2")
dc.set_dof_velocity_target(dof_ptr, 0.2)
2.4 力矩控制
from omni.isaac.dynamic_control import _dynamic_control
import numpy as np
dc = _dynamic_control.acquire_dynamic_control_interface()
articulation = dc.get_articulation("/World/Franka_1")
dc.wake_up_articulation(articulation)
joint_efforts = [-np.random.rand(9) * 1000]
dc.set_articulation_dof_efforts(articulation, joint_efforts)
3. 信息获取
3.1 获取单个Franka状态
from omni.isaac.dynamic_control import _dynamic_control
dc = _dynamic_control.acquire_dynamic_control_interface()
art = dc.get_articulation("/World/Franka_1")
# Get information about the structure of the articulation
num_joints = dc.get_articulation_joint_count(art)
num_dofs = dc.get_articulation_dof_count(art)
num_bodies = dc.get_articulation_body_count(art)
print(num_joints)
print(num_dofs)
print(num_bodies)
# Print the state of each degree of freedom in the articulation
dof_states = dc.get_articulation_dof_states(art, _dynamic_control.STATE_ALL)
print(dof_states)
# print position for the degree of freedom
print(dof_state.pos)
# Get state for a specific degree of freedom
dof_ptr = dc.find_articulation_dof(art, "panda_joint2")
dof_state = dc.get_dof_state(dof_ptr, _dynamic_control.STATE_ALL)
print(dof_state)
print(dof_ptr)
其中,可以在Stage中查看到panda_joint2的具体位置。
3.2 获取物体状态
在这里,可以直接创建一个Cube对象,放置在World中。
我直接调用了自己的环境。
Core [omni.isaac.core] — isaac_sim 2022.2.1-beta.29 documentation
from omni.isaac.core import World
world = World()
world = World(stage_units_in_meters=1.0)
world.scene.add_default_ground_plane()
from omni.isaac.core.objects import DynamicCuboid
import numpy as np
Cube = world.scene.add(
DynamicCuboid(
prim_path = "/World/Cube",
name = "my_cube",
position = np.array([0,0,1]),
scale = np.array([1,1,1]),
color = np.array([1,1,1])))
world.reset()
position, oritentation = Cube.get_world_pose()
linear_velocity = Cube.get_linear_velocity()
angular_velocity = Cube.get_angular_velocity()
print("Position is:", position)
print("Orientation is:", oritentation)
print("Linear velocity is:", linear_velocity)
print("Angular velocity is:", angular_velocity)