Motion Planning Networks

本博客同時發佈於個人主頁:www.doctorsrn.cn

內容說明

主要介紹一篇使用深度學習方法去實現Motion Planning的論文,並將作者開源的實現代碼在本地進行復現,復現過程中涉及到Docker的使用,Colaboratory和Kaggle Kernel環境的使用等內容。主要內容包括兩部分:

  • 介紹論文Motion Planning Networks的主要內容
  • 在本地Docker pytorch環境中利用作者的開源代碼和提供的Simple 2D情況的數據集,訓練模型,並測試模型在2維情況下Motion Planning的效果,此外該部分還包括如下內容:
    • Docker容器中GUI程序的運行
    • 在Google Colaboratory環境中訓練該模型
    • 在Kaggle Kernel環境中訓練該模型

測試主機的環境是:

  • 系統:Ubuntu16.04
  • 顯卡:1060 6G

Paper: Motion Planning Networks(arxivgithub)

摘要

隨着運動規劃維度的增加,RRT*、A*、D*等算法效率都將降低,本文提出了一種不論障礙物形狀,端對端生成無碰撞路徑的網絡–Motion Planning Networks,簡稱MPNet
MPNet包含如下結構:

  • 一個Contractive Autoencoder(收縮式自動編碼器,CAE),對工作空間進行編碼
  • 一個前饋神經網絡,該神經網絡使用編碼的工作空間、起始和目標點配置,端對端生成可行的運動軌跡,供機器人進行跟蹤

作者測試了質點、剛體、7自由度機械臂在2D和3D環境下的規劃問題,結果表明MPNet效率很高,且泛化能力很強。MPNet的運算時間始終小於1秒,明顯低於現有的最先進的運動規劃算法。此外,在一個場景訓練的MPNet,可以藉助少量數據通過遷移學習,快速適應新場景。

簡介

機器人運動規劃意義重大,應用廣泛。開發了很多計算效率高的基於採樣的規劃算法–RRT,RRT*,P-RRT*。
本文提出了一種基於深度神經網絡(DNN)的迭代運動規劃算法–MPNet。
MPNet由兩部分構成:

  • 障礙物空間編碼器----Contractive Autoencoder:將障礙物點雲編碼至低維隱空間(latent space)
  • 路徑規劃器----前饋神經網絡:在給定t時刻機器人的配置、目標點配置和障礙物編碼後的隱空間時,預測t+1時刻機器人的配置

經過訓練後,MPNet可以與新的雙向迭代算法結合使用,來生成可行的軌跡。

神經網絡在Motion Planning相關工作

  • Hopfield網絡
  • Deep Reinforcement Learning
  • Lightning Framework

問題定義

QQ表示長度爲N(NN)N(N \in \mathbb{N})的的有序表,序列{qi=Q(i)}iN\{ q_i = Q(i) \}_{i \in \mathbb{N}}表示從iNi \in \mathbb{N}QQ中第ii個元素的映射。並且論文中Q(end)Q(end)Q.length()Q.length()分別表示集合QQ的最後一個元元素和集合中元素的個數。
XRdX \subset \mathbb{R}^d表示給定的狀態空間,dd是狀態空間的維數,且d2d \geq 2,障礙物空間和非障礙物空間分別定義爲XobsXX_{obs} \subset X, Xfree=X\XobsX_{free} = X \backslash X_{obs}。設初始狀態爲xinitXfreex_{init} \in X_{free},目標區域爲XgoalXfreeX_{goal} \subset X_{free}
設有序表τ\tau表示一條非負和非零長度的路徑。如果路徑τ\tau連接起xinitx_{init}xXgoalx \in X_{goal},則該路徑是可行路徑,即τ(0)=xinit\tau(0) = x_{init},τ(end)Xgoal\tau(end) \in X_{goal}且都位於非障礙物空間XfreeX_{free}中。
基於上述定義,運動規劃問題描述爲:給定三元組{X,Xfree,Xobs}\{ X,X_{free},X_{obs} \},出事狀態點xinitx_{init}和目標區域XgoalXfreeX_{goal} \subset X_{free},找到一條可行路徑τXfree\tau \in X_{free}滿足τ(0)=xinit\tau(0) = x_{init}, τ(end)Xgoal\tau(end) \in X_{goal}

MPNet

MPNet是一個基於神經網絡的運動規劃器,由兩個階段組成。第一階段對應於神經模型的離線訓練。 第二個對應於在線路徑生成。
pic1_4

離線訓練

