Tag Archives: lejos

0725 JAVA程式設計研習與新書發表


CAVE 的第二本重量級機器人專業書籍 "JAVA機器人程式設計與應用" 出版了,特別舉辦本次JAVA程式設計研習新書發表會。您只要參加本次活動就能輕鬆擁有本書以及3個小時的專業訓練。請速報名唷

活動時間:2010/7/25 13:30~17:00

講師:CAVE教育團隊專業講師

地點:巨匠電腦館前分校(台北市館前路34號4樓)

報名費:$1,500, 贈送 "JAVA機器人程式設計與應用"一本, 市價$450元.

注意事項:請自備NXT機器人套件,並依以下連結組裝範例: http://www.cavedu.com/lejosfile/car.lxf?attredirects=0&d=1

活動內容: 

leJOS程式環境介紹

基礎機器人控制語法

  馬達與感測器

  肺活量計 – 聲音感測器

  總是剛剛好 – 超音波感測器

機器人專題實作: 藍芽遙控車

JAVA機器人程式設計與實作 書中範例程式下載

ok, CAVE的部落格從 2009/10/10開始的每日一篇, 在昨天6/22不小心中斷了。當然這其實沒什麼大不了的, 繼續po就是了。

那麼接著新的開始要和大家分享的是<JAVA機器人程式設計與實作>的範例程式, 為了迎接即將出版的喜悅, CAVE將本書中的範例程式內容放在CAVE官網讓大家下載囉!!  之後會視情況放上試讀章節。

http://www.cavedu.com/lejosfile

有下有推, 也請大家給我們意見囉! <機器人新視界>第二版的範例程式也會盡快整理出來。

Java book 書名徵求

本書書名暫定<Java機器人物件導向程式設計>, 或者用比較趣味一點名字<機器人咖啡香 – Java Programming>這樣好像也不錯, 不會那麼死板。

因此阿吉想請各位朋友為本書構思一下書名, 書名一經採用, 將給您神秘小禮物一份。

現在進度 92%. 3月底定稿沒有問題。 想起從過年開始沒天沒夜的work, 這是值得的, 阿吉改到快掉頭髮了…

本書很榮幸請到 leJOS 創辦人之一, Juan Antonio, 為本書編寫第一章<leJOS歷史沿革與未來發展>, 會由阿吉翻譯。 本書出版之後會在封面看到Juan的名字。

http://www.juanantonio.info/jab_cms.php?id=228 <- Juan 的個人網站, 大家可以上去看看它的作品。 Quite serious.

Announcement – [Java 機器人物件導向程式設計]

書名: Java 機器人物件導向程式設計

作者: [CAVE小小原始人創意工坊]. 曾吉弘, 林祥瑞, 謝宗翰

內容簡述: leJOS是使用在LEGO NXT上的Java語言,與NXT-G圖像化程式相比, 更能完整發揮NXT的各樣效能。使用完整的Java函式庫, 除了各種I/O設備的控制程度更高之外, 也能自行設計人機介面與網路元件。 適合國高中生以及進階成人玩家使用。

出版: 碁峰資訊

預估頁數: 250

本書大綱:

Ch1 初次探索leJOS

Ch2 開發環境設定
Ch3 第一個機器人程式
Ch4 Java語法入門
Ch5 感應器
Ch6 leJOS百寶箱
Ch7 進階I/O控制
Ch8 通訊
Ch9 導航
Ch10多工與行為

Ch11 [專題]遙控游標
Ch12 [專題]雙光感軌跡車
Ch13 [專題]電子指北針
Ch14 [專題]藍牙遙控車
Ch15 [專題]遠端遙控
Ch16 [專題]足球機器人

附錄A:範例機器人組裝說明

附錄B:leJOS附加功能說明

附錄C:線上資源與參考文獻

Compass Reader Advanced by 祥瑞

Compass Reader Basic 的加強版, 可以按ENTER鍵記錄角度,左鍵切換方位角/方向角,右鍵清除已記錄的資料, EXIT鍵結束程式。

import lejos.nxt.*;
import lejos.nxt.addon.CompassSensor;
import lejos.util.Delay;
import javax.microedition.lcdui.Graphics;

class CompassAdvance implements ButtonListener {
    public CompassSensor compass = new CompassSensor(SensorPort.S1);
    public int lineLength = 50; //線長度
    public int arrowLength = 15; //箭頭線長度
    public int arrowAng = 30; //箭頭線與線的角度
    public int dots = 40; //圓周點的數目
    public int delay = 150; //更新螢幕間隔
   
    public int offsetX;
    public int offsetY;
    public Graphics g = new Graphics();
    public double direction;
    public boolean type = true;
    public double[] logs = new double[8];
   
