ROSを使ったURDF作成

物理シミュレーションをする時にROS(Robot Operating System)が必要になります．
また，物理オブジェクトを作るのにurdf形式で物体を用意する必要もあります．
色々ハマった箇所があったので，今回はそのROSのインストールとURDFの作成についてまとめました．

# 目次
1. [ROSをインストールする](#1-ROSをインストールする)
1. [ワークスペースを作成](#2-ワークスペースを作成)
1. [パッケージを作成](#3-パッケージを作成)
1. [launchファイルを作る](#4-launchファイルを作る)
1. [URDFファイルを作る](#5-URDFファイルを作る)
1. [URDFをrivzで確認](#6-URDFをrivzで確認)


# バージョン
- Ubuntu 14.04 Trusty
- ROS indigo
- Gazebo 2 (任意)

ROSの最新バージョンは`melodic`ですが，Ubuntu 14.04では対応していないので，`indigo`をインストールします．
Gazeboは物理エンジンで，ROSと連携できる機能があるため今回は一緒にインストールしましたが，特に必要ではないです．ROS indigoに対応しているGazeboは**バージョン2**です．(間違ってGazebo7を入れてしまってハマった)

# 1. ROSをインストールする

### source.listとキーの設定

```bash
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
```

### インストール

```bash
sudo apt-get update
sudo apt-get install ros-indigo-desktop-full
```

---
ハマった箇所

- 私の場合，Gazebo7を先に入れてしまってROSのインストールに失敗してハマりました．
(依存パッケージがインストールできない問題)
Ubuntu 14.04にはGazebo7が対応しているが，ROS indigoはGazebo2までしか対応していないことが原因でした．

```bash
sudo aptitude install ros-indigo-desktop-full
```

をして，解決方法を受け入れる（y）にすると，Gazebo2とROS indigoが両方入る．

---

### rosdepの初期化

```bash
sudo rosdep init
rosdep update
```

### 環境変数の設定

```bash
echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
source ~/.bashrc
```

### rosinstallの準備

```bash
sudo apt-get install python-rosinstall
```

## Gazeboのインストール
### source.listとキーの設定

```bash
sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu trusty main" > /etc/apt/sources.list.d/gazebo-latest.list'
wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
```

### インストール

```bash
sudo apt-get update
sudo apt-get install libsdformat1 libsdformat-dev gazebo2
```

### ROSと連携するプラグインをインストール

```bash
sudo apt-get install -y ros-indigo-gazebo-ros-control ros-indigo-ros-control ros-indigo-ros-controllers
```

## 参考にしたサイト
- ROS indigoの公式ドキュメント(日本語)  
<http://wiki.ros.org/ja/indigo/Installation/Ubuntu>


# 2. ワークスペースを作成

### 空のワークスペースを作成
```bash
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
```

### `catkin_make`で`build`と`devel`フォルダを作成

```bash
cd ~/catkin_ws/
catkin_make
```
有効化します

```bash
source devel/setup.bash
``` 
bashを立ち上げる時に自動で有効化するようbashrcに書き加えます．

```bash
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
```

### ROSの設定をbashrcに記述

`.bashrc`に次を追加します．

```bash
# Set ROS Network
export ROS_HOSTNAME=127.0.0.1
export ROS_MASTER_URI=http://${ROS_HOSTNAME}:11311
```
`ROS_HOSTNAME`はPCのIPアドレスを指定しますが，固定化されてない場合は`127.0.0.1`としておきます．

---
ハマった箇所

- ROSはsystemのpython(python2系)でないと動かないので，pyenvを使っている方はsystemに変更しておきましょう．


## 参考にしたサイト
- 公式ドキュメント(英語)  
<http://wiki.ros.org/ROS/Tutorials/InstallingandConfiguringROSEnvironment>
- ここをベースにしました  
<http://bril-tech.blogspot.com/2016/10/ros2-ros.html>

# 3. パッケージを作成
すでにROSは入っていて，新しくモデルを作りたいだけの時はここ(3. パッケージを作成)からで大丈夫です．

### ワークスペースのsrcフォルダにパッケージを作成する
`my_robo`というワークスペースを作ります．
`catkin_create_pkg <任意の名前>_description`でパッケージを作成します．

```bash
cd ~/catkin_ws/src
catkin_create_pkg my_robo_description
```

### 各種ディレクトリを作る
meshes, urdf, launch, rvizの4つのフォルダを作成します．

```bash
cd catkin_ws/src/my_robo_description
mkdir meshes urdf launch rviz
```
`meshes` : stlファイルを入れます
`urdf` : ここにurdfファイルを作ります
`launch` : launchファイル(urdfを確認するときに使います)を入れます
`rviz` : urdfを描画する際に使います


## 参考にしたサイト
- srcのフォルダ構成など  
<https://qiita.com/RyodoTanaka/items/174e82f06b10f9885265>


# 4. launchファイルを作る
urdfをrivzで視覚的に確認したいときに必要になります．どのワークスペースでもほぼ共通です．
display.launchファイルを作ります．

```bash
cd launch
gedit display.launch
```

display.launchに以下を記述します．

```xml
<launch>
 
  <arg name="model" default="$(find <パッケージのときに作った名前>_description)/urdf/<モデルの名前>.urdf"/>
  <arg name="gui" default="True"/>
  <arg name="rvizconfig" default="$(find <パッケージのときに作った名前>_description)/rivz/urdf.rviz"/>
 
  <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)"/>
  <param name="use_gui" value="$(arg gui)"/>
 
 
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
 
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true"/>
 
</launch>
```

## 参考にしたサイト
- display.launchの際に参照しました  
<http://bril-tech.blogspot.com/2016/10/ros3.html>

# 5. URDFファイルを作る
事前に適当な3DCADソフトでstlファイルを作っておき，`~/catkin_ws/src/my_robo_description/mesh/`に置きます．
urdfはXMLで記述されています．例えば

```xml
<?xml version="1.0"?>  <!-- xmlコードを認識してくれる -->
<robot name="my_robo"> <!-- 全体をrobotタグでくくる -->
  <link name="base_link">
 
    <visual>
      <geometry>
        <box size="0.400 0.200 0.100"/>  
      </geometry>
    </visual>
 
    <collision>
      <geometry>
        <box size="0.400 0.200 0.100"/>
      </geometry>
    </collision>
 
  </link>
</robot>
```
visualタグとcollisionタグは基本的に同じ記述をします．geometryタグで形状を指定します(boxは直方体を描画)．基本的に，**linkタグでパーツをそれぞれ指定していき，それをjointタグで結合していきます．**
各タグの詳しい説明は[ここ](http://wiki.ros.org/urdf/XML)を参照してください．

今回はmy_roboという名前のurdfを作成するので，適当なエディタで開きます．

```bash
cd urdf
gedit my_robo.urdf
```

### 必要な要素
#### linkタグ
- inertial : 物理パラメータを記述
  - origin : 座標x,y,z
  - mass : 質量(kg)
  - inertia : 慣性モーメントixx, iyy, izz, ivy, iyz, ixz
- visual : 見た目
    - origin : 座標x,y,z・オイラー角(向き)row, pitch, yaw
    - geometry : 形状を指定
        - mesh : stlを読み込む
    - (material) : colorを指定できます．必須ではない．
- collision : 物理的な接触範囲．visualと同じでいい．
    - origin
    - geometry
        - mesh

#### jointタグ
- parent : 物体の本体を指定
- child : 親linkに対して結合するlinkを指定
- origin : jointの方でパーツの位置を指定
- axis : 軸の座標x, y, z．回転させたいパーツのときに，回転軸をここで指定します．

### CADで作ったstlをurdfに取り込む
geometryタグ内にmeshタグを記述し，そこにstlのパスを指定します．

```xml
<geometry>
  <mesh filename="package://robot_description/meshes/base_link_simple.stl"/>
</geometry>
```

---
ハマった箇所

- 3DCAD(123D Designを使ってました)でstlを作るとき，プリミティブ物体ではなく，平面を指定して押し出しというように1から作った方がいいです．物理シミュレーション上で，連続で物体を呼び出すときに途中で読み込みエラーが出ます．
- 3DCAD上での軸がstlに採用されるので，タイヤなど回転させる物体を作る際は回転軸を考えてstlを作成してください．

---

### jointでくっつけたlinkの関係をチェック

```bash
check_urdf <作ったurdf>.urdf
```
jointとlinkの関係に問題がなければ，`successful`と出ます．


## 参考にしたサイト
- urdfのxml記述の必要な要素の説明．  
<http://wiki.ros.org/urdf/XML>
- R2D2を作るチュートリアル  
<http://wiki.ros.org/urdf/Tutorials/Building%20a%20Visual%20Robot%20Model%20with%20URDF%20from%20Scratch>


# 6. URDFをrivzで確認
rvizというソフトで作ったurdfを視覚的に確認できます．次でrvizを起動します．

```bash
roslaunch <パッケージのときに作った名前>_description display.launch model:=<開くurdfのパスを指定>
```

例えば，今回では`my_robo`を作っているので

```bash
roslaunch my_robo_description display.launch model:=urdf/my_robo.urdf
```
`model:=`のパスに注意．カレントディレクトリからの相対パスを指定してください．ただ，urdfモデルはデフォルトでパスを指定してあるため(display.launchファイルに記載)，パスを指定しなくても問題ないです．

---
ハマった箇所

- ascii codecのエラーが起こる場合，urdfのファイルに**スペース**ではなく**tab**が入っているとエラーになります．

---


### rvizでの設定
左側の`Displays`より，`Global Options`→`Fixed Frame`で`base_link`を選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/251371/b73f35bd-e4ae-5697-2515-bf07b61d4d35.png)

**左下の`Add`ボタンをクリックし，`rviz`→`RobotModel`を選択し`OK`を押します．** (これを忘れて表示されない！って焦りました)
追加すると，my_robo.urdfで定義した車体が表示されます．
![Screenshot+from+2016-09-14+17%3A55%3A13.png](https://qiita-image-store.s3.amazonaws.com/0/251371/1217df7f-18e3-8685-901e-b650753a39e6.png)

左側の`Displays`より，`RobotoModel`→`Links`→`base_link`を展開します．

- `Alpha`を`0.5`にして，物体を半透明にします．
- `Show Axes`にチェックを入れ，x軸(赤)y軸(緑)z軸(青)が表示させます．
- 全てのlinkに上記を行い，各linkの軸の位置を確認しましょう．

## 参考にしたサイト
<http://bril-tech.blogspot.com/2016/10/ros3.html>