私は最近プロジェクトに取り組んでおり、センサーネットワークを複雑にするのに十分に関与した最初のプロジェクトでした。結局のところ、コミュニケーションが全体的なパフォーマンスのボトルネックになっていると思います。経験豊富な人々がこの問題をどのように解決していたのだろうと思います。長い読みですが、なかなか面白いと思いますので、こだわってください。問題は、障害物コースをナビゲートし、ピンポンボールを茶色のボックスターゲットにドロップできる自律型飛行船を設計することでした。ここに行く:
センサー
- 4D Systems uCAM-TTLカメラモジュール-UARTインターフェイス
- HMC6352デジタルコンパス-I2Cインターフェイス
- Maxbotix Sonar ez4-1ピンアナログインターフェイス
アクチュエーター
- 2x L293Dモータードライバー(シンプルなホビーモーターに接続)-これらは、6つのモーターを双方向で駆動するために使用されました。速度を変えるためにPWM入力が必要でした。現在、3つのモーターは常に同じこと(上下の動きを制御するモーター)を使用していたため、3つのモーターすべてを制御するためにコントローラーから2つのPWM出力のみが必要でした。横方向の動きを制御する他の3つのモーターはすべて個別の制御(全方向移動)を必要としていたため、コントローラーからはさらに6つのPWM出力が必要でした。
- サーボモーター-PWMインターフェース
コントローラー
後で明らかになる理由により、2倍のATmega328Pを使用することになりました。プログラミングにはArduino Unoを使用しましたが(ISPにアクセスできませんでした)、カスタムPCBを製造したので、飛行船に不要な重量が加わるため、Arduinoボードを使用する必要がありませんでした。私たちがATmega328Pを選んだ理由については、私はarduino環境に非常に精通しており、それによってコード開発がはるかに迅速かつ簡単になったと思います。
通信と処理
- 2x Xbee Basic
- 2x ATmega328P
- C ++とopenCVを実行しているデスクトップコンピューター
カメラモジュールからわかるように、私たちのプロジェクトのほとんどはコンピュータービジョンに依存していました。飛行船はそれほどの重量しか運ぶことができず、マイクロコントローラーにコンピュータービジョンを実装するのは快適でした。そのため、XBeeを使用して画像データをデスクトップコンピューターに中継しました。サーバー側では、画像データを受け取り、openCVを使用して画像と図を処理しました。今度はサーバー側も高さ情報(ソナーから)とコンパス情報を知る必要がありました。
最初のしわは、いくつかの理由でマイクロコントローラーでカメラを制御できなかったことでした。主な問題は、uPの内部メモリがフレーム全体の格納を処理できないことでした。巧妙なコーディングによってこれを回避する方法があったかもしれませんが、この質問の目的のために、それが不可能であったとしましょう。この問題を解決するために、サーバー側でXBeeトランシーバーを介してカメラコマンドを送信し、XBeeレシーバー(飛行船に搭載)の出力をカメラの入力に配線しました。
次のしわは、I2CインターフェースがPWMピンの1つを使用しているため(それらをくそ...)、すべてのモーターを制御するのに十分なPWMが1つのATmega328Pにないということでした。そのため、2番目のものを使用することにしました。高さ制御は横方向の移動制御とは完全に独立しているため、コードは実際には並列処理に完全に対応しています(したがって、2マイクロはおそらくPWMコントローラーに接続されたものよりも優れていました)。したがって、U1は2つのPWM出力(アップ/ダウン)とソナーの読み取りを担当していました。U2は、コンパスの読み取り、6つのPWM出力(横方向モーター)の制御、およびソナーの読み取りを担当しました。U2は、XBeeを介してサーバーからコマンドを受信することも担当していました。
それが最初のコミュニケーションの問題につながりました。XBee DOUTラインは、マイクロコントローラーとカメラの両方に接続されていました。もちろん、プロトコルを設計して、マイクロコマンドがカメラコマンドを無視し、カメラコマンドがマイクロコマンドを無視するようにしたので、問題はありませんでした。ただし、カメラがマイクロコマンドを無視すると、出力ラインにNAKデータが返されます。このコマンドはマイクロを対象としているため、XBeeへのカメラ出力をオフにする必要があります。これを解決するために、カメラとXBee(最初のFET)の間、およびU2とXBee(2番目のFET)の間にあるマイクロ制御2 FETを作成しました。したがって、カメラがサーバーに情報を返そうとしたとき、最初のFETは「オン」で、2番目のFETは「オフ」でした。
したがって、これがどのように機能するかを理解するために、いくつかの例を示します。
- サーバーは画像を要求します-PIC_REQUESTはXBeeを通過し、U2とカメラに到着します。U2はそれを無視し、カメラは画像データを送り返します。
- サーバーは画像の処理を終了し、モーターデータを送信して飛行船に右折するように指示しています-MOTOR_ANGLE(70)はXBeeを通り抜け、U2とカメラに到着します。U2はマイクロコマンドとして認識し、カメラのFETをオフにします(ただし、カメラはすでにNAKで応答していますか?次に、U2はモーターのPWM出力を変更することでコマンドに応答します。次に、カメラのFETをオンに戻します(画像データが最も重要だったため、これがデフォルト設定でした)。
- サーバーは、デフォルトのホバー高さが50インチではなく90インチである必要がある障害物コースのポイントに到達したことを認識しています。SET_HEIGHTはXBeeを通過し、例2と同じことが起こります。U2はSET_HEIGHTコマンドを認識し、U1で割り込みをトリガーします。U1は高さ制御ループから出て、U2からのシリアルデータの受信を待ちます。そうです、より多くのシリアルデータ。この時点でU2のFETはオン(そしてカメラのFETはオフ)なので、サーバーはU2がU1にも送信している高さを受け取ります。これは確認のためでした。U1は、height2HoverAtの内部変数をリセットします。U2はFETをオフにし、カメラFETをオンに戻します。
私は間違いなくかなりの量の情報を省きましたが、いくつかの複雑さを理解するにはそれで十分だと思います。結局のところ、私たちの問題は単にすべてを同期させることでした。バッファにデータが残っていることがありますが、3バイトしかありません(すべてのコマンドは6バイトシーケンスでした)。時々、カメラとの接続を失い、それを再同期する必要があります。
だから私の質問は:これらのすべてのコンポーネント間の通信をより信頼性の高い/堅牢な/単純な/より良いものにするために、どのようなテクニックを提案するでしょうか?
たとえば、オンボードXBeeアウトとカメラの間に遅延回路を追加して、マイクロがNAKのマイクロコマンドに応答する前にカメラのトークラインをオフにする機会があったことを知っています。そのような他のアイデアはありますか?
おかげで、これには多くの編集が必要になると確信していますので、しばらくお待ちください。
Edit1:マイクロの1つを介してカメラのUARTデータを接続することは、私たちには不可能であるように思われました。カメラデータには、生のビットマップ、またはJPEGの2つのオプションがありました。生のビットマップの場合、カメラはデータをできるだけ早く送信します。ATmega328Pはシリアルバッファ用に128バイトしかありません(技術的にはこれは設定可能ですが、どうすればいいのかわかりません)、私たちはそれをバッファから取り出してXBeeに十分速く到達できるとは思いませんでした。これにより、JPEGメソッドは各パッケージを送信し、コントローラーがACKを受信するまで待機します(小さなハンドシェークプロトコル)。これが最も速いのは115200ボーでした。何らかの理由で、XBeeを介して大量のデータを確実に送信できる最速は57600ボーでした(これは、自動再送機能を許可するためにノードとネットワークのペアリングを行った後でも同じです)。マイクロ用にネットワークに追加のストップ(カメラからXBeeへのカメラではなく、カメラからマイクロへのXBee)を追加すると、画像の転送に時間がかかりすぎます。モーター制御アルゴリズムを機能させるには、画像に特定のリフレッシュレートが必要でした。