marunomaruno-memo

marunomaruno-memo

Lego Mindstoms NXT - leJOS - (5) タッチセンサー

2008年07月29日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (5) タッチセンサー

それでは、今度はタッチセンサーを使ってみましょう。

NXT には、つぎのセンサーがあります。ここに記述されているのは、
NXT ブロックにセンサーを取り付ける上での標準のポートです。

・タッチセンサー (ポート 1)
・音センサー (ポート 2)
・光センサー + ライト (ポート 3)
・超音波センサー (ポート 4)
・回転センサー (モーターA、B、C)


■ タッチセンサー

まずは、タッチセンサーの動きを確認するプログラムを作ります。

------------------------------------------------------
import lejos.navigation.Pilot;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.TouchSensor;

/**
 * モーターを前進させた後、タッチしたら終了する。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class TouchSensor01 {

    public static void main(String[] args) {

        // タッチセンサーオブジェクトをポート1で生成する
        TouchSensor touchSensor = new TouchSensor(SensorPort.S1);  // (1)
        
        // パイロットのオブジェクトを生成する
        Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);

        // 前進回転する
        pilot.forward();

        // 押されるまでループする
        while (!touchSensor.isPressed())                           // (2)
            ;

        // 停止する
        pilot.stop();
    }
}

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



□ TouchSensor touchSensor = new TouchSensor(SensorPort.S1); // (1)

タッチセンサーオブジェクトをポート 1 で生成します。
Java なので、センサーなどもオブジェクトとして生成しないと使
えません。

TouchSensor クラスには次のようなコンストラクターやメソッドが
あります。


□ コンストラクター
---
TouchSensor(ADSensorPort port)
ポートを指定して、タッチセンサーのオブジェクトを生成しま
す。
---


□ メソッド
---
boolean isPressed()
センサーが押されたら true を返します。
---


なお、センサーポートは SensorPort クラスの定数で提供されてい
ます。

□ ポートを表す定数
---
static SensorPort[] PORTS センサーポートの定数が、S1, S2, S3,
S4 の順に入っている配列
static SensorPort S1 センサーポート 1
static SensorPort S2 センサーポート 2
static SensorPort S3 センサーポート 3
static SensorPort S4 センサーポート 4

---
PORTS は、配列で、S1 ~ S4 の値を持ちます。


□ while (!touchSensor.isPressed()); // (2)

タッチセンサーが押されたかどうかは、isPressed メソッドを使う
ことでわかります。この値が true のときにタッチされたことにな
るので、while ループで、false の間ループさせます。当然、この
間はモーターが動き続けることになります。



■ トライボットの「バンパー」のプログラム

これは、トライボットの 2 番目の工程で作った「バンパー (タッ
チセンサー)」のプログラムです。ただし、後退する時間は回転数
ではなく、0.5 秒という時間で行っています。


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

/**
 * 「トライボット」使用
 * 前進し、そこでタッチしたものをつかみ、後退する。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class Bumper01 {

    public static void main(String[] args) {

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

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

        // タッチするまで前進
        pilot.forward();
        while (!touchSensor.isPressed())
            ;
        pilot.stop();
        
        // アームを閉じる
        Motor.A.backward();
        NxtUtil.pause(500);
        Motor.A.stop();

        // 0.5 秒後退
        pilot.backward();
        NxtUtil.pause(500);
        pilot.stop();
    }
}

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




■ 前進した分だけ後退する

今度は、前進した分だけ後退するようにします。
これには、前進した分の時間を計測して、これを後退するときの待
ち時間に設定すればいいです。前進した分の時間は、
停止した時刻 - 前進を始めた時刻
で取得できます。この、時刻を取得するのが、System クラスの
currentTimeMillis メソッドです。


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

/**
 * 「トライボット」使用
 * 前進し、そこでタッチしたものをつかみ、前進した分、後退する。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class Bumper02 {

    public static void main(String[] args) {

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

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

        // タッチするまで前進
        long startTime = System.currentTimeMillis();    // (1)
        pilot.forward();
        while (!touchSensor.isPressed())
            ;
        pilot.stop();
        long forwardingTime = System.currentTimeMillis() - startTime; // (2)
        
        //    アームを閉じる
        Motor.A.backward();
        NxtUtil.pause(500);
        Motor.A.stop();

        // 前進分後退
        pilot.backward();
        NxtUtil.pause(forwardingTime);
        pilot.stop();
    }
}
------------------------------------------------------



以上

C 言語のソースコード・メトリクス測定ツール

2008年07月26日 | C / C++
C 言語のソースコード・メトリクス測定ツール

■ SourceMonitor Version 2.4
http://www.campwoodsw.com/sourcemonitor.html

C言語だけではなく、いろいろな言語(C++, C, C#, VB.NET, Java,
Delphi)のメトリクスを測定できます。
C 言語のメトリクスとしては、以下のものが取得できます。

・Lines: ソースファイル上の物理的な行数

・Statements: セミコロンで区切られた論理行数

・Percent Branch Statements: if, else, for, while, goto,
break, continue, switch, case, default, return の割合

・Percent Lines with Comments: C 形式 (/*...*/) または C++
形式 (//...) のコメント行数の割合

・Functions: 関数の数

・Average Statements per Function: 関数の中の論理行数の平均

・Maximum Function Complexity: 複雑度の最大値

・Maximum Block Depth: 関数の中のブロックのネスト数の最大値

・Average Block Depth: 関数の中のブロックのネスト数の平均値

・Average Complexity: 平均複雑度

以上

Lego Mindstoms NXT - leJOS - (4) Pilot クラス

2008年07月22日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (4) Pilot クラス

前回は、2 つのモーターを管理する PairMotor クラスを作りまし
たが、このクラスと同じようなクラス lejos.navigation.Pilot が
標準で用意されています。もちろん、Pilot クラスは NXT で動く
ロボットを作るための基礎になるクラスとして作られています。

この Pilot クラスを利用して、前回作ったクラス ForwardBack02
を作り直してみましょう。

------------------------------------------------------
import lejos.navigation.Pilot;
import lejos.nxt.Motor;
import u.NxtUtil;

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

    public static void main(String[] args) {
        
        Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);    // (1)

        // 前進、1000ミリ秒間
        pilot.forward();                 // (2)
        NxtUtil.pause(1000);
        
        // 停止、1000ミリ秒間
        pilot.stop();                    // (4)
        NxtUtil.pause(1000);

        // 後退、1000ミリ秒間
        pilot.backward();                // (5)
        NxtUtil.pause(1000);

        // 停止
        pilot.stop();

    }

}

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



□ Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B); // (1)

車輪径 2.1、トラック幅 4.4、左モーター C ポート、右モーター
B ポートでパイロット・オブジェクトを生成します。

なお、車輪径は、車輪の直径、トラック幅は、2 つの車輪の接地点
間の距離です。単位は書かれていないのですが、多分、cm です。
(★) このプログラムでは、いちおう、cm として設定しています。


□ 主なコンストラクタ
---
Pilot(float wheelDiameter, float trackWidth, Motor leftMotor,
Motor rightMotor)
パイロット・オブジェクトを指定された物理パラメーターで生
成します。
---


□ 主なメソッド
---
void backward()
stop() メソッドが呼ばれるまで後退する。

void forward()
stop() メソッドが呼ばれるまで前進する。

int getAngle()
最後にtacho countのリセットをしたときからの回転角度を取
得する。

Motor getLeft()
左側のモーターを取得する。

int getLeftActualSpeed()
左側モーターの実速度(角度/秒)を取得する。負数は後退時の
値。100 ミリ秒ごとに測定。

int getLeftCount()
左側モーターの回転数を取得する。正数は前進時の値。

Motor getRight()
右側のモーターを取得する。

int getRightActualSpeed()
右側モーターの実速度(角度/秒)を取得する。負数は後退時の
値。100 ミリ秒ごとに測定。

