Sheet 1
一般向けロボットコース
  カリキュラム
    step0 - 体験コース
    Step1 - プログラムでロボットを動かそう
      車体
        トライボット
      目標
        ロボットを組み立てる
        簡単ソフトを使って動かす
        プログラムをとりあえず入力してみる
      1回目
        目標
          ブロックを組み立て、動かしてみる
        内容
          車体
            トライボット
          NXTブロックのコマンドを使ってモーターやセンサーを確認
          NXTソフトを使ってみる
          ブロック
            モーター
            音ブロック
            画面ブロック
        カリキュラム
          Lego概要
          トライボット組立て
          NXTコマンド
            NXTコマンドの確認
            モーターを使って動かす
          NXTソフトウェア
            モーターを使って動かす
            PCとの接続確認
            音を出したり、画面に絵を表示してみよう
      2回目
        目標
          NXTソフトウェアを使ってロボットを動かしてみる
          センサーを使って動きを制御する
        内容
          構造
            順次
            繰り返し
          ブロック
            タッチセンサー
            超音波センサー
            音センサー
              オプション
            光センサー
              オプション
        カリキュラム
          NXTソフトウェアの概要
            前回の復習、必要に応じて
          超音波によって動きを変える
          タッチによって動きを変える
          音によって動きを変える
          光によって動きを変える
      3回目
        目標
          アルゴリズムを考える
          共通ブロックを使って、動きを部品化する
          NXTソフトウェアのまとめ
        内容
          構造
            くり返し
            判断
            関数
          ブロック
            共通ブロック
          NXTソフトウェアを使った総合演習
        カリキュラム
          共通ブロックを作る
          共通ブロックを使う
          創作課題
      4回目
        目標
          Javaに慣れよう
            Javaの細かい文法はStep2 で行い、ここではサンプルを写してみる程度
        内容
          構造
            順次
          API
            Motor
          leJOSはこちらでインストールしておく
        カリキュラム
          NXTソフトウェアで作ったものをJavaで作り直してみる
      5回目
        目標
          Javaに慣れよう
        内容
          構造
          ブロック
          6回目の準備
        カリキュラム
          NXTソフトウェアで作ったものをJavaで書く
          いろいろな課題
          6回目で作りたい物のアイディアを書く
            PPT使う　/　模造紙
      6回目
        目標
          まとめ
        内容
          構造
          ブロック
        カリキュラム
          総合演習
            創作課題
    step2 - Javaプログラムでロボットを動かそう
      目標
        Javaプログラムの決まりごとを学ぶ
        自分でプログラムを組んでみる
      1回目
        目標
          leJOSの概要理解と使い方になれる
          Javaを知ろう
        内容
          Javaの概要
          文法
            順次
            System.out.println
            Thread.sleep()
            class、mainメソッド、ブロック
              mainにthrowsを入れるか?
            コメント
            データ型、変数、リテラル
            算術演算子、文字列連結演算子
          API
            Motor
            Button.waitForPress()
        カリキュラム
          Java概要
          Javaインストール
            オプション
          leJOS概要
          leJOSインストール
            オプション
          HelloWorldを出す
            HelloWorld.java
          モーターを動かす
            ForwardBack01.java
      2回目
        センサーを使い、動きを制御する
        内容
          文法
            繰り返し
            while
            for
            boolenan
            条件演算子
          API
            TouchSensor
            UltrasonicSensor
        カリキュラム
          同じ操作を何回か繰り返す
          タッチセンサー
            TouchSensor01.java
              Pilotを使っているが、修正予定
          超音波センサー
            USSensor01.java
              Pilotを使っているが、修正予定
      3回目
        目標
          繰返しを極める
        内容
          文法
            do-while
          API
            SoundSensor
            LightSensor
          ここまでのまとめの課題
        カリキュラム
          音センサー
            SoundSensor01.java
              Pilotを使っているが、修正予定
          光センサー
            LightSensor01.java
              Pilotを使っているが、修正予定
          実習
      4回目
        目標
          音を出す
          画面に表示する
          条件によって、複雑な動きをする
        内容
          文法
            if
            定数
            論理演算子
          API
            Sound
              オプション
            LCD
        いろいろな音を出す
          Beep01.java
          SystemSound01.java
        画面に測定値を表示する
          Sensor01.java
      5回目
        目標
          イレギュラー(異常事態)に対処しよう
        内容
          文法
            try~catch
          API
        カリキュラム
          例外
          6回目で作りたい物のアイディアを書く
            PPT使う　/　模造紙
      6回目
        目標
          まとめ
        内容
          総合演習
        カリキュラム
          総合演習
            創作課題
    step3 - きれいなプログラムを目指そう
      目標
        少し難しいプログラムを組んでみる
        誰にでもわかるようにプログラムをきれいにする
        自分で設計もしてみる
      1回目
        目標
          自分でクラスやメソッドを作り、使う
            staticメソッドで十分?
        内容
          文法
            メソッドを作る
            クラスを作る
          API
        カリキュラム
          2つのモーターを合わせて管理するクラスを作る
          Pilotオブジェクトを使ってプログラミングしよう
            ForwardBack12.java
            TrunRight11.java
      2回目
        目標
          オブジェクト指向の利点を理解する
        内容
          文法
            リスナー
            クラスの利用
          API
            Pilot
          配列
            使うか?
        ボタンを使ってプログラムを止めよう
          ButtonListener.java
          EscapeListener.java
        タッチしたらロボットを止めよう
          TouchListener12.java
          Touch2ExitListener.java
      3回目
        目標
          機能を分割して組み立てる
            この回は失敗し、次回につなげる
            1回完結でなくて大丈夫か?
          リスナーの概念を理解する
        内容
          役割分担したクラス
          文法
            ButtonListener
            SensorPortListener
          API
        カリキュラム
          分担したコードをまとめてみよう
          課題説明
          機能を役割分担しよう
            まっすぐ走る
            障害物にぶつかったら少し後退して方向を換える
            黒線をまたいだら、150 度回転して、進行方向を逆にする
          役割にしたがってコードを書こう
      4回目
        目標
          機能を分解して組み立てる
          行動制御APIを使う
        内容
          文法
            配列
          API
            Behavior
            Arbitrator
          役割分担したクラスをまとめる
        カリキュラム
          役割をまとめよう
            Bumper21
          役割にしたがったコードを書こう
            DriveForward
            HitWall
            DarkLine
          役割に優先順序をつけよう
      5回目
        目標
          人が見てわかるプログラムを書こう
        内容
          文法
          API
          課題を与えて、お互いにレビューする
        カリキュラム
          課題
          レビュー
          レビュー後のフィードバック
      6回目
        目標
          まとめ
        内容
          総合演習
        カリキュラム
          総合演習
            レース
    step4 - ETロボコン向け
      目標
        チャンピオンシップ大会に出場
        6回くらいか?
      1回目
        目標
        内容
      2回目
        目標
        内容
      3回目
        目標
        内容
      4回目
        目標
        内容
      5回目
        目標
        内容
      6回目
        目標
        内容
  残しトピック
    NXTソフトウェア
      記録･再生ブロック
      変数ブロック
      メッセージの送信
      メッセージの受信
      キープアライブ
      ファイルアクセス
      モーターリセット
    Java言語
      マルチスレッド
      syncronized
    leJOS
      lejos.nxt.comm パッケージ
      lejos.pc.commパッケージ
      Sound.playTone()
      FileOutputStream
      Datalogger
      NXTコマンド
        nxjdataviewer
        nxjbrowse
    内容
      NXT同士の通信
      NXTとPCとの通信
      NXTのデバッギング
      画面への描画
      制御のフィードバック
      ロギング
    センサー
      色センサー
      GyroSensor
      CompassSensor
      温度センサー
  準備
    APIが英語版しかないので、ある程度は和訳(中学生がわかる)したものを用意する必要あり
      自分で調べる
    同じPCを継続して使う手段、または、違うPCでも違和感なく使えるようにする
      ファイルサーバーを用意
      USBメモリーを用意して自分で(?)管理
      作業前にリフレッシュする
    leJOS、開発環境などは家でもできるような手順書やCDなどを用意する
    スキルレベルのチェックシート作成
  保留 /疑問点
    NXTソフトウェアはロボット1台につきひとつか?(ライセンス)
      6台にひとつ
    NXTソフトウェア2.0はいつでるのか?
      2009年1月
    leJOSは、NXT2.0の機能への対応はいつごろか?
    ETロボコンで使うセンサーは何か? そのセンサーを一般のカリキュラムに取り入れる必要はあるか?
      なし
    開発環境をどうする?
      Step2はエディッタを使う
        DOSプロンプトを使うのは困難
      すべてEclipseを使う
        これ
      Eclipse以外の統合開発環境はあるか
    コースの実施日以外に来て自習することは?
      空いていればOK?
    NXTの貸出?
      他の講習が間に入る可能性があるので無理
    自分のPCの持ち込み可
      OK
    休んだ子の対応
    身体障害者への対応
      施設には障害者用の設備がない
    知的障害者への対応
      チェックリストでチェックする
