目次

移動アルゴリズム

 メカを動かせるようになったので、移動アルゴリズムを
 考えていきます。



 Arduinoのloopの中に記述するコードを考えていきます。

 動作は、次のシーケンスになります。
  1. 路面センサーの情報取得
  2. 路面センサーの情報から左右のモータのDUTY比決定
  3. 左右のモータにDUTY比を出力
  4. 1にもどる
 平面を走行する場合、このシーケンスで充分ですが  MCRのコースは、坂道や立体交差もあるので、その  情報を加味してDUTY比を決定します。
  1. 路面センサーと傾斜センサーの情報取得
  2. 路面センサーの情報から左右のモータのDUTY比決定
  3. 傾斜センサーの情報により、DUTY比に係数をかける
  4. 左右のモータにDUTY比を出力
  5. 1にもどる
 路面センサーの情報からDUTY比を決定するためには  どういう情報が来るのかを出していきます。  8ビットのデータは、0から255までの256通り  ありますが、これらすべてに対応しなくてもよいと  わかっています。  外せない4パターンは、以下。  クランク、レーンチェンジを考えなければ  白線がセンターにくるように、制御します。  センターに白線がある場合のパターンは以下。  左あるいは右に寄っているときのパターンは以下。  走行状態によっては、両端に白線が見える  こともあります。  ここまでに挙げたパターン以外は、無視する  仕様にして、スケッチを考えます。  生の路面センサーから、文字列に変換した  パターンでDUTY比を決めることに。  文字列は、以下。 #define ALL_BLACK 0 #define ALL_WHITE 1 #define LEFT_WHITE 2 #define RIGHT_WHITE 3 #define CENTER 4 #define LIMIT_RIGHT 5 #define RIGHT 6 #define BIT_RIGHT 7 #define BIT_LEFT 8 #define LEFT 9 #define LIMIT_LEFT 10 #define BOTH_WHITE 11 #define ILLEAGAL 12  生の路面センサーから変換する関数を定義します。 UBYTE decode(UBYTE x) { UBYTE result ; /* judge */ switch ( x ) { case 0x00 : result = ALL_BLACK ; break ; case 0xff : result = ALL_WHITE ; break ; case 0xf0 : result = LEFT_WHITE ; break ; case 0xf8 : result = LEFT_WHITE ; break ; case 0x0f : result = RIGHT_WHITE ; break ; case 0x1f : result = RIGHT_WHITE ; break ; case 0x18 : result = CENTER ; break ; case 0x1c : result = CENTER ; break ; case 0x38 : result = CENTER ; break ; case 0x03 : result = LIMIT_RIGHT ; break ; case 0x06 : result = RIGHT ; break ; case 0x0c : result = BIT_RIGHT ; break ; case 0x30 : result = BIT_LEFT ; break ; case 0x60 : result = LEFT ; break ; case 0xc0 : result = LIMIT_LEFT ; break ; case 0xc3 : result = BOTH_WHITE ; break ; case 0xc1 : result = BOTH_WHITE ; break ; case 0x83 : result = BOTH_WHITE ; break ; case 0x81 : result = BOTH_WHITE ; break ; default : result = ILLEAGAL ; break ; } return result ; }  走行を次の3状態に分け、より細かくDUTY比を  設定できるようにします。  実際コースを見て、走行パターンを考えます。  レーンチェンジから見ていきます。  動作シーケンスは、以下とします。
  1. 路面センサー情報取得
  2. 情報を文字列変換
  3. LEFT_WHITEかRIGHT_WHITEを検出したならLANEモードにする
  4. dlane[0]、dlane[1]に文字列保存
  5. 最低速度でALL_BLACKを検出するまで直進
  6. ALL_BLACKを検出したなら、dlane[0]が示す方向に移動
  7. 最低速度でCENTERを検出するまで直進
  8. CENTERを検出したなら、dlane[1]が示す方向に移動
  9. NORMALモードにして、ぬける
 クランクを見ます。  動作シーケンスは、以下とします。
  1. 路面センサー情報取得
  2. 情報を文字列変換
  3. ALL_WHITEを検出したならCRANKモードにする
  4. 最低速度でLEFT_WHITEかRIGHT_WHITEを検出するまで移動
  5. LEFT_WHITEかRIGHT_WHITEを検出したならdcrankに文字列保存
  6. 最低速度でALL_BLACKを検出するまで直進
  7. ALL_BLACKを検出したなら、dcrankが示す方向に移動
  8. 最低速度でCENTERを検出するまで直進
  9. CENTERを検出したなら、dcrankが示す方向と逆に移動
  10. NORMALモードにして、ぬける
 NORMALモードのシーケンスは、後で記述するとして  途中までコードに変換します。 sensor = get_sensor(); sensorx = decode(sensor); /* judge */ if ( sensorx == ALL_WHITE ) { if ( mode == NORMAL ) { /* change mode */ mode = CRANK ; /* slow move */ } } if ( sensorx == LEFT_WHITE || sensorx == RIGHT_WHITE ) { if ( mode == NORMAL ) { /* change mode */ mode = LANE ; /* slow move */ /* */ dlane[0] = sensorx ; if ( sensorx == LEFT_WHITE ) { dlane[1] = RIGHT_WHITE ; } else { dlane[1] = LEFT_WHITE ; } /* clear */ turn_cnt = 0 ; } if ( mode == CRANK ) { dcrank = sensorx ; /* */ } } if ( sensorx == ALL_BLACK ) { if ( mode == CRANK ) { } if ( mode == LANE ) { if ( turn_cnt == 0 ) { /* LEFT move */ if ( dlane[turn_cnt] == LEFT_WHITE ) { /* set duty */ } /* RIGHT move */ if ( dlane[turn_cnt] == RIGHT_WHITE ) { /* set duty */ } /* increment */ turn_cnt++ ; } else { /* LEFT move */ if ( dlane[turn_cnt] == LEFT_WHITE ) { /* set duty */ } /* RIGHT move */ if ( dlane[turn_cnt] == RIGHT_WHITE ) { /* set duty */ } /* clear */ turn_cnt = 0 ; } } } if ( sensorx == CENTER ) { } if ( sensorx == LIMIT_RIGHT ) { } if ( sensorx == RIGHT ) { } if ( sensorx == BIT_RIGHT ) { } if ( sensorx == BIT_LEFT ) { } if ( sensorx == LEFT ) { } if ( sensorx == LIMIT_LEFT ) { } if ( sensorx == BOTH_WHITE ) { }  CRANK、LANEでは、旋回、車線変更が入るので  時間待ちが必要になります。  時間待ちは、Arduinoの組込み関数delayを利用します。
目次

inserted by FC2 system