在前幾篇文章中,我們依次講解了如何創建一個地形、如何將地形添加到訓練環境中,并在上一期深入分析了復雜地形之一——臺階地形的創建方式與訓練意義。本文將繼續聚焦復雜地形訓練中另一類代表性地形——斜坡(Slope)與金字塔斜坡(Pyramid Sloped Terrain),結合實際代碼,詳細解析其構建方式與背后的機器人訓練邏輯。
為什么訓練斜坡地形?
在機器人行走能力的訓練體系中,除了臺階,斜坡地形同樣是不可或缺的基本訓練場景。與臺階這種離散高度變化的結構不同,斜坡呈現出的是連續的高度傾斜面,這就要求機器人在前進過程中必須持續調整自身平衡與步態協調,而不是僅僅對付幾級臺階的跳躍或抬腿。
從強化學習的角度來看,斜坡訓練的最大價值在于其對機器人感知與運動控制系統的全局調動能力的挑戰。它能有效提高機器人在實際環境中對復雜地形的適應能力——無論是上坡、下坡、轉彎或非平整路面,都離不開斜坡地形所鍛煉出的綜合運動能力與抗干擾能力。
可以說,一個能夠在斜坡上穩定行走的機器人,將在面對真實世界中各種坡度變化的路況時表現出更強的泛化能力與魯棒性。
基礎臺階地形(Stairs Terrain)
在 Isaac Gym 提供的 terrain_utils.py 腳本中,我們可以找到一個函數 big_slope() 用于構建斜坡地形。其核心代碼如下:
def big_slope(terrain, slope=1):x = np.arange(0, terrain.width)y = np.arange(0, terrain.length)xx, yy = np.meshgrid(x, y, sparse=True)xx = xx.reshape(terrain.width, 1)max_height = int(slope * (terrain.horizontal_scale / terrain.vertical_scale) * terrain.width / 10)terrain.height_field_raw[:, np.arange(terrain.length)] += (max_height * xx / terrain.width).astype(terrain.height_field_raw.dtype)return terrain
表面上看起來這段代碼比臺階地形的構造要復雜,但其實邏輯非常清晰。這里使用的是?NumPy 的稀疏矩陣(sparse meshgrid)來代替之前通過 for 循環實現的高度遞增邏輯,這樣計算效率更高、結構也更清晰。我們根據橫向位置 xx 來生成一個從0逐漸增大的坡度值,并將其賦值給地形數據 height_field_raw,從而形成一個橫向連續的斜坡。
需要特別說明的是,big_slope() 所構建的斜坡尺寸遠遠超出了正常單元地形的限制,它更多用于演示地形構建的方式,而不建議直接作為訓練環境使用。這種超尺度地形在拼接其他單元地形時往往會造成嚴重的不連續性,影響訓練效果,甚至導致機器人頻繁跌倒。
金字塔斜坡地形:更合理的訓練選擇
同樣的,在訓練地形中直接使用斜坡地形也是不可取的,會出現地形不連續的情況導致機器人在訓練中容易摔倒。為了解決普通斜坡在多地形拼接時帶來的突變問題,我們更推薦使用金字塔斜坡地形。它是一種帶有中心平臺的、四面坡度一致的“坡錐體”,相比臺階地形更加平滑、相比單一斜坡又避免了邊界突變問題,是強化學習中常見的一種地形設計方案。多個金字塔斜坡地形接壤如下圖所示:
結構特點:
·?中心帶有一個平坦的平臺,可以緩沖上下坡之間的高度落差;
·?四面斜坡對稱分布,適合多方向拼接;
·?訓練更穩定,可顯著減少因高度突變導致的失敗訓練樣本。
其對應的地形構建函數為 pyramid_sloped_terrain(),代碼如下:
def pyramid_sloped_terrain(terrain, slope=1, platform_size=1.):"""Generate a sloped terrainParameters:terrain (terrain): the terrainslope (int): positive or negative slopeplatform_size (float): size of the flat platform at the center of the terrain [meters]Returns:terrain (SubTerrain): update terrain"""x = np.arange(0, terrain.width)y = np.arange(0, terrain.length)center_x = int(terrain.width / 2)center_y = int(terrain.length / 2)xx, yy = np.meshgrid(x, y, sparse=True)xx = (center_x - np.abs(center_x-xx)) / center_xyy = (center_y - np.abs(center_y-yy)) / center_yxx = xx.reshape(terrain.width, 1)yy = yy.reshape(1, terrain.length)max_height = int(slope * (terrain.horizontal_scale / terrain.vertical_scale) * (terrain.width / 2))terrain.height_field_raw += (max_height * xx * yy).astype(terrain.height_field_raw.dtype)platform_size = int(platform_size / terrain.horizontal_scale / 2)x1 = terrain.width // 2 - platform_sizex2 = terrain.width // 2 + platform_sizey1 = terrain.length // 2 - platform_sizey2 = terrain.length // 2 + platform_sizemin_h = min(terrain.height_field_raw[x1, y1], 0)max_h = max(terrain.height_field_raw[x1, y1], 0)terrain.height_field_raw = np.clip(terrain.height_field_raw, min_h, max_h)return terrain
代碼解析:
金字塔形斜坡的代碼看起來非常復雜,但是有了之前的經驗理解起來應該不會特別費勁,讓我們逐行分析一下:
- 前半部分的邏輯是構造一個四向對稱的坡面。我們通過 meshgrid 生成稀疏坐標矩陣,再將其歸一化到 [0, 1] 區間。乘以最大高度后,就得到了一個圓錐狀的坡度高度圖。
- 接下來的幾行代碼則通過 clip 操作,將中心區域的高度限制為一個平臺區域。這樣可以防止頂部形成尖錐,于是就形成了一個四面坡、頂部平坦的金字塔型斜坡地形。
即便是多個訓練地形拼接,這種結構也能保持坡度過渡的平滑與連續,更適合機器人用于適應性與穩定性的強化訓練。
從模擬到現實的橋梁
臺階與金字塔臺階地形的引入,不僅豐富了訓練環境的復雜性,也幫助我們更接近真實世界中機器人的使用場景。合理設計地形,是讓機器人“聰明地行動”的第一步。結合高質量策略與結構合理的訓練環境,我們將能訓練出在多種真實環境中都能穩定運行的機器人。
至此,我們已完成“青龍機器人訓練地形詳解”系列的四篇講解:
地形創建基礎
從 SubTerrain 的基本構造方法入手,講解如何使用高度圖構建任意三維地形;
添加地形到訓練環境
介紹了如何將添加地形加載進的訓練環境,使地形訓練與強化學習框架有效結合;
復雜地形——臺階詳解
通過離散高度變化訓練機器人精確步態規劃與足部控制;
復雜地形——斜坡與金字塔斜坡
強化連續坡度中的穩定性控制與地形適應能力。
這幾類地形構成了訓練過程中基礎又典型的大部分復雜地形組合,可以幫助實現從“理想環境”向“復雜現實”的訓練過渡。而在未來的開發中,這些地形還可以靈活組合,生成更貼近實際場景的多樣化訓練環境,為強化學習策略提供更全面的挑戰與支持。
OpenLoong 開源社區提供了一個開放交流的平臺,在這里,大家可以共同探討機器人仿真的難點與創新點。歡迎大家在社區一起進行交流。