#author("2020-02-15T19:31:02+09:00","shin","shin")
#author("2020-02-15T19:41:46+09:00","shin","shin")
[[2019b/Member]]
目次
#contents

*課題3 [#r089c92b]
青と赤のボールを運搬して、空き缶の上に載せる。
#ref(2019b/Member/shin/Mission3/Kadai3-1.png,100%)
C、E、Fに置いてある空き缶の上のボールを、C’、E’、F'に置いてある空き缶の上に運搬する。

*ロボットの説明 [#x2f2f9a2]
一度で全てのボールを回収し、運搬するロボットを作成した。
#ref(2019b/Member/shin/Mission3/Kadai3-2.jpeg,50%)
#ref(2019b/Member/shin/Mission3/Kadai3-3.jpeg,50%)
超音波センサでボールを認識すると、バーが降り空き缶を固定することで確実にボールを回収できるようにした。三つの棒がある回転部分でボールの回収と、設置を行う。ライントレースをしやすいように、ライトセンサは二つ用いた。

*プログラムの説明 [#n61b7fdf]
**マスター側 [#dd1671bb]
***定義 [#rae60623]
 //left  sensor:S1    motor:C
 //right sensor:S2    motor:B
 #define CONN 1    //1のスレーブNXTと通信(マスターは0)
 #define grayS1 50    //左ライトセンサの基準
 #define grayS2 45    //右ライトセンサの基準
 #define blackS1 45    //左ライトセンサの基準
 #define blackS2 40    //右ライトセンサの基準
 int fast = 50;    //モータのスピード(直線)
 int slow = 30;    //モータのスピード(曲線)
***ライントレース [#r2afc9b2]
 void lineFollow(int breaksensor)    //S1:0, S2:1, S1+S2:2, S4:3
 {
    SetSensorLight(S1);
    SetSensorLight(S2);
    SetSensorLowspeed(S4);
    int lightL, lightR, dist = 100
    while(true){
        lightL = SENSOR_1;    //左ライトセンサの値
        lightR = SENSOR_2;    //右ライトセンサの値
        if((lightL>grayS1) && (lightR>grayS2)){
            OnFwdSync(OUT_BC, fast, 0);    //直線
        }else if((lightL>grayS1) && (lightR<grayS2)){
            OnFwdSync(OUT_BC, slow, 50);    //右へ
        }else if((lightL<grayS1) && (lightR>grayS2)){
           OnFwdSync(OUT_BC, slow, -50);    //左へ 
        }
        if((breaksensor == 0) && (lightL<blackS1)) break;    //左線の交差点判断
        if((breaksensor == 1) && (lightR<blackS2)) break;    //右線の交差点判断
        if((breaksensor == 2) && (lightL<grayS1) && (lightR<grayS2)) break;    //左右線の交差点判断
        if((breaksensor == 3) && (SensorUS(S4)<10)) break;    //空き缶判断
    }
    Off(OUT_BC);
 }
***右折、左折 [#y475e025]
 void turnLeft(int deg){
    SetSensorLight(S1);
    SetSensorLight(S2);
    RotateMotorEx(OUT_BC, fast, -deg, 0, true, true);
    RotateMotor(OUT_B, fast, 400);
    until((SENSOR_1>grayS1) && (SENSOR_2>grayS2)){
        OnFwd(OUT_B, fast);
    }
    Off(OUT_BC);
 }

 void turnRight(int deg){
    SetSensorLight(S1);
    SetSensorLight(S2);
    RotateMotorEx(OUT_BC, fast, -deg, 0, true, true);
    RotateMotor(OUT_C, fast, 400);
    until((SENSOR_1>grayS1) && (SENSOR_2>grayS2)){
        OnFwd(OUT_C, fast);
    }
    Off(OUT_BC);
 }
***マスターからスレーブへ [#d64e8c95]
 void sendMessage(int number){
    int val = 0;
    SendRemoteNumber(CONN, MAILBOX1, number);
    until(val == number){
        ReceiveRemoteNumber(MAILBOX2, true, val);
    }
 }
***メイン [#p4b3dd00]
 task main(){
    SetSensorLight(S1);
    SetSensorLight(S2);
    int val = 0;
    until(BluetoothStatus(CONN) == NO_ERR);    //スレーブと接続できるまで待つ
    RemoteStartProgram(CONN, "lineFollow_s.rxe");    //スレーブプログラム開始
 //ボール1回収
    RotateMotorEx(OUT_BC, fast, 180, 0, true, true);
    lineFollow(3);
    sendMessage(11);
    RotateMotorEx(OUT_BC, fast, 400, 0, true, true);
    sendMessage(1);
    sendMessage(12);
 //ボール2回収
    RotateMotorEx(OUT_BC, fast, -500, 0, true, true);
    lineFollow(1);
    turnRight(40);
    lineFollow(2);
    RotateMotorEx(OUT_BC, fast, 70, 0, true, true);
    lineFollow(3);
    sendMessage(11);
    sendMessage(2);
    sendMessage(12);
 //ボール3回収
    turnLeft(270);
    lineFollow(2);
    turnRight(30);
    lineFollow(3);
    RotateMotorEx(OUT_BC, fast, -150, 0, true, true);
    OnFwdSync(OUT_BC, fast, 0); 
    lineFollow(3) ;
    sendMessage(11);
    sendMessage(3);
    sendMessage(12);
 //ボール3置く
    turnRight(270);
    lineFollow(2);
    RotateMotorEx(OUT_BC, fast, 70, 0, true, true);
    lineFollow(2);
    turnLeft(40);
    lineFollow(1);
  
    turnRight(40);
    lineFollow(2);
    RotateMotorEx(OUT_BC, fast, 70, 0, true, true);
    lineFollow(2);
    turnRight(40);
    lineFollow(3);
    RotateMotorEx(OUT_BC, fast, -150, 0, true, true);
    OnFwdSync(OUT_BC, fast, 0);
    lineFollow(3);
    sendMessage(11);
    sendMessage(4);
    sendMessage(12);
 //ボール2置く
    turnRight(290);
    lineFollow(2); 
    turnLeft(50); 
    lineFollow(3);
    RotateMotorEx(OUT_BC, fast, -150, 0, true, true);
    OnFwdSync(OUT_BC, fast, 0);
    lineFollow(3);
    sendMessage(11);
    sendMessage(5);
    sendMessage(12);
 //ボール1置く
    RotateMotor(OUT_C, fast, -400);
    RotateMotor(OUT_B, fast, 400);
    until((SENSOR_1>grayS1) && (SENSOR_2>grayS2)){
        OnFwd(OUT_B, fast);
    }
    Off(OUT_BC);
    lineFollow(3);
    RotateMotorEx(OUT_BC, fast, -200, 0, true, true);
    OnFwdSync(OUT_BC, fast, 0);
    lineFollow(3);
    sendMessage(11);
    sendMessage(6);
    sendMessage(12);
    RotateMotorEx(OUT_BC, fast, -100, 0, true, true);
    SendRemoteNumber(CONN, MAILBOX1, 21);
 }
**スレーブ側 [#d178a8b9]
***定義 [#cbc3c4a7]
 #define CONN 0
 #define barDown RotateMotor(OUT_C, 100, 500)    //固定棒下げる
 #define barUp RotateMotor(OUT_C, 100, -500)    //固定棒上げる
***ボールの回収と設置 [#d87faba8]
 void ball(int count = 0){
    if(count == 1) RotateMotor(OUT_B, 40, 430);    //ボール回収
    if(count == 2) RotateMotor(OUT_B, 40, 330);    //ボール回収
    if(count == 3) RotateMotor(OUT_B, 40, 460);    //ボール回収
    if(count == 4) RotateMotor(OUT_B, 40, -460);    //ボール放す
    if(count == 5) RotateMotor(OUT_B, 40, -330);    //ボール放す
    if(count == 6) RotateMotor(OUT_B, 40, -430);    //ボール放す
 }
***メイン [#wb3b4192]
 task main(){
    int val=0, oldval;
    while(true){
        ReceiveRemoteNumber(MAILBOX1, true, val);
        if(val != oldval){
            if((val>0) && (val<10)){
                ball(val);
            }else if(val == 11){
                barDown;
            }else if(val == 12){
                barUp;
            }else if(val == 21){
                break;
            }
            SendResponseNumber(MAILBOX2, val);
        }
        oldval = val;
    } 
 }

*まとめ [#l51d1cd7]
今回の課題3は、期末テストがあったり自分が風邪をひいてしまったりであまり製作に参加できなくて残念だった。自分はこの先、プログラミングをしたりするようなことはなかなかないと思うが、半年間やってみてとても面白かったし良い経験ができたと思う。

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