UnityでROS#のチュートリアルを動かしてみた

# はじめに
UnityでROSを動かすためのアセットROS#のチュートリアルをOculusQuest上で動かしてみたところ、
色々躓いたところがありましたので書いておきます。
今回ROSは初めて触ったので、基本的なところがわかっていない状態で進めています。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VirtualBoxの設定で治るとの情報を見つけて、試してみたところ治った！！<br>この後はGazebo=&gt;Unity側の受信処理まで動いて、ロボットが動くようになりました <a href="https://t.co/J2cMIVMWBb">pic.twitter.com/J2cMIVMWBb</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1227204759624376321?ref_src=twsrc%5Etfw">February 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[ROS# wiki]
(https://github.com/siemens/ros-sharp/wiki)
ROS#のページです。ここに記載のある1. Installation and Configuration ～ 2.3 Gazebo Simulation Example
を今回動かしています。

[アセットストア]
(https://assetstore.unity.com/packages/tools/physics/ros-107085)
ROS#のアセットストアのページです。
試行中、アセットストアからダウンロードしたものからリポジトリの最新版(更新はいくつか入っているようでした)に切り替えたのですが、自分が遭遇した問題とは関係なかったようです。

[VirtualBox上にROSの開発環境を作る]
(https://qiita.com/ck_qiita/items/c123328bcc9a996e2bd9)
VirtualBoxの環境設定時に参考にさせていただきました。

[ROS講座]
(https://qiita.com/srs/items/5f44440afea0eb616b4a)
ROSの環境設定時と、ROSの基礎知識の確認に参考にさせていただきました。ROS入門から各種応用まで非常に幅広い内容を丁寧に解説されています。

#開発環境
Unity 2019.3.0f5
ROS# 当初1.6 => リポジトリから2020/2/8にダウンロードに切り替え
Oculus Integration for Unity - 12.0
VirtualBox 6.1.2
ホストOS Windows10 Home バージョン1909
ゲストOS 当初Ubuntu 18.04 LTS => Ubuntu 16.04 LTS
ROS kinetic

#躓いたところ
1. ゲストOS
最初、UbuntuのLTS最新版でよいかと思い18.04 LTSを入れたのですが、ROSのバージョンkineticを使う場合は16.04 LTSが必要でした。
ROSのバージョンMelodicであれば18.04 LTSでよいのですが、[TurtleBot2](https://github.com/siemens/ros-sharp/wiki/User_Inst_TurtleBot2)をみるとkineticを使っている前提のようにも見えたのでkineticを選択しました。ROS#自体はMelodicで動作するようですので、Melodic+18.04 LTSでもよかったのかもしれません(未確認です)。

2. VirtualBoxの設定
当初、ディスプレイ->スクリーン->3Dアクセラレーションを有効化：有効化の設定で使用していたのですが、これが原因で、後でGazeboを起動するときにSegmentation Faultが発生しており、解決に非常に時間がかかりました。設定は後で変更できるので、現象が発生するようであれば無効化に切り替えてもよいと思います。

3. Guest Additionsのインストール
画面サイズの追従やクリップボードの共有のために必須の設定なのですが、Ubuntuのインストール直後にそのまま設定すると失敗します。必要なパッケージを設定してから実行する必要があります。[VirtualBox Guest Additionsのインストール](https://ichibariki.hatenablog.com/entry/2018/05/13/173056)を参考に設定しました。

4. ROSで謎のエラーが発生する
チュートリアルの[2.1 Transfer a URDF from ROS to Unity](https://github.com/siemens/ros-sharp/wiki/User_App_ROS_TransferURDFFromROS)を実行したところ、ROS側で以下のようなエラーが発生しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/56a73f2f-57ff-2d51-ab15-e8835f752788.png)
これについては、
catkin_make
のあとに
source ~/.bashrc
を実行することで解決しました(どうやらcatkin_makeの後は毎回必要なようです)。自分の.bashrcには、[ROSのインストール](https://qiita.com/srs/items/e0e0a9dc3f94c2d3348e)のスクリプトで設定された内容が追加されています。

5. RVIZ起動でエラーが発生する。
チュートリアルの[2.2 Transfer a URDF from Unity to ROS](https://github.com/siemens/ros-sharp/wiki/User_App_ROS_TransferURDFToROS)を実行したところ、ROS側で以下のようなエラーが発生しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/1e5e88a9-a8d0-6e3c-f21f-12b8c63c820a.png)
これについては、catkin_ws/srcフォルダで、
git clone https://github.com/ros/joint_state_publisher.git
cd ..
catkin_make
source ~/.bashrc
を実行することで解決しました。

6. OculusQuestで実行するとエラーが発生する
チュートリアルの[2.3 Gazebo Simulation Example](https://github.com/siemens/ros-sharp/wiki/User_App_ROS_GazeboSimulationExample)を実行したところ、PC(Unityのエディタ)では問題なかったのですが、OculusQuest上で実行すると、大量のNullReferenceExceptionが発生しました。発生していた場所はJoyPublisher.csだったのですが、調査のためにあちこちDebug.Logを入れていたところ、なぜかStartにDebug.Logを追加すると現象が発生しなくなりました。原因は不明なのですが、とりあえずはこれで動かしています。

7. ROS側で2回目以降の受信ができない。
前項と同じチュートリアルで、1回目の受信ログは残るのですが、２回目以降の受信ログが残らない現象が発生していました。
rostopic echo /joy
で確認してみると、Unity側からのメッセージは送られているように見えました。
受信のスクリプトjoy_to_twist.pyで、受信処理の最後のrate.sleep()をコメントアウトしたら動くようになりました(メッセージを受信するごとに動かすところなので、ここでウェイトを入れる必要はないはず)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/a5ca5e53-ab94-d25f-bc4f-d578d14fff6b.png)

#追記1
OculusQuestで実行する部分は、元のチュートリアルから追加した部分になります。OculusQuestでジョイスティックを使用するために、RosConnectorに付加されたコンポーネントJoy Axis Reader(２か所)の設定を以下のように変更しています。
Horizontal => Oculus_CrossPlatform_PrimaryThumbstickHorizontal
Vertical => Oculus_CrossPlatform_PrimaryThumbstickVertical