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 ; } } } |