学生エンジニア小話

プログラミングのお話

Raspberry Piで作るロボット設計

f:id:takuseno:20161211175245j:plain

今大学で半期を通してチームでロボットを作るという授業をとっています。

僕がシステム設計を担当しているので、どのように設計したのかを紹介したいと思います。

どんな感じのロボットか

ものすごい初期の画像しかないのですが、ロボットの雰囲気はこんな感じです。

f:id:takuseno:20161211091217j:plain

モーターがついているだけです笑。今は以下のような構成になっています。

  • モーター
  • バッテリー
  • Raspberry Pi
  • 超音波距離センサー
  • カメラ
  • スピーカー
  • マイク

これらのものを使ってロボットにタスクをやらせます。

特に規定はなく自由に作れるのですが、このチームではなるべく多くのアプリケーションを開発しようということになりました。

設計方針

なるべく多くのアプリケーションをみんなで作るために、モジュールをうまく隠蔽してAndroidアプリケーションのような感覚で作れるようにすることを目指しました。さらにメンバーで各モジュールを動かすためのプログラムをいかにうまく組み込むかというのも考慮して以下のような設計にしました。

f:id:takuseno:20161211170155j:plain

アプリケーションが直接各モジュールを動かすのではなく、coreと名付けたOSのようなものを通してモジュールを操作します。そしてモジュールはそれぞれ独立したプロセスで動いていて、coreと標準入出力をpipeでつなぐことで通信します。これにより、各モジュールを動かすプログラムはC言語でもいいし、Pythonでもいいという感じで制限をなくすことができました。

工夫しなければならなかったこと

カメラで顔認識を行なっているのですが、Raspberry Piの性能だと顔認識をキャプチャした毎フレームで同期的に行おうとすると他の処理をブロックしてしまうため、顔認識など値を取得してくるモジュールはすべてコールバックでプログラムを書く形にしました。

アプリケーションのコード

このような設計にすることでアプリケーションのコードはこれだけシンプルになりました。

from lib import client
import time
import threading

def sensor_listener(request):
    right = request['right']
    left = request['left']
    if right < 100 or left < 100:
        if right != left:
            if right > left:
                client.move(int(left), 100)
            else:
                client.move(100, int(right))
        else:
            client.move(100, 80)
    else:
        client.move(100, 100)
    client.get_distance(distant_listener)

class MainThread(threading.Thread):
    def __init__(self):
       super(MainThread, self).__init__()
    def run(self):
        client.get_distance(sensor_listener)

thread = MainThread()
client.startListener(thread)

たったこれだけでロボットは壁を距離センサーで検知したら避けやすい方に曲がって進むということができるようになりました(100とかいう数字はこのロボット内での単位なのであまり意味はない)。アプリケーションはcoreと通信するためのインターフェースをclientとして用意しているので、アプリケーションの実装者は下のレイヤーを全く気にする必要がなくなりました。

シミュレータ

中間発表で他の班がシミュレータを実装したというのを聞いて、こっちもやってやろうということでシミュレータを実装しました。実際の様子がこれです。

simulator

これは上のコードをそのまま動かした様子です。距離センサーのための障害物と顔認識のための顔を簡単に置けるようにしています。

これは以下のような構成にすることで実現しました。

f:id:takuseno:20161211173202j:plain

coreより下の各モジュールはスタブプログラムと差し替えてcoreからのリクエストをサーバーに送っています。もともとWebやクラウドをがっつりやっているのでこのシミュレータはブラウザ上で動いていて、シミュレーションサーバーとwebsocketで通信するというなんともWeb系ぽい方法でやっています。

このシミュレータにより、ロボット実機がなくてもアプリケーションを作れるようになりました。

課題

シミュレータはちょっと理想的な動きをしてしまうので意図的にセンサーの値などにノイズを加えたりして実地環境でも耐えうるようにしないといけません。また、顔認識の精度も実地だと照明などの関係でかなり低くなることが予想されているのでその辺もアプリケーション側が対応しないといけません。

まとめ

大学の授業ではありますが、頑張り次第では新規性?はなくとも面白いことができますということでした。