LoginSignup
1
2

More than 5 years have passed since last update.

leJOS EV3 の LinearCalibrationFilter

Posted at

これは、ETロボコン Advent Calendar 2015 - Adventarの 6日目のエントリーです。

主にleJOS担当な某地区実行委員です。6日目、当日になってもエントリが無かったので、小ネタですが書いてみます。

ETロボコン 2015 の公式プラットフォームの1つにもなっている leJOS EV3 ですが、EV3本体、センサー、モータの API 以外にもロボテックス関連のちょっとよい API がいろいろあります。今回はその中から LinearCalibrationFilter クラスを紹介します。

leJOS EV3 はセンサーフレームワークという手順でセンサー値を取り出します。様々なセンサーを統一的な手段で扱うようにするためですが、ちょっと面倒くさいです。こんな感じです。

センサー = new センサークラス(ポート);
センサープロバイダー = センサー.getMode(センサーモード);
float[] sample = new float[センサープロバイダー.sampleSize()];
センサープロバイダー.fetchSample(サンプル, 0);

leJOS EV3 では、このセンサーフレームワークを応用したフィルタクラス群があって、lejos.robotics.filter パッケージにあります。LinearCalibrationFilter はその中の1つで、センサーのキャリブレーション、目標値との差分を取り出すことができます。

例として、ライントレースでよく使われるカラーセンサーの輝度検出モードを扱う場合には以下のようにします。

EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S3); // カラーセンサー
SensorMode redMode = colorSensor.getRedMode(); // 輝度検出モード
float[] sample = new float[redMode.sampleSize()];
LinearCalibrationFilter calibrator = new LinearCalibrationFilter(redMode);

これで準備はできました。キャリブレーションは以下のようにします。ESCAPEボタンが押されるまでキャリブレーションを行います。

calibrator.startCalibration();                 // キャリブレーション開始
while (!Button.ESCAPE.isDown()) {
    calibrator.fetchSample(sample, 0);           // キャリブレーション実行

    // この間に、輝度の最大と最小が得られる所、適当にセンサー位置を変える
    // モータで自動でやるのもよし、手で動かすのもよし
}
calibrator.stopCalibration();                  // キャリブレーション停止
calibrator.save("redcalpar");                  // キャリブレーション結果のセーブ

ちなみにキャリブレーション中は、センサー値にローパスフィルターもかかります。

これでキャリブレーション結果が leJOS EV3 内の /home/root/sensorCalibration/redcalpar.cal に格納されます。このファイルの中身は以下のようなものです。

sampleSize=1
calibrationType=0.0
type=LinearCalibrationFilter
scale=1.0
offset=0.38000003
項目 説明
sampleSize サンプル数、要するにセンサー値の数
calibrationType 0 ならセンサー値そのもの、1ならスケールに対する割合、なぜか float
type キャリブレーションしたクラス
scale センサー値のスケール。センサー値がとり得る幅のこと
offset キャリブレーションしたセンサー値の最小値の最大値の中間値

キャリブレーション結果を使った実行は以下のような感じです。

LinearCalibrationFilter tracker = new LinearCalibrationFilter(redMode, "redcalpar");
while (!Button.ESCAPE.isDown()) {  // ESCAPE ボタンが押されるまで
    tracker.fetchSample(sample, 0);
    float error = sample[0];         // offset (要するに目標値)との差分

    // 差分から PID 制御してモータ動かすなりなんなりと

}

ちなみに、このキャリブレーションでないモードでの実行ではローパスフィルターかかりません。かけたい場合は lejos.robotics.filter.LowPassFilter も使いましょう。

LinearCalibrationFilter の詳しい仕様は leJOSのAPIドキュメントを参照。

lejos.robotics 配下には、この他にも使えそうなものがあるので、興味のある方は調べてみてください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2