marunomaruno-memo

marunomaruno-memo

ロボロボロボコン2012

2012年11月01日 | LEGO
ロボロボロボコン2012
http://www.enjoy-robo.com/images/pdf/roboroborobocon2012_book.pdf

ロボロボロボコンとは
レゴNXTマインドストームを使用したロボット大会です。小学2年生から大人まで、誰でも参加できます。レースは、年齢に関係なく同じレースで競い合います。

ロボットレースを通じて、”考える楽しさ”を共有する場所です。(前身の「クリスマスロボコン」が2010年から始まり、今年で3回目を迎えます。)

日時:12月16日(日) 11時~16時30分
場所:かながわ労働プラザホールB
http://www.zai-roudoufukushi-kanagawa.or.jp/?l-plaza/
レース:鬼ごっこレース!
(A)自走型部門
(B)ラジコン部門

お申込み http://www.enjoy-robo.com/form_roborobo/
お問い合わせ info@enjoy-robo.com

※まだ、募集しておりますので、興味のある方はお問い合わせください。

[leJOS][NXT] Bluetooth を使った送受信

2012年05月11日 | LEGO
[leJOS][NXT] Bluetooth を使った送受信
================================================================================

※ このサンプルは leJOS 0.9.1 で作成している。

Bluetooth を使って、データを送受信する。
プログラムは以下の 3 つを作った。

Sender11      リモートデバイス側。NXT のセンサーから値を読んで、Bluetooth を使っ
              て相手(Receiver11)に送信する

Receiver11    ローカルデバイス側。Sender11 から送られてきたデータを受信して、画
              面に表示する。

SensorValues  エンティティ。送受信時に使う NXT のセンサーの値を保持する。

Bluetooth では、データを送受信するときに、リモートデバイス側とローカルデバイス側
とで通信をする。このとき、リモートデバイス側のプログラム(Sender11)を先に起動して
おく。


■ リモートデバイス側

NXT の Esacape ボタン以外を押下したときに、各センサーの値を読み取って、相手の 
NXT に送信する。Esacape ボタンを押下したときは、プログラムを終了する。


□ Sender11.java
---
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

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;
import lejos.nxt.comm.Bluetooth;
import lejos.nxt.comm.NXTConnection;

/**
 * NXTのセンサーからデータを取得し、Bluetoothを使って値を送信する。
 * リモートデバイス側(先にこちらのプログラムを起動しておく)
 * leJOS 0.9.1
 * @author marunomaruno
 * @version 1.0, 2012/03/14
 * @since 1.0
 */
public class Sender11 {
    public static void main(String[] args) throws Exception {
        // センサーを設定する
        TouchSensor touchSensor = new TouchSensor(SensorPort.S1);
        SoundSensor soundSensor = new SoundSensor(SensorPort.S2);
        LightSensor lightSensor = new LightSensor(SensorPort.S3);
        UltrasonicSensor ultrasonicSensor = new UltrasonicSensor(SensorPort.S4);

        // センサーが安定するまで待つ
        Thread.sleep(200);

        // ローカルデバイスとの通信を待つ
        LCD.drawString("Waiting...", 0, 0);
        NXTConnection connection = Bluetooth.waitForConnection();    // (1)

        // 接続できない場合、プログラムを終了する
        if (connection == null) {    // (2)
            LCD.clear();
            LCD.drawString("Connect fail", 0, 0);
            Button.waitForAnyPress();
            System.exit(1);
        }

        // ローカルにもログをとっておく
        File file = new File("values.dat");
        file.delete();
        file.createNewFile();
        DataOutputStream log = new DataOutputStream(new FileOutputStream(
                file));

        // Bluetooth 用のデータストリームを取得する
        DataOutputStream out = connection.openDataOutputStream();    // (3)

        // センサー値を保持するオブジェクトを確保する
        SensorValues values = new SensorValues();    // (4)

        // ESCが押されたら終わり
        while (Button.waitForAnyPress() != Button.ID_ESCAPE) {
            try {
                // IDをカウントアップする
                values.id++;

                // センサーから値を取得する
                values.buttonId = Button.readButtons();
                values.touch = touchSensor.isPressed() ? 1 : 0;
                values.sound = soundSensor.readValue();
                values.light = lightSensor.readValue();
                values.ultrasonic = ultrasonicSensor.getDistance();

                values.tachoCountA = Motor.A.getTachoCount();
                values.tachoCountB = Motor.B.getTachoCount();
                values.tachoCountC = Motor.C.getTachoCount();

                // データを画面に表示する
                LCD.clear();
                values.print(System.out);

                // ログファイルに出力する
                values.write(log);

                // Bluetoothに出力する
                values.write(out);    // (5)

            } catch (IOException e) {
                System.out.println(" write error " + e);
            }
        }

        // ログファイルを閉じる
        try {
            log.close();

        } catch (IOException e) {
            LCD.drawString("Close Exception", 0, 0);
            LCD.drawString(e.getMessage(), 0, 1);
            Button.waitForAnyPress();
        }

        // 通信を閉じる
        try {
            LCD.clear();
            LCD.drawString("Closing... ", 0, 0);
            out.close();    // (6)
            connection.close();    // (7)

        } catch (IOException e) {
            LCD.drawString("Close Exception", 0, 0);
            LCD.drawString(e.getMessage(), 0, 1);
            Button.waitForAnyPress();
        }

        // 終了メッセージを表示する
        LCD.clear();
        LCD.drawString("Finished", 0, 0);
        Button.waitForAnyPress();
    }
}
----

(1) ローカルデバイスとの通信を待つ

Bluetooth クラス の waitForConnection() メソッドを使って、ローカルデバイスとの通
信を待つ。通信があれば、待ち状態は解除され、BTConnection オブジェクトが返る。
なお、NXTConnection は、BTConnection のスーパークラス。

    NXTConnection connection = Bluetooth.waitForConnection();    // (1)

---
static BTConnection waitForConnection() 
          現在のデフォルトの PIN を使って取得する。
---

PIN は、ペアリングするときに使用する 4 桁の数字。デフォルトだと、「0000」または
「1234」。


□ Bluetooth クラス

java.lang.Object
  lejos.nxt.comm.NXTCommDevice
      lejos.nxt.comm.Bluetooth

Bluetooth 通信をあらわすクラス。

メソッド
---
static BTConnection connect(RemoteDevice remoteDevice) 
static BTConnection connect(String target, int mode) 
static BTConnection connect(String target, int mode, byte[] pin) 

static RemoteDevice getKnownDevice(String fName) 
static ArrayList<RemoteDevice> getKnownDevicesList() 

static BTConnection waitForConnection() 
static BTConnection waitForConnection(int timeout, int mode) 
static BTConnection waitForConnection(int timeout, int mode, byte[] pin) 
---


