marunomaruno-memo

marunomaruno-memo

Lego Mindstoms NXT - leJOS - (3) クラス

2008年07月15日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (3) クラス

今回は、自分でクラスを作ってみましょう。なので、今回は、leJOS
の新しい API は出てきません。


■ ユーティリティのクラスを作る

ForwardBack01 クラスのままだと、少しみにくいので、つぎの 2
つのクラスを作ります。ユーティリティとして作るので、今までの
ようなデフォルト・パッケージを使うのではなく、1文字ですが、
「u」というパッケージにしておきましょう。

PairMotor: ペアでモーターを扱うクラス
NxtUtil: スリープなどをユーティリティとして扱う
ユーティリティ・クラス

これらを使って ForwardBack01 を変更しました。NBC もどきにな
りますが、けっこう見やすく、また、作りやすくなったと思います。

ただし、メモリが少ないので、オブジェクトをつくりすぎると、す
ぐにメモリーがいっぱいになってしまうと思いますので注意してく
ださい。


□ モーターをペアで管理するクラス PairMotor

このクラスの定数 BC を使うことで、左右のモーターを同じ値で同
時に動かすことができます。

ただし、前進、後退、停止と、左右のモーターを取得するメソッド
しかありません。


------------------------------------------------------
package u;
import lejos.nxt.Motor;

/**
 * モーターをペアで管理するクラス。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/12
 * @since 1.0
 */
public class PairMotor {
    
    private Motor leftMotor;

    private Motor rightMotor;

    /**
     * 右をB、左をC モーターをペアにしたモーター。 
     */
    public static final PairMotor CB = new PairMotor(Motor.C, Motor.B);
    
    /**
     * このインスタンスを生成するコンストラクターです。
     * @param leftMotor 左側のモーター
     * @param rightMotor 右側のモーター
     */
    public PairMotor(Motor leftMotor, Motor rightMotor) {
        this.leftMotor = leftMotor;
        this.rightMotor = rightMotor;
    }

    /**
     * 左側のモーターを取得します。
     * @return 左側のモーターを戻します。
     */
    public Motor getLeftMotor() {
        return leftMotor;
    }

    /**
     * 右側のモーターを取得します。
     * @return 右側のモーターを戻します。
     */
    public Motor getRightMotor() {
        return rightMotor;
    }

    /**
     * ペアのモーターを前進させます。
     */
    public void backward() {
        rightMotor.backward();
        leftMotor.backward();
    }

    /**
     * ペアのモーターを後退させます。
     */
    public void forward() {
        rightMotor.forward();
        leftMotor.forward();
    }

    /**
     * ペアのモーターを停止させます。
     */
    public void stop() {
        rightMotor.stop();
        leftMotor.stop();
    }

    /**
     * ペアのモーターのパワーを指定します。
     */
    public void setSpeed(int speed) {
        rightMotor.setSpeed(speed);
        leftMotor.setSpeed(speed);
    }

    /**
     * モーターを回転しますす。
     * @param angle 回転角度
     */
    public void rotate(int angle) {
        rightMotor.rotate(angle);
        leftMotor.rotate(angle);
    }

    /**
     * モーターを回転しますす。
     * @param angle 回転角度
     */
    public void rotateTo(int angle) {
        rightMotor.rotateTo(angle);
        leftMotor.rotateTo(angle);
    }

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



□ NXT プログラミングを行う上で使用するツールのクラス NxtUtil

現在は、指定されたミリ秒だけスリープするメソッド pause があ
るだけです。今後、必要に応じて増えていきます。

------------------------------------------------------
package u;

/**
 * NXT プログラミングを行う上で使用するツールのクラス。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class NxtUtil {

    /**
     * 指定ミリ秒間待機します。
     * 
     * @param milliseconds 待機させたいミリ秒。
     */
    public static void pause(long milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
        }
    }
}
------------------------------------------------------



□ 前進し、後退するクラス

上記のユーティリティ・クラスを使って、ForwardBack01.java を作
り直したクラスです。

------------------------------------------------------
import u.NxtUtil;                                // (1)
import u.PairMotor;

