marunomaruno-memo

marunomaruno-memo

Lego Mindstoms NXT - leJOS - (8) ボタン・リスナー

2008年08月26日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (8) ボタン・リスナー

leJOS では、ボタンを押す、などのイベントを拾って、そのイベン
トに対する操作を実現する仕組みが用意されています。

たとえば、トライボットが動いているときに、エスケープ・ボタン
を押したらトライボットが止まるようにしてみましょう。

トライボットは、500 ミリ秒ずつ前進と後退を繰り返します。前進、
後退の間に 500 ミリ秒間のの停止があります。


■ リスナーを使わない実装

いままでの知識だけで実装してみます。
これだと、後退して、500ミリ秒間停止しているときでないと、プ
ログラムは停止しません。すなわち、好きなときにプログラムを停
止することができないのです。

------------------------------------------------------
import lejos.nxt.Button;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * エスケープボタンを押すと止まる。
 * (ただし、後退直後に押さないと止まらない)
 * @author maruno
 * @version 1.0, 2008-06-26
 * @since 1.0
 */
public class ButtonListener01 {

    public static void main(String[] args) {

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

        while (!Button.ESCAPE.isPressed()) {    // (1)
            trybot.forward();
            NxtUtil.pause(500);
            trybot.stop();

            NxtUtil.pause(500);

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

            NxtUtil.pause(500);

        }
    }

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



□ while (!Button.ESCAPE.isPressed()) { // (1)

エスケープ・ボタンが押されていない間繰り返します。



■ リスナーを使った実装

それでは、エスケープ・ボタンを押したことを検知して、そのとき
の動作をするリスナークラスを使って、先ほどのプログラムを作り
直します。

なお、リスナークラスは、パッケージ l に入れることにします。

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

/**
 * 「トライボット」使用
 * エスケープボタンを押すと止まる。
 * @author maruno
 * @version 1.0, 2008-06-26
 * @since 1.0
 */
public class ButtonListener02 {

    public static void main(String[] args) {

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

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

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

            NxtUtil.pause(500);

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

            NxtUtil.pause(500);

        }
    }

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



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

エスケープ・ボタンにリスナーを登録します。登録するには、ボタ
ンのオブジェクトの addButtonListener メソッドを使います。


□ addButtonListener メソッド
---
void addButtonListener(ButtonListener aListener)
ボタンイベントのリスナーオブジェクトを追加します。
---


□ while (true) { // (2)

今度は無限ループにしておきます。


□ リスナーのソースです。


------------------------------------------------------
package l;

import lejos.nxt.Button;
import lejos.nxt.ButtonListener;

/**
 * エスケープ・ボタンを押下したときに動作するリスナー
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/29
 * @since 1.0
 */
public class EscapeListener implements ButtonListener {    // (1)
    /*
     * (非 Javadoc)
     * 
     * @see lejos.nxt.ButtonListener#buttonPressed(lejos.nxt.Button)
     */
    public void buttonPressed(Button button) {    // (2)
        System.exit(0);
    }

    /*
     * (非 Javadoc)
     * 
     * @see lejos.nxt.ButtonListener#buttonReleased(lejos.nxt.Button)
     */
    public void buttonReleased(Button button) {    // (3)
        System.exit(0);
    }
}

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



□ public class EscapeListener implements ButtonListener { // (1)

エスケープ・ボタンが押されたことを処理するリスナー・クラスは、
ButtonListener インタフェースを実装します。


□ ButtonListener インタフェースのメソッド
---
void buttonPressed(Button b)
void buttonReleased(Button b)
---


□ public void buttonPressed(Button button) { // (2)

ボタンが押されたときの処理を実装します。今回は、プログラムを
終了するようにします。


□ public void buttonReleased(Button button) { // (3)

ボタンから離れたときの処理を実装します。今回は、プログラムを
終了するようにします。



■ 内部クラスを使った実装

この程度の実装のリスナーなら、わざわざ別クラスにすることもな
いでしょう。
static な内部クラスを使って実装します。


------------------------------------------------------
import lejos.nxt.Button;
import lejos.nxt.ButtonListener;
import tb.Trybot;
import u.NxtUtil;

/**
 * 「トライボット」使用
 * エスケープボタンを押すと止まる。
 * @author maruno
 * @version 1.0, 2008-06-26
 * @since 1.0
 */
public class ButtonListener03 {

    public static void main(String[] args) {

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

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

        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 EscapeListener implements ButtonListener {    // (1)
        /* (非 Javadoc)
         * @see lejos.nxt.ButtonListener#buttonPressed(lejos.nxt.Button)
         */
        public void buttonPressed(Button button) {
            System.exit(0);
        }

        /* (非 Javadoc)
         * @see lejos.nxt.ButtonListener#buttonReleased(lejos.nxt.Button)
         */
        public void buttonReleased(Button button) {
            System.exit(0);
        }
    }

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



□ static class EscapeListener implements ButtonListener { // (1)

内部クラスを使い、EscapeListener クラスを実装します。



以上


Lego Mindstoms NXT - leJOS - (7) トライボット・オブジェクト

2008年08月19日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (7) トライボット・オブジェクト

前回、トライボットを動かすプログラムを作りました。これをもと
に、トライボット・クラスを作ってみましょう。

■ トライボットクラス

まず、「物が置かれるまで停止」や、「タッチするまで前進」など
をメソッドとして扱えるようにします。この、物を置かれるまで停
止などは、超音波センサーを使っていますが、そのようなセンサー
やモーターなどを標準のポートにつなげたトライボット・オブジェ
クトや、標準とは別のポートにつけることもできるようにします。
操作用の各メソッドは、その実行時間をミリ秒単位で返すようにし
ます。とりあえず、つけておけば何かの役に立つかもしれません。
さらに、センサーのしきい値も標準値を用意し、なにも指定しなけ
れば、しきい値として標準値を使うようにしましょう。
また、将来は複数台のトライボットを使えるようにするため、個々
のオブジェクトを識別できるように名前をつけられるようにします。
他と区別つくように、パッケージ tb としておきます。


□ 定数の概要
---
static int LIGHT_THRESHOLD
光センサーで明暗を分ける標準のしきい値

static int SOUND_THRESHOLD
音センサーで音を聞き分ける標準のしきい値

static int ULTRASONIC_THRESHOLD
超音波センサーの前に物を置いたことを検知する標準の
しきい値
---


□ コンストラクタの概要
---
Trybot(String name)
トライボットを、すべて標準ポートで生成します。

Trybot(String name, float wheelDiameter, float trackWidth,
Motor leftMotor, Motor rightMotor, Motor arm,
TouchSensor touchSensor, SoundSensor soundSensor,
LightSensor lightSensor,
UltrasonicSensor ultrasonicSensor)
トライボットを、指定されたポートで生成します。
---


□ メソッドの概要
---
long closeArm(long millis)
指定されたミリ秒間、アームを閉じます。

long forwardUntilDark()
暗くなるまで前進します。

long forwardUntilDark(long threshold)
暗くなるまで前進します。

long forwardUntilTouch()
タッチされるまで前進します。

Motor getArm()
アームを取得します。

LightSensor getLightSensor()
光センサーを取得します。

String getName()
名前を取得します。

SoundSensor getSoundSensor()
音センサーを取得します。

TouchSensor getTouchSensor()
タッチセンサーを取得します。

UltrasonicSensor getUltrasonicSensor()
超音波センサーを取得します。

long openArm(long millis)
指定されたミリ秒間、アームを開きます。

long reverseMilliSeconds(long millis)
指定されたミリ秒間後退します。

long rotetoLeftMilliSeconds(long millis)
指定されたミリ秒間左回転します。

long stopUntilAnySound()
音がするまで停止します。

long stopUntilAnySound(long threshold)
音がするまで停止します。

long stopUntilPut()
物が置かれるまで停止します。

long stopUntilPut(long threshold)
物が置かれるまで停止します。
---


□ 上記APIに基づいたクラス

------------------------------------------------------
package tb;

import lejos.navigation.Pilot;
import lejos.nxt.LightSensor;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.SoundSensor;
import lejos.nxt.TouchSensor;
import lejos.nxt.UltrasonicSensor;
import u.NxtUtil;

/**
 * トライボットで必要な操作を管理するクラスです。 名前を指定するだけで、すべて標準のポートでこのオブジェクトを生成できます。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/24
 * @since 1.0
 */
public class Trybot extends Pilot {

    /**
     * 超音波センサーの前に物を置いたことを検知する標準のしきい値
     */
    public static final int ULTRASONIC_THRESHOLD = 51; // 物を置くしきい値

    /**
     * 音センサーで音を聞き分ける標準のしきい値
     */
    public static final int SOUND_THRESHOLD = 50; // 音のしきい値

    /**
     * 光センサーで明暗を分ける標準のしきい値
     */
    public static final int LIGHT_THRESHOLD = 40; // 光のしきい値

    private String name; // 名前
    private Motor arm; // アーム
    private TouchSensor touchSensor; // タッチセンサーオブジェクト
    private SoundSensor soundSensor; // 音センサーオブジェクト
    private LightSensor lightSensor; // 光センサーオブジェクト
    private UltrasonicSensor ultrasonicSensor; // 超音波センサーオブジェクト

    /**
     * トライボットを、すべて標準ポートで生成します。 標準ポートは以下のとおりです。
     * 
     * 

*

    *
  • 左モーター: ポート B *
  • 右モーター: ポート C *
  • アーム: ポート A *
  • タッチセンサー: ポート 1 *
  • 音センサー: ポート 2 *
  • 光センサー + ライト: ポート 3 *
  • 超音波センサー: ポート 4 *

*


*
* @param name 名前
*
*/
public Trybot(String name) {
this(name, 5.6f, 13f, Motor.C, Motor.B, Motor.A, new TouchSensor(
SensorPort.S1), new SoundSensor(SensorPort.S2),
new LightSensor(SensorPort.S3), new UltrasonicSensor(
SensorPort.S4));
}

/**
* トライボットを、指定されたポートで生成します。
*
* @param name 名前
* @param wheelDiameter 車輪径
* @param trackWidth トラック幅
* @param leftMotor 左モーター
* @param rightMotor 右モーター
* @param arm アーム
* @param touchSensor タッチセンサー
* @param soundSensor 音センサー
* @param lightSensor 光センサー
* @param ultrasonicSensor 超音波センサー
*/
public Trybot(String name, float wheelDiameter, float trackWidth,
Motor leftMotor, Motor rightMotor, Motor arm,
TouchSensor touchSensor, SoundSensor soundSensor,
LightSensor lightSensor, UltrasonicSensor ultrasonicSensor) {
super(wheelDiameter, trackWidth, leftMotor, rightMotor);
this.name = name;
this.arm = arm;
this.touchSensor = touchSensor;
this.soundSensor = soundSensor;
this.lightSensor = lightSensor;
this.ultrasonicSensor = ultrasonicSensor;
}

/**
* タッチされるまで前進します。
* @return このメソッドの実行にかかった時間
*/
public long forwardUntilTouch() {
long startTime = System.currentTimeMillis();
forward();
while (!touchSensor.isPressed())
;
return System.currentTimeMillis() - startTime;
}

/**
* 暗くなるまで前進します。
* @return このメソッドの実行にかかった時間
*/
public long forwardUntilDark() {
return forwardUntilDark(LIGHT_THRESHOLD);
}

/**
* 暗くなるまで前進します。
* @param threshold 暗くなるしきい値
* @return このメソッドの実行にかかった時間
*/
public long forwardUntilDark(long threshold) {
long startTime = System.currentTimeMillis();
forward();
while (lightSensor.readValue() >= threshold)
;
stop();
return System.currentTimeMillis() - startTime;
}

/**
* 指定されたミリ秒間後退します。
* @param millis 後退する時間(ミリ秒)
* @return このメソッドの実行にかかった時間
*/
public long reverseMilliSeconds(long millis) {
long startTime = System.currentTimeMillis();
backward();
NxtUtil.pause(millis);
stop();
return System.currentTimeMillis() - startTime;
}

/**
* 指定されたミリ秒間左回転します。
* @param millis 回転する時間(ミリ秒)
* @return このメソッドの実行にかかった時間
*/
public long rotetoLeftMilliSeconds(long millis) {
long startTime = System.currentTimeMillis();
getLeft().backward();
getRight().forward();
NxtUtil.pause(millis);
stop();
return System.currentTimeMillis() - startTime;
}

/**
* 指定されたミリ秒間、アームを閉じます。
* @param millis 閉じる時間(ミリ秒)
* @return このメソッドの実行にかかった時間
*/
public long closeArm(long millis) {
long startTime = System.currentTimeMillis();
arm.backward();
NxtUtil.pause(millis);
arm.stop();
return System.currentTimeMillis() - startTime;
}

/**
* 指定されたミリ秒間、アームを開きます。
* @param millis 開く時間(ミリ秒)
* @return このメソッドの実行にかかった時間
*/
public long openArm(long millis) {
long startTime = System.currentTimeMillis();
arm.forward();
NxtUtil.pause(millis);
arm.stop();
return System.currentTimeMillis() - startTime;
}

/**
* 物が置かれるまで停止します。
* @return このメソッドの実行にかかった時間
*/
public long stopUntilPut() {
return stopUntilPut(ULTRASONIC_THRESHOLD);
}

/**
* 物が置かれるまで停止します。
* @param threshold 物が置かれるしきい値
* @return このメソッドの実行にかかった時間
*/
public long stopUntilPut(long threshold) {
long startTime = System.currentTimeMillis();
stop();
while (ultrasonicSensor.getDistance() >= threshold)
;
return System.currentTimeMillis() - startTime;
}

/**
* 音がするまで停止します。
* @return このメソッドの実行にかかった時間
*/
public long stopUntilAnySound() {
return stopUntilAnySound(SOUND_THRESHOLD);
}

/**
* 音がするまで停止します。
* @param threshold 音を認識するしきい値
* @return このメソッドの実行にかかった時間
*/
public long stopUntilAnySound(long threshold) {
long startTime = System.currentTimeMillis();
stop();
while (soundSensor.readValue() <= threshold)
;
return System.currentTimeMillis() - startTime;
}

// 標準のゲッターの記載は省略します。

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


もちろん、これだけのメソッドでは、足りません。
「物が置かれるまで停止する」というメソッドがあれば、当然、
「物が置かれると前進する」などのメソッドも必要です。
ただ、あまり作りすぎてしまうと、メモリーが足りなくなると思い
ますので、必要なものだけを作っておいた方がいいでしょう。(も
う、すでに作りすぎているかもしれませんが。。。)



■ このクラスを作って Trybot01 を作り変えます。

かなりすっきりしました。でも、これはやりすぎかもしれません。
この調子でやっていったら、メソッドは際限なく増えてきますね。

------------------------------------------------------
import tb.Trybot;

/**
 * トライボット」使用 
 * 前進し、そこでタッチしたものをつかみ、後退、回転し、
 * 黒線があるところまで前進し、黒線のところでつかんだものを離す。
 * 
 * @author maruno
 * @version 1.0, 2008-06-20
 * @since 1.0
 */
public class Trybot02 {

    public static void main(String[] args) {

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

        // 物が置かれるまで停止
        trybot.stopUntilPut();

        // タッチするまで前進
        trybot.forwardUntilTouch();

        // 音がするまで停止
        trybot.stopUntilAnySound();

        // アームを閉じる
        trybot.closeArm(500);

        // 後退
        trybot.reverseMilliSeconds(500);

        // 回転
        trybot.rotetoLeftMilliSeconds(500);

        // 黒線のところまで前進して停止
        trybot.forwardUntilDark();

        // アームを開く
        trybot.openArm(500);
    }
}

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



□ Trybot trybot = new Trybot("trybot"); // (1)

名前を指定して Trybot オブジェクトを生成します。これは、すべ
て標準のポートを利用しています。


以上


Lego Mindstoms NXT - leJOS - (6) 各種センサー

2008年08月05日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (6) 各種センサー

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

それでは、タッチセンサーだけではなく、その他のセンサーも NXT
ブロックにつけてその動きを確認してみましょう。このプログラム
は、それぞれのセンサーからの値を NXT 画面に表示するものです。
プログラムを終わらせるには、エスケープボタンを押します。


------------------------------------------------------
import u.NxtUtil;
import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.LightSensor;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.SoundSensor;
import lejos.nxt.TouchSensor;
import lejos.nxt.UltrasonicSensor;

/**
 * 「トライボット」使用
 * センサーの値を読み取り、表示する。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class Sensor01 {

    public static void main(String[] args) {

        // タッチセンサーオブジェクトをポート1で生成する。
        TouchSensor touchSensor = new TouchSensor(SensorPort.S1);

        // 音センサーオブジェクトをポート2で生成する。
        SoundSensor soundSensor = new SoundSensor(SensorPort.S2);    // (1)
        
        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);    // (2)
        
        // 超音波センサーオブジェクトをポート4で生成する。
        UltrasonicSensor ultrasonicSensor = new UltrasonicSensor(SensorPort.S4);    // (3)
        
        Motor.A.forward();
        
        while (!Button.ESCAPE.isPressed()) {    // (4)
            LCD.refresh();
            
            // タッチセンサーの値の表示
            LCD.drawString("Touch    = " + touchSensor.isPressed(), 0, 0);

            // 音センサーの値の表示
            LCD.drawString("Sound    = " + soundSensor.readValue(), 0, 1);    // (5)
            
            // 光センサーの値の表示
            LCD.drawString("Light    = " + lightSensor.readValue(), 0, 2);    // (6)
            
            // 超音波センサーの値の表示
            LCD.drawString("US       = " + ultrasonicSensor.getDistance(), 0, 3);    // (7)
            
            // モーター回転速度センサーの値の表示
            LCD.drawString("Tacho    = " + Motor.A.getTachoCount(), 0, 4);    // (8)
            
            // モーター回転センサーの値の表示
            LCD.drawString("Rotation = " + Motor.A.getStopAngle(), 0, 5);    // (9)

        }
        Motor.A.stop();
        NxtUtil.pause(1000);
    }
}

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



□ SoundSensor soundSensor = new SoundSensor(SensorPort.S2); // (1)

音センサーオブジェクトをポート2で生成する。


□ コンストラクタ
---
SoundSensor(lejos.nxt.ADSensorPort port)
音センサーオブジェクトを指定ポートで生成する。

SoundSensor(SensorPort port, boolean dba)
音センサーオブジェクトを指定ポートで生成する。このとき、
DB か DBA モードかもあわせて指定する。
---


□ 主なメソッド
---
int readValue()
現在のセンサー値を読む。

void setDBA(boolean dba)
DB か DBA モードか指定する。
---


□ LightSensor lightSensor = new LightSensor(SensorPort.S3); // (2)

光センサーオブジェクトをポート3で生成する。


□ コンストラクタ
---
LightSensor(lejos.nxt.ADSensorPort port)
光センサーオブジェクトを指定ポートで生成する。

LightSensor(lejos.nxt.ADSensorPort port, boolean floodlight)
光センサーオブジェクトを指定ポートで生成する。このとき、
投光ライトを点灯するかどうかを指定する。
---


□ 主なメソッド
---
int readNormalizedValue()
現在のセンサーの正規化値を読む。

int readValue()
現在のセンサーの値を読む。

void setFloodlight(boolean floodlight)
投光ライトの点灯 / 消灯を設定する。
---


□ UltrasonicSensor ultrasonicSensor = new UltrasonicSensor(SensorPort.S4); // (3)

超音波センサーオブジェクトをポート4で生成する。


□ コンストラクタ
---
UltrasonicSensor(lejos.nxt.I2CPort port)
超音波センサーオブジェクトを指定ポートで生成する。
---


□ 主なメソッド
---
int getDistance()
対象への距離を取得する。
---


□ while (!Button.ESCAPE.isPressed()) { // (4)

エスケープボタンが押されたらループを終了します。
Button クラスは、NXT ボタンを操作するクラスです。


□ 定数
---
static Button[] BUTTONS
エンター、エスケープ、左、右ボタンがこの順に入っているボ
タン配列

static Button ENTER
エンター・ボタン

static Button ESCAPE
エスケープ・ボタン

static Button LEFT
左ボタン

static Button RIGHT
右ボタン
---


□ 主なメソッド
---
int getId()
ボタンの ID を取得する。

boolean isPressed()
ボタンが押されたかどうかを検査する。

void waitForPressAndRelease()
ボタンから押されたり離れたりするまで待つ。
---


□ LCD.drawString("Sound = " + soundSensor.readValue(), 0, 1); // (5)
□ LCD.drawString("Light = " + lightSensor.readValue(), 0, 2); // (6)
□ LCD.drawString("US = " + ultrasonicSensor.getDistance(), 0, 3); // (7)
□ LCD.drawString("Tacho = " + Motor.A.getTachoCount(), 0, 4); // (8)
□ LCD.drawString("Rotation = " + Motor.A.getStopAngle(), 0, 5); // (9)

それぞれのセンサーの値を NXT 画面に表示します。



■ トライポッドの動きを NXC プログラムで再現する

------------------------------------------------------
import u.NxtUtil;
import lejos.navigation.Pilot;
import lejos.nxt.LightSensor;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.SoundSensor;
import lejos.nxt.TouchSensor;
import lejos.nxt.UltrasonicSensor;

/**
 * 「トライボット」使用 
 * 前進し、そこでタッチしたものをつかみ、後退、回転し、
 * 黒線があるところまで前進し、黒線のところでつかんだものを離す。
 * 
 * @author maruno
 * @version 1.0, 2008-06-20
 * @since 1.0
 */
public class Trybot01 {

    private static int PUT_THRESHOLD = 51; // 物を置くしきい値

    private static int SOUND_THRESHOLD = 50; // 音のしきい値

    private static int LIGHT_THRESHOLD = 40; // 光のしきい値

    public static void main(String[] args) {

        TouchSensor touchSensor = new TouchSensor(SensorPort.S1); // タッチセンサーオブジェクト
        SoundSensor soundSensor = new SoundSensor(SensorPort.S2); // 音センサーオブジェクト
        LightSensor lightSensor = new LightSensor(SensorPort.S3); // 光センサーオブジェクト
        UltrasonicSensor ultrasonicSensor = new UltrasonicSensor(SensorPort.S4); // 超音波センサーオブジェクト

        // パイロットのオブジェクトを生成する
        Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);

        // 物が置かれるまで停止
        while (ultrasonicSensor.getDistance() >= PUT_THRESHOLD)
            ;

        // タッチするまで前進
        pilot.forward();
        while (!touchSensor.isPressed())
            ;

        // 音がするまで停止
        pilot.stop();
        while (soundSensor.readValue() <= SOUND_THRESHOLD)
; // アームを閉じる Motor.A.backward(); NxtUtil.pause(500); Motor.A.stop(); // 後退 pilot.backward(); NxtUtil.pause(500); pilot.stop(); // 回転 pilot.getLeft().backward(); pilot.getRight().forward(); NxtUtil.pause(500); pilot.stop(); // 黒線のところまで前進して停止 pilot.forward(); while (lightSensor.readValue() >= LIGHT_THRESHOLD) ; pilot.stop(); // アームを開く Motor.A.forward(); NxtUtil.pause(500); Motor.A.stop(); } } ------------------------------------------------------



以上