Raspberry Piでワカサギを釣ってみる

## WHY
ついカッとなってやった、今は反省している。
![image](https://qiita-image-store.s3.amazonaws.com/0/64964/65440df7-e8ea-6ffb-7809-68e9ecb1f15b.png)


## WHAT
ラズパイを使ってワカサギを釣る方法です。
ワカサギ釣りとは、氷上に穴を開けて魚を釣るあれのことです

### 概要

- ラズパイにはカメラとモータをつけた
- 画像処理で竿の先のアタリを検知できたら、モータを回すようにした
- 誘い（ちょいちょいって動かして魚を誘う動き）も自動化した
- アタリはパーティクルフィルタというトラッキングアルゴリズムを使った


## 工作的なもの
電子工作はやったことがないので、最低限の準備しかしていません。
基本的には、ラズパイには以下のものが付いているだけです。

- 電源：困ったことに氷上には電源がないのでスマフォの充電用バッテリを使います
- カメラ：普通の1000円くらいのWEBカメラ
- Wifiアダプタ
    - 困ったことに氷上にはWifiが飛んでないので
    - [ad-hocネットワークを作って](http://qiita.com/UedaTakeyuki/items/851fc8c19f36b96a0ae6)macと通信します
    - `SSH -X`でカメラの画像を表示してテストとかします
- ブレッドボード
    - ラズパイに付いているGPIO（General Purpose Input/Output）と繋ぎます
    - ミニ四駆とかのモーター
    - モーターの接続は[こちら](http://www.hiramine.com/physicalcomputing/raspberrypi/webiopi_motordriver.html) を参考にしました。
    - モーターの回転数を制御するギアボックス。トルクとかわからなくても回ればOKの精神で。
- 釣り糸：釣り糸とギアボックスをそのまま無理やり付けました。３Dプリンタとかはでてきません。

![no_fish_big.jpg](https://qiita-image-store.s3.amazonaws.com/0/64964/1261f720-d10c-89b2-f6e9-5eafd03d7828.jpeg)

## モータを回す
GPIOの出力（0、1）を切り替えることで右回転・左回転が可能です。
pythonからコントロールするために、`rpi.gpio`をインストールしておきます。
`sudo apt-get install python-rpi.gpio`

2秒間右回転→2秒間左回転のテストコード。

```
import RPi.GPIO as GPIO
import time

def init_gpio():
    GPIO.setmode(GPIO.BCM)
    
    channel_list = [14, 15, 18]
    GPIO.setup(channel_list, GPIO.OUT)

def stop():
    GPIO.output(14, False)
    GPIO.output(15, False)
    GPIO.output(18, False)

def rotate_right(duration):
    stop()
    GPIO.output(14, True)
    GPIO.output(15, False)
    GPIO.output(18, True)
    time.sleep(duration)
    stop()

def rotate_left(duration):
    stop()
    GPIO.output(14, False)
    GPIO.output(15, True)
    GPIO.output(18, True)
    time.sleep(duration)
    stop()

def cleanup():
    GPIO.cleanup()


init_gpio()

rotate_right(2)

rotate_left(2)

cleanup()
```

![no_fish_big.jpg](https://qiita-image-store.s3.amazonaws.com/0/64964/38580666-57f6-8578-c014-f8bfa1e11288.jpeg)

なんとか糸を回すことができそうです。

## アタリを感知する
カメラだけで竿の先の小さな動きを感知しないといけません。
今回はパーティクルフィルタを使ってみました。
パーティクルフィルタはランダムに沢山の粒子を生成して、目的の状態と近い粒子を選択してということを繰り返してトラッキングするアルゴリズムです。
竿の先だけ検知するのが難しいので今回は、**竿の先に緑の紙をつける**という苦肉の解決策を実行しました。

![sky.jpg](https://qiita-image-store.s3.amazonaws.com/0/64964/c25af539-a9af-bc41-705b-e118223bf6e9.jpeg)

わりと真面目に考えて、以下のアルゴリズムとなりました。

- 初期モードは誘い（attract）モードで竿を動かす
- 竿の揺れが収まったら次に検知（detect）モードに移行
- もし
    - 強い竿の揺れがあったら、釣り上げ（fish）モードで上げて待機モード（wait）に。
    - 待機モードでは`s`キーが押されるまでまつ
    - 一定時間検知がなければ初期のattractモードに移行。これを繰り返す

主に氷上で組んだpythonスクリプト。
https://github.com/tan-z-tan/raspi_fishing/blob/master/src/RaspiFishing.py
[`SSH -X`でGUIを飛ばす](http://qiita.com/tan-z-tan/items/5b6bb15d969997c5ac09)前提で書いています。

### 誘い（ちょいちょいって動かす）
何も考えてなくて氷上で実装したからこれだけ。

```
motor.rotate_left(0.53)
motor.rotate_right(0.7)
```

0.53と0.7みたいな定数は、手間暇かけた職人の温かい定数です。
モータの巻き上げと下げで秒数が同じでも微妙に回転角が違うことに起因します。

## 氷上でやってみた
なんと釣れてしまいました。
機械に釣られた可哀想なワカサギの姿。
でもうれしい。

![IMG_20160213_103856.jpg](https://qiita-image-store.s3.amazonaws.com/0/64964/d041bc91-59a2-f7be-4fbe-52e67dea085c.jpeg)


### 4時間くらいの釣果
**ラズパイ：2匹**
**人間平均：6.75匹**
![image](https://qiita-image-store.s3.amazonaws.com/0/64964/56044d52-0495-d82c-63f8-b04f5717a156.png)

**結論：人間がやったほうが釣れる**

マジメに書くと、全体的に魚が少なすぎてテストとかがほとんどできなかった。
ワカサギは100匹とか釣れる時だと、入れて上げるだけの機械的な作業になるので機械化すると成果を発揮する。。。はず。

ラズパイFishingコンテストとか開催したい。