□ BTConnection クラス

java.lang.Object
  extended by lejos.nxt.comm.NXTConnection
      extended by lejos.nxt.comm.BTConnection

Bluetooth の接続をあらわすクラス。つぎに示す NXTConnection クラスを継承している。

メソッド
---
void  closeStream()
int   getSignalStrength()
void  openStream()
void  setActiveMode(int mode)
---


□ NXTConnection クラス

java.lang.Object
  lejos.nxt.comm.NXTConnection

一般的な NXT leJOS の接続を表すクラス。


メソッド
---
void             close() 
DataInputStream  openDataInputStream() 
DataOutputStream openDataOutputStream() 
InputStream      openInputStream() 
OutputStream     openOutputStream() 
---


(2) 接続できない場合、プログラムを終了する

Bluetooth.waitForConnection() メソッドで、接続ができない場合は、null が返るので、
これをチェックする。

    if (connection == null) {    // (2)


(3) Bluetooth 用のデータストリームを取得する

このプログラムは、センサーから読み取ったデータを相手に送信する側なので、出力スト
リームを開く。

    DataOutputStream out = connection.openDataOutputStream();    // (3)


(4) センサー値を保持するオブジェクトを確保する

NXT のセンサーからの値は、SensorValues オブジェクトとして生成する。

    SensorValues values = new SensorValues();    // (4)


(5) Bluetooth に出力する

SensorValues オブジェクトの write() メソッドに、Bluetooth の出力ストリーム・オブ
ジェクトを渡して書き込む。

    values.write(out);    // (5)


(6)(7) 通信を閉じる

通信が終わったら、出力ストリーム、接続ともに閉じる。

    out.close();    // (6)
    connection.close();    // (7)


■ ローカルデバイス側

Bluetooth を使って送られてきたデータを受信して、その値を表示するプログラム。
リモートデバイス側の名前を指定して、相手を特定する。


□ Receiver11.java
---
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.bluetooth.RemoteDevice;

import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.comm.Bluetooth;
import lejos.nxt.comm.NXTConnection;

/**
 * Bluetoothを使って送られてきたデータを受信して、その値を表示する。
 * ローカルデバイス側(先に、リモートデバイス側を起動しておく)
 * leJOS 0.9.1
 * @author marunomaruno
 * @version 1.0, 2011/08/14
 * @since 1.0
 */
public class Receiver11 {
    public static void main(String[] args) throws Exception {

        // リモートデバイスと接続する
        LCD.drawString("Connecting...", 0, 0);

        // リモートデバイスのNXT名を設定する
        RemoteDevice device = Bluetooth.getKnownDevice("NXT名");    // (1)

        // リモートデバイスが見つからない場合、プログラムを終了する
        if (device == null) {
            LCD.clear();
            LCD.drawString("No such device", 0, 0);
            Button.waitForAnyPress();
            System.exit(1);
        }

        // 接続する
        NXTConnection connection = Bluetooth.connect(device);    // (2)

        // 接続できない場合、プログラムを終了する
        if (connection == null) {
            LCD.clear();
            LCD.drawString("Connect fail", 0, 0);
            Button.waitForAnyPress();
            System.exit(1);
        }

        // データストリームを開く
        DataInputStream in = connection.openDataInputStream();    // (3)

        // ローカルにもログをとっておく
        File file = new File("values.dat");
        file.delete();
        file.createNewFile();
        DataOutputStream log = new DataOutputStream(new FileOutputStream(file));

        SensorValues values = new SensorValues();

        // メッセージを受け取る
        try {
            while (Button.ESCAPE.isDown() != true) {
                // ストリームから値を読み込む
                values.read(in);    // (4)

                // ログファイルに出力する
                values.write(log);

                // データを画面に表示する
                LCD.clear();
                values.print(System.out);

                // 待つ
                Thread.sleep(200);
            }

        } catch (IOException e) {
            System.out.println(" write error " + e);
        }

        // ログファイルを閉じる
        try {
            log.close();

        } catch (IOException e) {
            LCD.drawString("Close Exception", 0, 0);
            LCD.drawString(e.getMessage(), 0, 1);
            Button.waitForAnyPress();
        }

        // 通信を閉じる
        try {
            LCD.clear();
            LCD.drawString("Closing...", 0, 0);
            in.close();
            connection.close();

        } catch (IOException e) {
            LCD.drawString("Close Exception", 0, 0);
            LCD.drawString(e.getMessage(), 0, 1);
            Button.waitForAnyPress();
        }

        LCD.clear();
        LCD.drawString("Finished", 0, 0);
        Button.waitForAnyPress();
    }

}
---

(1) リモートデバイスのNXT名を設定する

Bluetooth クラスの getKnownDevice() メソッドを使って、相手のデバイス名を指定して、
接続先のデバイスを取得する。

    RemoteDevice device = Bluetooth.getKnownDevice("NXT名");    // (1)

リモートデバイスが見つからない場合は、null が返る。


Bluetooth クラスのメソッド
---
static RemoteDevice getKnownDevice(String fName) 
static ArrayList<RemoteDevice> getKnownDevicesList() 
---


□ RemoteDevice クラス

java.lang.Object
  javax.bluetooth.RemoteDevice

リモートデバイスをあらわすクラス。


主なメソッド
---
 String  getBluetoothAddress() 
 String  getDeviceAddr() 
 int     getDeviceClass() 
 String  getFriendlyName(boolean alwaysAsk) 
static RemoteDevice getRemoteDevice(Connection conn) 
 boolean isAuthenticated() 
 boolean isEncrypted() 
 void    setDeviceAddr(String deviceAddr) 
 void    setFriendlyName(String fName) 
---


(2) 接続する

    NXTConnection connection = Bluetooth.connect(device);    // (2)

接続できない場合は、null が返る。


Bluetooth クラスのメソッド
---
static BTConnection connect(RemoteDevice remoteDevice) 
static BTConnection connect(String target, int mode) 
static BTConnection connect(String target, int mode, byte[] pin) 
---


(3) データストリームを開く

このプログラムは、Bluetooth から受信した値を画面に表示するので、入力ストリームを
開く。

    DataInputStream in = connection.openDataInputStream();    // (3)


(4) ストリームから値を読み込む

SensorValues オブジェクトの read() メソッドに、Bluetooth の入力ストリーム・オブ
ジェクトを渡して書き込む。

    values.read(in);    // (4)


■ エンティティ

NXT のセンサーの値を管理するエンティティ・クラス。
入力ストリームや出力ストリームのオブジェクトを受け取ることで、そのストリームに対
する入出力も行う。
なお、データの値は int 値として送受信している。

管理している値はつぎのとおり。
    ------------- ------------------------
    フィールド名  意味
    ------------- ------------------------
    id            ID
    buttonId      ボタンのID
    touch         タッチセンサーの値
    sound         音センサーの値
    light         光センサーの値
    ultrasonic    超音波センサーの値
    tachoCountA   モーターAのタコカウント
    tachoCountB   モーターBのタコカウント
    tachoCountC   モーターCのタコカウント
    ------------- ------------------------


□ SensorValues.java
---
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintStream;

/**
 * NXTのセンサーの値を保持するエンティティ
 * leJOS 0.9.1, Android 2.2
 * @author marunomaruno
 * @version 1.0, 2012/03/14
 * @since 1.0
 */
public class SensorValues {

    int id;    // ID

    int buttonId;    // ボタンのID
    int touch;    // タッチセンサーの値
    int sound;    // 音センサーの値
    int light;    // 光センサーの値
    int ultrasonic;    // 超音波センサーの値

    int tachoCountA;    // モーターAのタコカウント
    int tachoCountB;    // モーターBのタコカウント
    int tachoCountC;    // モーターCのタコカウント

    /**
     * 値を表示する。
     * @param out 表示するストリーム
     */
    public void print(PrintStream out) {
        out.println(id);
        out.println(toSensorString());
        out.println(toMotorString());
    }

    /**
     * データを入力する。
     * @param in 入力ストリーム
     * @throws IOException
     */
    public void read(DataInputStream in) throws IOException {
        id = in.readInt();

        buttonId = in.readInt();
        touch = in.readInt();
        sound = in.readInt();
        light = in.readInt();
        ultrasonic = in.readInt();

        tachoCountA = in.readInt();
        tachoCountB = in.readInt();
        tachoCountC = in.readInt();
    }

    /**
     * データを出力する。
     * @param out 出力ストリーム
     * @throws IOException
     */
    public void write(DataOutputStream out) throws IOException {
        out.writeInt(id);

        out.writeInt(buttonId);
        out.writeInt(touch);
        out.writeInt(sound);
        out.writeInt(light);
        out.writeInt(ultrasonic);

        out.writeInt(tachoCountA);
        out.writeInt(tachoCountB);
        out.writeInt(tachoCountC);

        out.flush();
    }

    /**
     * すべてのセンサーの値からなる文字列を組み立てる。
     * @return 組み立てた文字列
     */
    public String toSensorString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append(buttonId);
        sb.append(", ");
        sb.append(touch);
        sb.append(", ");
        sb.append(sound);
        sb.append(", ");
        sb.append(light);
        sb.append(", ");
        sb.append(ultrasonic);
        sb.append("]");

        return sb.toString();
    }

    /**
     * すべてのモーターの値からなる文字列を組み立てる。
     * @return 組み立てた文字列
     */
    public String toMotorString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append(toMotorString(new int[]{tachoCountA}));
        sb.append(", ");
        sb.append(toMotorString(new int[]{tachoCountB}));
        sb.append(", ");
        sb.append(toMotorString(new int[]{tachoCountC}));
        sb.append("]");

        return sb.toString();
    }

    /**
     * 指定されたモーター値の配列からなる文字列を組み立てる。
     * @param values 値の配列
     * @return 組み立てた文字列
     */
    public String toMotorString(int[] values) {
        if (values.length == 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append(values[0]);
        for (int i = 1; i < values.length; i++) {
            sb.append(", ");
            sb.append(values[i]);
        }
        sb.append("]");

        return sb.toString();
    }

    /*
     * (非 Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(id);

        sb.append("[");
        sb.append(toSensorString());
        sb.append(", ");
        sb.append(toMotorString());
        sb.append("]");

        return sb.toString();
    }
}
---

                                                                            以上


leJOS (18) BMPファイルの表示

2011年04月04日 | LEGO
2011-04-04
BMPファイルの表示
================================================================================

leJOSのAPIには、画像ファイルを表示するメソッドが実装されていないようです。

実際には、javax.microedition.lcdui.Graphics クラスの drawImage メソッドが使えそ
うな感じですが、エラーになります。
使い方が誤っているかもしれませんが、ここで、NXC でも使えるBMPファイルを使って画
像をLCDに表示するクラス・メソッド LEDEx#drawGraphic を作りました。

BMPファイルの制限は以下のとおりです。
・横100ドット × 縦64ドット 以内
・白黒(2色)
・圧縮していない

上記の条件に反した画像ファイルを使おうとすると、IllegalArgumentException をス
ローします。

LCDExクラスは、lejos.nxj.LCD クラスを継承しているので、LCDクラスのメソッドは使用
できます。

使い方は、APIを参照してください。

■サンプル・プログラム LCDExSample01
---
import java.io.File;

import jp.marunomaruno.lejos.nxt.LCDEx;
import lejos.nxt.Button;

public class LCDExSample01 {
    public static void main(String[] args) throws Exception {
        LCDEx.clear();
        LCDEx.drawGraphic(new File("mono100.bmp"), 0, 0);
        LCDEx.drawString("Hello", 10, 7);
        Button.waitForPress();
    }
}
/*
 * このプログラムを動かす前に、bmpファイルをNXTにダウンロードします。
 *    nxjupload ファイル名
 */
---



■LCDEx
---
package jp.marunomaruno.lejos.nxt;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.microedition.lcdui.Graphics;

import lejos.nxt.LCD;

/**
* LCD に画像を表示したりするユーティリティです。
*
* @author marunomaruno
* @version 1.0, 2011-04-03
* @since 1.0
*/
public class LCDEx extends LCD {
private static Graphics g = new Graphics();

private LCDEx() {

}

/**
* LCDにfileで指定したBMPファイルの画像を座標(x, y)から表示します。
* BMPファイルは、幅100ピクセル、高さ64ピクセル以内の、圧縮なし2色データとします。
*
* @param file
* BMPファイル
* @param x
* 描画する開始点のx座標
* @param y
* 描画する開始点のy座標
* @param invert
* trueのとき、白黒反転して描画する
* @throws IOException
* BMPファイルがない場合など
* @throws IllegalArgumentException
* 使用できるBMPファイルでない場合
*/
public static void drawGraphic(File file, int x, int y, boolean invert)
throws IOException {
// 座標の指定が範囲外のときは例外をスローする
if (x < 0 || y < 0) {
throw new IllegalArgumentException("Illegal point.");
}

FileInputStream in = new FileInputStream(file);

byte[] info = new byte[0x3e];

in.read(info);
// int bfSize = parse4bytes(info, 0x2); // ファイルサイズ (byte)
int offBits = parse4bytes(info, 0xA); // ファイル先頭から画像データまでのオフセット (byte)
int width = parse4bytes(info, 0x12); // 画像の幅 (ピクセル)
int height = parse4bytes(info, 0x16); // 画像の高さ (ピクセル)
int bitCount = parse2bytes(info, 0x1C); // 1 画素あたりのデータサイズ (bit)
int compression = parse4bytes(info, 0x1E); // 圧縮形式

// System.out.println(" offBits = " + Integer.toHexString(offBits));
// System.out.println(" width = " + Integer.toHexString(width));
// System.out.println(" height = " + Integer.toHexString(height));
// System.out.println(" bitCount = " + Integer.toHexString(bitCount));
// System.out.println("compression = " +
// Integer.toHexString(compression));

// 描画サイズが大きいときは例外をスローする
if (width > LCD.SCREEN_WIDTH || height > LCD.SCREEN_HEIGHT) {
throw new IllegalArgumentException("Illegal file format.");
}

// モノクロでないときは例外をスローする
if (bitCount != 1) {
throw new IllegalArgumentException("Illegal file format.");
}

// 圧縮されているときは例外をスローする
if (compression != 0) {
throw new IllegalArgumentException("Illegal file format.");
}

// 描画データの先頭までスキップする
in.skip(offBits - 0x3e);

// 描画する
int byteWidth = width / 8; // あまりを含めないのバイト数
int remainderBitWidth = width % 8; // あまりビット数
int readingUnitWidth = ceil((width + 7) / 8, 4); // 4バイト単位の読み込むバイト数

byte[] widthData = new byte[readingUnitWidth];

y = height - 1 + y;
int count = -1;
while ((count = in.read(widthData)) != -1) {

// System.out.printf("%d ", count);
int i = 0;
for (i = 0; i < Math.min(byteWidth, count); i++) {
drawByte(widthData[i], x + i * 8, y, invert);
}

if (remainderBitWidth > 0) {
drawByte(widthData[i], x + i * 8, y, remainderBitWidth, invert);
}

y--;
}

in.close();
}

/**
* LCDにfileで指定したBMPファイルの画像を座標(x, y)から表示します。
* BMPファイルは、幅100ピクセル、高さ64ピクセル以内の、圧縮なし2色データとします。
*
* @param file
* BMPファイル
* @param x
* 描画する開始点のx座標
* @param y
* 描画する開始点のy座標
* @throws IOException
* BMPファイルがない場合など
* @throws IllegalArgumentException
* 使用できるBMPファイルでない場合
*/
public static void drawGraphic(File file, int x, int y) throws IOException {
drawGraphic(file, x, y, false);
}

/**
* LCDにfileで指定したBMPファイルの画像を画面左上から表示します。
* BMPファイルは、幅100ピクセル、高さ64ピクセル以内の、圧縮なし2色データとします。
*
* @param file
* BMPファイル
* @throws IOException
* BMPファイルがない場合など
* @throws IllegalArgumentException
* 使用できるBMPファイルでない場合
*/
public static void drawGraphic(File file) throws IOException {
drawGraphic(file, 0, 0);
}

private static int ceil(int byteWidthWithRemainder, int base) {
return byteWidthWithRemainder + (base - byteWidthWithRemainder % base)
% base;
}

private static int parse4bytes(byte[] data, int pos) {
return (parse2bytes(data, pos + 2) << (2 * 8))
+ parse2bytes(data, pos + 0);
}

private static int parse2bytes(byte[] data, int pos) {
return (data[pos + 1] << 8) + data[pos + 0];
}

private static void drawByte(int data, int x, int y, boolean invert) {
drawByte(data, x, y, 8, invert);
}

private static void drawByte(int data, int x, int y, int bitCount,
boolean invert) {
if (x >= LCD.SCREEN_WIDTH || y >= LCD.SCREEN_HEIGHT) {
return;
}

for (int i = 0; i < bitCount; i++) {
if (((data & 0x00000080) == 0) ^ invert) {
g.fillRect(x + i, y, 1, 1);
}
data <<= 1;
}
}

}
---</pre>


なお、BMPのフォーマットについては以下のサイトを参考にしました。

Bitmapファイルフォーマット
http://www.umekkii.jp/data/computer/file_format/bitmap.cgi

BMP ファイルフォーマット
http://www.kk.iij4u.or.jp/~kondo/bmp/


以上

leJOS メモ サウンドファイルを鳴らす

2011年02月23日 | LEGO
■サウンドファイルを鳴らす

leJOSの Sound.playSample() メソッドは、wavファイルしか鳴らせません。
したがって、事前にwavファイルを用意する必要があります。

このとき、NXTソフトウェアがあれば、NXT用のrsoファイルがいくつか用意されています。
この、rsoファイルをwavファイルに変換するツールがあります。
下記のURLから、
Wav2Rso
というプログラムをダウンロードして使います。
名前は wav->rso ですが、rso->wav もできます。

http://bricxcc.sourceforge.net/utilities.html


---
import java.io.*;
import lejos.nxt.*;

public class PlayingFile01 {
    public static void main(String[] args) {
    	Sound.playSample(new File("Hello.wav")); // wavファイルを鳴らす
    	Sound.pause(1000);
    }
}
/*
このプログラムを動かす前に、wavファイルをNXTにダウンロードします。
  nxjupload  wavファイル名
*/
---



NXCメモ(5)

2011年02月22日 | LEGO
NXC Version 1.2.1 r3
---

■モーターのタコカウントを取得する

モーターのタコカウントを取得する関数。でも、この関数は3つとも同じ値が取得できたので、内容の違いがない。
MotorTachoCount
MotorBlockTachoCount
MotorRotationCount

ただ、MotorBlockTachoCountを使うと、違うモーターに対するものでも、MotorTachoCount、MotorBlockTachoCountの値が 0 にリセットされるので注意が必要。

---
task main() {
     OnFwd(OUT_BC, 75);
     Wait(10000);
     Off(OUT_BC);
     NumOut( 0, LCD_LINE2, MotorTachoCount(OUT_B));
     NumOut(30, LCD_LINE2, MotorBlockTachoCount(OUT_B));
     NumOut(60, LCD_LINE2, MotorRotationCount(OUT_B));
     NumOut( 0, LCD_LINE3, MotorTachoCount(OUT_C));
     NumOut(30, LCD_LINE3, MotorBlockTachoCount(OUT_C));
     NumOut(60, LCD_LINE3, MotorRotationCount(OUT_C));
     Wait(5000);
}
---


NXCメモ (4)

2011年02月17日 | LEGO
NXC Version 1.2.1 r3
---

■ 分割コンパイル

NXCでは、分割コンパイルはできそうにない。
モジュールの中に、mainタスクがないと、コンパイルエラーになる。

---
# Status: NXC code generation finished
# Error: No task named "main" exists
File "C:\util.nxc" ; line 18
---


■ long型のリテラル

サフィックス「L」が指定できない。
リテラルとしては、32768も指定できるので、問題はなさそう。


NXCメモ (3)

2011年02月16日 | LEGO
NXC Version 1.2.1 r3
---

■NXCでは、配列の初期値として、変数の値や定数(const)の値を設定できない

(例)つぎはコンパイルエラー

---
task main() {
     const int n1 = 10;
     const int n2 = 20;

     int a[2] = {n1, n2};
}
---
line 6: Error: Invalid constant expression
---


以上



Lego Mindstoms NXT - leJOS - (17) ファイル入出力

2010年04月05日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (17) ファイル入出力
================================================================

ファイル入出力を行います。

今回は、光センサーの調整を行い、このデータをファイルに格納してお
きます。
そのファイルに格納した値を入力することで、プログラムを起動するた
びに光センサーの調整を行う必要がなくなります。


■ファイル出力

光センサーからreadNormalizedValue()メソッドを使って、暗いときの
値と明るいときの値をファイルに保存します。


---
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;

import lejos.nxt.Button;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;

/**
 * 「トライボット」使用
 * 光センサーの最小値と最大値をint型でファイルに保存する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class Calibrator02 {

    public static void main(String[] args) throws Exception {

        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);

        // ファイルを作成する。
        File file = new File("light.dat");              // (1)
        file.delete();                                  // (2)
        file.createNewFile();                           // (3)
        DataOutputStream out = 
                new DataOutputStream(
                        new FileOutputStream(file));    // (4)
        
        // 最小値を設定する。
        System.out.println("Press Button if dark.");
        Button.waitForPress();
        int lowValue = lightSensor.readNormalizedValue();
        lightSensor.setLow(lowValue);
        System.out.println(lowValue + " " + 
                            lightSensor.readValue());
        out.writeInt(lowValue);                         // (5)
        
        // 最大値を設定する。
        System.out.println("Press Button if bright.");
        Button.waitForPress();
        int highValue = lightSensor.readNormalizedValue();
        lightSensor.setHigh(highValue);
        System.out.println(highValue + " " + 
                            lightSensor.readValue());
        out.writeInt(highValue);

        // ファイルを閉じる
        out.close();                                    // (6)
    }
}
---

□ File file = new File("light.dat");              // (1)

ファイル名を指定して、Fileオブジェクトを生成します。

Fileクラスのコンストラクタ
---
File(String name) 
---


Fileクラスの主なメソッド
---
 boolean         createNewFile()
 boolean         delete()
 boolean         exists()
 static int      freeMemory()
 String          getName()
 long            length()
 static File[]   listFiles()
 void            moveToTop()
 static void     reset()
 boolean         setReadOnly() 
---


□ file.delete();                                  // (2)
□ file.createNewFile();                           // (3)

新規にファイルを生成したいので、一度、指定されたファイルを削除
(delete)してから、新規に作成(createNewFile)しなおします。
leJOSの場合は、一度削除してからでないと、同じファイル名の場合、
不具合が起きる場合があります。


□ DataOutputStream out = new DataOutputStream(
                  new FileOutputStream(file));     // (4)

DataOutputStreamオブジェクトを指定したファイルを基に作ります。
このクラスを使うと、プリミティブ型の Java データを移植性のある形
で出力ストリームに書き込むことができます。

DataOutputStreamクラスの主なコンストラクタ
---
DataOutputStream(OutputStream out) 
---

DataOutputStreamクラスは、フィルタークラスとして、OutputStreamオ
ブジェクトをその生成時に指定します。ここでは、コンストラクターの
引数として、FileOutputStreamオブジェクトを指定しています。


DataOutputStreamクラスの主なメソッド
---
 void     close() 
 void     flush()
 int      size()
 void     write(byte[] b, int off, int len)
 void     write(int b)
 void     writeBoolean(boolean v)
 void     writeByte(int v)
 void     writeChar(int v)
 void     writeFloat(float v)
 void     writeInt(int v)
 void     writeShort(int v) 
---


FileOutputStreamクラスの主なコンストラクタ
---
FileOutputStream(File f)
FileOutputStream(File f, boolean append)
---


□ out.writeInt(lowValue);                         // (5)

int 型データを、上位バイトを先頭とする 4 バイトデータ(ビックエン
ディアン)として基本となる出力ストリームに書き込みます。


□ out.close();                                    // (6)

出力ストリームを閉じ、これに関連するすべてのシステムリソースを解
放します。 


■ファイル入力

ファイルから光センサーの最小値と最大値を取得して、センサーを調整
します。

---
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;

import lejos.nxt.Button;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;

/**
 * 「トライボット」使用
 * 光センサーの最小値と最大値をファイルから読み取り、調整する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class Calibrator03 {

    public static void main(String[] args) throws Exception {

        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);

        // ファイルを作成する。
        File file = new File("light.dat");
        DataInputStream in = 
                new DataInputStream(
                        new FileInputStream(file));     // (1)
        
        // 最小値を設定する。
        int lowValue = in.readInt();                    // (2)
        lightSensor.setLow(lowValue);
        System.out.println(lowValue);
        
        // 最大値を設定する。
        int highValue = in.readInt();
        lightSensor.setHigh(highValue);
        System.out.println(highValue);

        // ファイルを閉じる
        in.close();                                     // (3)
        
        // 終了メッセージ
        System.out.println("Press button for exit program.");
        Button.waitForPress();
    }
}
---

□ DataInputStream in = 
           new DataInputStream(
                   new FileInputStream(file));     // (1)

データ入力ストリームにより、アプリケーションは、プリミティブ型の
 Java データを基本となる入力ストリームからマシンに依存せずに読み
込むことができます。

DataInputStreamクラスの主なコンストラクタ
---
DataInputStream(InputStream in)  
---

DataInputStreamクラスは、フィルタークラスとして、InputStreamオブ
ジェクトをその生成時に指定します。ここでは、コンストラクターの引
数として、FileInputStreamオブジェクトを指定しています。


DataInputStreamクラスの主なメソッド
---
 void     close() 
 boolean  readBoolean()
 byte     readByte()
 char     readChar()
 double   readDouble()
 float    readFloat()
 void     readFully(byte[] b)
 void     readFully(byte[] b, int off, int len)
 int      readInt()
 long     readLong()
 short    readShort()
 int      readUnsignedByte()
 int      readUnsignedShort()
 String   readUTF()
 int      skipBytes(int n) 
---


FileInputStreamクラスの主なコンストラクタ
---
FileInputStream(File f) 
---


□ int lowValue = in.readInt();                    // (2)

4 バイトの入力データを読み込んで、int 値を返します。


□ in.close();                                     // (3)

入力ストリームを閉じ、これに関連するすべてのシステムリソースを解
放します。 


                                                           以上


Lego Mindstoms NXT - leJOS - (16) 光センサーの調整

2010年03月24日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (16) 光センサーの調整
================================================================================

■光センサー調整を調整する

光センサーから取得する値は、ロボットを動かす回りの環境によって、異なります。

また、センサー一般にいえることですが、センサー自体の性能によっても、取れる値の範
囲が違ってきます。たとえば、NXT標準の光センサーは10ビットなので、0~1023までの値
を取得することができますが、8ビットのセンサーや、12ビットのセンサーの場合ですと、
取れる値の範囲は、それぞれ0~255、0~4095と、違う範囲の値になってしまいます。
もちろん、ハードウェアが違えば、プログラムも違ってきますが、このようなセンサーの
値などは標準的にパーセントで取得できると、どの環境、どのハードウェアでも同じしき
い値でプログラミングできるようになります。

つぎのプログラムは、まず、暗いところと、明るいところの光量を取得し、それぞれを光
量の最小値、最大ととして設定します。そして、任意のところの光量を測定して表示しま
す。


□calibrateLow()とcalibrateHigh()を使う

これらのメソッドは、直前にreadValue()メソッドで読んだ光量をもとに、最小値、最大
値を設定します。これの後、readValue()メソッドを実行した結果は、0~100の間に収まる
ようになります。

---
import lejos.nxt.Button;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;

/**
 * 「トライボット」使用
 * 光センサーを調整する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class LightSensor13 {
    public static void main(String[] args) throws Exception {
        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);

        // センサーが安定するまで少し待つ
        Thread.sleep(100);

        // 最小値を設定する。
        System.out.println("Press Button if dark.");
        Button.waitForPress();
        int lowValue = lightSensor.readValue();                          // (1)
        lightSensor.calibrateLow();                                      // (2)
        System.out.println(lowValue + " " + lightSensor.readValue() + " " + 
                                            lightSensor.readNormalizedValue());

        // 最大値を設定する。
        System.out.println("Press Button if bright.");
        Button.waitForPress();
        
        int highValue = lightSensor.readValue();
        lightSensor.calibrateHigh();                                    // (3)
        System.out.println(highValue + " " + lightSensor.readValue() + " " + 
                                             lightSensor.readNormalizedValue());

        // 値を取得
        System.out.println("Press Button.");
        Button.waitForPress();
        System.out.println(lightSensor.readValue() + " " + 
                           lightSensor.readNormalizedValue());

        // プログラムを終える
        System.out.println("Press Button to exit.");
        Button.waitForPress();
    }
}
---

□ int lowValue = lightSensor.readValue();            // (1)

readNormalizedValue()メソッドによって、実際の値を取得します。
このメソッドは、NXTの場合は、0~1023までの範囲の値を取得します。
APIによると、145 (暗い) から 890 (太陽光)の範囲とのことです。


□ lightSensor.calibrateLow();                                // (2)

calibrateLow()メソッドで、このメソッドの直前にreadValue()メソッドで読み取った値
を、次にreadValue()メソッドで読んだときに 0 と読めるように設定します。


□ lightSensor.calibrateHigh();                              // (3)

calibrateHigh()メソッドで、このメソッドの直前にreadValue()メソッドで読み取った値
を、次にreadValue()メソッドで読んだときに 100 と読めるように設定します。


■setLow()とsetHigh()を使う

これらのメソッドは、直前にreadNormalizedValue()メソッドで読んだ光量をもとに、最
小値、最大値を設定します。これの後、readValue()メソッドを実行した結果は、0~100の
間に収まるようになります。

---
import lejos.nxt.Button;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;

/**
 * 「トライボット」使用
 * 光センサーを調整する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class LightSensor13 {
    public static void main(String[] args) throws Exception {
        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);

        // センサーが安定するまで少し待つ
        Thread.sleep(100);

        // 最小値を設定する。
        System.out.println("Press Button if dark.");
        Button.waitForPress();
        int lowValue = lightSensor.readNormalizedValue();            // (1)
        lightSensor.setLow(lowValue);                                // (2)
        System.out.println(lowValue + " " + lightSensor.readValue());

        // 最大値を設定する。
        System.out.println("Press Button if bright.");
        Button.waitForPress();
        int highValue = lightSensor.readNormalizedValue();
        lightSensor.setHigh(highValue);                              // (3)
        System.out.println(highValue + " " + lightSensor.readValue());

        // 値を取得
        System.out.println("Press Button.");
        Button.waitForPress();
        System.out.println(lightSensor.readNormalizedValue() + " " + 
                           lightSensor.readValue());

        // プログラムを終える
        System.out.println("Press Button to exit.");
        Button.waitForPress();
    }
}
---

□ int lowValue = lightSensor.readNormalizedValue();            // (1)

readNormalizedValue()メソッドによって、実際の値を取得します。
このメソッドは、NXTの場合は、0~1023までの範囲の値を取得します。
APIによると、145 (暗い) から 890 (太陽光)の範囲とのことです。


□ lightSensor.setLow(lowValue);                                // (2)

setLow()メソッドで、readNormalizedValue()メソッドで読み取った値を、readValue()メ
ソッドで読んだときに 0 と読めるように設定します。


□ lightSensor.setHigh(highValue);                              // (3)

setHigh()メソッドで、readNormalizedValue()メソッドで読み取った値を、readValue()
メソッドで読んだときに 100 と読めるように設定します。


■光センサー調整ユーティリティ

光センサーを調整する部分をユーティリティ化します。

---
import lejos.nxt.Button;
import lejos.nxt.LightSensor;

/**
 * 「トライボット」使用
 * 光センサーを調整するユーティリティ。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class Calibrator01 {

    /**
     * 光センサーを調節する。
     * 調節し終わったら、いずれかのボタンの押下をうながし、待ち状態になる。
     * @param lightSensor 光センサー
     */
    public static void calibrate(LightSensor lightSensor) {    // (1)
        // 最小値を設定する。
        System.out.println("Press Button if dark.");
        Button.waitForPress();
        int lowValue = lightSensor.readNormalizedValue();
        lightSensor.setLow(lowValue);
        System.out.println(lowValue + " " + lightSensor.readValue());

        // 最大値を設定する。
        System.out.println("Press Button if bright.");
        Button.waitForPress();
        int highValue = lightSensor.readNormalizedValue();
        lightSensor.setHigh(highValue);
        System.out.println(highValue + " " + lightSensor.readValue());

        // スタートする。
        System.out.println("Press Button to start.");
        Button.waitForPress();
    }

}
---

