ROS KineticでのUSBカメラ接続とキャリブレーションまで

# 動機

ROSでのロボットの操作、センサーデータの取扱いを学ぼうと思い、
[ROSプログラミングバイブル](https://www.amazon.co.jp/dp/4274221962)を購入して見たので、参考にしながら、備忘録として書いていく。
他にも、ネットにはいろいろ情報が溢れいているし、ROS Wikiにもさまざまな情報があるので、それらも活用して行く予定。

本来の目的は、ステレオで深度計測をしたり、アラウンドビューモニターみたいに全周囲を撮影できるよう、複数のカメラをつなぎたいのだけれども、今回はひとまず1台の接続。


# 環境
- Ubuntu 16.04 LTS
- ROS Kinetic Kame
- 今回使用したのUSBカメラ（Logicool C270　UVC対応）1台

# カメラ接続

## カメラ接続確認
USBカメラをPCにつないで、

```
$ lsusb
```
または

```
$ ls /dev/device*
```
で接続確認。「Logitec~」とかがリストに出てきたり、「device0」があるようならば、認識はされている。

## uvc_cameraパッケージのインストール
古い情報を元に、usb_camパッケージをインストールしてたら、後々のキャリブレーションあたりでドツボにハマったみたいなので、改めて上記本に倣って実施したら、問題なくいけたので、こちらをuvc_cameraをベースにします。

```
$ sudo apt-get install ros-kinetic-uvc-camera
```
image関連のパッケージもインストール

```
$ sudo apt-get install ros-kinetic-image-*
$ sudo apt-get install ros-kinetic-image-view
```

ここからは実際の機動確認
いつものように、

```
$ roscore
```
別の端末を立ち上げて、

```
$ rosrun uvc_camera uvc_camera_node
```
とすると、色々メッセージが出てくる。

```
[ WARN] [1522822252.725651583]: [camera] does not match name narrow_stereo in file /home/kondo/.ros/camera_info/camera.yaml

```
というWarningは出るけど、当然、内部パラメータのキャリブレーションファイルを設定していないので、今は無視。接続が問題ないなら、USBカメラのライトがついているはず。

[rostopic list]などで確認すれば、トピックメッセージがあることが分かる。
（/camera_info, /image_rawなど）

## 映像確認

このノードを立ち上げたまま（今、roscoreと、uvc_camera_nodeの２つ）、また新しい端末を立ち上げて、

```
$ rosrun image_view image_view image:=/image_raw
```
とすると、ビューワーが立ち上がって、カメラ映像が見える。
rqt_image_viewやRVizからも映像を見ることができる。




# キャリブレーション
映像を見るだけならこれでいいが、物体認識やステレオ、計測などをするためには、カメラの内部パラメータ（焦点距離、画像中心、レンズ歪みなど）を取得して、やりたい画像処理の前に適用して画像を補正する必要が出てくる。

キャリブレーションツールが用意されているので、それを使うだけ。
これまではOpenCVで撮影してキャリブレーション関数を動かしたりとかソフトウェアを自作していたが、なんと便利。実際使ってみるとすごい楽ちん。

下記、リンクを参考。
[ RobotやSystemを完成させるまで Wiki*のROS/Package/ar_track_alvar](http://wikiwiki.jp/naonaorange/?ROS%2FPackage%2Far_track_alvar)


## キャリブレーション関連パッケージのインストール

一度全部の端末を落として、再起動。

```
$ sudo apt-get install ros-kinetic-camera-calibration
$ roscore
$ rosrun uvc_camera uvc_camera_node
```
## チェッカーボードの用意
ROSのところ、OpenCVなどいろいろなところにチェッカーボードの画像はあるので、印刷して、平らな板に貼り付け。
準備として、

- 白黒の正方形の大きさを計測（～mm）
- 縦・横の白黒の”交点”を数える（横長で、9x7列なら、8x6個）

を調べておく。

## キャリブレーションツールの実行

```
$ rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.025 image:=/image_raw
```
25mmサイズなら、メートル閑散で表記のように。本だとカメラに名前をつけていて、最後に、[camera:=/camera]のオプションも追加していたけれども、なぜか自分の環境だとエラーが出てしまった。名前を外すと、起動した（なぜだろう...）。

GUIが立ち上がるので、あとはカメラの前でボードを上下左右に移動させたり、回転させたり、傾けたり、"x", "y", "Size", "Skew"というゲージがあって、その移動や回転によるデータが十分にたまると、緑のゲージが伸びていって、よきところで、[CALIBRATE]ボタンが押せるようになる。

数分待つ（一瞬、ウィンドウがフリーズしたように見えるが...）と[SAVE]と[COMMIT]ボタンが押せるようになるので、[SAVE]。
/tmp/calibrationdata.tar.gz　に保存される。


## パラメータファイルの抽出と配置

圧縮ファイルを好きなところに移動させて展開する。キャリブレーションに使った画像が数十枚ばらばらっと展開されてしまうので、どこかフォルダを作ってその中で解凍するのがよい？

```
$ tar -xvzf calibrationdata.tar.gz
```
とすると、たくさんの画像と、ost.txt, ost.yamlが展開される。
以下のように、ファイル名の変更、パーサーを使ってConvertと、配置を行う。

```
$ mv ost.txt ost.ini
$ rosrun camera_calibration_parsers convert ost.ini camera.yaml
$ mkdir ~/.ros/camera_info
$ mv camera.yaml ~/.ros/camera_info
```
つぎに、さっき指定できなかったカメラの名前を変更する。
camera.yamlを編集のために開いて、上のほうにある、

```
camera_name: narrow_stereo
```
となっているのを、

```
camera_name: camera
```
と書き変えをする。


# 動作確認
また、端末を閉じておき、再度立ち上げをしましょう。

```
$ roscore
$ rosrun uvc_camera uvc_camera_node
```
を実行してみると、今度はファイルがないとか怒られずに、エラーなく表示されるはず。

#おわりに

~/.ros/camera_infoに、カメラの設定ファイルを置いたので、常にデフォルトで読み出してくれる。ただ、今後カメラを替えたり、複数カメラをつけたいときは、それぞれのカメラに対して、別々の設定ファイルを紐付けする必要がある。

ノード立ち上げ時の指定の仕方、launchファイルによる省力化は次回。