兩個神經網絡模型:

  • Contractive AutoEncoder (CAE)
  • Deep Multi-Layer Perceptron(DMLP)深度多層感知器
  1. Contractive AutoEncoder (CAE)
    將障礙物空間XobsX_{obs}編碼至特徵空間ZRmZ \in \mathbb{R}^m,編碼函數,解碼函數,編碼器目標函數
  2. Deep Multi-Layer Perceptron(DMLP)
    給定Z,xt,xTZ,x_t,x_T,預測下一時刻狀態x^t+1Xfree\hat{x}_{t+1} \in X_{free}
    使用RRT*算法在不同環境下生成的可行路徑數據來訓練DMLP,路徑的形式是元組τ={x0,x1, ,xT}\tau^* = \{ x_0, x_1, \cdots, x_T\}
    目標函數是誤差均方差函數(MSE)

在線路徑規劃

提出了一種啓發式增量雙向路徑生成算法,生成連接起始狀態和目標狀態的端到端可行路徑,路徑生成算法:
pic1_1
pic1_2
pic1_3

  1. Obstacles Encoder f(xobs)f(x_{obs})
    離線階段訓練的CAE
  2. DMPL
    離線階段訓練的DMPL
  3. Lazy States Contraction (LSC)
    冗餘點收縮。在給定路徑τ\tau時,對路徑進行優化,將未連接但可以直接相連的路徑點進行連接。
  4. Steering
    steerTo函數在給定兩個狀態點x1,x2x_1,x_2作爲輸入下,檢查由兩個狀態點連接成的路徑是否位於無障礙物空間。障礙物檢測的路徑點可以寫成:τ(δ)=(1δ)x1+δx2,δ[0,1]\tau(\delta) = (1-\delta)x_1 + \delta x_2, \delta \in [0,1].
  5. isFeasible
    給定路徑τ={x0,x1, ,xT}\tau = \{ x_0, x_1, \cdots, x_T\},判斷該路徑是否可行
  6. Neural Planner
    一種基於DMLP的啓發式雙向增量路徑生成方法,即圖中的算法2
  7. Replanning
    圖中的算法3.給定路徑τ={x0,x1, ,xT}\tau = \{ x_0, x_1, \cdots, x_T\},若檢查出該路徑中存在連續兩點是不可連接的,使用下面的方法重新對這兩點進行規劃:
    • Neural Replanning
    • Hybrid Replanning

實現細節

  1. 數據集的生成
    將一些四邊形方塊作爲障礙物隨機放置在40x40或者40x40x40的區域中成爲工作空間,分別用來生成2維或3維的數據集。障礙物放置位置不同,就會生成不同的工作空間。
    起始點和終止點的生成: 在工作空間的無障礙物空間中隨機採樣nn個(nNn \in \mathbb{N})狀態點組成一個表,再從該表中隨機取出一對狀態點組成起始點和終止點對。
    路徑生成: 利用RRT*算法生成起始點和終止點之間的可行路徑,用於訓練和測試。

    具體細節:針對s2D、c2D、c3D情況,均生成110個不同的工作空間,在每個工作空間中再使用RRT*算法生成5000個無障礙物路徑。
    訓練集:取100個工作空間,將每個空間中4000個路徑作爲訓練集。
    測試集:有兩種:第一種,取訓練集100個工作空間,將每個空間中未用於訓練的200個路徑作爲測試集;第二種,取10個未用於訓練的工作空間,將每個工作空間中2000個未用於訓練的路徑作爲測試集。
    對於Baxter的訓練,使用簡單環境,不包含障礙物,即不需要障礙物編碼,直接使用50000個可行路徑訓練DMLP模型。

  2. 模型結構

  • Contractive AutoEncoder (CAE)結構:編解碼函數均由三個線性層和一個輸出層構成,線性層激活函數爲PReLU,解碼單元和編碼單元的結構剛好相反,下面主要介紹編碼單元結構:

    • 輸入:1400×d1400 \times d大小的點雲向量,1400是指每個維度的點數,dN2d \in \mathbb{N}_{\ge2}是指工作空間的維度。
    • 對於2D工作空間,輸入爲1400x2維,三個線性層分別包含512、256、128個隱神經元,輸出爲28維。即編碼後的障礙物表示爲ZR28Z \in \mathbb{R}^{28}
    • 對於3D工作空間,輸入爲1400x3維,三個線性層分別包含786、512、256個隱神經元,輸出爲60維。即編碼後的障礙物表示爲ZR60Z \in \mathbb{R}^{60}
    • 2D情況CAE模型構建代碼:
    self.encoder = nn.Sequential(nn.Linear(2800, 512),nn.PReLU(),nn.Linear(512, 256),nn.PReLU(),nn.Linear(256, 128),nn.PReLU(),nn.Linear(128, 28))
    
  • Deep Multi-layer Perceptron (DMLP)結構:是一個12層的深度神經網絡。

    • 輸入: 質點或者剛體情況,輸入值爲編碼後的障礙物ZZ、起始點和終止點配置向量三者的拼接。2D質點、3D質點和剛體的配置維度分別爲2、3、3,對於Baxter機器人沒考慮障礙物,所以輸入只包含起始點和終止點配置向量的拼接,Baxter的配置空間維度爲7。
    • 中間層:前9層每一層均爲線性層,激活函數爲PReLU,使用Dropout,每一層神經元個數分別爲:1280, 1024, 896, 768, 512, 384, 256, 256, 128;第10層和第11層不使用Dropout,神經元個數分別爲64和32;第12層,即輸出層,其輸出的維度是配置空間的維度,比如2D質點配置空間的維度爲2。
    • 2D情況DMLP模型構建代碼:
    self.fc = nn.Sequential(
          nn.Linear(input_size, 1280),nn.PReLU(),nn.Dropout(),
          nn.Linear(1280, 1024),nn.PReLU(),nn.Dropout(),
          nn.Linear(1024, 896),nn.PReLU(),nn.Dropout(),
          nn.Linear(896, 768),nn.PReLU(),nn.Dropout(),
          nn.Linear(768, 512),nn.PReLU(),nn.Dropout(),
          nn.Linear(512, 384),nn.PReLU(),nn.Dropout(),
          nn.Linear(384, 256),nn.PReLU(), nn.Dropout(),
          nn.Linear(256, 256),nn.PReLU(), nn.Dropout(),
          nn.Linear(256, 128),nn.PReLU(), nn.Dropout(),
          nn.Linear(128, 64),nn.PReLU(), nn.Dropout(),
          nn.Linear(64, 32),nn.PReLU(),
          nn.Linear(32, output_size))
    

    其中input_size和output_size值分別爲32,2。

  1. 超參數的設置
    使用Adagrad優化器,學習率0.1,Dropout參數爲0.5,動量項參數爲0.001。用於訓練的CAE模型的工作空間有30000個。

