Virtual BoxでURSimオンラインシミュレーション　～環境構築編～

##はじめに
はじめましてdeこんにちは,電脳妖精☆ミントです.
今回は,URSimを仮想環境(以降 : ゲストOS)にインストールした後,ホストOSからPythonスクリプトによるURSimの動作確認までの開発環境構築を行います.
URSimってなに？という方は,岡本 拓海( @MrBearing )氏の記事や参考サイトを見ていただきたい...

記事を書くことに慣れていないので間違いや読みづらいところがあるかもしれません.
また,本記事で生じた不利益、損失の責任は一切負いかねますので,ご了承ください.

##読んでほしい人！
本記事は,「手元にURロボットがない！でも環境構築や動作確認をしたい！」という方向けであります.
また,Linux系の仮想環境構築に慣れている方やPythonﾁｮｯﾄﾃﾞｷﾙ方,UR触ったことある方には簡単?なものになっているので,興味がある方は是非読んでいただきたいと思います.
「ここ違うヨ」「まるでわからん」という方はコメントしていただけると嬉しいです.

## 今回の目標！
※埋め込みはイメージです.
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">にゃーん <a href="https://t.co/O5ltSdaTKl">pic.twitter.com/O5ltSdaTKl</a></p>&mdash; 電脳妖精☆ミント@NT金沢 (@MINT9821) <a href="https://twitter.com/MINT9821/status/1132503749597880320?ref_src=twsrc%5Etfw">2019年5月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##開発環境
それではさっそくやっていきましょう！
今回使用するURSimはLinux系OSでしかサポートされていないようなので仮想環境を使います.
また,ゲストOSにLinux Mintを使いますが,提供元のURSimさんからver.17.1を推奨されているので,それを使います.

- Windows 10 (ホストOS)
- Linux Mint 17.1 Mate (ゲストOS)
- Virtual box 6.0.8 (ホストOS)
- URSim 3.6 (ゲストOS)
- Python 3.7.x (ホストOS)　←各自導入しておいて下さいネ^^
- TeraTarm (ホストOS)　←確認用なので必須ではないです

##環境構築手順
それではさっそく環境構築をしていきたいと思います.
また,Virtual boxのインストールから仮想OSの用意までは,他サイトさんの方が詳しくされていると思うのでそちらを参考にしてください.

### Virtual boxのインストール
Virtual boxのインストールですが,Windows版の最新のものを使用して下さい.ここら辺の詳しい情報は他サイトさんで...
参考までに私の使用したバージョンのURLを下記しておきます.

URL : https://www.virtualbox.org/wiki/Downloads

URLに飛んでいただいて,**Windos hosts**をクリックすると.exeがダウンロードできます.
ダウンロードができたら,ホストOSであるWindowsへインストールしてください.
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/ccc4e0ee-078a-5931-09e5-b6f5a0c72c41.png)

### Linux Mintの用意
今回は,**Linux Mint 17.1 Mate**を使います,バージョンの違いによって動作しなくなる可能性もあるのでご注意ください.
参考までに,使用したDLリンクを下記します.

URL : https://www.linuxmint.com/edition.php?id=174

### Virtual boxのネットワーク初期設定

インストールが完了したら,Virtual boxのネットワーク設定を行います.
設定の手順を下記します.
**ただし,最初からこの設定がしてあった場合,この章は飛ばしていただいて構いません.**

- Virtual boxを起動し,マネージャの**ツール**を選択.
- ツールの"三"を選択し,**ネットワーク**を選択.
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/3a37dd27-3c52-6d90-dead-7d12ad68fadb.png)

- **作成**を選択し,新しくネットワークアダプタを作成します.
- 作成したら,DHCPサーバの欄にある**有効**にチェックを入れます.
- 次に,**プロパティ**を選択し,下に出てくる**アダプター(A)**の「アダプターを手動で設定にチェック」を入れます.
- **適用**を選択して設定は完了です.
- 一応,ホストOSからコマンドプロントを使用して,Virtual boxのIPv4が**(優先)**になっているのを確認してください.
- (もし**(重複)**になっていた場合は,Virtual boxのネットワークアダプタを削除して,もう一度作成してみてください.直るかも...？)

### ゲストOSの構築
Virtual boxにLinux Mintを構築していきます.
構築方法は他サイトさんを参考にしていただきたい.(投げやりでスミマセン...)
大まかな設定だけ下記します.
また,メモリサイズについてですが,今回私は初期設定のまま行いましたが,余裕があるよという方は多めに取っておいてもよいかもしれません.
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/fbd2cbb5-cda8-1054-1a17-adbef442849c.png)

