*ロボットの紹介 [#xad7c17c]
-アームの部分が予定より大きくなってしまったので、ロボットの本体を少し後ろに設置することで重心が前に行き過ぎないようにしました。
-このロボットが完成したのは課題の直前でした。それまでに何度も試行錯誤を続け、やっとの思いで完成しました。最初に作ったロボットは、タッチセンサーを付けその上二段式のアームを取り付けたのでロボットの前の部分がどうしても重くなってしまい、ロボットの後方に、余ったパーツをたくさん取り付けやっとバランスが取れるような状態でした。そのロボットはあまりに重すぎたため、一つ一つの動作がとても大きくなってしまい、ライントレースすらままならない状況だったので改良を余儀なくされました。そこで作り直した二代目のロボットは一台目に比べると小さくはなりましたが、タッチセンサーがついていたのでまだまだ大きいままでまた作り直しました。そうして改良に改良を重ね、ついに完成したロボットがこちら↓です。
#ref(2013a/Member/Hiko/Mission1/image.jpg,10%)
**改良の結果 [#u0a8fba8]
-それでもアームの部分が予定より大きくなってしまったので、ロボットの本体を少し後ろに設置することで重心が前に行き過ぎないようにしました。
-アームの形をシンプルにすることで、アームを壊れにくくしました。
-缶をつかむメインのアーム以外にも下に缶が倒れないようにサポートする動かないアームを取り付けましたが、それでもたまに倒れてしまうことがあり今後の課題です。
-タッチセンサーを使わないことで、缶が軽すぎて反応しないという問題点を解決しました。
#ref(2013a/Member/Hiko/Mission1/image.jpg,10%)
アームの力が強すぎて部品が破損する可能性があるのでトルクギア(力がかかり過ぎると空回りする白い特殊なギア)をアーム駆動に使用することで、この問題を解決しました。
-タッチ(センサーを使わないことで、缶が軽すぎて反応しないという問題点を解決しました。
-アームの力が強すぎて部品が破損する可能性があるのでトルクギア(力がかかり過ぎると空回りする白い特殊なギア)をアーム駆動に使用することで、この問題を解決しました。
*コース攻略 [#b8c0055d]
-タッチセンサーを使わないので、時間ごとにロボットの動きを変え攻略しました。
-閾値の値を変えることで交差点を渡るようにしました。
-しきい値の値を変えることで交差点を渡るようにしました。
-時間ごとに区切ったプログラムが切り替わるごとに音を出すようにしたことで、どのプログラムがうまくいって、どのプログラムがうまくいかないのかが分かりやすくなりました。
-最後の缶を置くところは、ロボットが180度回転し缶を置いて少し下がりまた180度回転して元に戻りゴールに帰るというプログラムにしました。
#ref(2013a/Member/Hiko/Mission1/robotics-2013a-mission1.jpg,100%)
**コースを攻略する上での難関 [#x74cb940]
+缶をつかむ
-まず、缶をつかむことが最初の難関でした。人間ならつかむものを判断してそれに合わせてつかみ方やつかむ強さを変えられますが、ロボットは決められた通りに動くだけなのでそんな芸当はできません。なので、思っていた以上に缶をつかむことはとても大変なことだと改めて理解しました。最初に私はアーム2本で缶をつかもうと考えていました。しかし何度やってもうまくつかめず、運んでいる最中に倒れてしまいます。そこで、缶をつかむメインのアーム以外にも下に感が倒れないようにサポートする動かないアームを取り付けることで以前に比べ安定性が増しました。
+交差点
-プログラム自体あまり得意ではなかった私は交差点をうまく渡らせることができず困っていましたが、ペアの人やほかの友達に教えてもらい、しきい値を変えたりロボットに内蔵されてるカウンターをうまく使えばいいことを理解し、何とか交差点を渡らせることができるようになりました。
+円
-交差点を抜けるとすぐに円になります。ここではロボットが大きいせいもあり、円をうまく回れないという問題が起こりました。なぜうまくいかないかを考えると、毎回円の内側を走っていると失敗することがわかりました。なのでロボットが一番走りやすい所を通るように何度か線を横断するプログラムにしました。
+缶を置く
-このプログラムを作るうえで一番根気がいる作業でした。ロボットが止まる→180度回転→缶を置く→少しバック→また180度回転→再びライントレースに戻る、という流れは決まっていたのですが、それにかかる時間を決めるのがとても大変な作業でした。
*プログラムの説明 [#ab8ab5e8]
#define THRESHOLD 45
#define HIPOWER 7
#define LOWPOWER 2
#define THRESHOLD 45 //しきい値の定義
#define HIPOWER 7 //直線を走る時のパワー
#define LOWPOWER 2 //カーブを走る時のパワー
#define set_power_H SetPower(OUT_AC,HIPOWER);
#define set_power_L SetPower(OUT_AC,LOWPOWER);
#define set_power_N SetPower(OUT_B,LOWPOWER);
#define set_power_N SetPower(OUT_B,LOWPOWER); //缶を挟むパワー
#define go_fwd set_power_H; OnFwd(OUT_AC);
#define arm_fwd set_power_N; OnFwd(OUT_B);Wait(30);Off(OUT_B);
#define arm_bwd set_power_N; OnRev(OUT_B);Wait(30);Off(OUT_B);
#define turn_left1 set_power_L ;OnFwd(OUT_C);OnRev(OUT_A);
#define turn_left0 set_power_L ;\
  OnFwd(OUT_C);Off(OUT_A);
#define turn_right0 set_power_L ;\
  OnFwd(OUT_A);Off(OUT_C);
#define turn_right1 set_power_L ;\
  OnFwd(OUT_A);OnRev(OUT_C);
#define STEP 1
#define nMAX 200
#define short_break Off(OUT_AC); Wait(100);
#define CROSS_TIME 300
#define cross_line set_power_L;\
 OnFwd(OUT_A);OnRev(OUT_C);\
   Wait(CROSS_TIME);short_break;

↑ここまでがこのプログラムの定義

task main () {
	SetSensor(SENSOR_2, SENSOR_LIGHT);
	int nOnline=0;
	ClearTimer(0);
 while(FastTimer(0)<=600){
  while(nOnline < nMAX && FastTimer(0)<=600){
    
   if(SENSOR_2< THRESHOLD -13) {
      turn_left1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -11){
     turn_left0;
   }else if(SENSOR_2< THRESHOLD -7){
     go_fwd;
   }else if(SENSOR_2< THRESHOLD -1){
     turn_right0;
   }else{
      turn_right1;
    }
    nOnline=0;
    }
    Wait(STEP);
   }
 }
	arm_fwd;
	PlaySound(SOUND_CLICK);

↑このプログラムで缶をつかむ

while(FastTimer(0)<=1600){
  while(nOnline < nMAX && FastTimer(0)<=1600){
   if(SENSOR_2< THRESHOLD -13) {
      turn_left1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -11){
     turn_left0;
   }else if(SENSOR_2< THRESHOLD -7){
     go_fwd;
   }else if(SENSOR_2< THRESHOLD -1){
     turn_right0;
   }else{
      turn_right1;
    }
    nOnline=0;
    }
    Wait(STEP);
   } 
 }
	PlaySound(SOUND_DOUBLE_BEEP);
	ClearTimer(0);
	turn_right1;
	Wait(10);
	arm_fwd;

↑いったん内側を走行する

while(FastTimer(0)<=1200){
  while(nOnline < nMAX && FastTimer(0)<=1200){
 
  
   if(SENSOR_2< THRESHOLD -15) {
      turn_right1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -13){
     turn_right0;
   }else if(SENSOR_2< THRESHOLD -7){
    go_fwd;
   }else if(SENSOR_2< THRESHOLD +2){
     turn_left0;
   }else{
      turn_left1;
    }
    nOnline=0;
    }
    Wait(STEP);
    }
 } 
	PlaySound(SOUND_DOWN); 
	turn_left1;
	Wait(10);
	arm_fwd;

↑円を回りやすい外回りで回る、そして缶をつかみなおす

 while(FastTimer(0)<=2000){
  while(nOnline < nMAX && FastTimer(0)<=2000){
   if(SENSOR_2< THRESHOLD -13) {
      turn_left1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -11){
     turn_left0;
   }else if(SENSOR_2< THRESHOLD -7){
     go_fwd;
   }else if(SENSOR_2< THRESHOLD -1){
     turn_right0;
   }else{
      turn_right1;
    }
    nOnline=0;
    }
    Wait(STEP);
   }
 }
	PlaySound(SOUND_LOW_BEEP);
	turn_right1;
	Wait(20);
	arm_fwd;

↑二つ目の円も外回りで回る

 while(FastTimer(0)<=2900){
  while(nOnline < nMAX && FastTimer(0)<=2900){
   if(SENSOR_2< THRESHOLD -15) {
      turn_right1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -13){
     turn_right0;
   }else if(SENSOR_2< THRESHOLD -7){
   go_fwd;
   }else if(SENSOR_2< THRESHOLD +2){
     turn_left0;
   }else{
      turn_left1;
    }
    nOnline=0;
    }
    Wait(STEP);
    } 
  } 
	PlaySound(SOUND_FAST_UP);
	arm_fwd;
 while(FastTimer(0)<=4500){
  while(nOnline < nMAX && FastTimer(0)<=4500){
   if(SENSOR_2< THRESHOLD -13) {
      turn_right1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -11){
     turn_right0;
   }else if(SENSOR_2< THRESHOLD -7){
     go_fwd;
   }else if(SENSOR_2< THRESHOLD -1){
     turn_left0;
   }else{
      turn_left1;
    }
    nOnline=0;
    }
    Wait(STEP);
   }
  }  
	PlaySound(SOUND_DOUBLE_BEEP);
	turn_left1; Wait(275);
	arm_bwd;
	OnRev(OUT_AC); Wait(100);
	turn_left1; Wait(275);

↑ここがこのプログラムの最後の難関、ここでロボットが缶を離し置いた缶にぶつからないように一歩下がって一回転して、ゴールへ

 while(FastTimer(0)<=5500){
  while(nOnline < nMAX && FastTimer(0)<=5500){
   if(SENSOR_2< THRESHOLD -13) {
      turn_left1;
      nOnline++;
   }else{
    if(SENSOR_2< THRESHOLD -11){
     turn_left0;
   }else if(SENSOR_2< THRESHOLD -7){
     go_fwd;
   }else if(SENSOR_2< THRESHOLD -1){
     turn_right0;
   }else{
      turn_right1;
    }
    nOnline=0;
    }
    Wait(STEP);
   }
	short_break;
	turn_right1;Wait(nMAX*STEP);
	cross_line;
	nOnline=0;
   }
}