實驗結果

MPNet計算時間的平均值小於1s,與Informed-RRT*和BIT*算法相比,MPNet速度分別是它們的40和20倍。

討論

  1. Dropout導致的隨機性
    對於DL,在測試階段或者在線執行階段,通常做法是關閉Dropout。但是Dropout對路徑在線生成s是有利的,因爲Dropout顯著提升了本模型的性能。
    出現上述情況的原因分析:DMLP在重規劃階段,由Dropout引入的隨機性使DMPL可以生成與之前不同的路徑,下圖就說明了這種特徵:
    pic1_5
    同樣的起點和終點,DMLP生成了多條不同的路徑,這種能力有助於路徑重規劃的成功,因此添加Dropout對MPNet的性能是有利的。

  2. 遷移學習
    pic1_6

  3. 完備性
    因爲MPNet先使用DMPL進行規劃得到粗略的路徑,若該路徑不可行則調用重規劃方法。所以MPNet的完備性取決於重規劃方法是否完備,而重規劃方法採用了混合經典規劃方法,所以進一步可得MPNet的完備性取決於所採用的經典方法的完備性。如果經典方法採用A*算法,則MPNet是完備的;因爲本文采用的是RRT*算法,所以MPNet是概率完備的。

  4. 計算複雜度
    。。。

結論和未來工作

未來工作:

  • 將MPNet應用於動態環境,因爲其有良好的泛化能力
  • 增加對工作空間編碼的神經注意(neural attention)

代碼實現和復現

論文作者開源的代碼可在github上下載,開源代碼使用python2和pytorch實現,沒有提供訓練好的模型。

搭建本地開發環境

開源代碼使用pytorch實現,使用Docker快速搭建pytorch環境,當然也可以通過其他方式安裝pytorch環境。
Docker的使用,包括安裝、gui的支持等可以參考另一篇博客:Moveit Docker的安裝與配置過程
使用Docker建立pytorch環境,步驟如下:

  • 拉取pytorch官方Docker鏡像:docker pull pytorch/pytorch:latest
    pytorch鏡像略大,需要等一會才能下載完,下載結束後通過docker image ls可以看到下載完成的鏡像
  • 創建pytorch鏡像的Docker容器:
    xhost +local:root
    nvidia-docker run -it \
      -v /home/srn/SRn/MPNet:/workspace \
      --env="DISPLAY" \
      --env="QT_X11_NO_MITSHM=1" \
      --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
      pytorch/pytorch:latest bash
    
    建議新建bash文件,如run.bash,將以上命令存入bash文件中,並給定執行權限chmod +x run.bash,然後運行./run.bash
    注意: 以上命令將本地MPNet代碼目錄掛載到Docker容器中,根據自己代碼位置需要修改MPNet代碼目錄。
  • 進入容器後安裝matplotlib庫:
    apt-get updata
    pip install matplotlib -i https://pypi.douban.com/simple 
    apt-get install python3-tk
    

對開源代碼進行一些修改