int getRightCount()
右側モーターの回転数を取得する。正数は前進時の値。

int getSpeed()
現在の設定速度を取得する。

float getTravelDistance()
回転数をリセットしてからの走行距離を取得する。

float getTurnRatio()
360 度回転するときの比率(★)

boolean isMoving()
NXT ロボットが動いているとき true を返す。

void resetTachoCount()
回転数をリセットする。

void rotate(int angle)
NXT ロボットを回転する。左回転のとき正数、右回転のとき負
数を指定する。

void setSpeed(int speed)
速度(角度/秒)を設定する。

void steer(int turnRate)
指定角度分、NXT ロボットを回転する。 turnRate 値は -200
から 200 の間で指定する。

void stop()
NXT ロボットを停止する。

void travel(float distance)
指定された距離分移動する。正数は前進時の値。

---


□ pilot.forward(); // (2)

ロボットを前進させます。


□ pilot.stop(); // (4)

ロボットを停止します。


□ pilot.backward(); // (5)

ロボットを後退させます。


------------------------------------------------------
import lejos.navigation.Pilot;
import lejos.nxt.Motor;
import u.NxtUtil;

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

    public static void main(String[] args) {

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

        Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);

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

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

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



□ pilot.steer(180); // (1)
NxtUtil.pause(TURN_TIME);

右に 180 度曲がる指定。

なお、steer メソッドを使った場合、動く時間をその直後で指定す
る必要があります。

純粋に指定した角度だけ曲げたいのであれば、rotate メソッドを
使います。ただし、これの場合は、おそらく、床の素材(摩擦具合)
や、バッテリーの残量に影響されて、本当に指定した角度分曲がる
かどうかはわかりません。(★)


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

import lejos.navigation.Pilot;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import u.NxtUtil;

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

    public static void main(String[] args) {

        final int MOVE_LIMIT_TIME = 1000 * 10;

        Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);

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

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


□ int rotateAngle = random.nextInt(401) - 200; // (1)

-200 から 200 までの乱数を設定します。


□ pilot.steer(rotateAngle); // (2)


(1) で取得した乱数値を使って、NXT ロボットを回転させます。


□ LCD.drawInt(pilot.getRightActualSpeed(), 1, 1); // (3)
LCD.drawInt(pilot.getLeftActualSpeed(), 1, 2);

左右のモーターの実測速度を表示します。


以上

半角英字の入力チェックとインプットメソッドの無効化

2008年07月21日 | Java
■ JavaScriptで、半角英字の入力チェックとインプットメソッドの無効化

---
<script type="text/javascript">
    /** 半角英文字チェック */
    function alphabetCheck() {
       var str = document.form.detail.value;
       if (str.match(/[^A-Za-z\s.-]+/)) {
          alert("半角英字のみで入力してください。");
          return 1;
       }
       return 0;
    }
</script>

...

<form name="form" action="..." method="post">
    <input type="text" name="detail" onblur="alphabetCheck();" style="ime-mode:disabled;"> 
    <input type="submit" value="送信" onClick="return alphabetCheck();">
</form>

---


□ onblur

テキストフォームからフォーカスが外れたときに、指定された関数
を実行する。


□ onClick

ボタンがクリックされたときに、指定された関数を実行する。


□ style="ime-mode:disabled;"

IE5.5(?)以降限定で、インプットメソッドを無効にする。

以上

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)

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


以上


Lego Mindstoms NXT - leJOS - (2) NXT 画面とモーター

2008年07月08日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (2) NXT 画面とモーター

leJOS 上で動く Java のプログラムのサンプルをいくつかつくりま
す。
このサンプルにしたがって、API も参照していきます。


■ NXT 画面に "Hello World!" と 5 秒間表示

まずは、NXT 画面に文字列を表示してみましょう。

次のアプリケーションは、前回の稼動確認に使ったものと同じです。
NXT 画面に "Hello World!" と 5 秒間表示されます。

------------------------------------------------------
import lejos.nxt.LCD;                                 // (1)