import lejos.nxt.*;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
Button.waitForPress();
}
}
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.*;
import lejos.navigation.*;
public class TouchSensor01 {
public static void main(String[] args) {
TouchSensor touchSensor = new TouchSensor(SensorPort.S1);
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
pilot.forward();
while (!touchSensor.isPressed()) ;
pilot.stop();
}
}
import lejos.nxt.*;
import lejos.navigation.*;
public class USSensor01 {
public static void main(String[] args) {
UltrasonicSensor ultrasonicSensor = new UltrasonicSensor(SensorPort.S4);
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
pilot.forward();
while (ultrasonicSensor.getDistance() > 50);
pilot.stop();
}
}
import lejos.nxt.*;
import lejos.navigation.*;
public class SoundSensor01 {
public static void main(String[] args) {
SoundSensor soundSensor = new SoundSensor(SensorPort.S2);
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
pilot.forward();
while (soundSensor.readValue() < 50);
pilot.stop();
}
}
import lejos.nxt.*;
import lejos.navigation.*;
public class LightSensor01 {
public static void main(String[] args) {
LightSensor lightSensor = new LightSensor(SensorPort.S3);
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
pilot.forward();
while (lightSensor.readValue() > 50);
pilot.stop();
}
}
import lejos.nxt.Button;
import lejos.nxt.Sound;
/**
* ビープ音を鳴らすプリケーション。
*
* @author marunomaruno
* @version 1.0, 2008/06/04
* @since 1.0
*/
public class Beep01 {
/**
* @param args
*/
public static void main(String[] args) {
Sound.setVolume(Sound.VOL_MAX); // (1)
System.out.println("Press any button to beep.");
Button.waitForPress();
Sound.beep(); // (2)
System.out.println("Press any button to beep twice.");
Button.waitForPress();
Sound.twoBeeps(); // (3)
System.out.println("Press any button to buzz.");
Button.waitForPress();
Sound.buzz(); // (4)
System.out.println("Press any button to exit.");
Button.waitForPress();
}
}
import lejos.nxt.Button;
import lejos.nxt.Sound;
/**
* システム音を鳴らすプリケーション。
*
* @author marunomaruno
* @version 1.0, 2008/06/04
* @since 1.0
*/
public class SystemSound01 {
/**
* @param args
*/
public static void main(String[] args) {
Sound.setVolume(Sound.VOL_MAX);
System.out.println("Press any button to code 0.");
Button.waitForPress();
Sound.systemSound(true, 0); // (1)
System.out.println("Press any button to code 1.");
Button.waitForPress();
Sound.systemSound(true, 1);
System.out.println("Press any button to code 2.");
Button.waitForPress();
Sound.systemSound(true, 2);
System.out.println("Press any button to code 3.");
Button.waitForPress();
Sound.systemSound(true, 3);
System.out.println("Press any button to code 4.");
Button.waitForPress();
Sound.systemSound(true, 4);
System.out.println("Press any button to exit.");
Button.waitForPress();
}
}
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);
}
}
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();
}
}
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();
}
}
import lejos.navigation.*;
import lejos.nxt.*;
public class ButtonListener12 {
public static void main(String[] args) {
// Escapeボタンにリスナーを実装する
Button.ESCAPE.addButtonListener( new EscapeListener());
// パイロットのオブジェクトを生成する
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
while (true) {
pilot.forward();
Sound.pause(500);
pilot.stop();
Sound.pause(500);
pilot.backward();
Sound.pause(500);
pilot.stop();
Sound.pause(500);
}
}
}
import lejos.nxt.*;
public class EscapeListener implements ButtonListener {
public void buttonPressed(Button button) {
System.exit(0);
}
public void buttonReleased(Button button) {
System.exit(0);
}
}
import lejos.navigation.*;
import lejos.nxt.*;
public class TouchListener12 {
public static void main(String[] args) {
SensorPort.S1.addSensorPortListener( new Touch2ExitListener());
Pilot pilot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
... (中略 ButtonListener12.javaと同じ) ...
}
}
import lejos.nxt.*;
public class Touch2ExitListener implements SensorPortListener {
public void stateChanged(SensorPort aSource, int aOldValue, int aNewValue) {
if (aSource.getId() == SensorPort.S1.getId() && aSource.readBooleanValue()) {
System.exit(0);
}
}
}
黒線で囲まれたところからロボットが出ずに、その中だけで障害物を避けながらロボットを動かす
package bhvr;
import l.EscapeListener;
import lejos.navigation.Pilot;
import lejos.nxt.Button;
import lejos.nxt.Motor;
import lejos.subsumption.Arbitrator;
import lejos.subsumption.Behavior;
/**
* まっすぐ走る、
* 障害物にぶつかったら少し後退して方向を換える、
* 黒線をまたいだら、黒線をまたいだら360度回転して、進行方向を逆にする
*
* @author marunomaruno
* @version 1.0, 2008/09/29
* @since 1.0
*/
public class Bumper21 {
public static void main(String[] args) {
// ESCAPE ボタンを押すとプログラム停止する
Button.ESCAPE.addButtonListener(new EscapeListener());
// トライボットのオブジェクトを生成する
Pilot trybot = new Pilot(5.6f, 13f, Motor.C, Motor.B);
Behavior[] behaviors = { // (1)
new DriveForward(trybot), // 直進する
new HitWall(trybot), // 障害物にぶつかったときに後退して90度回転する
new DarkLine(trybot), // 黒線を超えたときに後退し、150度回転する
};
Arbitrator arbitrator = new Arbitrator(behaviors); // (2)
arbitrator.start(); // (3)
}
}
package bhvr;
import lejos.navigation.Pilot;
import lejos.subsumption.Behavior;
/**
* 直進する振舞いを規定するクラス
* @author marunomaruno
* @version 1.0, 2008/09/29
* @since 1.0
*/
public class DriveForward implements Behavior { // (1)
private Pilot pilot;
public DriveForward(Pilot pilot) { // (2)
this.pilot = pilot;
}
public boolean takeControl() { // (3)
return true;
}
public void suppress() { // (4)
pilot.stop();
}
public void action() { // (5)
pilot.forward();
}
}
package bhvr;
import lejos.navigation.Pilot;
import lejos.nxt.SensorPort;
import lejos.nxt.Sound;
import lejos.subsumption.Behavior;
/**
* 障害物にぶつかったときに後退して90度回転する振舞いを規定するクラス
* @author marunomaruno
* @version 1.0, 2008/09/29
* @since 1.0
*/
public class HitWall implements Behavior {
private Pilot pilot;
public HitWall(Pilot pilot) {
this.pilot = pilot;
}
public boolean takeControl() {
return SensorPort.S1.readBooleanValue();
}
public void suppress() {
Sound.systemSound(true, 2);
pilot.stop();
}
public void action() {
pilot.backward(); // 後退する
Sound.pause(500);
pilot.rotate(90); // 回転する
}
}
package bhvr;
import lejos.navigation.Pilot;
import lejos.nxt.LCD;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;
import lejos.nxt.Sound;
import lejos.subsumption.Behavior;
/**
* 黒線を超えたときに 150 度回転する振舞いを規定するクラス
* @author marunomaruno
* @version 1.0, 2008/09/29
* @since 1.0
*/
public class DarkLine implements Behavior {
private static final int THRESHOLD = 40; // 黒線を判断するしきい値
private Pilot pilot;
private LightSensor lightSensor;
public DarkLine(Pilot pilot) {
this.pilot = pilot;
lightSensor = new LightSensor(SensorPort.S2);
}
public boolean takeControl() {
LCD.drawInt(lightSensor.readValue(), 1, 1);
return lightSensor.readValue() < THRESHOLD;
}
public void suppress() {
Sound.systemSound(true, 3);
pilot.stop();
}
public void action() {
pilot.stop();
pilot.rotate(150);
}
}