本帖最后由 十日无冬 于 2024-9-11 15:00 编辑
地形初始化逻辑
地形的创建函数create_sim位于AzureLoong/gpugym/envs/base/legged_robot.py中,它会在模拟初始化之后,机器人环境创造之前执行,具体代码如下
def create_sim(self):
""" Creates simulation, terrain and evironments
"""
self.up_axis_idx = 2 # 2 for z, 1 for y -> adapt gravity accordingly
self.sim = self.gym.create_sim(self.sim_device_id, self.graphics_device_id, self.physics_engine, self.sim_params)
mesh_type = self.cfg.terrain.mesh_type
if mesh_type in ['heightfield', 'trimesh']:
self.terrain = Terrain(self.cfg.terrain, self.num_envs)
if mesh_type=='plane':
self._create_ground_plane()
elif mesh_type=='heightfield':
self._create_heightfield()
elif mesh_type=='trimesh':
self._create_trimesh()
elif mesh_type is not None:
raise ValueError("Terrain mesh type not recognised. Allowed types are [None, plane, heightfield, trimesh]")
self._create_envs()
通常的,我们创建地形会选用的mesh_type是trimesh,所以在这段代码中,将会执行的是Terrain的初始化和_create_trimesh函数。_create_trimesh函数会初始化仿真环境并设置动静摩擦系数等物理属性,这里就不展开讲解了。
在create_sim方法执行结束后会调用生成机器人的方法,这也意味着地形已经生成完毕,可以添加机器人到地形上了。
地形创建和添加
地形的使用主要包括了如何创建一个地形和如何把这个地形放入仿真环境中两部分,而这两部分都在Terrain类中。
Terrain中有三种添加地形的逻辑,分别为课程地形,选定地形,和随机地形
if cfg.curriculum:
self.curiculum()
elif cfg.selected:
self.selected_terrain()
else:
self.randomized_terrain()
它们和根据env.terrain.curriculum和env.terrain.selected参数选择执行。而这三种地形创建逻辑的创建方式都大同小异,其中最关键的两行代码为:
terrain = self.make_terrain(choice, difficulty)
self.add_terrain_to_map(terrain, i, j)
selected_terrain中创建地形的代码稍有不同,但是创建方式仍然是一样的。
以之前讲解的jump_plat举例,它被创建需要经过三个主要步骤:初始化subTerrain,根据difficulty确定参数,创建地形(修改height_field_raw)。在上一篇中的jump_plat_terrain函数就承担了最后的创建地形的任务。
这些步骤都在make_terrain函数中,它需要两个入参,其中choice表示从众多地形中选择一种,而difficulty表示该地形的难度。make_terrain函数可以被简化如下:
def make_terrain(self, choice, difficulty):
terrain = terrain_utils.SubTerrain( "terrain",
width=self.width_per_env_pixels, length=self.width_per_env_pixels, vertical_scale=self.cfg.vertical_scale, horizontal_scale=self.cfg.horizontal_scale) height = 0.7 * difficulty
jump_plat_terrain(terrain, height = height, platform_size=2.)
return terrain
通过上述的操作一个subTerrain就被创建好了,接下来就要通过add_terrain_to_map函数将其添加到地图上。该函数主要承担了协调地形位置的任务,即将地形放入对应的行列位置上而不重叠,这里就不展开解析了。
实战问题案例
在仿真训练中,经常会遇到各种无法溯源无法解决的问题。在青龙机器人的平地移动训练过程中,我们就发现在mesh_type='plane'的情况下,无法准确的测量足底接触力,非常影响对训练结果的观测和下一步调优的方向确定。
为了解决这一问题,我们选择将mesh_type改为trimesh,但是注释掉了添加地形的函数,这样确保了训练地形仍是平地,且对整体代码的影响最小。
terrain = self.make_terrain(choice, difficulty)
# self.add_terrain_to_map(terrain, i, j)
|