本次主要測試MPNet部分代碼,對訓練數據集生成部分的代碼之後在測試。由於MPNet代碼使用python2編寫,docker建立的環境是python3,所以要做一些修改,主要有下面的一些修改:

  • 修改print函數: 使用python的2to3函數進行修改: 2to3 -w python_file
  • 修改整除符號///
  • 修改包含zip函數的部分,比如data_loader.py中的data=zip(dataset,targets),修改爲data=list(zip(dataset,targets))

以上修改主要是因爲python2和python3之間的差異導致的。
此外要註釋掉某些python文件中的import nltk語句,這條語句導入的庫並沒有用上,docker容器中也沒有安裝這個庫,所以註釋掉。

訓練模型

MPNet主要有兩部分構成:

所以要分別訓練兩個模型。主要針對2維情況下MPNet的工作進行測試,訓練用的數據集使用論文作者分享的simple2D數據集,當然你也可以通過數據集生成代碼自己去生成訓練集,包括3維空間的規劃,這是之後的工作。
將simple2D數據集下載到本地,並解壓。這是本機的文件結構圖:
pic2_1
目錄中除了原始文件,其他文件有些是2to3生成的,有些是訓練生成的模型文件。其中data/dataset目錄是解壓數據集後的目錄。

訓練CAE

按照上面的數據集修改MPNet/AE/data_loader.py中的數據路徑,也可以修改CAE.py中的訓練參數,然後開始訓練CAE模型:
python MPNET/AE/CAE.py
這一步訓練耗時較短,大概15分鐘。

訓練DMLP模型

修改MPNet/data_loader.py中的數據路徑和上一步生成的CAE模型數據的路徑,也可以修改train.py中的訓練參數,然後開始訓練DMLP模型:
python MPNET/train.py
這一步耗時較久,訓練300個epoch在本機需要13個小時。在300個epoch後,手動終止了訓練。

測試MPNet的效果

完成上面兩步訓練後就可以測試MPNet的效果了,修改neuralplanner.py中模型的路徑參數。由於原代碼中沒有可視化函數,自己寫了一個2維情況的可視化函數,主要是繪製出障礙物點雲、RRT*生成的路徑和MPNet生成的路徑。可視化函數內容爲:

def visualize_function(i, j, g_path, a_path, a_path_length):
	'''
	i: i-th obstacle
	j: j-th path generated by rrt*
	g_path: path generated by mpnet
	a_path_length: actual path length
	'''
	dataPath = '/workspace/data'

    #繪製障礙物點雲圖
	temp=np.fromfile(dataPath+'/dataset/obs_cloud/obc'+str(i)+'.dat') #len=2800
	ob = temp.reshape(len(temp)//2,2) 
	#plt.plot([x[0] for x in ob], [x[1] for x in ob])
	plt.scatter([x[0] for x in ob], [x[1] for x in ob])

	#繪製生成的路徑
	plt.plot([p[0] for p in g_path], [p[1] for p in g_path],color='red',linewidth=2.5,linestyle='-')

    
	#繪製實際路徑
	plt.plot([a_path[a][0] for a in range(a_path_length)],
	[a_path[a][1] for a in range(a_path_length)])
	
	plt.show()

下面是測試顯示的效果圖:
pic2_2
pic2_3
圖中藍色塊是障礙物點雲,藍色路徑是原始RRT*算法生成的路勁,紅色路徑是MPNet生成路勁,可以看到效果還不錯,更多數據之後再測試。

以上修改後的代碼可以參看上傳到github的代碼。

調試遇到的bug彙總

  1. mpnet的python代碼使用Tab縮進,如果自己修改代碼使用空格縮進,混用空格和Tab縮進會導致python代碼運行出現如下錯誤:

IndentationError: unindent does not match any outer indentation level

解決辦法: 統一使用空格縮進,在vscode中使用ctrl+shift+p調出命令窗口,輸入關鍵字“space”,找到“Convert Indentation to Spaces”功能,使用該功能就可以將當前python代碼中的Tab縮進轉換爲空格縮進。

  1. Docker使用pytorch官方提供的鏡像,在安裝matplotlib時(pip install matplotlib -i https://pypi.douban.com/simple),出現如下錯誤:

import _tkinter if this fails your python may not be configured for tk
ImportError: libX11.so.6: cannot open shared object file: No such file or directory

大概原因還是docker中gui顯示的問題,google之後使用下面命令解決:
apt-get install python3-tk
重要參考網站:
https://stackoverflow.com/questions/5459444/tkinter-python-may-not-be-configured-for-tk
https://stackoverflow.com/questions/25281992/alternatives-to-ssh-x11-forwarding-for-docker-containers
https://linuxmeerkat.wordpress.com/2014/10/17/running-a-gui-application-in-a-docker-container/

To be continued…

end of file

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章