松田 孝裕 進藤 寛也 嵩西 健太
6月7日
デロリアン2号
2つの光センサーで、黒い線を挟んで、それぞれのセンサーは、ある一定以上の明るさになったら、反対のタイヤが少しバックして、また前進していく。
また、他のロボットにぶつかって、右に曲がって、相手のロボットを避けるときは、一度バックし、右に曲がって、前に進み、その後、左斜め前に進んでいく。その後、黒い線上に戻ったら、また、黒い線上を進んでいく。
今回も2つのモーターはタイヤへと使い、前進や、後退、旋回などする。
次に、今回初めて使う、光センサーについてである。光センサーは、その赤外線によって、それ上に存在するものの明るさを感知する。そして、プログラムで明るさを設定し、そこでのif(条件)として行動をプログラムする。例えば、光センサーが感知した明るさの度数が40以下のとき、後退するなどである。明るさの度数が、40以下ということは、光センサーがほぼ黒い線を感知したということとされている。その赤外線をロボットの車体の下にくるようにすると、その黒い線に反応して行動するということになる。今回のロボットには光センサーを2つ使い、その赤外線によって、黒い線がその間にくるようにしてある。そして、2つのその赤外線によって、黒い線らか外れたことを感知たときには、さらにその黒い線上から車体がそれないように軌道を修正する。
次に、タッチセンサーについてである。タッチセンサーは、そのセンサーにつながれた部分の摩擦の度数を感知する。さらにそこにくっつけたブロックが何かに接触すると、摩擦が起こる。ブロックが何かに接触している間はその摩擦が生じていて、感知している。つまり、そのブロックがどのくらいの間、ものに接触しているか感知する。それによって、プログラムとして、ロボットがものに接触しているときif(条件)として行動を設定する。
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサの定義 SetSensor(SENSOR_3,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH); SetPower(OUT_A,5); //モータの製造誤差をキャンセル SetPower(OUT_C,3); OnFwd(OUT_A+OUT_C); while(true) //以下のプログラムを無限ループ { SetPower(OUT_A,5); SetPower(OUT_C,3); OnFwd(OUT_A+ OUT_C); if(SENSOR_1>43) //センサ1が黒よりはずれたら { OnRev(OUT_C); //時計回りに旋回 if(SENSOR_1<43); //センサ1が黒を読み取れば OnFwd(OUT_A+ OUT_C); //直進 } if(SENSOR_3 >43) //センサ3が黒よりはずれたら { OnRev(OUT_A); //反時計回りに旋回 if(SENSOR_3<43); //センサ3が黒を読み取れば OnFwd(OUT_A+OUT_C); //直進 } if(SENSOR_2==1) //障害物にあたると { //右に避け、その後軌道内に戻る OnRev(OUT_A+OUT_C); Wait(50); Off(OUT_A+OUT_C); OnFwd(OUT_A); OnRev(OUT_C); Wait(362/4); //一旋回するのに要する時間が3620msecなので90°(1/4)だけ旋回させる。 OnFwd(OUT_A+OUT_C); Wait(110); OnFwd(OUT_C); OnRev(OUT_A); Wait(362/4); OnFwd(OUT_A+OUT_C); Wait(150); OnFwd(OUT_C); //また線上へと向かって OnRev(OUT_A); //いく。センサーが線上 Wait(40); //に行ったらまた上のプ OnFwd(OUT_A+OUT_C); //ログラムへ until ((SENSOR_3< 43)||(SENSOR_1<43)); } }
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサの定義 SetSensor(SENSOR_3,SENSOR_LIGHT); SetSensor(SENSOR_2,SENSOR_TOUCH); SetPower(OUT_A,5); //モーターの誤差 SetPower(OUT_C,3); //をなくす OnFwd(OUT_A+OUT_C); //前進して線上ま while(true) //で行き { if(SENSOR_1<40) //黒い所に達した { //ら後退して前進 OnRev(OUT_A); //して線上に調節 Wait(10); //する OnFwd(OUT_A+ OUT_C); } if(SENSOR_3 <40) //左側が黒い線に { //きたときと同じ OnRev(OUT_C); //ように右側のと Wait(10); //きも調節 OnFwd(OUT_A+OUT_C); } if(SENSOR_2==1) //障害物にぶつか { //ったら、後退し OnRev(OUT_A+OUT_C); //てから後ろへ旋 Wait(100); //回する Off(OUT_A+OUT_C); OnFwd(OUT_A); OnRev(OUT_C); Wait(362/2); OnFwd(OUT_A+OUT_C); //また前進 }
}
task main() { SetSensor(SENSOR_2,SENSOR_TOUCH); SetSensor(SENSOR_1,SENSOR_TOUCH); SetSensor(SENSOR_3,SENSOR_TOUCH); SetPower(OUT_A,5); SetPower(OUT_C,3); OnFwd(OUT_A+OUT_C); while(true) { if(SENSOR_1==1) { OnRev(OUT_A+OUT_C); Wait(50); Off(OUT_A+OUT_C); OnFwd(OUT_A); OnRev(OUT_C); Wait(362/4); OnFwd(OUT_A+OUT_C); } if(SENSOR_3==1) { OnRev(OUT_A+OUT_C); Wait(50); Off(OUT_A+OUT_C); OnFwd(OUT_C); OnRev(OUT_A); Wait(362/4); OnFwd(OUT_A+OUT_C); } }
このページには、練習問題の、壁に対して90度に反射するロボット、ライントレース(ぶつかると反転する)、ライトレース(ぶつかると右側にさけていく)のプログラムをすべて載せたが、これから書く反省は、今回の課題として提出する、ライントレース(ぶつかると右側にさけていく)ものライントレース(ぶつかると反転する)ものについてである。 タイヤをつけてロボットを走らせたとき、数秒間でタイヤが外れて、走らなくなる。これは、モーターの元々の力が違うため、タイヤの動きにズレが生じ、こうなると考えた。そこでまず、モーターのセットパワーでその製造誤差をなくした。
光センサーを2つつけ、両側から黒い線を挟んで、センサーに反応させた。これによって、黒い線からロボットの軌道が外れにくくした。
Waitで旋回させるときにも工夫した。一周の時間を計り、その後、例えば、90度だけ旋回させるとき、(一周の時間)/4をして、プログラム上でも、表現した。これによって、それが、一周の時間をいくつで割ったのか、一目で分かる。これによって、実際の時間を入力するより、何度旋回するか、分かりやすくなる。
また、ライントレースロボットが、障害物にぶつかって、右に曲がるときには、工夫したことが多かった。右に曲がって、元のラインに戻るとき、あまりその動きが大きすぎると、途中でライン上に乗ってしまって、うまく右に避けていく動作が終了しないという問題があった。そのため、できるだけ、相手のロボットにあたらないように、かつ、周りのラインにもあたらないように、適度な大きさの動きにするのが難しかった。
このライントレースや、ぶつかったら、右にさけるという動作も、どちらも、書くラインによるところが大きかった。
今回のプログラムは、最初、明るさが低い(黒い線上にいるとき)を基準にして、そのときにプログラムを組んでいった。だが、明るさが高いとき(線上から外れたとき)にもプログラムを組んでいく方法もある。これによって、センサーから外れたときと線上にいるときで、プログラムを組むこといよって、センサ−1つで線上(線のあるところと線のないところの境界線上)を動くことができる。このプログラムも、別に作ってみるとよいと思った。そういう訳で、白いところと、黒いところ、それぞれについて反応するロボットを作った。ただし、センサーは2つ使っている。
2つの光センサーを使ったが、それぞれのセンサーが反応したときのプログラムとして、バックした後、前進させた。これについて、もう少し、動きを繊細にできるとよいと思った。もう少し、滑らかに黒い線上を動けるとよいと思った。
今回のロボットは、練習問題のタッチセンサーを使った、反射ロボットからの流れから、そのロボットを流用した。今回は、前回の課題でプログラムを担当したものが、ロボット作りを担当できて、よかった。これからも、プログラム作り、ホームページ作り、ロボット作りを担当を入れ替わりながら、作業が、偏らないようにしていこうと思う。そういう訳で、今回のロボットは、ロボット作りになれていないものが作ったため、ロボットはオーソドックスなタイプになった。
太い線にしたときは、黒を読み取る。細い線にしたときは、白を読み取るようにプログラムを作ろうと思った。これは、それぞれの場合について領域の広い方を読みとらせるほうが有利だからである。そこで、このページに載せたプログラムについては、黒い線の方を読み取らせているので、線を太くして、センサーが読み取りやすいような線を書いた。
それで、コースについては、星のカービィのシルエットの形にした。星のカービィは、絵描き歌が「基本は丸」といっているように、あまり急なカーブはなく、特徴のある、よいコースであると思った。カーブでは、コースの線をより太くして、カーブしやすいようにした。
また、今回は、4つ切りの画用紙を4枚貼付けたが、コースを書いたとき、結構、画用紙の外まで大きく書いてしまった。すると、コース上にいても、画用紙からロボットがはみ出したり、右に大きく曲がって避けるとき、画用紙からはみ出してしまう。そのとき、ロボットは、画用紙上の黒い線を読み取るのではなく、紙以外のところを読み取ってしまう。なので、紙を余分に大きくする必要がある。また、紙はつるつるしていると、黒い線も反射して、明るくなってしまい、うまくコースを読み取らなくなる。なので、紙の、できれば、少しざらざらしている方ががいい。
今回も、先生にロボットと、コースの写真を撮ってもらい、貼付けるつもりである。
そもそも、マジックで書く黒い線を太さを均等にすることが大事だった。太い線にしないと、光センサーが読み取らないことがある。
画用紙上に書く線については、これによってロボットがうまく動くかが関係してくるので、慎重に考えた。あまりに簡単なせんにしては、つまらないし、カーブをつけすぎると難しくなってしまうということを考えた。
また、プログラムの書き方としても工夫した。ifの条件をwaitと同じように次のプログラムの行にいくまでにする動作として考えた。そして、waitの代わりにifをつかってuntilのように使ったりもした。
最後の行のプログラムからまた最初の上へと戻るときも苦戦した。最後にやはり行動を終了してからにしないと、うまく行動がうまく上のプログラムへとつながらなかった。そこで、untilの文を使った。
カーブについて学んだことがあった。そもそも、車がカーブするときには、前輪が回転することによって、曲がることができる。しかし、このロボティクスで使うロボットは、前輪を回転させることはできない。そこで、ロボットは小刻みに旋回と前進を繰り返してカーブする。ここで、旋回をしたときにはうまく動くかもしれないが、片方のタイヤだけ回転させてから前進というようにカーブさせるときはうまく曲がらないときがある。そんなときは、前輪と後輪が離れていることが原因かもしれない。つまり、前輪と後輪が離れているときには、前輪と後輪が近いときより、カーブしにくいのである。だから、前輪と後輪を近くするとよい。 黄色いレーザーを二つつけたが、そのうちどちらが障害物にあたっても、タッチセンサーが反応するようにした。つまり、二つのレーザーからそれぞれのばしたコードの両方を同じ端子に二つ重ねてつないだ。