別棟備忘録4

*

Japaninoロボ Ep.4 障害物回避 避けるとは何か②

      2015/10/24

前回のエントリでは赤外線距離センサを使った障害物回避の一手法について記述した。
その後、「避けるとは何か?」を深く考えることで、別のアプローチで障害物を回避するいくつかのスケッチが考案された。以下、その中で比較的まともに動作したものの紹介。

 スケッチM「回避型」 スケッチA「空間発見型」

スケッチMの図
「車や船などが障害物をどのように避けるか」を形にしたスケッチ。
障害物が近づいてきたときに、障害物に遠い側のモーターを逆転させる(…というか、障害物に近い側のモーターのみ順転させるイメージ)で舵を切って進む。スケッチAはセンサーの値の和が250を切るところまで旋回し、開けた空間を見つけて進む。
delay()関数を使っていないあたり洗練されている感じがする。プログラムの「前進」の位置は多分スケッチAが適切。(…なんだと思う。)
以下、スケッチA「空間発見型」のプログラム。(今になって読み返してみると、流れ図と一致しない部分が…とりあえずそのまま掲載。)

int dis_L = 0;
int dis_R = 0;
int dis_LR = 0;
void setup(){
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(13,OUTPUT);
  analogWrite(6,100);
  analogWrite(10,100);
}
void loop(){
  int dis_L = analogRead(0);
  int dis_R = analogRead(1);
  dis_LR = dis_L + dis_R;
  if(dis_LR < 300){
      digitalWrite(4,LOW); //前進
      digitalWrite(5,HIGH);
      digitalWrite(8,LOW);
      digitalWrite(9,HIGH);
    }else{
  if(dis_L < dis_R){
      digitalWrite(4,HIGH); //左旋回
      digitalWrite(5,LOW);
      digitalWrite(8,LOW);
      digitalWrite(9,HIGH);
  }else{
      digitalWrite(4,LOW); //右旋回
      digitalWrite(5,HIGH);
      digitalWrite(8,HIGH);
      digitalWrite(9,LOW);
}
 while(dis_LR < 250){
  int dis_L = analogRead(0);
  int dis_R = analogRead(1);
  dis_LR = dis_L + dis_R;
    }
   }
  }

実際の動作風景 スケッチA「空間発見型」

というわけで、スケッチSと比べればすーいすいっと回避しており、意図したような動きになっている。当然ながらスケッチ(というか、流れ図)によって挙動が大きく違うことを再確認。
ただこのスケッチAそしてスケッチMには、角の部分にはまると抜け出せなくなる欠点が見つかり(動画参照)。。。やはり、このあたりはやってみないとわからない。(「いや、わかるだろ。」)
そんな探査機としては失格な挙動もメンバーからは「かわいい」という声も上がり、賛否が分かれる問題作となった。

 スケッチU「ランダム型」

スケッチU

「障害物回避」という意味ではシンプルに障害物を見つけたら旋回する。ただ、先述のスケッチと異なり、前進する際に「ランダム・ウォーク」の要素を取り入れ、障害物がなくても曲がりながら進むようにしたスケッチ。(このスケッチが考案された背景には次回エントリで触れる「探査面積」を増加させるという意図とともに、メンバーの「とりあえずランダムでよくね?」という建設的?提案があった。)

int dis_L = 0;
int dis_R = 0;
int dis_LR = 0;
int N = 1000;
int M = 500;
long time1 = 0;
long time2 = 0;
long time3 = 0;
void setup(){
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(13,OUTPUT);
  
  analogWrite(6,100);
  analogWrite(10,100);
  
  digitalWrite(4,LOW); //前進
  digitalWrite(5,HIGH);
  digitalWrite(8,LOW);
  digitalWrite(9,HIGH);
}
void loop(){
  dis_L = analogRead(0);
  dis_R = analogRead(1);
  dis_LR = dis_L + dis_R;
  if(dis_LR > 500){
      digitalWrite(4,LOW); //右旋回
      digitalWrite(5,HIGH);
      digitalWrite(8,HIGH);
      digitalWrite(9,LOW);
      delay(300);
      digitalWrite(4,LOW); //前進
      digitalWrite(5,HIGH);
      digitalWrite(8,LOW);
      digitalWrite(9,HIGH);
  }
  time3 = millis();
  time2 = millis() - time1;
  if(time2 > N){
    digitalWrite(13,HIGH);
    randomSeed(dis_L);
    N = random(1000,3000);
    M = random(100,300);
  digitalWrite(4,HIGH); //左旋回
  digitalWrite(5,LOW);
  digitalWrite(8,LOW);
  digitalWrite(9,HIGH);
  delay(M);
  digitalWrite(4,LOW); //前進
  digitalWrite(5,HIGH);
  digitalWrite(8,LOW);
  digitalWrite(9,HIGH);
  digitalWrite(13,LOW);
  time1 = millis();
}
}

実際の動作風景

見よ!このキョロキョロ感!! …しかし、決して何か見えているわけではない。。
ただ、先述の2つのスケッチのように途中で角にはまってしまうようなことはない点と、なんだか急に動きが探査機テイストを帯びた点については一定の評価ができるとする見方もできる。

・FAQ よくある質問・

Q.「様々なスケッチを楽しく考案する」だけで、課題研究として成立するのですか?

A.…するどい。課題研究としてオチをつけにいったエピソード5をお楽しみに。
・内部リンク・
エピソード5: 回避性能の定量評価
Japaninoを用いたマイコンロボット製作に戻る

 - Japaninoマイコンロボ