□ public static void calibrate(LightSensor lightSensor) {    // (1)

光センサを調整するメソッドです。


■このユーティリティを使うプログラム

---
import lejos.nxt.Button;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;

/**
 * 「トライボット」使用
 * 光センサーを調整する。このとき、光センサー調整クラスを使う。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/15
 * @since 1.0
 */
public class LightSensor14 {
    public static void main(String[] args) throws Exception {
        // 光センサーオブジェクトをポート3で生成する。
        LightSensor lightSensor = new LightSensor(SensorPort.S3);

        // センサーが安定するまで少し待つ
        Thread.sleep(100);

        // 光センサーを調整する
        Calibrator01.calibrate(lightSensor);                    // (1)
        
        // 値を取得
        System.out.println(lightSensor.readNormalizedValue() + " " + 
                           lightSensor.readValue());

        // プログラムを終える
        System.out.println("Press Button to exit.");
        Button.waitForPress();
    }
}
---

□ Calibrator01.calibrate(lightSensor);                    // (1)

光センサを調整するユーティリティを使います。staticメソッドなので、クラス名.メソ
ッド名で呼び出します。

                                                                           以上



Lego Mindstoms NXT - leJOS - (15) タイマーとストップウォッチ

2010年03月16日 | LEGO
◆ Lego Mindstoms NXT - leJOS - (15) タイマーとストップウォッチ
================================================================================

NXTボタンを使ったリスナー、センサーを使ったリスナーは、それぞれ、

(8) ボタン・リスナー 2008-08-26 
http://blog.goo.ne.jp/marunomarunogoo/d/20080826

(9) リスナー 2008-09-02 
http://blog.goo.ne.jp/marunomarunogoo/d/20080902

で行いました。今度は、タイマーを使ったリスナーを学習しましょう。

■時間がきたらプログラムを終える

タイマーを使って、時間がきたらプログラムを終了させます。
ついでに、今までのEscボタン押下でもプログラムが止まるように、ButtonListener も合
わせて実装しましょう。

□リスナーを利用するクラス

まずは、その場で10秒間回転するプログラムです。
ただし、mainメソッドの中では、20秒間回転するようになっています。
タイマーリスナーを使い、10秒で終了するようにしています。

TimerListener01.java
------------------------------------------------------
import jp.marunomaruno.nxt.timer.s01.ExitListener;
import lejos.nxt.Motor;
import lejos.util.Timer;
import lejos.util.TimerListener;

/**
 * 「トライボット」使用
 * その場で10秒間回転する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/08
 * @since 1.0
 */
public class TimerListener01 {
    public static void main(String[] args) throws Exception {

        // 10秒でプログラムを終了するタイマーを設定する。
        TimerListener timerListener = new ExitListener();     // (1)
        Timer timer = new Timer(10000, timerListener);        // (2)
        timer.start();                                        // (3)
        
        // その場で20秒回転する。
        Motor.B.forward();
        Motor.C.backward();
        Thread.sleep(20000);
        
        timer.stop();                                         // (4)
    }
}
------------------------------------------------------

□TimerListener timerListener = new ExitListener();    // (1)

タイマーリスナーのオブジェクトを生成します。
これは、TimerListenerインターフェースを実装したオブジェクトになります。
今回は、ExitListenerクラスとして作りました。


□Timer timer = new Timer(10000, timerListener);        // (2)

タイマーリスナーは、このタイマーオブジェクトに設定します。


コンストラクター
---
Timer(int theDelay, TimerListener el) 
    イベント遅延の時間をtheDelayミリ秒とし、リスナーelとするタイマーオブジェクト
を生成するとコンストラクターです。
---

メソッド
---
 int getDelay() 
    theDelayミリ秒経過するごとに、 timedOut()メソッドにメッセージを送ります。

 void start() 
    タイマーを起動します。このとき、timedOut()メソッドにメッセージを送ります。

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


□timer.start();                                        // (3)

タイマーを起動します。


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

タイマーを停止します。


■ExitListener

プログラムを終わらせるリスナーです。
このリスナーは、いずれかのボタン(想定はESCAPEボタン)押下または、指定された時間に
なったらプログラムを終了するリスナーとして作ります。

------------------------------------------------------
package jp.marunomaruno.nxt.timer.s01;

import lejos.nxt.Button;
import lejos.nxt.ButtonListener;
import lejos.nxt.Sound;
import lejos.util.TimerListener;
/**
 * Escボタン押下または、指定された時間になったらプログラムを終了するリスナー。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/08
 * @since 1.0
 */
public class ExitListener implements ButtonListener, TimerListener {    // (1)
    /* (non-Javadoc)
     * @see lejos.nxt.ButtonListener#buttonPressed(lejos.nxt.Button)
     */
    public void buttonPressed(Button button) {    
        exit(262);    // C
    }

    /* (non-Javadoc)
     * @see lejos.nxt.ButtonListener#buttonReleased(lejos.nxt.Button)
     */
    public void buttonReleased(Button button) {
        exit(277);    // C#
    }

    /* (non-Javadoc)
     * @see lejos.util.TimerListener#timedOut()
     */
    public void timedOut() {                                            // (2)
        exit(294);    // D
    }

    /**
     * トーンを鳴らしてプログラムを終了する。
     * @param freq 周波数
     */
    private void exit(int freq) {                                        // (3)
        Sound.playTone(freq, 200);
        Sound.pause(300);
        System.exit(0);
    }
}
------------------------------------------------------

□public class ExitListener implements ButtonListener, TimerListener {    // (1)

このクラスには、ButtonListenerインターフェースと、TimerListenerインターフェース
を実装しています。

ButtonListenerインターフェースは、以下のメソッドがあります。詳しくは、
(8) ボタン・リスナー
を参照してください。
    public void buttonPressed(Button button)
    public void buttonReleased(Button button)


また、TimerListenerインターフェースは、以下のメソッドを持ちます。
    public void timedOut()


□public void timedOut() {                                            // (2)

このtimedOut()に、タイムアウトしたときの処理を記述します。今回は、このクラスのpr
ivateメソッドであるexit()メソッドを呼び出して、そこでプログラムを終了させます。


□private void exit(int freq) {                                        // (3)

これは、指定された周波数のトーンを鳴らしてプログラムを終了します。


■ストップウォッチ

今度は、ストップウォッチのように、NXT画面に動かしてからの経過秒数を表示するプロ
グラムを作りましょう。

□TimerListener02.java
------------------------------------------------------
import jp.marunomaruno.nxt.timer.s01.StopwatchListener;
import lejos.nxt.Button;
import lejos.nxt.Motor;
import lejos.util.Timer;
import lejos.util.TimerListener;

/**
 * 「トライボット」使用
 * その場で回転し、1秒ごとに経過時間を画面に表示する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/08
 * @since 1.0
 */
public class TimerListener02 {
    public static void main(String[] args) throws Exception {

        // 1秒ごとに画面表示するタイマーを設定する。
        TimerListener timerListener = new StopwatchListener();    // (1)
        Timer timer = new Timer(1000, timerListener);

        // 開始する。
        System.out.println("Press any button to start stopwatch.");
        Button.waitForPress();
        timer.start();                                            // (2)
        
        // その場で回転する。
        Motor.B.forward();
        Motor.C.backward();
        
        // 終了する。
        System.out.println("Press any button to stop stopwatch.");
        Button.waitForPress();
        timer.stop();                                            // (3)
        Motor.B.stop();
        Motor.C.stop();

        // プログラムを終了する。
        System.out.println("Press any button to exit program.");
        Button.waitForPress();
    }
}
------------------------------------------------------

□TimerListener timerListener = new StopwatchListener();    // (1)

つぎで作る、ストップウォッチを実装するリスナーのオブジェクトを生成します。


□timer.start();                                            // (2)

タイマーを起動します。


□timer.stop();                                            // (3)

タイマーを停止します。


■ストップウォッチ・リスナー

呼び出されるごとに経過時間を画面に表示するリスナーです。

□StopwatchListener.java
------------------------------------------------------
package jp.marunomaruno.nxt.timer.s01;

import lejos.util.Stopwatch;
import lejos.util.TimerListener;

/**
 * 呼び出されるごとに経過時間を画面に表示する。
 * 
 * @author marunomaruno
 * @version 1.0, 2010/03/08
 * @since 1.0
 */
public class StopwatchListener implements TimerListener {    // (1)

    private Stopwatch stopwatch;                      // (2) ストップウォッチ
    
    /**
     * コンストラクター。
     */
    public StopwatchListener() {
        this.stopwatch = new Stopwatch();            // (3)
        this.stopwatch.reset();                      // (4)
    }
    
    /* (non-Javadoc)
     * @see lejos.util.TimerListener#timedOut()
     */
    @Override
    public void timedOut() {                         // (5)
        System.out.println(stopwatch.elapsed() / 1000);    // (6)
    }
}
------------------------------------------------------

□public class StopwatchListener implements TimerListener {    // (1)

TimerListenerを実装します。


□private Stopwatch stopwatch;    // (2) ストップウォッチ

ストップウォッチ・オブジェクトを入れるフィールドを宣言します。

コンストラクター
---
Stopwatch() 
---
            
メソッド
---
 int elapsed() 
    経過時間をミリ秒単位で返します。

 void reset() 
    時間をリセットします。
---


□this.stopwatch = new Stopwatch();    // (3)

ストップウォッチ・オブジェクトを生成します。

コンストラクターは、この引数のないものだけです。


□this.stopwatch.reset();                // (4)

ストップウォッチをリセットします。


□public void timedOut() {                           // (5)

タイムアウトしたときのメソッドを定義します。


□System.out.println(stopwatch.elapsed() / 1000);    // (6)

ストップウォッチから経過時間を取得して表示します。elapsed()メソッドは、ミリ秒で
取得するので、秒単にするため、1000で割っています。

                                                                        以上

LEGO MINDSTORMS NXT の二輪倒立ロボットを、Java言語で制御するための技術資料

2010年02月26日 | LEGO
ETロボコン2010も、いよいよ始まりました。
http://www.etrobo.jp/ETROBO2010/

昨年は、Javaで NXT走行体の「二輪倒立ロボット」をJava言語で制御することをあきらめたのですが、いま、いろいろと見てみると、いくつかあるようです。

LEGO MINDSTORMS NXT の二輪倒立ロボットを、Java言語で制御するための技術資料
http://www.jacom.co.jp/
トップページより、
→「ETロボコン2009に向けた取り組みについて」
→「技術情報のページへ」
→「ファイルダウンロード」
この方は、昨年、参加されたようです。
(http://haneuma2009.blog54.fc2.com/blog-date-200908-1.html)

上記とは別に、つぎもありました。こちらはBluetoothによるリモコンです。
GELway - A self-balancing robot
http://code.google.com/p/gelway/




leJOS 0.8.5 で超音波センサーが動かない -> ポート4以外に接続で動く

2009年11月17日 | LEGO
leJOS 0.8.5 で超音波センサーが動かない -> ポート4以外に接続で動く
=========================================================

leJOS 0.8.5 を使うと、超音波センサーからの値(getDistance()
メソッドの返り値)がつねに 255 のままになる。なぜだろう?

PC の環境は以下のとおり。
WindowsXP SP2
JavaSE1.6

leJOS のフォーラムには、以下の記事があった。
「.8.5 on NXT2.0- Ultrasonic/Color Sensor don't return
values.」
http://lejos.sourceforge.net/forum/viewtopic.php?t=1706
これによると、超音波センサーだけではなく、色センサーでも
同じ現象が起きているようだ。
この現象の対処は、ポート4 ではなく、別のポートにセンサー
をつなげればよい。

上記のプログラムも、ポート4 以外につなげたところ、センサー
は働くことを確認できた。


なお、NXT に、leJOS 0.8.0 に入れなおしたところ、超音波
センサーからの値はちゃんと読み取れるようになった。
ちなみに、このプログラムは leJOS 0.6.0、leJOS 0.7.0 のい
ずれでも動作する。


確認プログラムは以下のとおり。
---
import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.Sound;
import lejos.nxt.UltrasonicSensor;

public class USSensor01 {

    public static void main(String[] args) {

        // 超音波センサーオブジェクトをポート4で生成する。
        UltrasonicSensor ultrasonicSensor = 
                     new UltrasonicSensor(SensorPort.S4);
        
        while (!Button.ESCAPE.isPressed()) {
            LCD.refresh();
            
            // 超音波センサーの値の表示
            LCD.drawString("US = " +
                     ultrasonicSensor.getDistance(), 0, 3); 
        }
        Sound.pause(1000);
    }
}
---


以上



Java プログラムでロボットを動かそう

2009年11月05日 | LEGO
ロボットが目覚める! 『中学生からはじめるプログラミング』

対象: 中学生から社会人まで

STEP2.
Java プログラムでロボットを動かそう

開催日 <集中コース>
‘09 年11 月21 日(土) A カリキュラム
‘09 年11 月28 日(土) Bカリキュラム

時間/会場 9 時30 分~17 時 シェアグリッド研修室

受講料
日間お申込み \12,600(税込)
2 日間お申込み \20,160(税込)

カリキュラム

●A カリキュラム
<目標>: JAVA の決まり事を学ぶ
■プログラムとJava を知ろう
■センサーを使って動きを制御しよう
■プログラムを極めよう!<同じ動きを繰り返す>
●Bカリキュラム
<目標>:自分でプログラムを組む
■プログラムを極めよう!<状況判断して動かす>
■イレギュラー(異常事態)も対処しよう
■ロボットを思い通りに動かそう

お申込・お問合せ
045・350・5661
info@enjoy-robo.com
http://www.enjoy-robo.com
有限会社シェアグリッド
横浜市中区山下町252
グランベル横浜ビル6 階
※教材のロボットは、教育用レゴ マインドストームNXT を使用します。