ROS講座120 WebCameraのパラメーターを指定して起動する。

# 環境
この記事は以下の環境で動いています。

| 項目 | 値 |
|:-:|:-:|
| CPU | Core i5-8250U |
| Ubuntu | 18.04 |
| ROS | Melodic |
| webカメラ | [BSW200MBK](https://www.buffalo.jp/product/detail/bsw200mbk.html) |

インストールについては[ROS講座02 インストール](https://qiita.com/srs/items/e0e0a9dc3f94c2d3348e)を参照してください。
またこの記事のプログラムはgithubにアップロードされています。[ROS講座11 gitリポジトリ](https://qiita.com/srs/items/25a56a6abda41dcf396e)を参照してください。

# 概要
前回Webカメラを`uvc_camera`を使って起動しましたが、今回はカメラの性能を発揮するために詳細なパラメーターを指定して起動します。

# uvc_cameraの問題
[uvc_camera](http://wiki.ros.org/uvc_camera)ではデフォルトのフォーマットでしか起動できません。例えば今回使うwebカメラのページを見ると以下のように30fpsが出ると書いてあります。

![webカメラ性能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/fa35c906-714a-8a62-afaa-2428dbc9c749.png)

しかし`roslaunch cam_lecture cam_view.launch`で起動したimageトピックのレートを`rostopic hz /image_raw`で調べてみると15Hz程度しか出ていません。これはドライバなどのソフトの性能が悪いのではなく設定の問題です。
USBカメラを接続して`v4l2-ctl --list-formats-ext`を実行すると以下のようの出力になります。

```text:上記のコマンドの結果
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.100s (10.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.125s (8.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.200s (5.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)
```

USB webカメラ(UVC: USB Video Camera)からデータを吸い出すときにはformatとsizeを指定します。上記の出力を見るとフォーマットは`YUYV`と`MJPG`がsizeは`640x480`、`160x120`、`176x144`、`320x240`、`352x288`、`800x600`、`1280x720`、`1920x1080`に対応しています。逆にこれ以外のサイズを指定してWebカメラを起動することはできません。
また各formatとsizeの組の後に最大Hzが書いてあります。画像のサイズが大きいとデータサイズが大きくなってHzが出なくなってしまいます。上記のlaunchではデフォルト設定でformatはYUYVでsizは640x480になっていますWebカメラとしては30Hzが出るようですが、一つ上の800x600が10fpsなのを見ると転送容量がギリギリなのでしょう。YUYVはraw形式なので転送容量が大きくなります。
もっと高いHzを出すためにはformatをMJPGにする必要があります。このような細かい設定をするには`libuvc_camera`を使う必要があります。

# lubuvc_cameraの使い方

## デバイスの確認

USBカメラを刺した状態で`lsusb`を実行すると以下のような表示ができます。上から2行目がUSBカメラを表します。vender idは0458、device idは708cとわかります。

```text
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 005: ID 0458:708c KYE Systems Corp. (Mouse Systems) Genius WideCam F100
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
```

確かに`ll /dev/bus/usb/003/005`とするとファイルがあることが分かります。libusb_cameraは`/dev/video0`ではなくこっちの方をつかみに行くのですが、一般ユーザーだとpermissionがありません。

```text
crw-rw-r-- 1 root root 189, 260 Jan 24 17:33 /dev/bus/usb/003/005
```

`sudo chmod 666 /dev/bus/usb/003/005`で解決するのですが、毎回コマンドを打つ必要が出てくるので、udevを書いて自動でpermissionがつくようにします。

## udevの記述
udevファイルを記述します。ファイルを新規に作成します。`/etc/udev/rules.d/99-uvc.rules`というファイルで以下のように記述します

```text:99-uvc.rules
SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0458", ATTRS{idProduct}=="708c", MODE="0666"
```

`ATTRS{idVendor}==`、`ATTRS{idProduct}==`の値はlsusbで取得したものを入れてください。ファイルを書いた後にUSBを抜き差しします。

## libuvc_cameraの実行

以下のlaunchを実行すると画像が大きいサイズでもrateが出ます。width、height、rateが`v4l2-ctl`コマンドで出てきたものと違うと起動できません。

```xml:cam_lecture/launch/cam_view_libuvc.launch
<?xml version="1.0"?>
<launch>
  <node pkg="libuvc_camera" type="camera_node" name="mycam">
    <param name="width" value="1280"/>
    <param name="height" value="720"/>
    <param name="frame_rate" value="30"/>
    <param name="video_mode" value="mjpeg"/>
  </node>
  <node name="image_view" pkg="image_view" type="image_view" >
    <remap from="image" to="/image_raw"/>
  </node>
</launch>
```

# ソースコード
# ビルド
```shell
cd ~/catkin_ws
catkin_make
```

# 実行

# 参考
[libuvc_camera](http://wiki.ros.org/libuvc_camera)

# 目次ページへのリンク
[ROS講座の目次へのリンク](https://qiita.com/srs/items/5f44440afea0eb616b4a)