![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/1806e54a-15aa-1b6b-b04a-8bda8a2227fc.png)

### ゲストOSのネットワーク設定　前編
まずはゲストOSのネットワーク設定をしていきます,手順は以下の通りです.
####OpenSSH-serverのインストール
初期状態のLinuMintには`OpenSSH-server`がインストールされてないので,インストールと有効化を行います.

- **インストール**

```
$ sudo apt-get purge openssh-server
$ sudo apt-get install openssh-server
```

- **有効化**

```
$ sudo service sshd start
$ sudo service sshd status
●ssh.service - OpenBSD Secure Shell Server
  Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
  Active: active (running) since ...
```

`Active`になっていれば設定完了です！

####ポート開放
次に,今回使用するポート解放のため`ufw`コマンドを用いてファイアーウォールの設定を行います.
開放するポートは以下の通りです.

|ポート番号|使用用途|
|:---:|:---:|
|22|SSH|
|30002|URSim|

それではまずufwの設定状態を確認します.

```
$ sudo ufw status
Status: inactive
```

`inactive`と表示されたらufwの設定は無効になっています.
したがって,ufwを有効化します.

```
$ sudo ufw enable
$ sudo ufw status
Status: active 
```

`active`になっていたら有効化は完了です.
有効化できましたら,実際にポートの開放を行っていきます.

```
$ sudo ufw allow 22
$ sudo ufw allow 30002
```

コマンドを実行したらufwの状態を確認してみましょう.

```
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
30002                      ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)
30002 (v6)                 ALLOW       Anywhere (v6)
```

このように表示されたらポート開放は完了です！

### ゲストOSのネットワーク設定　後編
前編が終わりましたら,一度ゲストOSをシャットダウンしてVirtual boxのメニュー画面へ戻りましょう.
さて,Virtual BoxでのホストOSからのアクセス方法は様々ありますが,今回は**NAT+ポートフォワーディング設定**を使用してアクセスします.
したがって,NATに対してポートフォワーディングの設定を追加します.
手順は以下の通りです.

- ゲストOS(画像では"Mint")を選択し,`設定` > `ネットワーク`を選択します.
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/6bfc5322-5d4f-1ef5-ca15-6aae89766962.png)
- **アダプター1**を選択し,高度な選択をすると`ポートフォワーディング`という項目があるのでクリック.
![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/3ec07864-5806-0e05-68c8-d8fa37e81767.png)
- ホストポートとゲストポート(**22** & **30002**)を設定します.なお,**ホストポートは適宜に設定してくだい.**
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/3cd553fb-be3f-14e1-ce6d-709170f861d1.png)
- 次に**アダプター2**を選択し,ネットワークアダプターを有効化し,以下のように設定てください.

割り当て・・・`ホストオンリーアダプター`
名前・・・`VirtualBox Host-Only Ethernet Adapter`
![008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/f26f8118-97ca-dea0-0002-62c7b98eab72.png)

- OKをクリックしたら設定は完了です！

### URSimのインストールと実行
さて,いよいよURSimのインストールを行います！
ゲストOSを起動してくださいネ.
今回使用したURSimのダウンロードURLを下記します.

URL : https://www.universal-robots.com/download/?option=40156#section16632

ダウンロードしたgzファイルを任意の場所に解凍してください.
ちなみに,ファイル構造が`URSim_Linux-3.6.0.tar.gz　＞　ursim-3.6.0.30512.tar.gz　＞　ursim-3.6.0.30512`となっていますので,注意です.

- **./install.sh**の実行

解凍したファイルの直下に./install.shがあるので,これを実行してインストールを行います.
インストールには少々時間がかかりますので,しばらくお待ちください...

```
mint@VirtualBox ~ $ cd 任意のディレクトリ/ursim-3.6.0.30512
mint@VirtualBox ~/任意のディレクトリ/ursim-3.6.0.30512 $ sudo ./install.sh
```

- URSimの実行

今回は**ursim-3.6.0.30512 UR5**を使用します.
GUI環境を使用中ならばデスクトップにショートカットが作成されているはずなので,それを実行してください.
CUI環境を使用中ならば以下のコマンドでURSimの実行が可能です.

```
mint@VirtualBox ~/任意のディレクトリ/ursim-3.6.0.30512 $ ./start-ursim.sh UR5
```

- 実行画面
![010.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/e03db9db-44b8-f9e4-25db-f3dfd91901d1.png)

さて,以上で開発環境は整いました！最後にサンプルプログラムを使って実際に動かしていきます.