/**
 * NXT 画面に "Hello World!" を 5 秒間表示するプリケーション。
 * 
 * @author marunomaruno
 * @version 1.0, 2008/06/04
 * @since 1.0
 */
public class HelloWorld {

    public static void main(String[] args) {
        LCD.drawString("Hello World!", 2, 3);         // (2)
        LCD.drawString("12345678901234567890", 0, 5); // (3)
        LCD.refresh();                                // (4)
        try {
            Thread.sleep(5000);                       // (5)
        } catch (InterruptedException e) {
        }
    }
}

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


□ import lejos.nxt.LCD; // (1)

lejos.nxt パッケージの LCD クラスをインポートします。


□ LCD.drawString("Hello World!", 2, 3); // (2)

NXT 画面の 3 行目 2 カラム目から "Hello World!" を描画します。
なお、行やカラムは 0 から数えます。


□ LCD.drawString("12345678901234567890", 0, 5); // (3)

NXT 画面の 5 行目 0 カラム目から "1234567890123456" を描画し
ます。
表示されるのは 1 行あたり 16 文字だけです。これよりも長い分
は無視されます。


□ drawString メソッド
---
static void drawString(String str, int x, int y)
画面の座標 (x, y) から文字列 str を表示します。
---

NXT 画面は 16 文字 X 8 行を表示できます。引数 str は表示した
い文字列、x, y は、画面左上を原点 (0, 0) としたときの表示す
る文字列の左下の座標です。

文字列が表示できないときでも、エラーにすることはありません。


□ LCD.refresh(); // (3)

NXT 画面を更新します。


□ Thread.sleep(5000); // (4)

5 秒間、スレッドを停止します。このことにより、NXT 画面上に表
示された文字列がそのまま 5 秒間表示し続けます。なお、sleep
メソッドは、必須例外の InterruptedException をスローするので、
try-catch ブロックで囲っておきます。

この sleep メソッドがないと、NXT 画面には一瞬だけ文字列が表
示されるだけのようです。(★)



□ lejos.nxt.LCD クラス

NXT 画面に対するユーティリティ・クラス。すべてのメソッドがス
タティックです。
座標は、画面左上を原点 (0, 0) とし、右下を (15, 7) としたも
のです。

おもなメソッド一覧
------------------------------------------------------
static void clear() 
    画面をクリアします。

static void drawInt(int i, int x, int y) 
    画面の座標 (x, y) から数値 i を表示します。

static void drawString(String str, int x, int y) 
    画面の座標 (x, y) から文字列 str を表示します。

static void refresh() 
    画面を更新します。

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




■ 走らせる

モーターを動かして、トライボットを走らせます。

△ NXC との違い
---
NXC のときは、ファイル名が ForwardAndBackward01.nxc でしたが、
ForwardAndBackward01 だとクラス名が長く、ダウンロードできな
いので、このような名前にしました。
---


------------------------------------------------------
import lejos.nxt.Motor;                       // (1)

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

    public static void main(String[] args) {
        // BCモーター前進、1000ミリ秒間
        Motor.B.forward();                    // (2)
        Motor.C.forward();
        try {
            Thread.sleep(1000);               // (3)
        } catch (InterruptedException e) {
        }

        // BCモーター停止、1000ミリ秒間
        Motor.B.stop();                       // (4)
        Motor.C.stop();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        // BCモーター後退、1000ミリ秒間
        Motor.B.backward();                   // (5)
        Motor.C.backward();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        // BCモーター停止
        Motor.B.stop();                       // (6)
        Motor.C.stop();
    }
}
------------------------------------------------------



□ import lejos.nxt.Motor; // (1)

必要なクラスをインポートします。


□ Motor.B.forward(); // (2)
Motor.C.forward();

Motor クラスの定数にそれぞれのポートに定義されたモーター定数
(A, B, C) が用意してあります。これらのモーター定数オブジェ
クトを使ってモーターを操作します。

前進するには、forward メソッドを使います。
B, C 2 つのモーターを使っているので、この 2 つとも同じように
前進させる必要があります。