    public CompassAdvance() {
        Button.ENTER.addButtonListener(this);
        Button.LEFT.addButtonListener(this);
        Button.RIGHT.addButtonListener(this);
        Button.ESCAPE.addButtonListener(this);
        for(int i=0; i<logs.length; i++) logs[i] = -1;
    }
   
    public void work() {
        g.fillRect(35, 0, 30, 30);
        g.fillRect(35, 40, 30, 12);
        for(int i=0; i<=30; i++) {
            g.drawLine((int)(Math.sqrt(3)*i/2), 15-i/2, (int)(Math.sqrt(3)*i/2), 15+i/2);
            g.drawLine((int)(100-15*Math.sqrt(3)+Math.sqrt(3)*i/2), 15-(30-i)/2, (int)(100-15*Math.sqrt(3)+Math.sqrt(3)*i/2), 15+(30-i)/2);
        }
        g.drawString("LOG", 50-LCD.FONT_WIDTH*3/2, 32);
        g.drawString("EXIT", 50-LCD.FONT_WIDTH*4/2, 54);
        g.drawString("TYPE", 0, 32);
        g.drawString("CLEAR", 100-LCD.FONT_WIDTH*5, 32);
        Button.ENTER.waitForPress();
        LCD.clear();
        while(true) {
            direction = compass.getDegreesCartesian();
            g.drawLine(getLocationX(0, lineLength), getLocationY(0, lineLength), 100-getLocationX(0, lineLength), 64-getLocationY(0, lineLength));
            g.drawLine(getLocationX(0, lineLength), getLocationY(0, lineLength), getLocationX(0, lineLength) + (int)(Math.cos(Math.toRadians(90-arrowAng))*arrowLength), getLocationY(0, lineLength) + (int)(Math.sin(Math.toRadians(90-arrowAng))*arrowLength));
            g.drawLine(getLocationX(0, lineLength), getLocationY(0, lineLength), getLocationX(0, lineLength) – (int)(Math.cos(Math.toRadians(90-arrowAng))*arrowLength), getLocationY(0, lineLength) + (int)(Math.sin(Math.toRadians(90-arrowAng))*arrowLength));
            g.drawString("N", getLocationX(direction, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("W", getLocationX(direction+270, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+270, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("E", getLocationX(direction+90, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+90, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("S", getLocationX(direction+180, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+180, lineLength+10)-LCD.FONT_HEIGHT/2);
            for(int i=0; i<360; i+=360/dots) g.drawLine(getLocationX(direction+i, lineLength), getLocationY(direction+i, lineLength), getLocationX(direction+i, lineLength-5), getLocationY(direction+i, lineLength-5));
            for(int i=0; i<8; i++) LCD.drawString(getDirectionString(logs[i]), 0, i);
            LCD.drawString(getDirectionString((360-direction)%360), 16-getDirectionString((360-direction)%360).length(), 0);
            Delay.msDelay(delay);
            LCD.clear();
        }
    }
   
    public void buttonReleased(Button b){
        int ID = b.getId();
        if(ID==b.ID_ENTER) {
            for(int i=logs.length-2; i>=0; i–) logs[i+1] = logs[i];
            logs[0] = compass.getDegrees();
        }
        else if(ID==b.ID_LEFT) type = !type;
        else if(ID==b.ID_RIGHT) {
            for(int i=0; i<logs.length; i++) logs[i] = -1;
        }
        else {System.exit(0);}
    }
   
    public void buttonPressed(Button b) {}
   
    public String getDirectionString(double direction) {
        if(direction==-1) return "";
        else if(type) {
            if(direction==0) return "N";
            else if(direction==90) return "E";
            else if(direction==180) return "S";
            else if(direction==270) return "W";
            else return ((direction<90 || direction>270)?"N":"S") + (int)((direction<90 || (direction>180 && direction<270))?(direction%90):(90-direction%90)) + ((direction<180)?"E":"W");
        }else return String.valueOf((int)direction);
    }
   
    public int getLocationX(double ang, int length) {
        return 50 + (int)(Math.sin(Math.toRadians(ang))*length/2);
    }
   
    public int getLocationY(double ang, int length) {
        return 32 – (int)(Math.cos(Math.toRadians(ang))*length/2);
    }
 &nbsp

    public static void main(String args[]) {
        CompassAdvance compassAdc = new CompassAdvance();
        compassAdc.work();
    }
}

Compass Reader Basic by 祥瑞

利用compass sensor, 在螢幕顯示亙指北方的箭頭

import lejos.nxt.*;
import lejos.nxt.addon.CompassSensor;
import lejos.util.Delay;
import javax.microedition.lcdui.Graphics;

class Compass {
    public static CompassSensor compass = new CompassSensor(SensorPort.S1);
    public static int lineLength = 50; //線長度
    public static int arrowLength = 15; //箭頭線長度
    public static int arrowAng = 30; //箭頭線與線的角度
    public static int dots = 12; //圓周點的數目
    public static int delay = 150; //更新螢幕間隔
    
    public static int offsetX;
    public static int offsetY;
    public static Graphics g = new Graphics();
    public static double direction;
    public static void main(String args[]) {
        Button.ESCAPE.addButtonListener(new ButtonListener()
        {
            public void buttonPressed(Button b){System.exit(0);}
            public void buttonReleased(Button b){}
        });
        while(true) {
            direction = compass.getDegreesCartesian();
            g.drawLine(getLocationX(direction, lineLength), getLocationY(direction, lineLength), 100-getLocationX(direction, lineLength), 64-getLocationY(direction, lineLength));
            g.drawLine(getLocationX(direction, lineLength), getLocationY(direction, lineLength), getLocationX(direction, lineLength) + (int)(Math.cos(Math.toRadians(direction+90-arrowAng))*arrowLength), getLocationY(direction, lineLength) + (int)(Math.sin(Math.toRadians(direction+90-arrowAng))*arrowLength));
            g.drawLine(getLocationX(direction, lineLength), getLocationY(direction, lineLength), getLocationX(direction, lineLength) – (int)(Math.cos(Math.toRadians(90-direction-arrowAng))*arrowLength), getLocationY(direction, lineLength) + (int)(Math.sin(Math.toRadians(90-direction-arrowAng))*arrowLength));
            g.drawString("N", getLocationX(direction, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("W", getLocationX(direction+270, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+270, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("E", getLocationX(direction+90, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+90, lineLength+10)-LCD.FONT_HEIGHT/2);
            g.drawString("S", getLocationX(direction+180, lineLength+10)-LCD.FONT_WIDTH/2 , getLocationY(direction+180, lineLength+10)-LCD.FONT_HEIGHT/2);
            for(int i=0; i<360; i+=360/dots) g.drawLine(getLocationX(direction+i, lineLength), getLocationY(direction+i, lineLength), getLocationX(direction+i, lineLength-5), getLocationY(direction+i, lineLength-5));
            Delay.msDelay(delay);
            LCD.clear();
        }
    }
    
    public static int getLocationX(double ang, int length) {
        return 50 + (int)(Math.sin(Math.toRadians(ang))*length/2);
    }
    public static int getLocationY(double ang, int length) {
        return 32 – (int)(Math.cos(Math.toRadians(ang))*length/2);
    }
}

Mindsensors 分別讀取8個light sensor值 in leJOS (by祥瑞)

import lejos.nxt.*;
import lejos.nxt.addon.NXTLineLeader;
import lejos.util.Delay;

class LLRead {
    public static void main(String args[]) {
        Button.ESCAPE.addButtonListener(new ButtonListener() {
            public void buttonPressed(Button b) {System.exit(0);}
            public void buttonReleased(Button b) {}
        });
        
        NXTLineLeader LL = new NXTLineLeader(SensorPort.S1);
        int address;
        byte[] buf = new byte[8];
        int ret;
        int value;
        while(true) {
            for(address=0x49; address<=0x50; address++) {
                ret = LL.getData(address, buf, 2);
                value = (ret == 0 ? (buf[0] & 0xff) : -1);
                LCD.drawString("S" + (address-0x49) + " " + value, 0, address-0x49);
            }
            Delay.msDelay(200);
            LCD.clear();
        }
    }
}

遙控車 by 祥瑞

leJOS的第一個專題來了, 利用遙控手把(master)來控制車子(slave)前進後退轉彎。

有趣的是可以即時改變速度, 速度是900~-900(單位:度/s). 透過轉動馬達可以將速度在100(全速前進)與-100(全速後退)間調整。

左下方的touch sensor是速度歸零, 左上的則是關閉程式 (結束後另一台會拋出IOException,catch後藉此結束程式)。

因為我們的按鈕都用掉啦, 橘色:前進. 灰色: 後退. 左鍵: 左轉彎, 右鍵: 右轉彎。








 

 

新文章分類"LeJOS大軍"

我想CAVE的blog 終於也是要把LeJOS這一塊補起來的, 多虧阿吉的強棒學生, XXX的大力幫忙, 才升高一而已, LeJOS自修已經很有成果了!
現在和我在學NXC, 我得加點油, 不然沒東西可以教了…(他特地交代我要低調, 我是覺得有東西可以分享就大方點, 我會持續開導他的)。
以後也會開始po一些和 LeJOS, NXJ相關的技術文章, 敬請期待!!