| Basic whisker sensor class |
|---|
package JBot;
import stamp.util.os.* ;
import stamp.core.* ;
/**
* Basic whisker sensor class
*
* 触覚センサーを用いて障害物検知をする
* 障害物の45, 90 135度゜の方向を返す。
*/
public class WhiskerSensor extends BaseSensor {
/**
* 障害物が検出されたかどうかを示す
* 通常、イベントを用いるではなくポーリングを用いる
*
* 戻り:物体検出
*/
public boolean obstacleDetected () {
return CPU.readPin ( CPU.pin6 ) | CPU.readPin ( CPU.pin4 ) ;
}
/**
* 障害物位置を示す
* For simple detection systems the detection of an object
* on the right and left will return front.
*
* 戻り:障害物の相対方向 (left, right, etc.)
*/
public int obstacleDirection () {
switch ( ( CPU.readPin ( CPU.pin6 ) ? 2 : 0 )
+ ( CPU.readPin ( CPU.pin4 ) ? 1 : 0 )) {
case 0: // both low, 後進して右回り
return front ;
case 1: // P4 low, 後進して左回り
return right ;
case 2: // P6 low, 後進して右回り
return left ;
default:
case 3: // 直進
return none ;
}
}
/**
* 指定された方向の障害物までの距離を得る
* noneという値は障害物がないことを意味する
*
* 入力:調べる方向
*
* 戻り:指定された方向にある障害物までの距離
*/
public int obstacleDistance ( int direction ) {
return 0 ; // 方向に寄らずいつもゼロの距離を返す
}
/**
* 最小報告距離を設定する
* この距離より遠くにある物体に対しては報告しない
* 最小値はゼロである
*
* 入力:距離までの最小距離をcmで示す
*/
public void setMinimumEventDistance () {
/* デフォールトの場合では最小距離は無視する
* 例えば、接触センサーの場合は障害物にぶつかってから
* 方向が分かるからである
*/
}
/**
* 通知イベントを設定する
*
* 入力:Event event:変化が起こったときに報告するイベントオブジェクト */
public void setEvent ( Event event ) {
this.event = event ;
}
// このクラスあるいはサブクラスで用いるためにProtectedにする
/**
* 障害物のステータスが変った時にイベントを発生する
* サブクラスのメソッドにより呼ばれる
*/
protected void notifyEvent () {
if ( event != null )
event.notify () ;
}
}
|
| 単純な障害物回避タスク |
|---|
package JBot;
import stamp.util.os.* ;
/**
* 単純な障害物回避タスク
*
* センサーオブジェクトを用いて障害物から距離をおくことを試みる
* J-Botは決まった距離ずつ移動する
*/
public class AvoidObstacleTask extends Task {
JBotInterface jbot ;
BaseSensor sensor ;
public AvoidObstacleTask ( BaseSensor sensor, JBotInterface jbot ) {
this.sensor = sensor ;
this.jbot = jbot ;
}
protected void execute () {
final int turnAround = 1 ;
switch ( state ) {
case initialState:
if ( sensor.obstacleDetected ()) {
int direction = sensor.obstacleDirection () ;
if ( sensor.obstacleDistance ( direction ) < 5 ) {
// 非常に接近、5cm後退し回る
jbot.move ( -5 ) ;
jbot.wait ( turnAround ) ;
} else {
// 物体から離れて旋回する場所がある
if ( direction < 75 ) {
// 何か左にある
jbot.pivot ( -2 ) ;
} else {
// 何か前か右にある
jbot.pivot ( 2 ) ;
}
jbot.wait ( turnAround ) ;
}
} else {
// 何もない。1cm先に進む
jbot.move ( 1 ) ;
jbot.wait ( initialState ) ;
}
break;
case turnAround:
// J-Botは後進し、180゜旋回する
jbot.pivot ( 4 ) ;
jbot.wait ( initialState ) ;
break;
default: // 異常なステータスを捕捉する
stop () ;
break;
}
}
}
|
| AvoidObstacleTaskクラスをテストする |
|---|
import stamp.core.*;
import stamp.util.os.* ;
import JBot.* ;
/**
* AvoidObstacleTaskクラスをテストする
*
* J-Botを障害物を避けるように動かす
*/
public class AvoidObstacleTaskWhiskerTest1 {
public static void main () {
new AvoidObstacleTask
( new WhiskerSensor ()
, new RampingJBot ( new MultitaskingJBot ())) ;
Task.TaskManager () ;
System.out.println ( "All done" ) ;
}
}
|
| EEPROM Electrically Erasable Programmable Read-Only Memory |
|---|
| 電気的に消去(書き換え)できるROM。電源を切ってもデータは消えない。データの消去には5Vより高い電圧が必要だが、最近のEEPROMは内部で電源電圧の5Vを昇圧しているため、基板に実装したままデータを消去して書き換えるのが容易になりました。そのためシステムの動作中にデータを書き換えることができます。ただEEPROMには、およそ数十万~百万回までしか、消去/書き換えができないという欠点があります。さらにEEPROMはそのデータを1bitだけ書き換えるときにも、すべてのbitをいったん消去して書き換えなければならないため、RAMのようにランダムな読み書きは困難です。この欠点を改良したのがフラッシュメモリです。 |
| EEPROM記録を用いての障害物回避 |
|---|
package JBot;
import stamp.util.os.* ;
import stamp.core.* ;
/**
* EEPROM記録を用いての障害物回避
*
* センサーオブジェクトを用いて障害物から距離をおくことを試みる
* J-Botは決まった距離ずつ移動する
* 障害物情報はEEPROMに保存される
*/
public class AvoidObstacleRecordingTask extends AvoidObstacleTask {
int memoryIndex ;
int memorySize ;
public AvoidObstacleRecordingTask ( BaseSensor sensor, JBotInterface jbot ) {
super ( sensor, jbot ) ;
memoryIndex = 1 ;
memorySize = ( EEPROM.size () - 1 ) / 2 ;
// 最初の幾つかの障害物のみ記録する、255以下でなければいけない
if ( memorySize > 10 ) {
memorySize = 10 ;
}
// 保存される記録の数を保存する
EEPROM.write ( 0, (byte) memorySize ) ;
}
protected void execute () {
final int turnAround = 1 ;
switch ( state ) {
case initialState:
if ( sensor.obstacleDetected ()) {
int direction = sensor.obstacleDirection () ;
// EEPROMが一杯になったら出る
if ( memorySize == 0 ) {
stop () ;
break ;
}
// EEPROMに障害物の詳細を記録する
EEPROM.write ( memoryIndex, (byte)direction ) ;
EEPROM.write ( memoryIndex + 1, (byte)sensor.obstacleDistance ( direction )) ;
memoryIndex += 2 ;
-- memorySize ;
if ( sensor.obstacleDistance ( direction ) < 5 ) {
// 非常に接近、5cm後退し回る
jbot.move ( -5 ) ;
jbot.wait ( turnAround ) ;
} else {
// 物体から離れて旋回する場所がある
if ( direction < 75 ) {
// 何か左にある
jbot.pivot ( -2 ) ;
} else {
// 何か前か右にある
jbot.pivot ( 2 ) ;
}
jbot.wait ( turnAround ) ;
}
} else {
// 何もない。1cm先に進む
jbot.move ( 1 ) ;
jbot.wait ( initialState ) ;
}
break;
case turnAround:
// J-Botは後進し、180゜旋回する
jbot.pivot ( 4 ) ;
jbot.wait ( initialState ) ;
break;
default: // 異常なステータスを捕捉する
stop () ;
break;
}
}
}
|
| EEPROMに格納したデータをダンプする |
|---|
import stamp.core.*;
/**
* AvoidObstacleRecordingTaskによってEEPROMに格納したデータをダンプする
*
* EEPROMからデータを読み、それをメッセージウィンドウに表示する
*/
public class DumpObstacle {
public static void main() {
int memoryIndex = 1 ;
for ( int memorySize = (int) EEPROM.read ( 0 )
; memorySize > 0
; -- memorySize ) {
System.out.print ( memoryIndex ) ;
System.out.print ( " Direction: " ) ;
System.out.print ((int) EEPROM.read ( memoryIndex )) ;
System.out.print ( " Distance: " ) ;
System.out.println ((int) EEPROM.read ( memoryIndex + 1 )) ;
memoryIndex += 2 ;
}
}
}
|