↑ゴールに着く

-ポイントは、しきい値をたびたび変えることで交差点を渡ることと時間ごとに違うプログラムを使い分けているところです。

*感想 [#q6db5aad]
-ライントレースをするロボットを作ることは実際にやってみるととても難しく、様々な困難がありました。しかしその問題点を解決するためにどのようなロボット、そしてプログラムにすればよいかといろいろと悩むことで、新しい発見ができました。例えば、電池の残量やロボット本体の重さ・重心などの様々な原因で光センサーの値や移動速度が変化してしまうので、常に同じ動きができるわけではない。ではその問題が動作そのものにできるだけ支障を出さないようにするにはどうすればよいか。それには、Waitをあまり使わないようにすることが大切です。Waitはある一定時間その動作を続けるというプログラムなので、電池残量が大きくかかわってしまうからです。このほかにもいろいろな問題点がありましたが、そのたびになぜそうなるのか、どうすればそうならないか、を考えることで、大変でしたが何とかできるようになったと思います。
-タイマーでプログラムを切り替えるので、時間を正確にはからなければならずとても根気のいる作業になりました。

*反省点 [#gc8ee745]
-自分のパソコンでUSBメモリが起動できず、ペアにとても迷惑をかけてしまった。
-この講義の勉強にあまり時間をかけられなかった。
-サブルーチンや関数などを完璧に理解できてない。

*まとめ [#rc4a5766]
-最初はプログラムが全く理解できずにとても戸惑った。一応の完成はしたが、理解できていないところも多くペアには本当に迷惑をかけてしまって申し訳なかった。
-成功するときもあったが失敗のが多いので、今回の反省点を見つめなおし次回の次の課題に活かしていきたい。



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS