2008b/MemberOnly/進行状況A

課題3:懐中電灯に向かってブロックを投げるロボット

◇ 目次 ◇

課題内容

・白いホイールを投げるロボットを作成し、以下の動きをするようにプログラムを作成せよ。

  1.全方向から懐中電灯の方向を探しだし、手前50cmまで進んで懐中電灯を狙ってブロックを投げる。懐中電灯は動かさない。

  2.懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止    めれば50cmの距離まで近づいて懐中電灯を狙ってブロックを投げる。

・モータ、光センサ、タッチセンサはそれぞれ2個まで使用可。
(平面的な方向だけでなく懐中電灯の高さまで含めた方向を探す場合にはモータを3個使用してもよい)

制作ロボット

CIMG5120.JPG

まず、ロボットの制作から。
ホイールを投げるのにモーターを1つ使うため、駆動輪にはモーターを一つしか使用できない事になります。
なので、駆動部は組み立てガイドのトップシークレットの所にあるディファレンシャルギアを使う事になります。これにより、直進と左回転を一つのモーターだけで行う事が出来るようになります。

CIMG5121.JPG

次に投擲部の組み立てとなります。このチームでは、アームにホイールをセットし、アームを回転させることでホイールを飛ばす仕組みにしました。
モーターの回転力だけではホイールを遠くに飛ばす事は出来ないと思い、輪ゴムを使いアームを引っ張りストッパーで固定し、モーターによりストッパーを外す事でホイールを飛ばす仕組みにしました。

CIMG5122.JPG

光センサーを2つ取り付けました。

ロボットはこれで完成となりました。書いてしまうとこれだけの事ですが、どのようにしてアームのストッパーを外せばいいのかと言う点はかなり悩む事になり、大きく時間を使ってしまいました。

ロボットの工夫点

今回のロボットで最も苦労した点はギア比です。
ディファレンシャルギアは、カーブ処理を行うときに片方に負担がかかる事になります。 一気に移動する分にはいいのですが、細かくカーブを繰り返す時に、ギア比が重たいと上手く曲がってくれないという事態が発生しました。
勿論一番ギア比を軽くしてしまえば一件落着なのですが、後述の理由である程度のスピードは必要となったため、ある程度のスピードを持ち、かつ上手く曲がってくれるギア比を見つける必要がありました。

…が、結局はギア比最軽量となりました。やはりトップシークレットに書かれている通りであるだけはあります。

一言で言ってしまえばここは試行錯誤の繰り返しだった訳ですが、ギアを弄るためにロボットを何回も分解する必要があったため、ここで非常に時間を食われてしまいました。

プログラム説明

ロボットが完成したところでプログラムの制作となります。

プログラム1

1.全方向から懐中電灯の方向を探しだし、手前50cmまで進んで懐中電灯を狙ってブロックを投げる。懐中電灯は動かさない。

プログラム1担当の中根です。 このプログラムは3つの処理から成り立ちます。その3つとは 1.光を認知しなければ回転し続ける。 2.光を認知すればその光の方向へ直進する。 3.ライトとロボットの距離が50mとなったらブロックを投げる。

task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);//左の光センサーをセンサー1とする
SetSensor(SENSOR_3,SENSOR_LIGHT);//右の光センサーをセンサー2とする
while(SENSOR_1<=41)
{
OnRev(OUT_C);//センサー1の値が41以下なら回り続ける
}
while(SENSOR_1<=52)
{
OnFwd(OUT_C);//センサー2の値が52以下なら直進する つまり41=<値=<52のとき
}
OnRev(OUT_A);//センサーの値が52以上になるとブロックを投げる。
Wait(10)
Float(OUT_A);//停止
}

プログラム1工夫点

まず、1で、while(true)を用いて条件を満たさなければ永遠に回り続けることを表現しようとしたが、もっと簡単な方法が出来ると思い、trueを使わずに同じように表現しようとしました。光センサーの感知する値が41以下ならば回り続け、52以下だと直進する。 このようにすれば

while(true)
 (回転するプログラム)
if(sensor>=41)
 (直進するプログラム)
if(sensor>=52)
 (ブロックを投げるプログラム)

