- 追加された行はこの色です。
- 削除された行はこの色です。
#contents
*課題3:懐中電灯に向かってブロックを投げるロボットの制作 [#kf29cb1e]
以下の動きをするプログラムを作る。
その1、全方向から懐中電灯の方向を探しだし、30cmの距離まで近づいて懐中電灯に向かってブロックを投げる。(懐中電灯は動かさない。)
その2、懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めると30cmの距離まで近づいてブロックを投げる。
*本体 [#i2505d1b]
↓ギア: ディファレンシャルギアを使うことで1つのモーターでの駆動が可能に。
#ref(09 010.JPG)
#ref(09 009.JPG)
この部分で抑えることで右タイヤが後ろへ回らないようにしている。最初うまく止められなかったのでゴムを追加。
↓投擲用の部分: シンプルだが安定した投擲能力
#ref(09 008.JPG)
#ref(09 007.JPG)
#ref(09 002.JPG)
前回の課題の機体は複雑すぎて微調整するにもいちいち組みなおさなくてはならなかったので、今回の機体はパーツごとに分けて分解を容易にしてギアの調整をしやすくした。この部分にもギアが2つ使われているのは、ギアの大きさを変えて投擲の際の力加減を調整するため。
↓光センサー: シンプルに前方に二つ
#ref(09 004.JPG)
ライトの光を感知する部分。プログラムその1では片方のセンサーを必要としないが、その2でライトの光を追尾する際により細かく光を感知する必要があるため2つ設置。
↓車体全体: 小回りを良くするため小さ目の車体
#ref(09 006.JPG)
#ref(09 005.JPG)
前回の課題の機体が複雑すぎていろいろ試しながら作るということができなかったので、この機体は移動用の部分と投擲用の部分をしっかりと分けた。それによってギアを調節しつつプログラムが試せた。また、この機体の動くパターンは右回転と前進のみとなっている。これは実際に試した結果、右回転と左回転にしてしまうと車体の横幅がせまいため前進しようと右左の交互に動かした時少しずつしか前に進めなくなるのでこうした。これだとライトを追尾する際に左に曲がられると一回転しなければならないが、直進する際は右回転と左回転のものより断然早く追うことができる。これはライトの動きのパターンによってどちらが優秀か変わってくるところだが、自分たちは右回転と左回転にしたとき前進するのがあまりにも遅かったため右回転と前進のほうが早く追えると思いこちらを採用した。
*プログラム [#q00ab0fc]
**その1 [#la283e01]
#define THRESHOLD 99/ライトから30センチの明るさ
#define TURN_TIME 400/最初の回転時間
task main ()
{
SetSensor(SENSOR_1, SENSOR_LIGHT);/センサー1は光センサー
int light_max=0;/明るさを図るための変数を設定。この時点で最大の明るさを0に
ClearTimer(0);/タイマーを0に
while (FastTimer(0)<=TURN_TIME)
{ OnFwd(OUT_C); /回転
if(SENSOR_1>light_max){light_max=SENSOR_1;t_max=FastTimer(0);}}/回転中に最も明るい数値を記憶
Off(OUT_C);/いったん停止
Wait(100);
while (SENSOR_1<light_max){OnFwd(OUT_C); }/記憶した最も明るい数値の位置まで回転
Off(OUT_C);/停止
Wait(100);
while (SENSOR_1 <= THRESHOLD){OnRev(OUT_C); }/ライトから30センチの位置まで接近
Off(OUT_C);OnRev(OUT_A);Wait(50);
Off(OUT_A);/投擲
}
前回のプログラムはifやwhileを重ねた結果複雑になりすぎ、間違った場所を探すのにすごく手間がかかったので今回は単純に。まあ、比較的簡単なその1だからできたというのもあるけど・・・。
**その2 [#rabdbd77]
#define HIT OnRev(OUT_A);Wait(10);Off(OUT_A);Off(OUT_C);
#define THR 80
int count_up;
void TURN(int t)//回転用
{
OnRev(OUT_C);
Wait(t);
Off(OUT_C);
}
task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_LIGHT);
count_up=0;
while(true){
if ((SENSOR_1<THR)&&(SENSOR_3<THR))))//右も左も明かりを関知しない場合
{
count_up=0;
TURN(20);
Wait(5);
} //前進する
if((SENSOR_1>THR)&&(SENSOR_3<THR)&&(count_up==0))//明かりを関知し、かつカウントをしていない時
{
count_up=count_up+1;
Wait(100);
}//カウントを入れ、明かりが動くか待つ
if((SENSOR_1<THR)&&(SENSOR_3>THR)&&(count_up==1))//明かりを関知し、かつカウントが入っているとき二度目の明かりを感知したことになりつまり懐中電灯が止まったということ
{
Off(OUT_C);
HIT//打ち出す
}//止まって投げる
}
}
*感想 [#gca20991]
鈴: 自分は機体を作るのを担当して、プログラムは比較的簡単なその1を作った。この 課題は車体の動きを2パターンしか作れないためどの組み合わせがいいか迷った。後 ギアが複雑でいじるのが大変だった。~
k山:プログラムはその2を担当したが今回も大変で苦労した。
*コメント [#k917307d]
コメントお願いします。~
whileを使っているときは抜け出す条件を入れたほうがいいと思います。ロボットは止まってもプログラムは止まりません。~
あと、プログラムの説明をもう少し充実させましょう。変数を設定したら何を意味するのか、今回の場合何を持って光が停止したと判断するのか等を明確に説明しましょう。レポートなので FI~
コメント欄欲しいです…~
その1の方のプログラムで、変数t_maxを初期化していない点が気になります(消し忘れかな?)。~
その2の方は、FIさんも仰ってますが、whileに対し、ロボを停止させる際にbreakを入れておくといいと思います。 こさか(09/08/09 22:16)