[[2014b/Member]]
目次
#contents
*課題3の内容 [#u2fb7e32]
紙コップに入っている赤ボール2個と青ボール2個をそれぞれ空の紙コップに移し替える~
フィールドは課題2で作成した紙を2枚つなぎあわせて使用する。~
&ref(http://yakushi.shinshu-u.ac.jp/robotics/?plugin=ref&page=2014b%2FMission3&src=robotics-2014b-3.png);
#br
参照:[[課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission3]]~
今回はNXTを2台分使用して、4人一組で制作する。
#br

コップをつかむプログラム
 /* モーターAがハサミ、モーターBが腕 */
*ロボット本体 [#t13bd40a]
今回の課題は4人一組のチームを組んで行うので、プログラム担当とロボット制作担当の二人ずつに分かれて進めていった。自分はプログラム担当で、ハサミの部分(スレーブ側)のプログラムを作成した。何度も問題が発生したため、そのたびに改良を重ねた。それぞれの段階ごとに説明する。
**完成形 [#e5b45c86]
#br
全体像~
#ref(normal.jpg)~
#br
私達のチームのロボットの特徴はカニのような大きなハサミが付いていることである。~
このハサミでコップを掴み、うで全体を回すことでコップを持ち上げて中の玉をからのコップに注ぐ。~
ハサミにはコップから玉が落ちないようにフタもついていて、腕を持ち上げてから蓋を開くことで玉をからのコップに落とす。
#ref(normal0.jpg)~
また、このロボットでは本体(マスター)側がBluetoothで腕(スレーブ)側のプログラムを起動する。腕(スレーブ)側が仕事を終えたら音を出して終了を伝え、本体側がマイクユニットでその音を拾って次の行動へうつる仕組みになっている。
#br
腕を上げた状態~
#ref(up.jpg)~
この状態からフタを開くことで、下にあるからのコップに玉を落とす。
#br
#ref(pour.jpg)~
#br
本体下部に搭載した超音波センサを使ってコップを探して取りに行っている。

**試作品ver1 [#cacc142f]
#ref(ver1.0.jpg)~
一番最初に制作したロボットはこのような状態で、フタはなく、シンプルな作りだった。腕はハサミで掴むためのモーターとそれを持ち上げるモーターを2つつなげただけで、コップを傾けて玉を注ぐ予定だった。~
しかし、腕を本体に接続している部分がただピンで刺しているだけでとても弱く、腕の重さで垂れ下がってしまっていた。~
実際に動かしてみると注ぐときにコップのくちに全然届かなかった。~
#br
**試作品ver2 [#kae552a3]
そこで、腕の高さを確保するために本体上部にレールを装備し、そのレール上にモーターを置くことにした。このレールはコンピューター部分の両側から固定されているので、モーターをガッチリと固定することができた。また、このときに本体の不要なパーツを徹底的に取り除き、より軽量でわかりやすい構造に改良した。
#ref(ver1.1_2.jpg)~
#br
#ref(ver1.1.jpg)~
#br
このように、両側からガッチリと固定している。
#ref(rel.jpg)~

**フタを装着(完成品) [#t4141f74]
これらのような改良をしたあとに実際にプログラムを走らせたところ、コップから玉を注ぐすときにどうしても落下する位置がからコップからズレてしまった。この問題を解決するために、ハサミの上に可動式の蓋を付けた。このフタをモーターで開閉することで、任意のタイミングでたまを落とすことが可能になった。
#ref(close.jpg)~
#br
このように持ち上げてから、任意のタイミングで蓋を開く
#ref(ready.jpg)~






*プログラム [#aa5811a4]
自分は腕の部分(スレーブ)のプログラムを担当したので、主に腕のプログラムについて説明します。本体側(マスター)のプログラムについての詳細は担当メンバーのレポートを参照してください。

**本体(マスター)のプログラム [#gd47347a]


 const float diameter = 5.45; //タイヤの直径(cm)
 const float track = 12; //タイヤのトレッド幅(cm)
 const float pi = 3.1415; //円周率
 
 
 void fwdDist(float d) //距離dcm前進
 {
  long angle;
  angle = d/(diameter*pi)*360.0; //角度を計算する
  RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 0, true, true);
 }
 
 void turnAng(long ang) //角度ang度の時計回りの旋回
 {
  long angle;
  angle = track/diameter * ang;
  RotateMotorEx(OUT_BC, SPEED_SLOW, angle, 100, true, true);
 }
 
 void ReturnAng(long ang) //角度ang度の半時計回りの旋回
 {
  Wait(500);
  long angle;
  angle = track/diameter * ang;
  RotateMotorEx(OUT_BC, SPEED_SLOW, angle, -100, true, true);
 }
 
 
 int searchDirection(long ang) //現在の方向を中心にang度の範囲で探し、障害物までの距離を返す
 
 {
  long angle,tacho_min=0, tacho_corr;
  int d_min;
 
  d_min=600; //仮の最小値
 
  angle = (track/diameter)*ang; //旋回角度からタイヤの回転を計算
  turnAng(ang/2); //指定された角度の半分を旋回
  ResetTachoCount(OUT_BC); //角度計測をリセット
 
  OnFwdSync(OUT_BC,SPEED_SLOW-15,-100); //半時計回りに旋回
  while(MotorTachoCount(OUT_B)<=angle){
  if(SensorUS(S1)<d_min){
   d_min=SensorUS(S1);
   tacho_min=MotorTachoCount(OUT_B);
   }
  }
 
  OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE);
  until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S1)<=d_min);
 
  Wait(14); //微調整
  Off(OUT_BC);Wait(500);
  return d_min;
 }

**ハサミ(スレーブ)のプログラム [#t84401d7]
最初はbluetoothを使って、~
(マスター)→(スレーブ)→(マスター)→(スレーブ)・・・・~
と言ったように仕事をバトンタッチしていく予定でプログラムを作っていったが、どうしても通信がうまく行かなかった。そのため、仕方なくbluetoothでスレーブのプログラムを起動だけして、スレーブからは音で仕事の終了を伝えることにした。

#br
***使用したマクロ一覧 [#h32e47ec]
/* モーターAがハサミ、モーターBが腕、モーターCが蓋 */

 レギュレーションモードで力をハサミにかけ続け、コップを持つ
 #define HOLD OnFwdReg(OUT_A,-40,OUT_REGMODE_IDLE);  //コップを挟む

 ハサミを50度開きコップをはなす
 #define RELEASE RotateMotor(OUT_A,50,50);  //コップをはなす

 コップをほぼ180度腕を回転させて持ち上げ、レギュレーションモードでその位置でとどまる
 #define UP_MAX RotateMotor(OUT_B,-80,185);OnFwdReg(OUT_B,0,OUT_REGMODE_IDLE); 

 コップをほぼ180度腕を回転させて床に下ろす
 #define DOWN RotateMotor(OUT_B,45,185);  //腕を下げる

 フタを120度回してコップにかぶせる
 #define OPEN RotateMotor(OUT_C,50,120);  //蓋を開ける

 フタを120度回してコップから外す
 #define CLOSE RotateMotor(OUT_C,50,-120);  //蓋を閉める

#br
#br
#br


***コップをつかむプログラム [#pcdc5b9a]
 /* モーターAがハサミ、モーターBが腕、モーターCが蓋 */
 #define HOLD OnFwdReg(OUT_A,-40,OUT_REGMODE_IDLE);  //コップを挟む
 
 task main()
 {
 
  HOLD;  //掴む
  Wait(500);  //ちょっと待つ
 
  Off(OUT_A);  //モーターAを切る
  Off(OUT_A);  //モーターAを切る(※)
 
  Wait(500);
 
 
  PlaySound(SOUND_UP);
  Wait(100);
  PlaySound(SOUND_UP);
  Wait(100);
 
 
 }
 
 
 
 ※ OnFwdRegでスピードをOUT_REGMODE_IDLEとしたところ、なぜかプログラム終了時にモーターが少し逆回転してハサミが勝手に開いてしまったため、この文を加えた。



***コップを離すプログラム [#r09c11a0]

コップを離すプログラム


 /* モーターAがハサミ、モーターBが腕 */
 /* モーターAがハサミ、モーターBが腕、モーターCが蓋 */
 #define RELEASE RotateMotor(OUT_A,50,50);  //コップをはなす
 
 task main()
 {
  ResetTachoCount(OUT_AB);  //モーターABの回転角をリセット
 
  RELEASE;  //コップを放す
 
  Wait(300);
 
  PlaySound(SOUND_DOWN);
  Wait(100);
  PlaySound(SOUND_DOWN);
  Wait(100);
 
 }



持ち上げてボールを移し、下ろすプログラム
***持ち上げてボールを移すプログラム [#g7b268da]

 /* モーターAがハサミ、モーターBが腕 */
 #define UP_HALF RotateMotor(OUT_B,-45,80);   //途中まで持ち上げる
 #define UP_MAX RotateMotor(OUT_B,-45,20);   //たまを移す
 #define DOWN RotateMotor(OUT_B,45,100);  //腕を下げる
 /* モーターAがハサミ、モーターBが腕、モーターCが蓋 */
 #define HOLD OnFwdReg(OUT_A,-40,OUT_REGMODE_IDLE);  //コップを挟む
 #define UP_MAX RotateMotor(OUT_B,-80,185);OnFwdReg(OUT_B,0,OUT_REGMODE_IDLE);   //コップを持ち上げてそのままキープ
 #define CLOSE RotateMotor(OUT_C,50,-120);  //蓋を閉める
 
 
 task main()
 {
 ResetTachoCount(OUT_AB);  //モーターABの回転角をリセット
 ResetTachoCount(OUT_ABC);  //モーターABCの回転角をリセット
 
 /*コップを持ち上げて玉を移す*/
 
 /*コップを掴んで蓋をする*/
 
  HOLD;  //掴む
 
  Wait(300);
  Wait(1000);
 
  UP_HALF;  //半分持ち上げる
  CLOSE;  //蓋をする
 
  Wait(1000);
 
 
 /*180度持ち上げて静止*/
 
  UP_MAX;  //もちあげる
  Wait(500);
 
 
 /*音で作業の終了を伝える*/
  PlaySound(SOUND_FAST_UP);
  Wait(300);
  PlaySound(SOUND_FAST_UP);
  Wait(300);
 
  Off(OUT_A);  //モーターAを切る(※)
 
 /*3秒待つ(この間に位置調整)*/
  Wait(3000);
 }
 






***フタを開き、玉を落とすプログラム [#ibd45400]


 /* モーターAがハサミ、モーターBが腕、モーターCが蓋 */
 #define OPEN RotateMotor(OUT_C,50,120);  //蓋を開ける
 
 /*完全に持ち上げて玉を移す*/
  UP_MAX;  
 
 /*ちょっと待つ*/
  Wait(1000);
 task main()
 {
  ResetTachoCount(OUT_ABC);  //モーターABCの回転角をリセット
 
 /*玉を移す*/
  OPEN;  //蓋を開ける
 
  PlaySound(SOUND_FAST_UP);
  Wait(100);
  PlaySound(SOUND_FAST_UP);
  Wait(100);
 
 }




***コップを下ろすプログラム [#j6e86885]

 /* モーターAがハサミ、モーターBが腕、モーターCが蓋 */
 #define DOWN RotateMotor(OUT_B,45,185);  //腕を下げる
 
 
 task main()
 {
  ResetTachoCount(OUT_ABC);  //モーターABCの回転角をリセット
 /*コップをおろす*/
  DOWN;
 
  Wait(300);
 
 /*音で作業の終了を伝える*/
  PlaySound(SOUND_UP);
  Wait(100);
  PlaySound(SOUND_UP);
  Wait(100);
 
 
  Wait(1000);
 
 
 }

*結果 [#g22c049d]
**一回目 [#q6ca5af0]
スタートはうまくいきコップを掴むところまではスムーズにいけたが、玉を注ぐときに誤差が起きてしまい床に落ちてしまった。その後に予定外の動きをしてしまい、強制停止。
**二回目 [#l4f3b655]
一回目同様に無事にコップを掴み、今度は誤差なく2個とも玉を注ぐことができ、更にコップを元の位置に戻すことができた。しかし、2セットめはコップをつかめずに終わった。

*反省・考察 [#x47d3297]
**ロボットの反省・考察 [#x52d98a4]
ハサミと腕に1つずつモーターを使う仕組みは一番最初から変わっていないが、本体の走行部分と腕との接合部分は何度も何度も改良を繰り返すことになった。最初に作ったときに仕事を各パーツごとに分担したが、そのためにお互いの作ったパーツをあとから組み合わせたとき、自分が担当していない部分の仕組みがよくわからず、改良が余計に大変になってしまった。また、重心のバランスや全体としての強度を軽視してしまったため、後からどんどんパーツを付け足すことになり、結局直前に1から作り直すことになってしまった。実際にプログラムができてから設計ミスが見つかったりもしたので、先に色々な動きをさせて動作チェックをするべきだったと思う。

**プログラムの反省・考察 [#wee9dbbf]
自分はスレーブのプログラムを担当していたが、腕の動きは単純なものばかりであまり苦労はしなかった。しかし、bluetooth通信でつまずき、かなりの時間を無駄にしたあげくに結局原因を突き止めることができなかった。そのため、bluetoothでプログラムを起動して音で終了を伝えるという、少し変な仕組みで2機間のやりとりをすることになった。この作戦は思っていたよりも簡単に成功したため、少し驚いた。時間が迫っていてとてもピンチだったのでこのアイデアは素晴らしいと思った。~
今回はbluetooth通信を回避することで何とか動かすことができたが、自分の書いたプログラムのデバッグができなくては困るので、書くだけでなくチェックもできるようになりたい。


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