ロボットアーム制御：環境構築編～Moveit2を動かしてみた

# はじめに
ずっと気になっていたMoveit2の確認をしていきたいと思います。
動作サンプルとしてロボットアームは、ユニバーサルロボット社（以下、UR）のUR5eを使う予定です。

ロボットアームはミリメートル精度が要求されるため、一定間隔で周期制御する必要があります。

例えば、URの動作環境では、2msの周期制御が推奨されており、Ubuntuのカーネルをリアルタイムカーネルにする必要があります。

今回は、リアルタイムカーネルにするまでに、いくつかハマったポイントがあったので、備忘録として残します。

# 構築した環境
開発しているPCが古くなったので、新しいPCを購入しました。
NVIDIAのグラフィックカードが搭載されているPCは、筐体が大きくて重いので、（個人的にも好きな…）AMD Radeon搭載の小さくて軽いPCを購入しまた。<br>
今回、構築した内容です。

|項目|内容|
|----|----|
|チップセット|AMD Ryzen 9 7940HS（内蔵GPU: Radeon 780M）<br>[AMD公式スペック表][link-AMD]|
|Ubuntu| 22.04.2 LTS ([公式Downloadサイト][link-ISO]）|
|Kernel| 6.2.16-rt3 ([要：Kernelコンパイル][link-UR-Realtime])|
|ROS2| Humble ([公式サイト][link-ROS2])|

購入したPCが「AMD Ryzen 9 7940HS w/Radeon 780M Graphics」のチップセット（以下、7940HS）で、2023年6月発売の新しいチップセットです。

結論から言うと、Ubuntu22.04で動きました。
Webで調べるとサスペンドからの復帰がうまくできない事例があったので、サスペンドの設定はOFFにしています。
# 事前準備
事前に必要なものとしては、以下の２つです。
1. ISOイメージ
　https://jp.ubuntu.com/download よりダウンロードしたもの。<br>
2. USBメモリ
8Gbyte以上のものが良いです。
  インストールメディアの作り方は、公式に記載してあります。
    https://ubuntu.com/tutorials/create-a-usb-stick-on-ubuntu#1-overview

# Ubuntuインストール作業
インストール作業で苦労したポイントを記載します。

1. [インストール画面の下1/3がはみ出て見えない](#インストール画面の下1/3がはみ出て見えない)
1. [グラフィックドライバの認識](#グラフィックドライバの認識)
1. [リアルタイムカーネル作成](#リアルタイムカーネル作成)

## 苦労したポイント
### インストール画面の下1/3がはみ出て見えない
　推測ですが、内蔵グラフィックが新しいのでunknownなカードになって、モニターの出力解像度が640x480になったようです。しかし、インストールアプリは、800x600の解像度で出力しているようで、**[続行」ボタンが見えないのでマウスで選択できない。**

（選択ボタンが見えない）インストール時のイメージ
![インストールイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113036/a027bf5a-f21c-9592-c1b4-496fb19a3e15.png)

「Ubuntu Server 22.04.2 LTS」はGUIがないので、これをインストールした後にGUIをインストールする方法もありますが、めんどくさがり屋の私は強引にインストールすることにしました。

[公式のチュートリアル][Link-Ubuntu-Install]の画面を見ながら、実際の画像を脳内変換して、**Tabキーで見えない位置のボタンにフォーカス移動させリターンで選択**してなんとかインストールすることができました。

インストール後は、Full HDの解像度で出力されています。GUIの操作も問題ありません。また、Wifi/Bluetooth/Ethernetも認識されています。

### グラフィックドライバの認識

このままでも問題ないのですが、グラフィック描画のハードウェアアクセラレーションが有効になっていません。技術者としては（個人的に…）許せない状況です。

Ubuntuの「設定」→「このシステムについて」を選択して、「グラフィック」の項目に「**llvmpipe**」の文字があったら、ハードアクセラレーションは有効になっていません。

[AMD公式のDriver][link-AMD-Driver]を探したのですが、まだサポートされていないようです。

#### カーネルアップデート
Kernelのアップデートで、サポートされるグラフィックチップセットが増えて7940HSがサポートされていることを期待します。
Ubuntuインストール直後のkernelバージョンは5.19でした。
下記コマンドを実行するとインストールできるカーネルが表示されます。

```[sh]
sudo apt-get update
sudo apt-cache search linux-image-
...
linux-image-6.2.0-26-generic --- 説明文
```

上記リストのgeneric中で一番新しいkernel6.2.0-26をインストールします。

注意点としては、imageとheaderとmodulesを入れるということです。
imageだけだとEthernetなどの周辺機器のドライバが入らないので、何もできなくなります。

```[sh]
sudo apt-get install linux-image-6.2.0-26-generic linux-headers-6.2.0-26-generic linux-modules-6.2.6-26-generic  
```

再起動して端末から以下のコマンドを実行して6.2の表示が出たら成功です。
```[sh]
uname -r
```

うまく起動しないときは、タイミングはシビアですがBIOS画面が出たあとにESCキーを押すとGrubメニューが表示されます。そのメニューからインストールされているKernelを選択できます。<br>
インストール前のKernelをカーソルキーで選択してリターンすれば、カーネルインストール前の状態になります。

#### グラフィックドライバの確認
kernel6.2にして、Ubuntuの「設定」→「このシステムについて」を確認すると、以前とは別のdriverが認識されています。<br>

**GFX1103(gfx1103,LLVM 15.07,DRM 3.49,…)**

Webで調べてると、
AMDのグラフィックカードのアーキテクチャ(RDNAと呼ばれている）が第3世代のものはGFX1103と表示されるようです。
今回のPCのグラフィックはRadeon 780MでRDNAの第３世代アーキテクチャなので、認識されているようです。
（公式のAMD Driverがサポートされれば、Radeon 780Mと型番が表示されると思います。）

簡単なOpenGLベンチマークを動かしてみます。
以下でインストールして、実行してみます。
```[sh]
sudo apt-get install glmark2
glmark2
```

実行結果のスコアは、「8054」でした。
参考： スコア比較
https://openbenchmarking.org/test/pts/glmark2-1.4.0

上記のスコアを比較してみるとハードアクセラレーションは効いているみたいです。

本当は、CUDA環境のAMD版である[ROCm][link-AMD-ROCm]も入れたいところですが、またの機会にします。

### リアルタイムカーネル作成
リアルタイムカーネルの作成は、URの[RTDEドライバ][link-UR-Realtime]のページを参考にしています。
注意点としては**ビルドには時間がかかります。** 
今回のPCでは１時間ぐらいでした。古いPCなどは6時間以上かかる場合があるので気を付けてください。<br>

[手順][link-UR-Realtime]を見るとβ版ですがUbuntu22.04からは、コンパイルしなくてもリアルタイムカーネルにできる手順があるようです。
β版なので、コンパイルする方法で構築しました。<br>

#### ハマりポイント
1. pemファイルの削除
カーネルのコンパイルする前に、「.config」ファイルを修正する必要があります。 
具体的には、X.509証明書のpemファイル名が設定してある箇所を「""」にするのですが、全pemのファイル名を「""」にしていました。<br> 
そうすると、コンパイルの最後で通りません。 原因を見つけるのにかなり苦労しました。
**削除するのは、「debian/canonical-certs.pem」だけです。**
よく読むと[手順][link-UR-Realtime]にも記載してありました。

2. 再コンパイル
カーネルのコンパイルがエラー等で止まってしまうと、再ビルドしたときエラーになります。
再ビルドするときは、以下のファイルを削除すれば、ビルドできます。

```[sh]
rm vmlinux-gdb.py
```

#### 手順の記載とは違うもの
カーネルのソースは以下ものをDownloadしました。

```[sh]
curl -SLO https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.2.16.tar.xz
curl -SLO https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.2.16.tar.sign
curl -SLO https://www.kernel.org/pub/linux/kernel/projects/rt/6.2/patch-6.2-rt3.patch.xz
curl -SLO https://www.kernel.org/pub/linux/kernel/projects/rt/6.2/patch-6.2-rt3.patch.sign
```

プロキシ環境は、bashにhttp_proxy,https_proxyの環境変数がセットしてあれば上記のコマンドで取得できます。

後は、[手順のページ][link-UR-Realtime]でダウンロードする部分を上記に置き換えて実施すれば、コンパイル＆インストールできます。
記載してあるその他のコマンドもProxy設定が必要であれば引数等で指定します。
例えば、pgp2だと以下の引数を追加します。
```[sh]
pgp2 --keyserver-options http-proxy=XXX.XXX.XXX.XXX:PPPP
```

# ROS2/Moveit2の確認
## ROS2 Humble
インストール作業は、[公式ドキュメント][link-ROS2-install]を見ながらトラブルなくインストールできました。

## Moveit2
インストール作業は、[公式ドキュメント][link-Moveit-install]を見ながら実施しました。

注意点としては、ROS2のデフォルトのDDSには不具合があるようで、Cyclone DDSに切り替えて使用するようコメントがありました（2022/09/26時点）。

以下、抜粋です。
```[sh]
sudo apt install ros-rolling-rmw-cyclonedds-cpp
# You may want to add this to ~/.bashrc to source it automatically
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
```


Proxy環境では、sudoでroot権限にするものがありますが、sudo だけではProxyの環境変数が引き継がれませんのでエラーになります。**"sudo -E"** として環境変数を引き継いで実行する必要があります。

```[sh]
sudo -E rosdep init
```

こちらも手順通りにすすめ、サンプルも無事動かすことができました。
Rvizもグラフィック描画のハードアクセラレーションが効いているせいか、ヌルヌル動きました。

### 便利機能
まだ使い込んでいないのですが、Moveit!でアームを扱う人にお馴染みのRvizの「MotionPlanning」に新機能がありました。

**Nullspace exploration** と言うもので、TCPの位置は大体そのままにそれ以外のアームのポーズを変更できるものです。
アームのポーズを作るのに１つ１つJointを動かしていたのでかなり便利な機能ではないかと思います。
参照しているドキュメントの[Moving Joints or in Null Space][link-Moveit-New1]の項目に動画も載っています。

# まとめ
環境としては、インストールで（少し？）トラブルがありましたが、長時間安定して動いています。また、コンパイル時間やグラフィック描画が以前より格段に速くなり快適な環境が構築できました。

次回は、[UR5e][Link-UR]をMoveit2で動かしてみたいと思っています。

[link-AMD]: https://www.amd.com/ja/products/apu/amd-ryzen-9-pro-7940hs
[link-ISO]: https://jp.ubuntu.com/download
[link-USB]: https://ubuntu.com/tutorials/create-a-usb-stick-on-ubuntu#1-overview
[Link-Realtime]: https://kernel.org/pub/linux/kernel/projects/rt/6.2/
[Link-Kernel]: https://www.kernel.org/pub/linux/kernel/v6.x/ 
[link-ROS2]: https://docs.ros.org/en/humble/index.html
[link-ROS2-install]: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html
[link-UR-Realtime]: https://sdurobotics.gitlab.io/ur_rtde/guides/guides.html#real-time-setup-guide
[Link-Ubuntu]: https://ubuntu.com/tutorials/create-a-usb-stick-on-ubuntu#1-overview
[Link-UR]: https://www.universal-robots.com/ja/%E8%A3%BD%E5%93%81%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%8A%E3%83%83%E3%83%97/ur5e/
[Link-Ubuntu-Install]: 　https://ubuntu.com/tutorials/install-ubuntu-desktop-1804#6-allocate-drive-space
[link-AMD-Driver]: https://www.amd.com/ja/support
[link-AMD-ROCM]: https://www.amd.com/ja/graphics/servers-solutions-rocm
[link-Moveit]: https://moveit.picknik.ai/main/index.html
[link-Moveit-install]: https://moveit.picknik.ai/main/doc/tutorials/getting_started/getting_started.html
[link-Moveit-New1]: https://moveit.picknik.ai/main/doc/tutorials/quickstart_in_rviz/quickstart_in_rviz_tutorial.html#moving-joints-or-in-null-space