SampleEV3Way for leJOS

ETロボコンの参加者に配布されるテストコース上で、EV3Wayを走行させるJavaのサンプルプログラム。

http://sourceforge.net/p/etroboev3/code/ci/master/tree/SampleCode/EV3way_leJOS_sample/ev3sample/

上記で公開されているプログラムをベースにして、倒立制御をタイマータスクで行うように改良した。 また、走行データのロギング,音楽再生などの機能追加を行った。

ダウンロード

以下のリンクをクリックして、ソースファイルをダウンロードする。

./SampleEV3Way20151010.zip

netbeansのプロジェクトディレクトリをそのままzip形式で圧縮してある。
ダウンロード後、zipファイルを展開して、netbeansでプロジェクトとして読みこめばそのまま利用できる。

EV3Way走行体の設定について

このプログラムでは、センサーとモーターを以下のように接続しているEV3Way走行体を前提している。
接続が異なる場合は、ソースコードを修正すること。

入力ポートの割当て 出力ポートの割当て
ポート センサー ポート モーター
1 タッチセンサー A 尻尾モータ
2 超音波センサー B 右車輪用モータ
3 カラーセンサー C 左車輪用モータ
4 ジャイロセンサー

プログラムのコンパイルとアップロード方法

プログラムのコンパイルとアップロード方法は、以下のURLを参考すること。

LeJOS EV3 実行/Netbeans開発環境構築メモ(Windows版)

使い方

  1. 走行体の後部モータに尻尾がつく位置まで跳ね上げておく。
  2. プログラムを起動する。しばらく(約40秒程度?)待つと、音楽を再生を開始する。(音楽の再生中にデバイスの初期化等を行う。)
  3. 音楽の再生が終了すると、尻尾が下がり自立可能状態になる。これで走行準備完了となる。
  4. 走行体のカラーセンサーがテストコースのグレーマーカーの上にくるように設置する。
    • 進行方向に向かって右側のラインエッジに走行体を設置する。(液晶の以下の表示に合わせること。)

      Black <|> White
    • カラーセンサーの赤い光の円の中心がラインのエッジの真上にくるようにすること。
  5. タッチスイッチを押すとスタート音が流れ、その後、ライントレース走行を開始する。
    スタート音が流れている間に、光センサーの校正を行って閾値を決定し、ジャイロセンサーを初期化しているので、絶対に走行体に触れないこと。また、振動も与えてはいけない。
  6. 走行中に、超音波センサーで前方に障害物を検出すると減速し、更に近づくと自動停止する。障害物が無くなると走行を再開する。
  7. 走行体は、以下の条件で停止する。
    • タッチスイッチが押された場合。
    • 走行開始後、2分を経過した場合。
    • 転倒したり大きな衝撃を受けた場合。
  8. 走行を終了すると、走行データの保存を開始する。
    長いビープ音が鳴ったら、ログの保存完了である。(最大で数十秒)

ログデータについて

EV3のSDメモリカード内に保存された走行のログデータの回収方法は以下のとおりである。

  1. EV3 Control Centerを起動してPCからEV3に接続する。
  2. Programsタブを開き、“SampleEV3WayLog.csv”を選択する。
  3. [Download file]ボタンを押して、PCに走行のログデータを保存する。

参考:EV3 Control Center の使い方

ログデータの分析

走行のログデータは、以下のようなcsv形式で保存されている。

# THRESHOLD: 0.219700
# Running time: 120008
# time, turn, speed, battery, angleL, angleR, bright, gyro, sonar
74,40.000000,40.000000,7369,1,-2,0.220000,-1.000000,1.512000
78,40.000000,40.000000,7367,1,-2,0.220000,-11.000000,1.512000
79,40.000000,40.000000,7367,1,-2,0.220000,-4.000000,1.512000
80,40.000000,40.000000,7367,1,-2,0.220000,-4.000000,1.512000
81,40.000000,40.000000,7367,1,-2,0.220000,-4.000000,1.512000
83,40.000000,40.000000,7367,1,-2,0.220000,-4.000000,1.512000
84,40.000000,40.000000,7351,1,-2,0.220000,-4.000000,1.512000
85,40.000000,40.000000,7351,1,-2,0.220000,1.000000,1.512000
87,40.000000,40.000000,7351,1,-2,0.220000,1.000000,1.512000
88,40.000000,40.000000,7351,1,-2,0.220000,1.000000,1.512000

csv形式のデータは汎用性が高く、各種のツールで読み込み可能なので、使いやすいツールで分析することが可能。 サンプルとして、配布しているZipファイルのlog_dataディレクトリ内に、走行時のログデータ(*.csv)とそれをグラフ化するためのgnuplot(*.plt)のスクリプトを入れてある参考にすること。

