ブロック(一番太いホイール)を投げるロボットを作成し、以下の動きをするようにプログラムを作成せよ。 (重複しないように一人一つ以上のプログラムを作成すること)
ただし、モータ、光センサ、タッチセンサはそれぞれ2個まで使用可。懐中電灯の代わりに携帯のライトなどを利用してもよい。
今回の課題では、1、2のプログラムを制作しました。
今回の課題では、モーターを2つまでしか使うことができませんでした。ブロックを投げるために必ずモーターが必要なため、必然的に走行部分に使えるモーターは1つとなってしまいます。そのため、このロボットにはモータ−1つで左右に曲がれる工夫がしてあります。
まず、大まかな構造として車体は曲がりやすいよう3輪で、前輪はキャスターです。図はロボットの構造を図示したものですが、実際は車体をコンパクトにするためギヤを立体的に配置しています。
写真のように、モーターとそれに接続されているギヤをディファレンシャルギヤの上に配置し、車体の全長を短くしています。
後輪にはディファレンシャルギヤが接続されています。このディファレンシャルギヤには、内部に小さな傘状のギヤが3つ入っています。また、その傘状のギヤの働きにより、ディファレンシャルギヤに接続された左右独立した車軸の一方が止められてももう一方に動力を伝達することができます。この、車軸を止める働きをするのがストッパーです。
写真の青いパーツでできているのがストッパーで、車輪が後退方向に進まないようにしています。
写真は左右の後輪部分を別々に撮ったものです。よく見ると左右でギヤの数が違うのがわかります。これは、モーターが正転、逆転したときに左右の後輪がそれぞれ逆の回転で前進方向、後退方向に回るようにするためです。このうち、後退方向に回ろうとするタイヤはストッパーによって止められるため、ディファレンシャルギヤの働きで前進方向に回転するタイヤのみに力が伝わり、左右に曲がることができます。
また、この左右に曲がる動作を繰り返すことで前進します。
今回制作したプログラムでは、光を探すプログラムで光センサを1つ使い、光を追うプログラムで光センサを2つ使っていますが、どちらのプログラムでも最も明るい方向で車体が正面に向く必要があるため、光センサは2つを平行に取り付けました。また、光を当てる高さによって光センサーの向きが調節できるように、黒い関節のようなパーツを使っています。
ホイール発射部分は、軽くすればそれだけブロックの飛距離が伸びると考え、できるだけシンプルなものにしました。黒と黄色のアームを1本ずつ使っていますが、それらのアーム同士はたった1つのパーツで接続しています。強度が無いように思いましたが、それは十分で、ストッパーを付けることで投げることもできて折り畳むこともできる便利な装置になりました。
アームを動かすモーターは、コンパクトに収めるため車体の内部に組み込む形で取り付けました。モーターからの動力はギヤで向きを変えてアームに伝えています。
アームの下には、アームを下ろしたときに地面につかないようにするための棒があります。
ホイールは、アームに付けた2つの棒のパーツの間に乗せます。このアームが上向きに回転し、ストッパーに当たることで停止し、ホイールのみがそのまま飛んでいくという仕組みです。飛距離は長くありませんが、一応飛ばすことができます。
#define x 50 //閾値 int max; //maxを定義 int time; //timeを定義 sub straight() //直進 { OnFwd(OUT_A); Wait(50); OnRev(OUT_A); Wait(50); } sub right() //右旋回 { SetPower(OUT_A,7); OnRev(OUT_A); } sub left() //左旋回 { SetPower(OUT_A,2); OnFwd(OUT_A); } sub block() //ブロックを投げる { Wait(100); OnFwd(OUT_C); Wait(35); Off(OUT_C); Wait(100); } task main() //光を探すプログラム { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサ1は光センサ SetSensor(SENSOR_3,SENSOR_LIGHT); //センサ3は光センサ max=SENSOR_1; //センサ1をmaxに指定 ClearTimer(0); //タイマ0をリセット while(Timer(0)<=43) //タイマ0が1周にかかる時間以下なら { right(); //右旋回 if(SENSOR_1>max) //センサ1が最大値なら { max=SENSOR_1; //センサ1をmaxに再指定 ClearTimer(1); //タイマ1をリセット } else //センサ1が最大値でないなら { max=max; //maxは維持 time=Timer(1); //タイマ1をtimeに指定 } } ClearTimer(1); //タイマ1をリセット while(Timer(1)<=time) //タイマ1がtime以下なら { left(); //左旋回 } Off(OUT_A); block(); //ブロックを投げる }
右旋回で1周し、より明るくなったらセンサの値を記録し、タイマ1をリセットする。そのセンサの値より暗かったら値とタイマ1はそのままにする。こうして最も明るい部分を探し、1周したらタイマ1がカウントした分だけ左旋回で戻り、ホイールを投げるようにした。このとき、左右のギヤの違いで摩擦の量も違い、ギヤが多い側の後輪の駆動力が極端に弱くなってしまったため、SetPowerを用いて均等になるように調節した。
#define x 50 //閾値 sub straight() //直進 { OnFwd(OUT_A); Wait(50); OnRev(OUT_A); Wait(50); } sub right() //右旋回 { SetPower(OUT_A,7); OnRev(OUT_A); } sub left() //左旋回 { SetPower(OUT_A,2); OnFwd(OUT_A); } task main { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサ1は光センサ SetSensor(SENSOR_3,SENSOR_LIGHT); //センサ3は光センサ while(true) //光を追跡するプログラム { if((SENSOR_1>x)&&(SENSOR_3>x)) //センサ1とセンサ3の値がx以上なら { straight(); //直進 } if((SENSOR_1<x)&&(SENSOR_3>x)) //センサ1の値がx以下なら { right(); //右旋回 } if((SENSOR_1>x)&&(SENSOR_3<x)) //センサ3の値がx以下なら { left(); //左旋回 } if((SENSOR_1<x)&&(SENSOR_3<x)) //センサ1とセンサ3の値がx以下なら { Off(OUT_A); //停止 } }
閾値を定義し、両方のセンサが閾値以上なら前進、センサ1が閾値以下でセンサ3が閾値以上なら右旋回、逆なら左旋回、両方のセンサが閾値以下なら停止するようにした。しかし、実際に動かしてみると光からそれても左右のセンサの値に余り差が出ず、うまく動かなかったため2つのセンサの間につい立てを付けた。
コメントをどうぞ