□ メソッド
---
void forward()
前進します。
---


△ NXC との違い
---
NXC では複数のモーターをあらわす定数として、
OUT_AB
OUT_AC
OUT_BC
OUT_ABC
がありましたが、leJOS では用意されていません。
---


□ Thread.sleep(1000); // (3)

1 秒間モーターを動かすために、スリープさせます。これがないと、
すぐに次の文に制御が移ります。その文によっては、モーターも、
一瞬しか動きません。


△ NXC との違い
---
NXC では Off 関数などを使って自分でモーターを止めない限り、
モーターは動き続きます。
---


□ Motor.B.stop(); // (4)
Motor.C.stop();

両方のモーターを停止します。


□ stop メソッド
---
void stop()
モーターを停止します。

---


□ Motor.B.backward(); // (5)
Motor.C.backward();

後退するには backward メソッドを使います。


□ メソッド
---
void backward()
後退します。
---


□ Motor.B.stop(); // (6)
Motor.C.stop();

(3) で記したように、leJOS では、プログラムが終了したらモー
ターも停止するので、この文はなくてもモーターは止まりますが、
書いておいた方が気持ちいいでしょう。



□ Moter クラス

モーターをあらわすクラスです。


□ おもな定数
---
static Motor A: モーターA
static Motor B: モーターB
static Motor C: モーターC
---

□ おもなメソッド
---
void backward()
後退します。

void forward()
前進します。

int getActualSpeed()
実測値のモーター速度 (度 / 秒) を取得します。速度は 100
ミリ秒ごとに測定します。負数は後退しているときです。

int getLimitAngle()
モーターが回転した度数を取得します。

int getMode()
モードを取得します。
1=前進, 2=後退, 3=停止, 4=フルオーティング

int getSpeed()
モーター速度 (度 / 秒) を取得します。

int getStopAngle()

int getTachoCount()
タコメーター数を取得します。

boolean isBackward()
後退しているとき true が返ります。

boolean isForward()
前進しているとき true が返ります。

boolean isMoving()
モーターが動いているとき true が返ります。

boolean isRotating()
モーターが回転しているとき true が返ります。

boolean isStopped()
モーターが停止しているとき true が返ります。

void resetTachoCount()
タコメーター数を 0 にリセットします。

void reverseDirection()
モータの方向を逆にします。

void rotate(int angle)
モーターを angle 度回転します。負数のときは逆回転です。

void rotateTo(int limitAngle)
モーターを limitAngle 度回転します。 getTachoCount() メ
ソッドの返り値は +- 2 度以内になります。負数のときは逆回転で
す。

void setSpeed(int speed)
モーター速度 (度 / 秒) を設定します。0 または正数を指定。
負数のときの動作は不定。

void stop()
モーターを停止します。
---

なお、これらのメソッドのうち、実際にそのメソッドでモーターが
動くのは roate メソッドと rotateTo メソッドの 2 つです。これ
ら以外は、どうやら、モーターに動く方向や速度を設定するだけで、
つぎのメソッドが来てから実際に動くようです。(★)


setSpeed メソッドは速度の指定ですが、これも負数は指定できま
せん。

---
★ rotate メソッドと rotateTo メソッドの違いは? rotateTo メ
ソッドの方が正確なのか? ただ、totateTo メソッドは、leJOS の
サンプルでも使用されていない。
isMoving メソッドと isRotating メソッドの違いもわからない。

---




Lego Mindstoms NXT - leJOS - (1) leJOS のインストール

2008年07月01日 | LEGO
2011-09-15 修正
Lego Mindstomes NXT - leJOS - (1) leJOS のインストール
================================================================================

Java で Lego Mindstomes NXT を動かすためには、NXT のファームウェ
ア自体を標準のものから変更する必要があります。もちろん、Java を
使った開発環境を PC 上に整える必要もあります。