$ tree log_data/
log_data/
├── Gyro_Long.plt
├── Gyro_Long_course.png
├── Gyro_Test.plt
├── Gyro_Test_course.png
├── LongCourseLog.csv
├── Odometer_Long.plt
├── Odometer_Long_course.png
├── Odometer_Test.plt
├── Odometer_Test_course.png
├── Photodetector_Long.plt
├── Photodetector_Long_course.png
├── Photodetector_Test.plt
├── Photodetector_Test_course.png
├── Sonar_Speed_Long.plt
├── Sonar_Speed_Long_course.png
├── Sonar_Speed_Test.plt
├── Sonar_Speed_Test_course.png
└── TestCourseLog.csv

技術解説

2015年シーズンの参加者の中から、EV3+jejos(Java実行環境)について、以下のような不満が寄せられていた。
今回、公開したプログラムは、これらの問題の回避策の1例として作成したものである。

1.走行が不安定。
2.スタートの失敗が多い。

1.走行が不安定。

症状・問題点

普通に走っていた走行体が、突然、フラつき始める。
ひどい場合は、そのまま転倒することもある。

考えられる原因

4msの周期で倒立制御が行われていないことが原因と考えられる。
おそらく、倒立走行のサンプルとして公開されていたソースコードをベースに拡張していったものと推察される。
これは、公開されていたサンプルが、単に倒立振子ライブラリの動作確認のために作られたものなので、複雑な走行アルゴリズムを組み込んでいくことに無理がある。
このサンプルは、以下のように、mainの中に無限ループを作り、ウェイトによって4msになるように調整して倒立制御の周期実行を実現している。これでは、ちょっとした外乱で、周期実行が乱され不安定になってしまう。

public static void main(String[] args) {
    初期化();
    for (;;) {
       倒立制御();
       Delay.msDelay(2);  // だいたい 4ms/ループ となるようにウェイト
    }
}

解決策

以下のソースのように、timertaskの中で、倒立制御を行うようにする必要がある。これで、4msの周期が(かなり)守られる。

初期化();
timer      = new Timer();
tracerTask = new TimerTask() {
    @Override
    public void run() {
        倒立制御();
    }
};
// 4msで周期タスク開始
timer.scheduleAtFixedRate(tracerTask, 0, 4); // tracerTask内のrun()メソッドが、4ms毎に呼び出される。

ただし、timertask内では、倒立制御に必要な最低限の処理だけに止め、実行時間が増大しないように(4msを超えないように)注意する必要がある。
よって、tracerTask内のrun()メソッドでは、以下のような負荷の大きな(大きくなる可能性のある)作業をしてはいけない。

  • ファイルの読み書きを行わない。
  • print文を使わない。(内部で出力がログファイルに書き込まれている。)
  • リアルタイムで無線通信?

このような制約があると、「制御のログを取る方法がないのでは?」と心配されるかもしれない。
このような場合は、大きな配列を用意しておき、ここに実行時のログを書き込んでいき、走行終了後に、配列の内容をファイルに書き出せば良い。
配列へのデータ書き込みは、メモリー間のコピーなのでシステムへの負荷は少なくて済む。

2.スタートの失敗が多い。

症状・問題点

  • スタートボタンを押しても、立たずにそのまま転倒する。
  • いきなりバックする。
  • いきなり大きくコースを外れる。

考えられる原因

ジャイロの初期化中に走行体を動かしたことが原因。
ジャイロの初期化中に振動を与えると、ジャイロの校正が正しく行えない。

解決策

ジャイロの初期化中は、走行体を動かさないことが重要である。 そこで、今回のサンプルでは、尻尾を使って走行体を自立させた状態にしてコース上に置いてもらい、 この状態で、タッチスイッチを押すとスタートする仕様にした。
タッチスイッチが押されると走行開始音が鳴る。この音がなっている間に、ジャイロの初期化を行い、光センサーの校正を行い、これら一連の処理が完了してから、尻尾を上げて走行を開始する。
このようなスタートシーケンスにしておけば、走行体に触られる事はない。

その他

BGMについて

走行中のBGMは、単なる遊びではない。
複数のタスクを同時に動かす事例として組み入れた。
また、タスクの切り替え処理等が正確に行われていないと、音飛びやリズムの乱れが生じることがあるので、 再生されているBGMを聞いていれば内部の処理が正常に機能しているかの判断材料になる。

電池電圧

電池電圧が低下すると走行体は不安定になるようなので、小まめに、電池電圧をチェックすること。