[[2013b/Member]]
*ライントレースをしながら缶を積んでいくロボット [#bc98846e]

#contents

**メンバー紹介 [#g1ae963c]
・chikuwa~
このページの執筆者。その辺に転がってる普通の大学生。謎のプログラムを書く。~

chikuwaの前回の課題ページはこちら~
[[2013b/Member/chikuwa/Mission1]]

・Pianoman~
主にプログラム担当。Macを自由自在に操り、華麗にプログラムを打ち込んでいく。~
簡潔で無駄のないプログラムを書く技術に定評がある。~

Pianoman氏の今回の課題のページはこちら~
[[2013b/Member/Pianoman/Mssion2]]


・Redcicudu~
主にハード担当。ロボットの半分は彼の優しさでできています。~
尚、ロボットの作成や練習には彼の部屋を度々使用させてもらった。本当にありがたいことである。~

Redcicudu氏の今回の課題のページはこちら~
[[2013b/Member/Redcicudu/Mission2]]

**はじめに [#ha42c211]

前回の失敗を踏まえ、今回はクリアしなければいけない課題を細かく分けてひとつずつクリアさせ~
最終的にそれらを統合して課題の解決を目指す。

具体的には今回の課題の難点は次のように分類できる。

・ライントレース

・缶の発見

・缶の積み上げ

・缶を積んだ状態での移動

・2つのNXTの連携

まずはこれらを一つずつつぶしていく。

**ロボットの制作 [#u1e286d7]

***大まかな指針 [#z62c2ee3]

Φまず缶をどのように積むか?~
→クレーン式?フォークリフト式?アームの上げ下げ式?2台に分けて作業分担?~

結論:アームの上げ下げ式。因みにアームは水平移動しない。~

理由:いろいろと試した結果、ほかの方法ではパーツが足りない。また缶を掴む際にしっかり掴めない。~

Φ主に使う部品~

モーター数:4つ~
(タイヤ:2つ、缶の上げ下げ:1つ、缶を掴む,離す:1つ)

NXT本体:2つ(←モーターを4つ使うため)

用いるセンサ:光センサ、超音波センサ~
(光センサ⇀ライントレースに使用、超音波センサ⇀缶の発見に使用)



***試作機 [#y7066b49]

&ref(2013b/Member/chikuwa/Mission2/試作機.jpg,70%,試作機);

↑NXTが不安定なうえに、前が重くなりがち...~
この頃はドライブベースはchikuwa、アームの上げ下げ部はRedcicudu氏、~
(写っていないが)アームのキャッチ部はPianoman氏が担当している。~


&ref(2013b/Member/chikuwa/Mission2/ball.jpg,30%,ball);

↑こんな風に後輪の代わりにボールを使う方法も最初は考えていた。~
しかしボールを転がすというより引きずる感じになってしまったので、この案は却下となった。~

Φ問題点

上図ではまだアームの掴む部分をつけていないが、もしこの状態でそれをつけると重みで本体が前に傾く可能性がある。~
また中央部がスカスカなのでもう一台NXTをつけると重みで機体が沈む。

Φ改善

そこで土台の隙間をさらにうめて、NXTを倒した状態で2つくっつけてみた。~
重心を前回より後方にすることで安定度が向上するようにしてみた。


そして次のような完成品が出来上がった。

***完成品 [#vce5cfa4]

Φ全体

&ref(2013b/Member/chikuwa/Mission2/完成品.jpg,70%,完成品);

↑アームをつけた状態で前に倒しても前のめりになることは無かった。~
超音波センサは縦に取り付けた方が感度が正確になるらしので、縦に取り付けてみた。~
ちなみに、主な製作者はRedcicudu氏である。~
NXT本体2つは通信させながら使用する。~

役割分担としては~
Masater側がタイヤ、光センサ、超音波センサを司り、~
Slave側が缶のキャッチ、上げ下げを司る。

Φ後部

&ref(2013b/Member/chikuwa/Mission2/後ろ.jpg,50%,後ろ);

↑赤丸で示したように小さなタイヤ二つをつけた。これはきちんと360°回転する。~
四輪駆動も試してみたが、カーブが曲がり切れなかったため最終的にこの方法を採用した。~
試しに動かしてみたところ、ゆっくりではあるがきちんと機体は一回転した。

Φアーム部

&ref(2013b/Member/chikuwa/Mission2/アーム部.jpg,50%,アーム部);


&ref(2013b/Member/chikuwa/Mission2/アーム部の正面.jpg,50%,アーム部の正面);


↑初めは、キャッチしても缶の重みでアームをすり抜けてしまうことが多かったが、~
ゴムをつけると安定して掴めるようになった。


**まずはアームだけで非常に簡単な動作を... [#y0ce77a6]

最初は二台のNXTの通信がうまく行くかどうか確かめる目的も兼ねて、~
アームを動かす練習をしてみる。

とりあえずは
 
 アームを下ろす→前進→缶をキャッチ→アームを上げる

という非常に単純な動作をさせてみる。

アームを下ろしたあと機体を前進させたのは、機体と缶の間にできる隙間をなくすためである。

また予め、モーターの角度を測るプログラムを用いてアームの上げ下げ、缶のキャッチ・リリースに~
必要な角度を計算しておき、命令"RotateMotor"を用いてみた。

***ソースコード [#b3c744af]

✡マスター(M)側
 #define CONN 1
 #define SIGNALON 11
 task main()
 {
  RotateMotor(OUT_B,75,4270);//アームを下げる
  SendRemoteNumber(CONN,MAILBOX1,SIGNALON);
    /*Sのメールボックス1にSIGNALON(1)を送信*/
  Off(OUT_AB);Wait(3000);//3秒間待機
  RotateMotor(OUT_A,85,-110);//缶をキャッチ
  RotateMotor(OUT_B,75,-4270);//アームを上げる
  }

✡スレイブ(S)側
 #define SIGNALON 11
 task main()
 {
  int msg;
  while(true){
  ReceiveRemoteNumber(MAILBOX1,true,msg);
    /*Mからメールボックス1にメッセージを受信*/
  if(msg==SIGNALON){//もし受け取ったメッセージがSIGNALON(11)なら
  OnFwd(OUT_AB,60);Wait(1000);//1秒前進
  }else{
   Off(OUT_AB);
   }
  }
 }

***結果 [#ee77c618]

うん。きちんと通信して、プログラム通りに動いてくれた。~
通信がうまく行ったようだ。~


Δ下ろし中~

&ref(2013b/Member/chikuwa/Mission2/下ろし中_加工済み.png,30%,下ろし中_加工済み);


モーター回転部(黄色の丸)は、おおよそ赤色で示したような軌跡を描く。~


Δ下ろし終わり~

&ref(2013b/Member/chikuwa/Mission2/下ろし終わり_加工済み.png,30%,下ろし終わり_加工済み);


赤丸で示したようにこのままだと隙間ができてしまう。~


Δ前進~

&ref(2013b/Member/chikuwa/Mission2/前進します_加工済み.png,30%,前進します_加工済み);


隙間を埋めるため少しだけ前進。~


Δキャッチ~

&ref(2013b/Member/chikuwa/Mission2/キャッチします.PNG,30%,キャッチします);


離さない様かなり強めの出力でキャッチ。~


Δ上げ終わり

&ref(2013b/Member/chikuwa/Mission2/上げ終わりました.PNG,30%,上げ終わりました);


ずり落ちることもなく、缶は上部へ~



***わかった事 [#k56bf0ae]

・"RotateMotor"がとても便利、モーターの出力を変えるたびに、~
 わざわざ動かす時間を変更しなくても良い。

・モーターに直接ギアをつけるのではなく、いくつか歯車を経由してるので、~
 動きが意外と遅かった。

・二台の通信に少し時間がかかる。

**次に超音波センサを用いて... [#cb057c59]
次は超音波センサの有効範囲確認のため、そしてスレイブ側からマスター側に値を送る練習のため、

 前進→缶を発見→アームを下ろす→前進→缶を掴む→缶を上げる→前進

という前回より少しだけ手間のかかる動作を出来るようにする。~
計4回も通信するので少し不安だが、テキストを参考に見様見真似で作ってみた。

計4回の内訳は~
M側からS側へ・・・2回~
S側からM側へ・・・2回~

各NXTが出す指令をまとめると次のようになる。

&ref(2013b/Member/chikuwa/Mission2/flowchart.PNG,55%,flowchart);



***ソースコード [#nf18e47f]
✡マスター側
 #define CONN 1
 #define SIGNAL_A 11
 #define SIGNAL_B 12
 #define SIGNAL_C 13
 #define SIGNAL_D 14
 #define go_forward OnFwd(OUT_AB,60);
 task main()
 {
  SetSensorLowspeed(S1);
  int msg;
  int msg_2;
  go_forward;
  if(SensorUS(S4)<10){//もし10センチ以内に缶を発見したら
   SendRemoteNumber(CONN,MAILBOX1,SIGNAL_A);
     /*Sのメールボックス1にSIGNAL_Aを送信*/ 
   ReceiveRemoteNumber(MAILBOX2,true,msg);
     /*Sからメールボックス2にメッセージを受信*/
    if(msg==SIGNAL_B){ //もしSIGNAL_Bを受信したら
     OnFwd(OUT_AB,60);Wait(1000);//1秒間前進
     SendRemoteNumber(CONN,MAILBOX3,SIGNAL_C);
       /*Sのメールボックス3にメッセージを送信*/
     ReceiveRemoteNumber(MAILBOX4,true,msg_2);
       /*Sからメールボックス4にメッセージを受信*/
      if(msg_2==SIGNAL_D){//もしメッセージがSIGNAL_Dなら
       go_forward;Wait(2000);//2秒前進         
       } 
     }
    }
 } 
 
&#10017;スレイブ側
 #define CONN 1
 #define SIGNAL_A 11
 #define SIGNAL_B 12
 #define SIGNAL_C 13
 #define SIGNAL_D 14
 task main()
 {
  int msg;
  int msg_2; 
  ReceiveRemoteNumber(MAILBOX1,true,msg);
   /*Mからメールボックス1にメッセージを受信*/
   if(msg==SIGNAL_A){//もしメッセージがSIGNAL_Aなら
    RotateMotor(OUT_B,75,4270);//アームを下ろす
    SendResponseNumber(MAILBOX2,SIGNAL_B);
     /*Mのメールボックス2にSIGNAL_Bを送信*/
    Off(OUT_AB);Wait(1000);//1秒間待機
    ReceiveRemoteNumber(MAILBOX3,true,msg_2);
     /*Mからメールボックス3にメッセージを受信*/
     if(msg_2==SIGNAL_C){//もしメッセージがSIGNAL_Cなら
      RotateMotor(OUT_A,85,-110);//缶を掴む
      RotateMotor(OUT_B,75,-4270);//アームを上げる
      SendResponseNumber(MAILBOX4,SIGNAL_D);
       /*Mのメールボックス4にSIGNAL_Dを送信*/
      }
     }
 }
***結果 [#s68379b6]

**トラブル発生? [#pec92f86]
ここでNXTに文法は合っているのにプログラムが送れないとうい事態が発生!!!~
ピアサポートセンターに行って直接先生にお聞きしてみたところ、NXTの容量がいっぱいになっているとご指摘いただきました。~
どうせもう使わないだろうし、一応USBにプログラムは入っているのでデータすべて削除!~
改めて送信してみると...ピッ。~
ちゃんと遅れました。一安心です。


**缶をどうやって見つけるか? [#g7b05218]

**ライントレースはどうする? [#k30a9f9a]

**それぞれの動きを一つのプログラムに [#k9b438c5]

**作戦 [#he6efb51]
***ルート決め [#o108ae07]
***狙う缶はお前だ! [#g0c1bf86]

**プログラム、ハードの再確認 [#u9170ed6]

**リハーサル [#e20b40a7]

**忍びくる魔の手 [#y120fa93]

**心を一つに [#c48c4f12]

**そして本番へ [#i4d35266]

**天国か地獄か [#v48459b0]

**全体を振り返って [#eb8f9122]

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