より少しでもプログラムの量を減らすことが出来ます。また41=<値=<52のときに直進、52をこえると次のプログラムに変わることを暗に示しています。あとはブロックを投げて、停止すれば完成です。

プログラム2

2.懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば50cmの距離まで近づいて懐中電灯を狙ってブロックを投げる。

プログラム2担当の松島です。

このプログラムは大きく分けて二つの処理に分ける事が出来ます。

1、懐中電灯の動きを止めるまで、懐中電灯の光を追い続ける。
2、直進し、ブロックを投げる。

処理2は簡単で

OnFwd(OUT_C);
Wait(200);
Off(OUT_C);
OnFwd(OUT_A);
Wait(20);
Off(OUT_A);

これだけでその動きはやってくれます。(モーターAが投擲用、モーターCが駆動用。)

このプログラムの大きな課題は1の処理です。
処理1をさらに分解すると
A:右の光センサーの光度が左の光センサーの光度より高ければ右に曲がる
B:左の光センサーの光度が右の光センサーの光度より高ければ左に曲がる
C:右の光センサーの光度と左の光センサーの光度が等しければ2の処理に移る
という3つの処理に分ける事が出来ます。

ただし、この時点でもいくつも問題があります。
•ディフェレンシャルギアは直進と左曲がりしか出来ない→右に曲がれない
•左右の光センサー間には誤差があり、両方の光度が等しければ、という処理をするのが難しい
これらの問題を解決していきます。

•右に曲がれない
これは、左に曲がり続ける事で解決する事にしました。

while(SENSOR_1<40){
OnRev(OUT_C);
}

センサー1は左のセンサーです。
左センサーの光度が低い間、つまり左センサーが光を感知するまで左に曲がり続けます。
これについては、下の図を見ていただいた方がわかりやすいかもしれません(後日アップ)

最低限のスピードが欲しかったのはこのためで、スピードが遅いと1週するだけでかなりの時間を食われてしまうからです。とはいえ、最終的には最遅ギアになってしまったわけですが…そこは妥協することにしました。

•左右の光センサー間の誤差
これは条件式を以下のようにする事で解決しました。

if(SENSOR_1>SENSOR_3+10){
左曲がりの処理
}
else if(SENSOR_3>SENSOR_1+10){ 
右曲がりの処理
}
else{
左右同値の処理
}

若干わかりにくいかもしれませんが、言うならば「センサー1、センサー3間に10以上の差があった時はそれぞれの方向に曲がる」という事を書いてあります。
逆に10以上の差がない時は左右同値とみなしました。そこは誤差の範囲内と判断しています。


以上をふまえ、最終的にこのようなプログラムになりました。

task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_LIGHT);
int sflag=0,fsflag=0; 

//サーチング処理
while(sflag==0){
if(SENSOR_1>SENSOR_3+10){
OnRev(OUT_C);
fsflag=0;
}
else if(SENSOR_3>SENSOR_1+10){
while(SENSOR_1<40){
OnRev(OUT_C);
}
fsflag=0;
}
else{
if(fsflag==0){
fsflag=1;
ClearTimer(0);
}
if(Timer(0)>20){
sflag=1;
}
			
Off(OUT_C);
			
}
} 

//投擲処理	
OnFwd(OUT_C);
Wait(200);
Off(OUT_C);
OnFwd(OUT_A);
Wait(20);
Off(OUT_A);
}

最終的にはタイマーも絡めてみました。
左右の光センサーが同値の時、少し待ち時間が欲しかったためです。

このプログラムでは、左右の光センサーが同値になっても、Timerが20になるまでの間は停止しているという処理にしてあります。これでさらに誤動作を減らす事を狙っています。

「よろしければコメントをお願いします」

  • 考え方が論理的でわかりやすく、すばらしいと思います。あとは、ロボットの説明を詳しくしてみてください。
    また、ディファレンシャル・ギアは組み方しだいでは左右どちらかに曲がるとすることもできます。-- FI? 2009-02-02 (月) 20:29:07


添付ファイル: fileCIMG5122.JPG 229件 [詳細] fileCIMG5121.JPG 224件 [詳細] fileCIMG5120.JPG 249件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-02-02 (月) 20:30:38