- 追加された行はこの色です。
- 削除された行はこの色です。
目次
#contents
*課題1 [#fa670487]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
#ref(コース.png,,100%)
**ミッション [#y8cc62e2]
次のいずれかのコースで黒い線に沿って動き、途中でボールをゴール付近に立てた350mlの空き缶(黄色で表示)に当てるロボットを製作せよ。 (相棒と違うコースを選ぶこと)
第1.第2コースがあるが、私は第1コースを選択した。
***第1コース [#hef0ce1d]
1:ロボットを長方形X内におき、Aをスタート
2:Bを右折
3:Kで一時停止して左折
4:Jを直進
5:Iを直進
6:Hを左折
7:Gで一時停止して左折
8:Eで一時停止して右折
9:Lを経て正方形Y内に入って停止
(一時停止の指定がある場所は、1秒間停止すること)
ボールはロボットが弧KJIH上にある時にQ地点の空き缶に当てる
*ロボットの説明 [#fc515f1f]
移動するための車の部分の基本的な構造は付属の冊子を参考に作成した。
ロボット作成において最も苦戦したのはボールを投げる機構だった。最終的にはボールをつかんで移動し、投げる際に離して本体で押し出すような仕組みとなった。
ロボット作成において最も苦戦したのはボールを投げる機構だった。
最終的にはボールをつかんで移動し、投げる際に離して本体で押し出すような仕組みとなった。
#ref(robotto3.jpg,,50%)
ロボットの全体像
#ref(robotto2.jpg,,50%)
ラインを感知するセンサー
#ref(robotto1.jpg,,50%)
ボールを掴むロボット
*プログラムの説明 [#if36ed0f]
**基本的なライントレースのプログラム [#he2d7f7e]
void line_trace()
{
SetSensorLight(S1);
long t0,t1;
t1=100;
t0=CurrentTick();
while(CurrentTick()-t0<t1){
if(SENSOR_1>55){
turn_r1;
t0=CurrentTick();
}else if(SENSOR_1>45){
turn_r0;
t0=CurrentTick();
}else if(SENSOR_1>40){
go_s;
t0=CurrentTick();
}else if(SENSOR_1>30){
turn_l0;
t0=CurrentTick();
}else{
turn_l1;
}
}
}
**AB間を走るプログラム [#aa3ef991]
void line_trace_AB()
{
SetSensorLight(S1);
OnFwd(OUT_BC,SPEED_SLOW);
Wait(1000);
long t0,t1;
t1=100;
t0=CurrentTick();
while(CurrentTick()-t0<t1){
if(SENSOR_1>55){
turn_l1;
t0=CurrentTick();
}else if(SENSOR_1>45){
turn_l0;
t0=CurrentTick();
}else if(SENSOR_1>40){
go_s;
t0=CurrentTick();
}else if(SENSOR_1>30){
turn_r0;
t0=CurrentTick();
}else{
turn_r1;
}
}
OnFwd(OUT_BC,30);
Wait(500);
while(SENSOR_1>55){
turn_r1;
}
}
**BK間を走るプログラム [#ye964d7c]
void line_trace_BK()
{
line_trace();
sleep;
}
**KJ間を走るプログラム [#x7583b08]
void line_trace_KJ()
{
while(SENSOR_1>55){
turn_l0;
}
line_trace();
OnFwd(OUT_BC,SPEED_SLOW);
Wait(300);
while(SENSOR_1<55){
turn_r0;
}
}
**JI間を走るプログラム [#c4499021]
void line_trace_JI()
{
line_trace();
}
**缶を探すプログラム [#q1b1e45f]
void fwdDist(float d) //距離 d cm 前進
{
long angle;
angle = d/(diameter*pi)*360.0; //角度を計算する
RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 0, true, true);
}
void turnAng(long ang) //角度 ang 度の時計回りの旋回
{
long angle;
angle = track/diameter * ang;
RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 100,true, true);
}
int searchDirection(long ang) //現在の方向を中心に ang 度の範囲で探し
//障害物までの距離を返す
{
long angle,tacho_min=0, tacho_corr ;
int d_min;
d_min=300; //仮の最小値
angle = (track/diameter)*ang; //旋回角度からタイヤの回転を計算
turnAng(ang/2); //指定された角度の半分を旋回
ResetTachoCount(OUT_BC); //角度計算をリセット
OnFwdSync(OUT_BC,SPEED_SLOW,-100); //半時計回りに旋回
while(MotorTachoCount(OUT_B)<=angle){
if (SensorUS(S4)<d_min){
d_min=SensorUS(S4); //仮の最小値を更新
tacho_min=MotorTachoCount(OUT_B);
}
}
OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE);
until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S4)<=d_min);
Wait(14); //微調整
Off(OUT_BC);Wait(500);
return d_min;
}
**ボールを放つプログラム [#x01719f2]
void throw_a_ball()
{
OnFwd(OUT_BC,70);OnFwd(OUT_A,20);
Wait(750);
OnRev(OUT_A,20);
Wait(750);
OnRev(OUT_BC,70);
Wait(750);
while(SENSOR_1<55){
turn_r0;
}
}
**IH間を走るプログラム [#u616d3db]
void line_trace_IH()
{
line_trace();
}
**HG間を走るプログラム [#of059791]
void line_trace_HG()
{
line_trace();
sleep;
}
**GF間を走るプログラム [#qdf65753]
void line_trace_GF(long min_t)
{
SetSensorLight(S1);
long t0,t1,t2;
t2=CurrentTick();
t1=150;
t0=CurrentTick();
while(CurrentTick()-t0<t1 ||CurrentTick()-t2<min_t){
if(SENSOR_1>55){
turn_r1;
t0=CurrentTick();
}else if(SENSOR_1>48){
turn_r0;
t0=CurrentTick();
}else if(SENSOR_1>42){
go_s;
t0=CurrentTick();
}else if(SENSOR_1>33){
turn_l0;
t0=CurrentTick();
}else{
turn_l1;
}
}
}
**FE間を走るプログラム [#r744bc26]
void line_trace_FE()
{
line_trace();
sleep;
while(SENSOR_1<55){
turn_l1;
}
}
**EL間を走るプログラム [#kbe92727]
void line_trace_EL()
{
line_trace();
}
**LY間を走るプログラム [#i43f6da8]
void line_trace_LY()
{
OnFwd(OUT_BC,30);
Wait(750);
Off(OUT_BC);
}
**プログラムを書く際の工夫 [#ae12b55e]
線を追うプログラムは、今までの学習で作ったプログラムを編集して作成した。ラインと白い部分の境界を進むプログラムで、光センサーの捉える明るさを5段階に分けて処理をする。光センサーが標準の明るさだと判断した場合はロボットを直進。少し暗いと判断した場合は左に曲がり、少し明るいと判断した場合は右に曲がる。最も暗いと判断した場合はその場で左旋回し、最も明るいと判断した場合はその場で右旋回する。センサーが交差点に到着した場合、センサーは線の内部を感知することになるため、最も暗いと判断する。したがってその場で左旋回することができるので、このプログラムだけで交差点を曲がることもできる。このようにすることによって、光センサーは線と余白の境界を往復しながら線をを追うことができる。しかし、このプログラムは左旋回はできても交差点を右に曲がることができないため、指定されたようにコースを移動するためにはこのプログラムを改変する必要があった。まず最初に行ったのが、各交差点を認識して、それぞれのルートに応じた進み方にすることだ。まず初めに、今までのプログラムだと線の左側を進んでいたためAB間を進んだとき交差点Bを感知することができなかった。そのためAB間のみに限りプログラムの処理を逆にして線の右側を進むようにした。次に、このプログラムどおりに進むと、交差点J.I.Eでは進行したい方向と異なる道に進んでしまう。これを改善するためにそれぞれ適切なプログラムを追加して、元のラインに戻ってくるように調整した。最後に、交差点GF間の線を追う際に必ずどちらかのカーブの内側を通ることにるが、ロボット本体にある程度の大きさがあり、曲がり切れずに交差点だと判断してしまうケースが多々あった。この問題の解決策としては、交差点Gを出発してから数秒の間はたとえセンサーが交差点に到着したと判断しても、無視して今までのプログラムを継続するようにプログラムすることで解決した。
*問題点とその改善案 [#oad796f8]
*感想 [#w2832c85]
ボールを投げる機構に苦戦したため、本体やセンサー類にあまり時間をとることができなかった。これをもう少しシンプルで操作しやすいものにできるようにしたかったが、周りのグループの作成したロボットを見て、まだまだ改善の余地があったと感じた。