/**
 * 「トライボット」使用
 * 1秒間前進し、その後1秒間停止、1秒間後退する。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class ForwardBack02 {

    public static void main(String[] args) {
        
        // CBモーター前進、1000ミリ秒間
        PairMotor.CB.forward();                 // (2)
        NxtUtil.pause(1000);                    // (3)
        
        // CBモーター停止、1000ミリ秒間
        PairMotor.CB.stop();                    // (4)
        NxtUtil.pause(1000);

        // CBモーター後退、1000ミリ秒間
        PairMotor.CB.backward();                // (5)
        NxtUtil.pause(1000);

        // CBモーター停止
        PairMotor.CB.stop();
    }
}
------------------------------------------------------


□ import u.NxtUtil; // (1)
import u.PairMotor;

ユーティリティのクラスをインポートします。


□ PairMotor.CB.forward(); // (2)

CB モーターを前進します。


□ NxtUtil.pause(1000); // (3)

1000 ミリ秒間スリープします。


□ PairMotor.CB.stop(); // (4)

CB モーターを停止します。


□ PairMotor.CB.backward(); // (5)

CB モーターを後退します。



■ 500 ミリ秒間前進し、その後右に180度曲がるプログラム

------------------------------------------------------
import u.NxtUtil;
import u.PairMotor;

/**
 * 「トライボット」使用
 * 500ミリ秒間前進し、その後右に180度曲がる。
 * @author maruno
 * @version 1.0, 2008-06-12
 * @since 1.0
 */
public class TrunRight01 {

    public static void main(String[] args) {

        final int MOVE_TIME = 500;
        final int TURN_TIME = 360;

        // CBモーター前進、500ミリ秒間
        PairMotor.CB.forward();                     // (1)
        NxtUtil.pause(MOVE_TIME);
        
        // 右に曲がる、500ミリ秒間
        PairMotor.CB.getRightMotor().backward();    // (2)
        NxtUtil.pause(TURN_TIME);

        // CBモーター停止
        PairMotor.CB.stop();                        // (3)
    }
}
------------------------------------------------------


□ PairMotor.CB.forward(); // (1)

左右どちらのモーターも前進。


□ PairMotor.CB.getRightMotor().backward(); // (2)
NxtUtil.pause(TURN_TIME);

右だけ後退。左モーターは前進のまま。
これを、TURN_TIME (360) ミリ秒間。
これで、ほぼ 180 度回転します。


□ PairMotor.CB.stop(); // (3)

モーター停止。



■ 制御文を使ったサンプル

ランダムにトライボットが 10 秒間動きます。
ランダムな時間値やパワー値の取得は、java.util.Random クラス
を使っています。

------------------------------------------------------
import java.util.Random;

import lejos.nxt.LCD;
import lejos.nxt.Motor;
import u.PairMotor;

/**
 * 「トライボット」使用 ランダムに10秒間動く。
 * 
 * @author maruno
 * @version 1.0, 2008-06-12
 * @since 1.0
 */
public class Random01 {

    public static void main(String[] args) {

        final int MOVE_LIMIT_TIME = 1000 * 10;    

        Random random = new Random(System.currentTimeMillis()); // (1)

        int moveTotalTime = 0;
        while (moveTotalTime <MOVE_LIMIT_TIME) {


□ Random random = new Random(System.currentTimeMillis()); // (1)

整数の乱数を取得するのに、java.util.Random オブジェクトを生
成。
ただし、API によると、Math.random メソッドも使用できるし、実
際に使えたので、double 型も NXT では OK のようです。


□ int rotateAngle = random.nextInt(721) - 360; // (2)

nextInt メソッドで、正整数の乱数を取得。
このとき、-360 ~ 360 の範囲で角度を取得したいので、上記の式
のように記述します。


□ int speed = random.nextInt(721); // (3)

速度を 0 ~ 720 の範囲で求めます。速度の単位は「度 / 秒」です。


□ int moveTime = Math.abs(rotateAngle * 1000 / speed); // (4)

モーターの回転する時間を求めます。モーターは、1秒間に rotate
Angle 度回転するので、上記の式のようにすると回転する時間(ミ
リ秒)が求まります。


□ Motor.B.setSpeed(speed); // (5)

モーターB に速度を設定します。


□ Motor.B.rotate(rotateAngle); // (6)

モーターB に回転角度を設定して回転させます。


□ LCD.drawInt(Motor.B.getActualSpeed(), 1, 1); // (7)

実測値のモーター速度 (度 / 秒) を取得して、画面に表示します。


以上