今回は、この開発環境を Eclipse で、また、実行環境 leJOS を NXT
にいれて、"Hello World!" を NXT 画面に表示するアプリケーションを
作り、動作確認まで行ってみましょう。

なお、ここでは、Eclipse を使って Java アプリケーションを作ったこ
とがある、という前提で話を進めます。

また、2008 年 1 月に記述していた記事「Lego Mindstomes NXT - NXC
プログラミング」で使った NXC との違いも補足していきたいと思って
います。サンプルも、なるべく同じ動きをするものにしたいと思ってい
ます。

そして、以前と同じように、推測で記しているところ(★を補足)がある
ので、注意されたい。


■ 開発環境

開発環境としては、Eclipse を使います。現在、Eclipse の leJOS plugin
もありますが、わたしの環境ではうまく動かないため、Eclipse は
単なる Java プロジェクトとし、プログラムのアップロードには外部
ツールを使って行うこととします。

参考: org.lejos.nxt.ldt.update-site

http://lejos.sourceforge.net/tools/eclipse/plugin/nxj/



■ インストール手順

つぎの手順のようにインストールします。

1. JavaSE と Eclipse を PC にインストールする
2. NXT USB driver を PC にインストールする
3. leJOS を PC にインストールする
4. leJOS を NXT にインストールする
5. Eclipse を設定する
6. アプリケーションを作り、動作確認する


■ 1. JavaSE と Eclipse を PC にインストールする

JavaSE と Eclipse のインストールはそれぞれ

J2SDK 1.4.2 のインストール
Eclipse とプラグインのインストール

を参照してください。ただし、ここに書かれているのはそれぞれバージ
ョンが古いので、最新のものについては、

SUN
http://java.sun.com/javase/

eclipse.org
http://www.eclipse.org/

を参考にしてください。


■ 2. NXT USB driver を PC にインストールする

NXT に付属しているソフトウェアなどを使って、ロボットを動かしたり
した場合は、このステップは必要ありません。

leJOS 以外で NXT を動かすのでなければ、自分で NXT USB driver を
PC にインストールする必要があります。


http://mindstorms.lego.com/Support/Updates/

から、MINDSTORMS NXT Driver v1.02 (現時点の最新)をダウンロードし、
解凍してインストールします。


■ 3. leJOS を PC にインストールする

leJOS をつぎからダウンロードします。現在(2008-06-10)の最新は 0.6.
0 です。

Download NXJ

http://lejos.sourceforge.net/p_technologies/nxt/nxj/downloads.php


3.1 まず、PC にインストールします。インストールといっても、ダウ
ンロードした ZIP ファイルを解凍するだけです。ただし、解凍先のフ
ォルダー名に空白文字(スペース)が入っていてはいけません。

ここでは例として C:/software に解凍することにします。すると、
C:/software/lejos_nxj
ができます。


3.2 つぎに、この解凍したフォルダーのパスをシステム環境変数
LEJOS_HOME とします。

LEJOS_HOME = C:/software/lejos_nxj


ついでに、環境変数 NXJ_HOME も、同様に指定したほうがいいでしょう。
NXJ_HOME = %LEJOS_HOME%
(2008-10-21 追記)


3.3 さらに、この解凍したフォルダーの中の bin フォルダーをシステ
ム環境変数 PATH に連結します。

PATH = %PATH%;%LEJOS_HOME%/bin


3.4 PC に leJOS がインストールされたことを確認します。新しくコマ
ンドプロンプトを開き、プロンプトから、次のコマンドを打ちます。こ
のコマンドの引数が指定されているのでエラーというメッセージが出ま
すが、下のような使い方のメッセージが表示されれば OK です。

------------------------------------------------------
> lejosdl
an error occurred: No classes specified
usage: nxj [options] class1[,class2,...]
-a,--all                        do not filter classes
-b,--bluetooth                  use bluetooth
-cp,--classpath <classpath>     classpath
-d,--address <address>          look for NXT with given address
-g,--debug                      Include debug monitor
-h,--help                       help
-n,--name <name>                look for named NXT
-o,--output <binary>            dump binary to file
-r,--run                        run program
-u,--usb                        use usb
-v,--verbose                    print class and signature information
-wo,--writeorder <write order>  write order (BE or LE)

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



