#contents

*課題内容 [#hfc72d64]
 紙コップに入っている赤ボール2個と青ボール2個を入れ替える
#ref(robotics-2014b-3.png)
**攻略にあたって [#s8c3b294]
#ref(手順.png)
 私たちのグループでは空きコップは使用せず、一度全てのボールを本体に保持してからそのままボールを入れ替えるという作戦を立てた。そのルートは上の通りである。~
 �,泙裟橘未離灰奪廚泙把梢覆垢襦�~
 �∪屮棔璽襪鯤飮�し、ロボットの向きを変え対角のコップまで進む。~
 ��青ボールを保持し、ロボットを反転させる。~
 �だ屮棔璽襪魘�いたコップに入れ、対角のコップに戻る。~
 �ザ�いたコップに青ボールを入れる、終了。~
 なお、ロボットの向きを変えるのはロボット前面がコップを掴む動作、背面がボールをコップに入れる動作を担っているためである。
*ロボットの説明 [#mfba6bf3]
#ref(ロボット1.jpg)
#ref(ロボット2.jpg)
#ref(ロボット3.jpg)
#ref(ロボット4.jpg)
#ref(ロボット5.jpg)
 本体前面にコップを掴みそのまま持ち上げるためのアームが、上部から背面にかけてボールを格納するコンテナ兼ボールを流すレールが搭載されているのが特徴である。~
 本体前面にコップを掴みそのまま持ち上げるためのアームが、上部から背面にかけてボールを格納するコンテナ兼ボールを流すレールが搭載されているのが特徴である。コップを高い位置まで上げる必要があるため、アームは長めに設計した。~
 以下に自分が作成した部位を中心に細かく解説する。
**土台部分 [#ma0d487b]
 NXTの基本形をもとにしている。コンピュータ部を二つ並列に並べ、アームやレール部、各種センサーを取り付けるための改良を施した。
**コンテナ兼レール部 [#g1a1ac22]
 レールの長さはボールがちょうど4つ収まる長さにしている。レールの先端にはストッパー(以下ストッパー1とする)があり、この開閉によってボールを入れる動作を実現している。しかしこれだけでは一度に4つ全てのボールが落ちてしまうため、2つずつに分けるための中間のストッパー(以下ストッパー2)を設けた。
#ref(ストッパー.jpg)
#ref(ストッパー.gif)
#ref(ボール投下.gif)
 複数のギアを組み合わせることで、一つのモーターで二つの動きを同時に連動させている。~
 これによってモーター等のパーツの削減や重量負荷の低減だけでなく、複数の動作を誤差なく連動させることができるといったメリットが得られる。~
~
 また、大きく張り出している部分があるが、これはボールが前方に飛び出さないようにするためである。
**コップを誘導するガイドパーツ [#u1ee9eb6]
#ref(ガイドパーツ.png)
 プログラムによる調整だけでコップを最適な位置に合わせるのは難しい。その問題を上のような扇型に広がったガイドパーツを設けることで解決した。このパーツによって左右のズレを補正し、あとは本来よりも長めに前進するだけででコップを最適な位置に合わせることができる。
*プログラムの説明 [#hf73a76c]
 今回の課題ではNXTを二つ連携させる必要があり、それぞれに役割が分担されている。相互の命令のやりとりはMAILBOXによって行われている。~
 マスター側で移動用の二つのモーターとストッパーの開閉、そしてスレーブ側でアームの2関節分を制御した。~
~
 なお、自分はプログラムにはあまり関わらなかったので詳しくは他のメンバーのページを参考にしてほしい。
**スレーブ側 [#jef2e8b0]
 #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);
  }
 }
 }
 二つのモーターによってそれぞれコップを掴む動作とアーム自体を持ち上げる動作を制御している。
**マスター側 [#m2be86f1]
 #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);
 }
 本来は超音波センサーによって自動的にコップの位置を補足する予定だったが、直前にセンサーがうまく反応しないことに気づき、急遽変更となった。~
 変更後のプログラムは事前にロボットの進む距離と旋回する角度を指定しておき、課題を実行するときにコップと最初のロボットの位置を調整するというものになっている。~
 なお、OPENとCLOSEがストッパーの開閉を制御する命令である。
*感想・反省 [#t47fea05]
 今回の課題では自分は主にロボット本体の設計を担当した。その中でもストッパーを含むレール部は自分でも満足のいく仕上がりになったと思う。本番では完全にではなかったが自分がつくった機構を皆の前で見せることができたのはよかった。しかし反省点としてセンサーが取り付け方が良くなかったのか、うまく反応させることができなかったのが心残りである。ここさえ改善できていたら課題を完璧にこなせていたかもしれない。これに関してはメンバー同士で集まる時間をもっと多くとればよかった。~
 また、今回は今までと違ってメンバーと協力する活動が増えた。複数人で作業を行うことでお互いに違った発想を交わすことができたし、楽しく作業を進めることができた。

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