2017b/Member 目次
ピンポン玉と紙コップを別々に回収して所定の場所に運ぶ。
今回の課題で重要な点はコップをつかみ、上げるアーム部分の機構をどうするかだと考える。 私たちの班では最初、機体がコンパクトになるようにコップを上げる際、回転方向にモータで回して上げる機構を考えたが、アームに1つモータを使うことを考えるとトルクが大きくなりアームを上げるためのモータに負担がかかってしまう。そこで、アームを垂直に上げるエレベータ式を採用した。 垂直に上げることで機体は大幅に縦に大きくなってしまうがモータへの負担が少なくなり、さらにコップを重ねる際に多少のずれには対応できるようになった。
上で述べているように機体は縦に大きくなっている。 この試作機では機体の安定性を求め、4輪にしてある。
この機体の工夫ポイントとして図のように後輪二輪を自由に稼働できるようにしたことが挙げられる。
しかし、実際にライントレースをさせた時に旋回できないということと、後輪がどちらを向いているかでまっすぐにバックさせたいだけなのに思わぬ方向にバックしてしまうという問題があった。
機体はさらに縦に伸びてしまったが、いくつかの改善を加えた。
図のようにモータの位置を試作機1よりも下に持ってくることで機体を安定させた。
試作機1、2とも機体の安定性を考え、2つのris本体同士が上の左図のように背を向けるように配置したのだがそれではrisが通信しあえないという重大な問題が発生した。
上の右図のようにrisを配置し、土台から作り直した。
本番ではいくつかの改善点をさらに加えたが大体の形は図のようである。
図のような構造にすることによりクラッチギアが機能するようにした。
クラッチギアとは一定の力以下の時は正常に回転するが、それ以上になると空回りするギアのことである。
これを使うことによってモータを回転させ続けコップをホールドするとき、モータへの負担を軽減することができる。
図のようにライントレースをするための下向きのセンサーとコップを感知するための前向きのセンサーを取り付けた。
そこで上図のような棒を取り付けた。
この図のように左の棒にコップを当てればコップが確実にセンサーの前にきて閾値が一定になる。
課題3の図の左上のコップを1つ目のコップ、真ん中上のコップを2つ目のコップ、右下のコップを3つ目のコップと定義してこの順番の通りに作業する。
A地点からスタートし、コップを重ねながらピンポン玉を置き、最後に3つの紙コップが重なった状態でY地点に置く。
また、今回の課題では地道に秒数を数えていけばライントレースなどセンサーを使った動作をしなくてもクリアできる。しかしそれでは電池消耗などで大きなズレが生じてしまう。
私たちの班では作業したい場所の近くでいかに機体に機体自体の位置を確定させるかに重点を置いた。
以下、タイヤなどがついている方を土台側、アームを動作させる方をアーム側と定義する。
土台側のrisにはタイヤ二輪とコップを感知するためのセンサー、ライントレースをするためのセンサーがついており、その分プログラミングも膨大なものとなっている。
#define SHIKIICHI 870 //コップを感知するセンサーが用いる閾値 #define CYOI 40 //通信のための定義
CYOI(40) という数字を通信しあい、動作の開始、完了などを認識する。
#define mae(w) ;OnRev(OUT_AC);Wait(w);Off(OUT_AC); //前進 #define usiro(g) OnFwd(OUT_AC);Wait(g);Off(OUT_AC); //後退 #define migisennkai(s) set_power_L;OnFwd(OUT_A);OnRev(OUT_C);Wait(s);Off(OUT_AC); //右旋回 #define hidarisennkai(n) set_power_L;OnFwd(OUT_C);OnRev(OUT_A);Wait(n);Off(OUT_AC);//左旋回
#define shikiichi 48 #define zennsinn OnRev(OUT_AC); //前進 #define turn_left1 set_power_L;OnFwd(OUT_A);OnRev(OUT_C); //左旋回 #define turn_right1 set_power_L;OnRev(OUT_A);OnFwd(OUT_C);//右旋回 #define turn_left2 set_power_L;Off(OUT_A);OnRev(OUT_C); //左折 #define turn_right2 set_power_L;Off(OUT_C);OnRev(OUT_A); //右折 #define LOWPOWER 1 #define HIGHPOWER 4 #define set_power_H SetPower(OUT_AC,HIGHPOWER); #define set_power_L SetPower(OUT_AC,LOWPOWER);
アームを上げ下げする定義では秒数で指定するものと最低位置から最高位置、最高位置から最低位置に上げ下げするもので分けて定義した。
また、アームがコップを離すための定義ではコップをつかむモータをオフにするだけのものとモータを逆回転させるものとで分けて定義した。
#define CYOI 40 //通信のための定義 #define tsukamu OnFwd(OUT_C); //つかむ #define hanasu Off(OUT_C); //はなす(モータをオフにするだけ) #define ageru OnFwd(OUT_B); Wait(230); Off(OUT_B); //アームを最低位置から最高位置まで上げる #define sageru OnRev(OUT_B); Wait(160); Off(OUT_B); //アームを最高位置から最低位置まで下げる #define up(z) OnFwd(OUT_B); Wait(z); Off(OUT_B); //アームをz秒上げる #define down(y) OnRev(OUT_B); Wait(y); Off(OUT_B); //アームをy秒上げる #define hiraku OnRev(OUT_C); Wait(008);Off(OUT_C); //アームを完全に開く
1つ目のコップについては以下のような流れで動作する。
コップ付近までライントレースで行く。(機体前方に取り付けた棒によりコップがアームの前に来る)→コップをつかむ→再びライントレースに戻る→交差点Bで機体自体の位置を確定→ピンポン玉を入れる
sub line_l() //1つ目のコップ付近まで行くサブルーチン { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=550){ if(SENSOR_2 < shikiichi -7){ turn_right2; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left2; } } PlaySound(SOUND_CLICK); Off(OUT_AC); }
ライン上外での作業からライン上に戻ってくる際に角度によって交差点と判断してしまう危険性がある。
そのため、交差点で止まるライントレースの前に3秒ほど強制的にライントレースを続けるサブルーチンを入れた。
sub line_ll() //強制的に3秒間ライントレースを続けるサブルーチン { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=300){ if(SENSOR_2 < shikiichi -7){ turn_right1; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left1; } } PlaySound(SOUND_CLICK); Off(OUT_AC); }
sub line_k() //交差点で止まるライントレース { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=25){ if(SENSOR_2 < shikiichi-6){ turn_right1; } else if (SENSOR_2 < shikiichi -4){ turn_right2; ClearTimer(0); } else if (SENSOR_2 < shikiichi -1){ zennsinn; ClearTimer(0); } else if (SENSOR_2 < shikiichi ){ turn_left2; ClearTimer(0); } else { turn_left2; ClearTimer(0); } } PlaySound(SOUND_CLICK); Off(OUT_AC); }
紙コップを少し上げることでピンポン玉をX地点に入れる。↓
2つ目については以下のような流れで動作する
障害物を感知するまでライントレースをする(障害物によって機体自体の位置を確定)→旋回し二つ目のコップをセンサーで感知→コップを重ねる→ピンポン玉を入れる
sub line_lll() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(SENSOR_1 < SHIKIICHI -40){ //閾値が810になるまでライントレースを続ける if(SENSOR_2 < shikiichi -7){ turn_right1; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left2; } } PlaySound(SOUND_CLICK); Off(OUT_AC); }
sub search3() //2つ目のコップを探すサブルーチン { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); while(SENSOR_1 < SHIKIICHI -40){ mae(10); //コップを感知するセンサーの閾値が810になるまで前進 } Off(OUT_AC); Wait(100); hidarisennkai(20); Wait(100); mae(30); Wait(300); //棒を使い、コップをアームの前に持ってくる ClearMessage(); SendMessage(OWARI); //動作完了をアーム側に伝える }
ピンポン玉をX地点に入れる動作に関しては1つ目と同じである
3つ目については以下のような流れで動作する
機体を大体コップ付近に持ってくる(この時、機体がコップに対し確実に左に来るようにする)→右旋回と前進を繰り返しコップを感知する→コップを重ねる→ピンポン玉を入れる
センサーがコップを感知するまで右旋回と前進を繰り返すことによってコップの前まで行く。
sub search4() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); while(SENSOR_1 < SHIKIICHI -40){ mae(020); migisennkai(010); } //コップを感知するセンサーの閾値が810になるまで前進と右旋回を繰り返す Off(OUT_AC); Wait(100); hidarisennkai(20); Wait(100); mae(30); Wait(300); //棒を使い、コップをアームの前に持ってくる ClearMessage(); SendMessage(OWARI); //動作完了をアーム側に伝える }
3つ目のコップを重ねるとアームがつかんでいるコップの数は当然3つになり、その重さで3つ目、2つ目のコップが落ちてしまうという問題があった。
そこでX地点にピンポン玉を入れる前と入れた後の両方でコップを押し込んだ
通信するプログラムの後にアーム側と対応した数字を記すことでわかりやすくした。
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); mae(050); line_l(); Wait(100); mae(40); SendMessage(CYOI);//1 //1つ目のコップをつかむ Wait(50); mae(30); migisennkai(250); line_ll(); line_k(); hidarisennkai(140); SendMessage(CYOI);//2 ClearMessage(); until(Message() == CYOI);//3 mae(160); Wait(100); ClearMessage(); SendMessage(CYOI);//4 //ピンポン玉をX地点に入れる until(Message() == CYOI);//4.5 usiro(180); ClearMessage(); hidarisennkai(100); line_lll(); shougaibutsu(); migisennkai(60); search3(); mae(030); Wait(100); SendMessage(CYOI);//5 //2つ目のコップを重ねる until(Message() == CYOI);//6 SendMessage(CYOI);//7 migisennkai(150); mae(050); SendMessage(CYOI);//8 //ピンポン玉をX地点に入れる ClearMessage(); until(Message() == CYOI);//9 usiro(060); Wait(50); ClearMessage(); hidarisennkai(120); mae(300); migisennkai(050); mae(060); search4(); Wait(50); mae(020); migisennkai(040); mae(020); SendMessage(CYOI);//10 //3つ目のコップを重ねる until(Message() == CYOI);//11 ClearMessage(); usiro(100); migisennkai(180); mae(080); SendMessage(CYOI);//12 until(Message() == CYOI);//13 ClearMessage(); mae(130); SendMessage(CYOI);//14 until(Message() == CYOI);//15 ClearMessage(); usiro(100); migisennkai(280); mae(030); SendMessage(CYOI);//16 //すべてのコップを離す until(Message() == CYOI);//17 usiro(070); }
task main() { until(Message() == CYOI);//1 tsukamu; //1つ目のコップをつかむ ClearMessage(); until(Message() == CYOI);//2 ClearMessage(); up(30); //ピンポン玉をX地点に入れるためにコップを少し上げる Wait(100); SendMessage(CYOI);//3 until(Message() == CYOI);//4 up(180); ClearMessage(); SendMessage(CYOI);//4.5 until(Message() == CYOI);//5 down(180); ClearMessage(); SendMessage(CYOI);//6 ClearMessage(); until(Message() == CYOI);//7 up(50); ClearMessage(); until(Message() == CYOI);//8 Wait(100); down(50); //コップが落ちないようにアームを少し下げて押し込む Wait(100); hanasu; Wait(100); tsukamu; Wait(50); up(200); ClearMessage(); SendMessage(CYOI);//9 ClearMessage(); until(Message() == CYOI);//10 ClearMessage(); Wait(100); sageru; SendMessage(CYOI);//11 until(Message() == CYOI);//12 down(040); //コップが落ちないようにアームを少し下げて押し込む up(050); ClearMessage(); SendMessage(CYOI);//13 until(Message() == CYOI);//14 down(030); //コップが落ちないようにアームを少し下げてさらに押し込む up(100); ClearMessage(); SendMessage(CYOI);//15 until(Message() == CYOI);//16 down(050); hiraku; //すべてのコップを離す SendMessage(CYOI);//17 }
基本点30点 技術点19.7点 計49.7点 第一位
今回の課題では試験期間と重なっていたこともあり、いままでの課題よりも時間がなかったので大変だった。その中でも授業外の空いている時間で班で集まり、意見を出し合って何とか完成させ本番でも成功することができてよかった。この授業は課題が難しく大変だったが良い経験ができてよかったと感じている。