3.5 leJOS NXT API ドキュメントを参照可能にする

%LEJOS_HOME%/docs/apidocs/index.html

をブラウザーのお気に入りにでも設定して、いつでも API を参照でき
るようにしてください。


■ 4. leJOS を NXT にインストールする

NXT のファームウェアを leJOS に変更します。

4.1 NXT と PC を USB ケーブルで接続し、NXT の電源を入れます。


4.2 NXT をリセットします。リセットは、USB ケーブルの入り口の近く
のブロックのジョイント部分の中を、ビンか何かとがっているものでさ
すことでリセットできます。
リセットボタンは4秒以上押し続けます。(2008-10-30 追記)
なお、リセットボタンの位置は、マニュアルを確認してください。


4.3 PC のコマンドプロンプトから次のコマンドを打ちます。

------------------------------------------------------
>lejosfirmdl
NXJ_HOME is C:/software/lejos_nxj
Checking VM C:/software/lejos_nxj/bin/lejos_nxt_rom.bin ... Size = 35216, max size = 81912
VM OK.
Checking Menu C:/software/lejos_nxj/bin/StartUpText.bin ... Size = 31592, max size = 81912
Menu OK.
NXT device in reset mode located and opened.
Starting VM flash procedure now...
VM flash complete.
Starting menu flash procedure now...
Menu flash complete.
New firmware started!
If battery level reads 0.0, remove and re-insert a battery

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



4.4 leJOS は、Libusb Filter Driver のインストールを要求してきま
すので、これをインストールします。
これは、%LEJOS_HOME%/3rdparty/lib にある
libusb-win32-filter-bin-0.1.12.1.exe
を使ってインストールします。


なお、Libusb Filter Driver は、WindowsVistaにはインストールできません。

(2008-10-21 追記)



NXT への leJOS のインストールが成功すると、NXT 画面が標準の画面
から leJOS の画面へと変わります。NXT の起動音も変わります。

なお、leJOS では、NXT 標準のファームウェアと違い、NXT ボタンの操
作が違います。
NXT を停止するボタンが使えないので、プログラムが暴走した場合は、
電池を抜いて止める必要があります。


□NXTのファームウェアに戻す

NXTソフトウェアを立ち上げておきます。
NXTのリセットボタンを4秒以上押し続け、画面が白くなったら次の操作をNXTソフトウェ
アで行います。
  [ツール]メニュー - [NXTファームウェアを更新] - [ダウンロード]ボタンをクリッ


(2008-10-30 追記)



■ 5. Eclipse を設定する

Eclipse で leJOS 用のアプリケーションを開発できるようにします。


5.1 Java プロジェクトを作成する

次の操作で、Java プロジェクトを作成します。

[ファイル]メニュー - [新規] - [プロジェクト] -
[Javaプロジェクト]を選択 - [次へ]

プロジェクト名は、[nxtsample] としておきます。


5.2 外部 JAR ファイルをプロジェクトに追加する

leJOS の classes.jar ファイルをこのプロジェクトのビルドパスに加
えます。

[nxtsample]で右クリック - [ビルドパス] - [外部アーカイブの追加]

で、ファイルの選択ウィザードが出ますので、そこで、
%LEJOS_HOME%/lib を開き、

classes.jar ファイル

を選択し、[開く] をクリックします。


5.3 Java コンパイラーのバージョンを設定する

コンパイラーのバージョンを 1.3 にします。

[nxtsample]で右クリック - [プロパティ] - [Javaコンパイラー]タグ

で、

[プロジェクト特定設定を使用可能にする]にチェック

し、

[コンパイラー準拠レベル] - [1.3]

にします。


5.4 外部ツールボタンに NXT へのダウンロードを設定する

外部ツールボタンをクリックすることで、現在編集中の Java のクラス
ファイルを NXT にダウンロードできるように設定します。


