[[2014b/Member]]
#contents
*課題内容 [#p4a4f87f]

 今回は紙コップに入っている2つのボールを入れ換えるロボットの製作をした。細かいルールなどは下のURLを参照してください。

http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission3
*ロボットについて [#z6c3cbb2]

ロボットは次の部品で成り立っている。
-基礎的な走行部分
-紙コップをつかむクワガタのような形のアーム部分
-つかんだ紙コップを持ち上げる腕の部分
-ボールを保持するレールの部分

 その他には光センサ、超音波センサがついている。しかしプログラムと時間の兼ね合いがうまくいかなかったので両方とも未使用である。

 このロボットはボールの入った紙コップをつかみ、上のレールに貯蔵する。そしてアームと逆側からボールを落とし他の紙コップに移動させるというものだ。レールには傾斜をつけボールが最後まで転がるようにした。この傾斜も角度をつけすぎるとアームがレールまで届かず、角度が緩やかだとボールが転がらないので調整に苦労した。また、ボールは真上から落とさないと紙コップが倒れてしまうので、真上から落とせるようにレールの後ろには壁をつけボールの転がる勢いをなくした。


&ref(./image4.JPG,50%);&ref(./image1.JPG,50%);

 本来ボールは下の左の写真のようにレールに4個貯蔵し2個づつ紙コップに落としたいのだが、ボールを落とす際4個全部落ちてしまうという問題が発生した。そこでレールの間にボールが全て落ちるのを防ぐストッパーを入れたところ問題は解決できた(下の右の写真)。このストッパーはギアと連結してあり上下運動をする。ボールを落とす部分とこのストッパーは逆に動くので、ボールを落とす部分が開くときにストッパーは上がり、逆にボールを落とす部分が閉まる時はストッパーは下がるのである。

&ref(./image2.JPG,50%);&ref(./image3.JPG,50%);
*プログラムについて [#l6aeae28]

 本来の作戦は

+右側からスタート
+ライントレースで交差点を識別
+そこから旋回、超音波センサで青いボールが入った紙コップを確認
+青いボールを回収
+赤いボールを取りに行く

であったが、超音波センサを低い位置につけてしまったため正常に動作せず、ロボットを作り直す時間的余裕がなかったため作戦を変更した。

 新しい作戦はロボットは下の図のような経路で動くようにした。超音波センサ、光センサを使わずに直進、サーボモータの機能を用いてある角度だけ旋回などのプログラムを用いたため、人間の手による位置調整が必要になってしまった。それを踏まえた新しい作戦は以下の通りだ。

+直進し赤いボールを回収(�,侶佻�)
+ある角度だけ旋回し青いボールを回収(�△侶佻�)
+回収して空になった紙コップに赤いボールを入れる
+またある角度だけ旋回し赤いボールが入っていた紙コップのもとへ向かう(��の経路)
+紙コップに青いボールを入れる
+終了
 
#ref(./miti.png,50%)

 マスターとスレーブによる通信機能を用いた。それぞれの仕事は以下のとおりである。

-マスター側
--基本走行
--レールからボールを落とす

-スレーブ側
--紙コップをつかむアームの開閉
--つかんだものをレールまで届ける腕の上下運動

 以下はマスター側のプログラムである。

 #define CONN 1
 #define SIGNALON 1

 #define OPEN_SPEED 15
 #define OPEN OnFwd(OUT_A,OPEN_SPEED);Wait(800);Off(OUT_A);
 #define CLOSE OnRev(OUT_A,OPEN_SPEED);Wait(1300);Off(OUT_A);

 #define SPEED_H 70
 #define SPEED_L 50
 const float diameter = 5.6;   //タイヤの直径(�僉�
 const float track = 10.5;   //タイヤのトレッド幅(�僉�
 const float pi = 3.1415;   //円周率

 float GetAngle_turn(float a)   //求める本体の回転角からタイヤの回転角を求める関数          
 {
	float ang = (a*track)/diameter;
	return ang;
 } 

 float GetAngle_go(float a)   //求める移動距離からタイヤの回転角を求める関数
 {
	float ang = a/(diameter*pi)*360.0;
	return ang;
 }

 sub angle_turn_L(float t)   //左にt度回転
 {
	int angle_turn_L = GetAngle_turn(t);
	RotateMotorEx(OUT_BC,SPEED_H,angle_turn_L,-100,true,true);//P37
	Off(OUT_BC);
 }

 sub angle_turn_R(float t)   //右にt度回転
 {
	int angle_turn_R = GetAngle_turn(t);
	RotateMotorEx(OUT_BC,SPEED_H,angle_turn_R,100,true,true);//P37
	Off(OUT_BC);
 }

 sub dist_go_F(float t)   //前にtセンチ進む
 {
	int angle_go_F = GetAngle_go(t);
	RotateMotorEx(OUT_BC,SPEED_H,angle_go_F,0,true,true);
	Off(OUT_BC);
 }

 sub dist_go_R(float t)   //後ろにtセンチ進む
 {
	int angle_go_R = GetAngle_go(t);
	RotateMotorEx(OUT_BC,-SPEED_H,angle_go_R,0,true,true);
	Off(OUT_BC);
 }


 task main()
 {

 dist_go_F(57.0);

 //コップを取るボール搭載の信号を送る
 SendRemoteNumber(CONN, MAILBOX1, SIGNALON);
 Wait(9000);

 angle_turn_R(150.0);

 dist_go_F(40.0);

 //コップを取るボール搭載の信号を送る
 SendRemoteNumber(CONN, MAILBOX1, SIGNALON);
 Wait(9000);

 //反転して
 dist_go_R(5.0);
 angle_turn_R(190.0);

 dist_go_R(20.0);

 //ボールを置く
 OPEN;
 Wait(1000);
 CLOSE;

 dist_go_F(50.0);

 //反転して
 dist_go_R(20.0);
 angle_turn_R(220.0);

 //コップまで近づく
 dist_go_R(33.0);

 //ボールを置く信号を送る
 OPEN;
 Wait(1000);
 CLOSE;

 //離れる
 dist_go_F(20.0);

 }


以下はスレーブ側のプログラムである。
 #define SIGNALON 1

 #define ARM_TIME1 1000  //アームの開閉時間1
 #define ARM_TIME2 2000   //アームの開閉時間2
 #define ARM_SPEED1 10    //アームの開閉スピード1
 #define ARM_SPEED2 50    //アームの開閉スピード2
 #define UP_TIME 2000     //アームを上げる時間
 #define UP_SPEED 50      //アームを上げるスピード
 #define DOWN_TIME 1800   //アームを下げる時間
 #define DOWN_SPEED 20    //アームを下げるスピード

 task main()
 {
 int msg;     //受け取った値を格納する変数
 while(true){
  ReceiveRemoteNumber(MAILBOX1, true, msg);     //MAILBOX1の値を受け取りmsgに格納
  if(msg==SIGNALON){
  OnFwd(OUT_C,DOWN_SPEED);Wait(DOWN_TIME);Off(OUT_C);     //アームを下げる
  OnRev(OUT_B,ARM_SPEED2);Wait(ARM_TIME2);Off(OUT_B);     //アームを閉じる
  OnRev(OUT_C,UP_SPEED);OnRev(OUT_B,ARM_SPEED2);Wait(UP_TIME);Off(OUT_C);Off(OUT_B);      //アームを上げる
  OnFwd(OUT_C,DOWN_SPEED);Wait(DOWN_TIME);Off(OUT_C);     //アームを下げる
  OnFwd(OUT_B,ARM_SPEED1);Wait(ARM_TIME1);Off(OUT_B);     //アームを開く
  ARM_UP2 OnRev(OUT_C,UP_SPEED);Wait(450);Off(OUT_C);     //アームを定位置に戻す

  }else{
   Off(OUT_BC);
  }
 }
 }

*反省と考察 [#lada5737]

-時間ぎりぎりになってプログラムが完成したため実際に走った時の超音波センサが使えないという不具合に気づくのが遅くなった。その結果ロボットはいじれないので渋々作戦を変更することになってしまった。そして人間の手で位置調整をするという精度の悪いプログラミングになってしまった。
-新しい作戦では使用しないセンサを搭載していたので、この点では無駄があったと思う。また、このロボは当初の作戦ではアームは上がっており、距離を測ってアームを下すというものであった。しかし、作戦を変えたときはアームを下していたほうが確実に紙コップをつかみに行くことができたはずだ。焦っていて視野が狭くなっていたかもしれないが成功率をあげるため早く気づき修正したかった。
-スレーブ側のプログラムはサーボモータの機能を使用しなかったので、これも人間の手による微調整が必要になってしまった。また、そのため電池の減少に影響を受けてしまった。時間に余裕をもって適切なプログラムを組みたかった。
-ロボットはそれぞれの部分が取り外し可能で収納には困らないようにできた。また、それぞれの機構も工夫していいものができたと思う。しかし紙コップをレールまで運ぶ際の腕などは軸が1つだけで支えられている状態だった。その結果ガタつくことになっていたのでガッツリ固定できるようにしたかった。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS