OpenMVをどうにかC#で制御したい

Pocket

OSSのいい所を味わっていきましょう。

  1. 事情
  2. しらべて実装
  3. 知見
  4. まとめ

1. 事情

つい先日Indiegogoで出資していたuArm Swiftというロボットが届きました。

このロボットには画像処理もサポートできるようにとOpen MVカメラが付属していたのですが、正直持て余していました。

何もしないのも持て余したままでつまらないので、とりあえず例によって、C#で制御できるか試しました。ロボット本体はC#用に色々整備しており、とくにUnityで制御できるアテもついている(この記事とか参照)ので、カメラもひとます様子を見ておこう、という魂胆です。

 

2. しらべて実装

やりたい事は大まかにいうとOpenMV IDEの真似です。

  • ボードのファームウェアバージョンがとれる(=基本的な通信ができる)状態にしたい
  • LEDをチカチカしたり、ボードを制御したい
  • 画像処理プログラムを実行/停止したい
  • 現在とっている画像をPC側にも持ってきたい

いずれも、答えはOpenMVのGitHubを読んでればわかります。とくに見るべきソースは以下2つ。

要点は以下の通りです。

  • シリアル通信をボーレート921600または12000000で接続するとIDE用の専用モードで接続したことになる
    • ボーレートが低い(115200とか)接続で普通にやってるとMicroPython REPLが動く
  • 基本的に、アスキーコード0x30から始まるデータを渡してやりとりする
  • 画像処理用のMicroPythonスクリプトを実行したい場合、スクリプトの内容全体を文字列として投げつける

で、動作環境は.NETなら割と何でもいいんですが、ここでは最終的に絵を出したいのでUnityを使った例で行きます。
以下にスクリプトの実装例(JpgToTexture.cs)を示します。
本来.NETのシリアル受信処理はそのまま使わない方がいいらしい1のですが、面倒なので普通にやっちゃってます。

長いので折りたたみ。

JpgToTexture.cs(クリックで展開)

 

さらに通信に使うProtocolというのも別ファイルで定義します。
上のスクリプトとは異なり、Unity特有のMonoBehaviorとかが関係ないので、こちらは本格的に普通のC#コードとなります。
こちらも一応たたんでおきます。

Protocol.cs(クリックで展開)

 

また上記の例では実行時デスクトップ直下にtest_openmv.pyというファイルが無いと動かないので、それも用意します。
内容としては、例えばエッジ検出の簡単なコードを置きたければ以下のようなものを。

要するに、ふだんOpenMV IDEで書いてるようなのと同じものならOKです。

 

以上の用意が出来たら、JpgToTextureを適当なPlaneなどにアタッチし、シリアル通信ポートの名前を正しく設定して動かします。以下が動かした例です。

エッジ検出するプログラムを読み込んで実行し、結果の画像をUnity側に引っ張りこめています。

 

3. 知見

  • 上記のプログラムだとOpenMV IDEに比べてFPSが出ない
    • ちょくちょくフレームバッファのサイズ取得に失敗しています。運にも依存します。詳細はよくわかってません。
  • PCに持ち込める画像はJPG圧縮されてるので粗い
    • 単純に通信量を削る(FPSを上げる)ためにそうなっているようです。PC側でbmp貰って画像処理しようとするのは基本NG、ということです。
  • この方法を使っている場合、カメラ画像以外の情報(物体認識の有無とか位置とか)はシリアル通信で取得できない(ように見える)
    • 両立したければ大人しくSPIとかUARTとかのピンを使いましょう、という話っぽいです。

 

4. まとめ

完璧ではないですが、C#Pythonを真似したコードでほぼOpenMVボードが制御できる事が分かりました。
ここではUnityに突っ込む方向性で紹介しましたが、あくまで画像表示に使ってただけなので、
通常のWindows向けコードでも同じような事は出来ます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です