惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

马浩飞丨博客

ROS实现多机话题通信 Cloudflare R2 个人图床 ROS2_Rviz2显示URDF模型 ROS2基本命令总结 使用zsh创建更高效的shell环境 Isaac Sim 仿真环境使用简介 Ubuntu设置定时任务 审稿意见撰写流程 Ubuntu 固定USB设备端口名(ttyUSB0->自定义) Git+Github的代码备份与多设备同步 【设备使用】法奥意威 FR5 机械臂 Python 控制 Python识别图片中文字和数字_easyocr 【设备使用】omega.7主手配置与使用方法 【论文笔记】ACT 使用低成本硬件的双手操作模仿学习 HDF5数据文件格式 【仿真实验】robomimic项目复现 【课程笔记】Stanford CS25 V2 - Robotics and Imitation Learning Ubuntu与Window双主机共用一套键鼠 Windows与Ubuntu双系统绑定同一个蓝牙设备(无需重新配对)
Isaac Sim 机械臂逆运动学控制
马浩飞 · 2025-03-07 · via 马浩飞丨博客

参考

前言

由于之前一直在用 Mujoco,现在由于某些原因切换到使用 Isaac Sim中,刚刚接触,记录摸索 Isaac Sim 实现机器人仿真中的一些笔记,供参考。

本次实现机器人逆运动学控制,由于示例中给了关节控制的例程,非常简单,但是当我想实现笛卡尔空间控制时,查阅文档找到了ArticulationKinematicsSolver🔗,但这里的参数需要传入一个kinematics_solver的实例对象,因此又找到了 KinematicsSolver🔗,进而知道需要先创建一个 Lula Kinematics Solver,本文就以Lula Kinematics Solver为基础,实现机械臂逆运动学控制

前提需求

  • 需要安装 WorkStation 版本的 Isaac Sim 4.5.0(Python 版本的 Isaac Sim 似乎确实某些功能,没有【Tool-Robotics-Lula Robot Description Editor】)
  • 已经有机械臂的 urdfusd 模型

1. Lula Robot Description 创建

Lula Kinematics Solver 的文档中可以知道,要想配置 Lula Kinematics Solver,需要有robot_descriptor.yaml 和机器人 urdf 这两个文件。其中 urdf 肯定已经都有了,本节从使用 Isaac Sim 的 Robot Description Editor 创建 robot_descriptor.yaml 开始。

以本文的 UR + 灵巧手为例,共有 6+6=12个关节是可控关节,但 Lula 关注将机器人移动到指定位置,不涉及末端执行器,因此只考虑 UR 的6个关节为活动关节,灵巧手关节视为固定关节。

(1)打开 Lula Robot Description Editor

启动 Isaac Sim:

1
2
cd ~/isaacsim
./isaac-sim.sh

将机器人USD文件拖入到 World 坐标系下。

image.png

打开【Tools -> Robotics -> Lula Robot Description Editor】,会发现窗口左侧出现Lula Robot Description Editor的面板。

然后点击【播放】按钮,Lula Robot Description Editor中会出现【Selection Panel】,在其中的 Select Articulation 位置选择自己的机器人,下方会展开一个 Set Joint Properties 面板。

(2)设置关节属性

按照 UR 机器人的活动关节,依次将 6 个 Joint Status 设置为 Active Joint,默认的关节位置,加速度限制等可以先不修改,后续熟悉了各参数含义再修改也没问题。

灵巧手/夹爪所包含的关节都设置为 Fixed Joint。

image.png

(3)碰撞球(只做运动学可省略)

需要再 Robot Description 文件中添加碰撞球,才能进行RMPFlow运动规划等,具体方法可以参考 Adding Collision Spheres,理论上对于六自由度机械臂,只需要添加Link2和Link4的碰撞就足够了

所有过程还是在Lula Robot Description Editor中完成。

  • 首先在【Selection Panel-Select Link】,选择Link2。
  • 然后再【Link Sphere Editor-Add Sphere】,添加碰撞球,可以拖动位置,右下角属性调整半径,直到全部覆盖当前link为止。

重复以上过程,添加Link4的碰撞球,效果如下:

image.png

(4)导出配置文件

保存 Lula Robot Description 文件:在【Export To File -> Export to Lula Robot Description File】,输入一个本地路径(必须以.yaml结尾),例如/home/mahaofei/Downloads/ur5e_hand.yaml,YAML文件会被保存在目标位置。

保存 XRDF 文件:虽然不知道有什么用,但是也是同样的保存方法。

image.png

2. 笛卡尔空间运动控制代码

参考代码:作用为设置机器人笛卡尔空间位置为position: [0.5, 0, 0.5], orientation: [0, 0, 0]。

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
61
62
63
64
65
66
67
68
69
import sys
import numpy as np
import argparse
from typing import Optional


from isaacsim import SimulationApp
simulation_app = SimulationApp({"headless": False})
from isaacsim.core.api import World
from isaacsim.core.prims import Articulation
from isaacsim.core.utils.stage import add_reference_to_stage, get_stage_units
from isaacsim.core.utils.viewports import set_camera_view
from isaacsim.storage.native import get_assets_root_path
from isaacsim.robot_motion.motion_generation import ArticulationKinematicsSolver, LulaKinematicsSolver
from isaacsim.core.utils.numpy.rotations import euler_angles_to_quats

from isaacsim.core.utils.types import ArticulationAction
from isaacsim.robot.manipulators.manipulators import SingleManipulator
import isaacsim.core.api.tasks as tasks

class KinematicsSolver(ArticulationKinematicsSolver):
def __init__(self, robot_articulation: Articulation, end_effector_frame_name: Optional[str] = None) -> None:

self._kinematics = LulaKinematicsSolver(robot_description_path="asset/isaac_sim/ur5e_hand/ur5e_hand.yaml",
urdf_path="asset/urdf_ros2/ur5e_hand/urdf/ur5e_hand.urdf")
if end_effector_frame_name is None:
end_effector_frame_name = "wrist_3_link"
ArticulationKinematicsSolver.__init__(self, robot_articulation, self._kinematics, end_effector_frame_name)
return


world = World(stage_units_in_meters=1.0)
world.initialize_physics()
world.scene.add_default_ground_plane()
set_camera_view(
eye=[2.0, 1.5, 1.8], target=[0.00, 0.00, 0.81], camera_prim_path="/OmniverseKit_Persp"
)


add_reference_to_stage(usd_path="asset/isaac_sim/ur5e_hand/ur5e_hand.usd", prim_path="/World/ur5e_hand")
ur5e_hand = SingleManipulator(
prim_path="/World/ur5e_hand",
name="ur5e_hand",
end_effector_prim_path="/World/ur5e_hand/wrist_3_link")
init_joint_positions=np.array([0.0, -np.pi/2, np.pi/2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
ur5e_hand.set_joints_default_state([init_joint_positions])
ur5e_hand.initialize()
ur5e_hand.post_reset()
world.scene.add(ur5e_hand)


controller = KinematicsSolver(ur5e_hand)
articulation_controller = ur5e_hand.get_articulation_controller()


while simulation_app.is_running():
world.step(render=True)
if world.is_playing():
if world.current_time_step_index == 0:
world.reset()
actions, succ = controller.compute_inverse_kinematics(
target_position=np.array([0.5, 0, 0.5]),
target_orientation=euler_angles_to_quats(np.array([0, 0, 0])),
)
if succ:
articulation_controller.apply_action(actions)
else:
print("IK did not converge to a solution. No action is being taken.")
simulation_app.close()