marunomaruno-memo

marunomaruno-memo

Lego Mindstoms NXT - leJOS - (9) リスナー

2008年09月02日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (9) リスナー


■ タッチセンサーに対するリスナーを実装する

つぎは、タッチセンサーに対するリスナーです。
これには、TouchSensor クラスではなく、SensorPort クラスを用
いて、ポートの番号で管理することになります。

ただ、このプログラムだと、タッチしてすぐにプログラムは停止せ
ず、停止するまでに 1 秒程度のタイムラグがあります。

------------------------------------------------------
import lejos.nxt.SensorPort;
import lejos.nxt.SensorPortListener;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * 1秒間前進し、その後1秒間停止、1秒間後退する。
 * その間に音を鳴らす。
 * エスケープ・ボタンが押されたら動きを止める。
 * @author maruno
 * @version 1.0, 2008-06-30
 * @since 1.0
 */
public class TouchListener01 {

    public static void main(String[] args) {

        // トライボットオブジェクトの生成
        Trybot trybot = new Trybot("trybot");

        SensorPort.S1.addSensorPortListener(new TouchListener());    // (1)

        while (true) {
            trybot.forward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);

            trybot.backward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);
        }
    }

    /**
     * タッチしたときに動作するリスナー
     * @author marunomaruno
     * @version 1.0, 2008/06/29
     * @since 1.0
     */
    static class TouchListener implements SensorPortListener {    // (2)
        /* (非 Javadoc)
         * @see lejos.nxt.SensorPortListener#stateChanged(lejos.nxt.SensorPort, int, int)
         */
        public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) {    // (3)
            NxtUtil.display(aSource, aOldValue, aNewValue, 2000);    // (4)
            System.exit(0);
        }
    }
}
------------------------------------------------------


ただし、これだと、タッチしていなくても、このメソッドが呼ばれ
てしまいます。
タッチセンサーの場合は、タッチされたかされないか、が返ればい
いので、2値に直して値を返す readBooleanValue メソッドを使う
必要があります。
タッチセンサーの場合は、このリスナーはすこし不便かもしれませ
ん。


□ SensorPort.S1.addSensorPortListener(new TouchListener()); // (1)

センサー・ポート S1 に、タッチセンサーのリスナーを追加します。


□ センサー・ポートの定数
---
static SensorPort[] PORTS
ポート 1 から ポート 4 まで入っている配列。

static SensorPort S1
ポート 1。

static SensorPort S2
ポート 2。

static SensorPort S3
ポート 3。

static SensorPort S4
ポート 4。
---


□ センサー・ポートの主なメソッド
---
void addSensorPortListener(SensorPortListener aListener)
指定されたリスナーをそのポートに追加します。

int getId()
ポート番号を返します。

boolean readBooleanValue()
boolean 値で値を返します。

int readRawValue()
実測値で値を返します。

int readValue()
Lego フレームワーク互換の値を返します。

---


□ static class TouchListener implements SensorPortListener { // (2)

static な内部クラスとして、SensorPortListener インタフェース
を実装します。


□ SensorPortListener インタフェースのメソッド
---
void stateChanged(SensorPort aSource, int aOldValue, int aNewValue)
センサーが指定されたポートで実測値の値が変わったときに呼
び出されます。

---


□ public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) { // (3)

センサーからの値が変わったときに呼び出されるメソッドの実装。


□ NxtUtil.display(aSource, aOldValue, aNewValue, 2000); // (4)

センサーの値を表示するメソッド display を NxtUtil クラスに用
意し、それを使います。
display メソッドの部分だけ示します。

------------------------------------------------------
    /**
     * 指定されたセンサーの情報をLCDに指定ミリ秒数表示します。
     * @param aSource センサー
     * @param aOldValue 変化がおきる前の値
     * @param aNewValue 変化後の値
     * @param milliseconds 表示ミリ秒数
     */
    public static void display(SensorPort aSource, int aOldValue, int aNewValue, int milliseconds) {
        LCD.clear();
        LCD.drawInt(aSource.getId(), 1, 1);   // ポートIDの値を表示する
        LCD.drawInt(aSource.getMode(), 1, 2); // モード値を表示する
        LCD.drawInt(aSource.getType(), 1, 3); // タイプ値を表示する
        LCD.drawInt(aOldValue, 1, 4);         // 変化がおきる前の値を表示
        LCD.drawInt(aNewValue, 1, 5);         // 変化後の値を表示する
        LCD.refresh();
        pause(milliseconds);
    }

------------------------------------------------------




■ 各センサーの値を読み取るリスナー

------------------------------------------------------
import l.EscapeListener;
import lejos.nxt.Button;
import lejos.nxt.SensorPort;
import lejos.nxt.SensorPortListener;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * 各センサーからの値を表示する。
 * @author maruno
 * @version 1.0, 2008-06-29
 * @since 1.0
 */
public class SensorListener01 {

    public static void main(String[] args) {

        // トライボットオブジェクトの生成
        Trybot trybot = new Trybot("trybot");

        Button.ESCAPE.addButtonListener(new EscapeListener());    // (1)

        SensorPort.S1.addSensorPortListener(new Listener());    // (2) タッチセンサー
        SensorPort.S2.addSensorPortListener(new Listener());    // (3) 音センサー
        SensorPort.S3.addSensorPortListener(new Listener());    // (4) 光センサー
        SensorPort.S4.addSensorPortListener(new Listener());    // (5) 超音波センサー

        while (true) {
            trybot.forward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);

            trybot.backward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);
        }
    }

    /**
     * センサーの値に変化がおきたときに動作するリスナー
     * @author marunomaruno
     * @version 1.0, 2008/06/29
     * @since 1.0
     */
    static class Listener implements SensorPortListener {    
        /* (非 Javadoc)
         * @see lejos.nxt.SensorPortListener#stateChanged(lejos.nxt.SensorPort, int, int)
         */
        public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) {
            NxtUtil.display(aSource, aOldValue, aNewValue, 2000);
        }
    }

}
------------------------------------------------------



□ Button.ESCAPE.addButtonListener(new EscapeListener()); // (1)

また、エスケープ・ボタンで終わるようにする。


□ SensorPort.S1.addSensorPortListener(new Listener()); // (2) タッチセンサー
SensorPort.S2.addSensorPortListener(new Listener()); // (3) 音センサー
SensorPort.S3.addSensorPortListener(new Listener()); // (4) 光センサー
SensorPort.S4.addSensorPortListener(new Listener()); // (5) 超音波センサー

各ポートにつけたセンサーのリスナーを追加する。このとき、リス
ナーの動きはすべて同じなので、同じリスナーを使います。


以上