##サンプルプログラムの実行！の前に...

サンプルプログラムを実行する前に,ちゃんとポート開放ができているか確認してみましょう.

- ゲストOSのIPアドレスを調べます

今回は**Terminal**から**ifconfig**を使って調べました.
![012.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/79eccbea-cc38-88d1-0920-fb6771898042.png)

- Tera Termを使って確認

ゲストOSでTera Termを起動して,先ほど調べたIPを使ってログインできるか確認してみてください.無事アクセスできれば完了です.
※私はTera Termを使用しましたが,確認方法はいろいろあると思いますので,よしなに.
![o1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/5d0b2c91-8874-24fc-c180-17dad6d9b98b.png)
![o2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/805c93c4-4b31-9d9f-971b-93a44289ef85.png)
![o3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/8f1e3f33-2c00-81a9-9071-664a6d695ade.png)

##サンプルプログラムの実行！

ホストOSからゲストOSにアクセスできることを確認できましたら,いよいよサンプルプログラムを実行していきます.
今回,言語にはPythonを使用します.
実行の概要として,URSim(ゲストOS)の30002ポートにTCPでコネクションしてスクリプトのテキストを送り付けます.

なお,今回使用するプログラムは岡本 拓海 氏(@MrBearing)の記事を大いに参考にさせていただいております.大変感謝いたします...
また,本記事でのプログラムの内容は省略させていただきますのでご了承ください.
氏の記事を下記します.
URL : https://qiita.com/MrBearing/items/a09ab5751be9333cddc5

###スクリプト本体

```php:ur_test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import time

HOST = "***.***.***.***"
PORT = 30002

def toBytes(str):
    return bytes(str.encode())

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.send(toBytes("movej([0,-1.57,0,0,-1.57,1.57], a=1.40, v=1.04)" + "\n"))
    # ラジアン
    time.sleep(3)
    data = s.recv(1024)
    s.close()
    print("Receved", repr(data))
    print("Program finish")

if __name__ == '__main__':
    main()
```

HOSTには,先ほど調べた`ゲストOSのIPアドレス`を,POSTにはURSimのためにポート開放した`30002`を入力します.
記述が終わりましたら,保存してください.

###使い方
ゲストOSの**URSim-UR5**を起動して,ホーム画面の`Run Program`を選択し,開かれた項目の`Move`を選択してください.
すると,以下のような表示になります.
![011.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/09305e89-5a88-1f62-b8d0-dbf41f219d5d.png)
次に,ホストOSで先ほど作成した.pyスクリプトを実行してください.
![013.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/ca5cb890-5edd-7170-44ac-0be8eba2494c.png)
無事,URSimのロボットアームが稼働したのを確認できましたら,外部制御の完成です！
いかがでしょう？うまくいきましたか...？

##もーわかんない！
今回,私がつまずいた点を下記したいと思います.何か参考になればと思います...

- DLしたgzファイルが解凍できない...！？
バグでしょうか...私が解凍時,ファイルがおかしくなってしました.落ち着いて,削除・再DL・解凍すれば」問題なかったです.

- ゲストから接続拒否される！　その1
pyスクリプトの実行時,↓こんなエラーが出たり,PINGは通るけどTera TermでSSH接続できない！というときは**OpenSSH-serverの再インストールと有効化**をしてみてください.
![o4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287252/019dee8e-7937-2c26-616c-26c1673517a5.png)

- ゲストから接続拒否される！　その2
.pyスクリプトのHOSTのアドレスやPOSTのポート番号が間違っていませんか？

- ゲストOSがネットワークにつながらなくなった...
あきらめて,ゲストOSを再構築したほうが楽です...

##まとめ
- URSimのゲストOSにおける環境構築ができた！
- ホストOSからゲストOSへの外部制御ができた！


お疲れ様でした,かなり説明が長くなってしまいました...
しかし,今回はあくまでも,環境構築編です.本記事が少しでも今後皆様の研究・開発のお役に立てば幸いです.
それでは皆さん,ごきげんよう.

##参考文献

- [iptablesが難しいためufwでWEBサーバーのファイアウォール設定](https://qiita.com/shimakaze_soft/items/c3cce2bfb7d584e1fbce)
- [Ubuntu 16.04 LTSでssh.serviceがunrecognized serviceと言われたときの対処法](https://qiita.com/musaprg/items/c0a9a6d5fb98cf75021f)
- [URScriptによるURロボットの外部制御](https://qiita.com/MrBearing/items/a09ab5751be9333cddc5)