まず、プロジェクト中に、[bin] フォルダを作ります。

そして、

[実行] - [外部ツール] - [外部ツール] - [新規]ボタンをクリック

して、

[名前] - [leJOS Download]

にします。 [メイン]タグ で、

[ロケーション] を [C:/software/lejos_nxj/bin/lejosdl.bat]

[作業ディレクトリー] を [${project_loc}bin]

[引数] を [${java_type_name}]

にそれぞれ設定して、


[適用]ボタン - [閉じる]ボタン

で設定を終わります。


つぎに、[外部ツールで実行]ボタンにこの [leJOS Download] を追加し
ます。

[外部ツールで実行]ボタンのプルダウン - [お気に入りの編成] -
[追加]ボタン - [leJOS Download]を選択 - [OK]


5.5 Javadoc ロケーションを設定する

[nxtsample]で右クリック - [プロパティ] - [Javadoc ロケーション]
タグ

で、

[Javadoc ロケーション・パス] に
[file:/C:/software/lejos_nxj/docs/apidocs/]

を設定します。


■ 6. アプリケーションを作り、動作確認する

nxtsample プロジェクトで、Java のアプリケーションをつくり、NXT
にダウンロードして動かしてみます。


6.1 HelloWorld アプリケーションを作る

nxtsample プロジェクトのデフォルトパッケージに、[HelloWorld] ク
ラスを新規作成します。

次のコードを入力します。

------------------------------------------------------
import lejos.nxt.LCD;

/**
* NXT 画面に "Hello World!" を 5 秒間表示するプリケーション。
*
* @author marunomaruno
* @version 1.0, 2008/06/04
* @since 1.0
*/
public class HelloWorld {

/**
* @param args
*/
public static void main(String[] args) {
LCD.drawString("Hello World!", 2, 3);
LCD.refresh();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
}

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


なお、このアプリケーションの説明は次回行います。


6.2 NXT にダウンロードして実行

コンパイルエラーがなくなったら、NXT と PC の間を USB ケーブルで
つなぎ、NXT の電源を入れます。

[外部ツールで実行]ボタン - [外部ツール] で、[leJOS Download] を
選択し、[実行]ボタンをクリックしてダウンロードを実行します。

Eclipse のコンソールに次のようなメッセージが表示されます。
------------------------------------------------------
leJOS NXJ> Linking...
leJOS NXJ> Uploading...
Found nxt name NXT address 00165304DE4E
leJOS NXJ> Upload successful in 187 milliseconds
------------------------------------------------------


そして、NXT 画面に "Hello World!" と 5 秒間表示されるはずです。

表示されたら、leJOS の音がして、アプリケーションは終了します。


これで、無事に leJOS を使って、NXT で Java プログラム を動かすこ
とができましたね。


6.3 注意点

クラスを作るとき、注意点がいくつかあります。


・クラス名は 16 バイト以内とする

これは、ダウンロードするときにそのファイル名が 20 バイト以内とい
う制限があるからです。そして、ダウンロードするバイトコードのファ
イルの拡張子は [.nxj] で、4 バイト分使うので、クラス名は 16 バイ
ト以内でないといけません。


・パッケージを作らない

上の制限と関連しますが、ダウンロードするファイル名は完全修飾名な
ので、パッケージにしているとすぐにその制限を越えます。


・パッケージを作っても、ダウンロードするときに、実行ファイル名を指定すれば大丈夫です。

---
> nxj -u -o 実行ファイル名 完全修飾クラス名
---(2010-03-17 追記)


・実行ファイル名(クラス名)は12文字以内にした方がよい

leJOS で実行ファイルをデフォルトに設定する際に、[Set as Default] で使えるクラス名は 12 バイトまでのようです。これよりそれより長いクラス名は、デフォルトのプログラムに指定できません。指定しても「Filename to big」とでます。(2011-09-15 追記)


△ NXC との違い
---
NXC ではダウンロードできるファイル名は 20 文字だった。(★)
---


以上