96SEO 2026-02-19 19:07 17
Sim是英伟达出的一款机器人仿真平台适用于做机器人仿真。

同类产品包括mujocovrep和pybullt等它的主要优势就是可以做并行强化学习仿真这对于提高训练效率是非常有好处的。
sim没有进行并行化训练原因就是如果想用并行化训练单纯使用isaac
sim是搞不出来的还要搭配另外的环境例如2023.1就要使用OmniIsaacGymEnvs或者ORbit。
如果是4.0的用户就是使用isaac
IsaacGymEnvs的安装非常简单按照官方仓库readme安装即可
提供了很多经典的强化学习训练场景最典型的就是Cartpole环境了。
https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs.git
PYTHON_PATH~/.local/share/ov/pkg/isaac_sim-*/python.sh
PYTHON_PATHC:\Users\user\AppData\Local\ov\pkg\isaac_sim-*\python.bat
PYTHON_PATH/isaac-sim/python.sh
按照官方的指示这样就可以把仓库安装好了然后执行就可以测试官方给的例程。
但是注意到这里用的是rlgames作为强化学习的库这并不是一个常见的库实际上英伟达自己在论坛上在推行一个叫做SKRL的库。
SKRL是英伟达自己推荐的一个强化学习库它的优势在于可以无缝衔接英伟达自己的并行仿真环境虽然说训练效果可能不如SB3好但是它适配了啊。
并且在使用多智能体的时候训练速度也是挺快的。
这里需要特别注意的是OIGE的配置文件和rlgame是不一样的具体可以参考官方给出的example在yaml文件中要做一些修改。
把skrl官方提供的yaml文件下载下来并使用它给出的python文件运行就可以将官方给的demo跑起来了。
在环境中设置了4096个agent运行起来还是非常顺畅的训练了1600个回合只花了1分钟左右
另外官方提供了headless可选性当headless设置成True时就不会显示界面这时候运行速度会更加快1600个回合只需要15秒钟不到的时间即可完成。
gym的衔接还是比较OK的至少官方给出的例程运行起来是没什么问题的。
在测试完官方给出的环境后肯定是希望可以测试下自己的环境。
作者自己使用的是UR5机械臂isaac
sim中本身已经提供了这一款机械臂了所以模型直接下载下来就可以是usd格式的模型。
在机器人控制方面官方提供的是RMPFLOW的轨迹规划库但是RMPFLOW本身要配置很多东西官方只提供了UR10的配置文件因此这里我选用了最简单的控制方法。
在网上下载了UR5的urdf文件然后使用ikpy函数库读取urdf文件并进行逆运动学求解把求解出来的关节角度再下发到模型中。
这里提供我写的UR5函数控制类作为参考
UR5,tcpOffset_posenp.array([0,0,0]),tcpOffset_orinp.array([1,0,0,0]),usd_path:
C:\\Users\\Administrator\\AppData\\Local\\ov\\pkg\\gym\\OmniIsaacGymEnvs\\omniisaacgymenvs\\robots\\myrobots\\model\\ur5_modify.usdprint(
self._usd_path)add_reference_to_stage(self._usd_path,
prim_path)super().__init__(prim_pathprim_path,namename,translationtranslation,orientationorientation,articulation_controllerNone,)self.robot_positiontorch.tensor([translation[0],translation[1],translation[2]]).to(cuda)self.tcpoffset_pose
tcpOffset_poseself.tcpOffset_quaternion
initView(self):self._ur5_viewArticulationView(prim_paths_expr/World/envs/.*/UR5,
reset_xform_propertiesFalse)self._ur5_ee_viewRigidPrimView(prim_paths_expr/World/envs/.*/UR5/tool0,
reset_xform_propertiesFalse)def
get_joints(self):jointsself._ur5_view.get_joint_positions()#print(joint,np.round(joints.cpu().numpy(),2))return
get_TCP_pose(self,isworld):pose,rotself._ur5_ee_view.get_local_poses()#获取机器人坐标系下的坐标xyzw?if
isworldTrue:poseposeself.robot_position#
加上机器人坐标系距离原点的位移#print(pose,np.round(pose.cpu().numpy(),4))return
set_joints(self,Joints6D,indices):self._ur5_view.set_joint_positions(Joints6D,
apply_joints(self,Joints6D,indices):joints
ArticulationActions(Joints6D)self._ur5_view.apply_action(joints,indicesindices)def
isworldposeTrue):applyTrue时使用applay
actionisworldposeTrue时转化至世界坐标系positionposition.cpu().numpy()orientionoriention.cpu().numpy()desire_jointsdesire_joints.cpu().numpy()robot_positionself.robot_position.cpu().numpy()if
robot_position####根据tcp坐标反求末端坐标然后求解ikTbase_tcp
mp.qua_wxyz2xyzw_array(oriention)
mp.qua_wxyz2xyzw(self.tcpOffset_quaternion)#
mp.quaternion_conjugate(Qend_tcp)Q_end
mp.quaternion_multiply_array(Qbase_tcp,
mp.rotate_vectors_array(Qbase_tcp,
mp.qua_xyzw2wxyz_array(Q_end)#####
jointresultself.get_iks(position,oriention,desire_joints)jointstorch.tensor(result).float().to(cuda)if
False):self._ur5_view.set_joint_positions(joints)else:joints
ArticulationAction(joints)self._ur5_view.apply_action(joints)def
orientions,q_desires):lenpositions.shape[0]joints[]for
range(len):positionpositions[i]orientionorientions[i]q_desireq_desires[i]jointself.get_ik(position,oriention,q_desire)joints.append(joint)#print(np.round(joint,2))return
ori,q_desire):输入机器人末端的目标位置计算逆运动学关节返回计算用于apply
action的ArticulationActionArgs:pose:
action的ArticulationActiontry:jointself._iksolver.inverse_kinematic_Q(posepose,oriori,q_desireq_desire)return
gym环境。
这个环境编写的教程现在官方的手册是看不到的如果你还是跟我一样使用2023.1版本那么你可以看下旧版本的手册是如何教你写这个的。
omniisaacgymenvs.tasks.base.rl_task
omniisaacgymenvs.robots.articulations.cartpole
omniisaacgymenvs.robots.myrobots.ur5
RigidPrimView,XFormPrimViewclass
None:self.update_config(sim_config)self._max_episode_length
3self._reset_posetorch.tensor(np.array([0,
dtypetorch.float32).to(cuda)RLTask.__init__(self,
sim_config.configself._task_cfg
self._task_cfg[env][numEnvs]self._env_spacing
self._task_cfg[env][envSpacing]self._cartpole_positions
environmentself.get_ur5()self.get_table()self.get_cube()super().set_up_scene(scene)self.ur5.initView()scene.add(self.ur5.get_view())self._cubes
XFormPrimView(prim_paths_expr/World/envs/.*/prop/.*,
reset_xform_propertiesFalse)scene.add(self._cubes)def
self.world.is_playing():returnreset_env_ids
self.reset_buf.nonzero(as_tupleFalse).squeeze(-1)#只获取没有复位的环境if
0:self.reset_idx(reset_env_ids)#TODO:复位的环境动作清零#获取当前位置joints
self.ur5.get_joints()self.cube_pos,
self._cubes.get_local_poses()self.tcp_pos,self.tcp_rotself.ur5.get_TCP_pose(isworldTrue)#设置动作增量targetself.tcp_posactions*0.05#执行动作self.ur5.set_pose(target,
applyTrue)#self.ur5.set_pose(self.cube_pos,
self._cubes.get_local_poses()self.tcp_pos,self.tcp_rotself.ur5.get_TCP_pose(isworldTrue)#计算与目标的误差作为关节角度pos_error
self.tcp_pospos_errortorch.clip_(pos_error,-1,1)self.obs_buf[:,0]
pos_error[:,0]self.obs_buf[:,1]
pos_error[:,1]self.obs_buf[:,2]
bufferdistancestorch.norm(self.cube_pos-self.tcp_pos,dim1)#rewardtorch.where(distances0.002,50,0)#reward
reward)#rewardtorch.where(distances
reward-0.1reward-distancesreward
0)#logging.warning(reward)#reward50self.rew_buf[:]
dim1)distance_xabs(self.cube_pos[:,0]-self.tcp_pos[:,0])distance_yabs(self.cube_pos[:,1]-self.tcp_pos[:,1])distance_z
2])resetstorch.where(distances0.005,1,0)reset_env_ids
resets.nonzero(as_tupleFalse).squeeze(-1)#只获取没有复位的环境if(len(reset_env_ids)0):logging.warning(msg(成功个数:,len(reset_env_ids)))resets
self._reset_pose.repeat(self._num_envs,
1)#(6-(envs,6))self.ur5.set_joints(reset_tensor,
indicestorch.arange(self._num_envs))def
env_ids):self.update_cube(env_ids)num_resets
0.2cube_poseself.cube_posegoalcube_posetorch.tensor(noise).cuda()goalgoal-self.ur5.robot_positionintijointnp.repeat(self._reset_pose.cpu().numpy()[np.newaxis,
axis0)jointsself.ur5.get_iks(goal.cpu().numpy(),self.origin_cube_orientation.cpu().numpy(),intijoint)jointstorch.tensor(joints,
dtypetorch.float32).cuda()indices
env_ids.to(dtypetorch.int32)self.ur5.set_joints(joints,
bookkeepingself.reset_buf[env_ids]
0################################def
Cartpole(prim_pathself.default_zero_env_path
translationself._cartpole_positions)#
fileself._sim_config.apply_articulation_settings(Cartpole,
get_prim_at_path(cartpole.prim_path),
self._sim_config.parse_actor_config(Cartpole))def
get_ur5(self):self.ur5UR5(prim_pathself.default_zero_env_path
translationself._cartpole_positions,ik_urdfPathE:\\1_Project\\py\\paper3\\sim-force2-real\\model\\ur5new\\ur_description-main\\ur_description-main\\urdf\\ur5.urdf)def
get_table(self):usdpathC:\\Users\\Administrator\\AppData\\Local\\ov\\pkg\\gym\\OmniIsaacGymEnvs\\omniisaacgymenvs\\robots\\myrobots\\model\\table\\table.usdadd_reference_to_stage(usdpath,
prim_pathself.default_zero_env_path
VisualCuboidcube_posenp.array([0.5,
1.00])cube_orientationnp.array([0.0000000000,
0.0000000])self.origin_cube_posetorch.tensor(np.tile(cube_pose,
1))).cuda()self.origin_cube_orientationtorch.tensor(np.tile(cube_orientation,
1))).cuda()VisualCuboid(prim_pathself.default_zero_env_path
/prop/prop_0,namefancy_cube,positioncube_pose,orientationcube_orientation,scalenp.array([0.05015,
0.3).cuda()self.cube_poseself.origin_cube_pose[indices]random_offsetsself._cubes.set_local_poses(self.cube_pose,self.origin_cube_orientation,indices)def
set_task_parameters(self):self.init_error_xyz0.05
skrl.resources.preprocessors.torch
clip_actionsFalse,clip_log_stdTrue,
max_log_std2):Model.__init__(self,
device)GaussianMixin.__init__(self,
nn.Sequential(nn.Linear(self.num_observations,
self.num_actions),nn.Tanh())self.log_std_parameter
nn.Parameter(torch.zeros(self.num_actions))def
role):actionself.mean_layer(self.net(inputs[states]))logself.log_std_parameteroutput{}return
clip_actionsFalse):Model.__init__(self,
device)DeterministicMixin.__init__(self,
nn.Sequential(nn.Linear(self.num_observations
self.net(torch.cat([inputs[states],
load_omniverse_isaacgym_env(task_nameUr5Insert)
RandomMemory(memory_size1000000,
https://skrl.read***docs.io/en/latest/api/agents/sac.html#models
StochasticActor(env.observation_space,
https://skrl.read***docs.io/en/latest/api/agents/sac.html#configuration-and-hyperparameters
cfg[experiment][write_interval]
cfg[experiment][checkpoint_interval]
SAC(modelsmodels,memorymemory,cfgcfg,observation_spaceenv.observation_space,action_spaceenv.action_space,devicedevice)#
SequentialTrainer(cfgcfg_trainer,
在这里我使用的是SAC并且在yaml配置文件里面改了很多参数最终才把整个程序跑起来并成功训练。
不得不吐槽一下SKRL对于这么一个简单的任务竟然对超参数那么敏感我使用PPO甚至训练了5W步都不收敛跟SB3比还是有点差距的。
这里我只设置了32个agentSAC大概在1000步左右就学会了怎么reach。
1000步的时间大概花了1分半钟。
不得不说这个速度相比官方的cartpole例程1024个agent相比是要慢非常多的。
这其中是什么原因我也不知道速度慢了差不多30倍。
首先训练速度并没有快很多1分钟1600步左右其次这个训练结果跟并行训练比确实差很多。
32个agent在1000回合左右reward就已经上去了并且有智能体已经能够陆续完成任务。
但是只有一个agent的时候甚至训练到了
然后可以测试下把机器人的数量加到512是个什么情况把机器人加到512后软件启动有了明显的卡顿等了1分钟界面才显示出来。
gym在并行训练上确实是有很强大的效果并且效率提升很大。
但是在自己编写环境时速度远远不及官方的例程好甚至会有点卡顿。
机器人模型是多关节的而cartpole只是2关节的关节数会对仿真速度造成影响。
GYM环境给你并行出来很多个机器人但是你在做数据处理的时候也非常考验你的编程能力。
例如这里我没有使用官方的控制库rmpflow而是选择了自己求解IK我写的是for循环求解IK那么每多一个机器人就会多求一次ik这里就会造成大量的时间消耗。
目前我还没有找到可以批量求IK的库。
此外不单是IK如果涉及到图像处理例如想使用opencv做一些边缘提取的话那么这种for循环更是灾难。
3.但尽管如此看到只有1个机器人的时候运行速度也远不如官方给的carpole例程
sim实际上nvida很早就推出了近些年也一直有在更新。
但每次更新出来bug都很多并且每次版本迭代API变化都很大。
并行仿真环境一开始先是isaac
gym接着又是orbit。
现在4.0之后前面三个版本直接弃用全部移植到isaac
sim的优势在于视觉的仿真正如官方给出的demo视觉的仿真可以做到非常的逼真这对于做视觉操作任务的研究无疑是非常好的特别是在做视觉的sim2real以及数据合成这一块。
但是力传感器的仿真一直存在问题不知道4.0会不会好一些。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback