目次 #contents *[[課題の説明>2014a/Mission1]] [#ofbcff9d] *メンバー [#tbb423e0] -bgpat: 主にプログラム担当 -只の某: 主にロボット作成担当 *コースの作成 [#b0a98824] &ref(2014a/Member/bgpat/Mission1/course.png,400x300); このような画像ファイルを作成して何枚かのA4用紙に分けて印刷し、台紙に貼り付けました。 薄い部分は黒いペンで塗りつぶしました。 *ロボット本体 [#i40141cf] **ドライブベース [#i6612d7b] **アーム [#i7d72672] *プログラム [#xe5408e4] **定数の定義 [#rc89c212] コースやロボットによって値は異なります。 /* トレースのスピード */ #define SPEED_HIGH 40 #define SPEED_MEDIUM 30 #define SPEED_LOW 25 #define SPEED_ZERO 0 /* 直角の制御 */ #define TURN_COUNT_MAX 300 #define GO_COUNT_MAX 150 /* アームの制御 */ #define BALL_DISTANCE 9 #define BALLBAR_TIME 100 #define BALLBAR_WAIT 1000 #define BALLBAR_SPEED 50 **関数の定義 [#fabca395] コードの簡略化のための関数です。 /* * 左右のモーターを回す * スピードが正のときは前、負のときは後に回す */ void On(int leftSpeed, int rightSpeed){ if(leftSpeed > 0){ OnFwd(OUT_C, leftSpeed); }else{ OnRev(OUT_C, -leftSpeed); } if(rightSpeed > 0){ OnFwd(OUT_A, rightSpeed); }else{ OnRev(OUT_A, -rightSpeed); } } /* 赤外線センサーの値を5段階(0〜4)で返す */ bool Light(){ if(SENSOR_3 < 40){ return 0; }else if(SENSOR_3 < 44){ return 1; }else if(SENSOR_3 < 48){ return 2; }else if(SENSOR_3 < 52){ return 3; }else{ return 4; } } /* 止まる */ void Stay(){ Off(OUT_AC); } /* 前へ進む */ void GoForward(){ On(SPEED_HIGH, SPEED_HIGH); } /* 左へ進む */ void GoLeft(){ On(SPEED_ZERO, SPEED_MEDIUM); } /* 右へ進む */ void GoRight(){ On(SPEED_MEDIUM, SPEED_ZERO); } /* 左回転 */ void TurnLeft(){ On(-SPEED_LOW, SPEED_LOW); } /* 右回転 */ void TurnRight(){ On(SPEED_LOW, -SPEED_LOW); } /* 後ろへ戻る */ void Back(){ On(-SPEED_HIGH, -SPEED_HIGH); } /* 左後へ戻る */ void BackLeft(){ On(SPEED_ZERO, -SPEED_MEDIUM); } /* 右後へ戻る */ void BackRight(){ On(-SPEED_MEDIUM, SPEED_ZERO); } /* ボールを見つけるとtrueを返す */ bool checkBall(){ if(SensorUS(S1) <= BALL_DISTANCE){ return true; } return false; } /* ボールを覆う */ void catchBall(){ OnFwd(OUT_B, BALLBAR_SPEED); Wait(BALLBAR_TIME); Float(OUT_B); Wait(BALLBAR_WAIT); } /* ボールを離す */ void releaseBall(){ OnRev(OUT_B, BALLBAR_SPEED); Wait(BALLBAR_TIME); Float(OUT_B); Wait(BALLBAR_WAIT); } **メイン関数 [#j9bbb92a] task main(){ /* 回転数を記録するための変数 */ int turnCount = 0; /* 曲がりながら進んだ回数を記録するための変数 */ int goCount = 0; /* 直角の回数 */ int nCorner = 0; /* ボールを認識した回数 */ int ballCount = 0; /* センサー類を初期化 */ SetSensorLowspeed(S1); SetSensorLight(S3); while(true){ Wait(1); /* ボールを拾う処理 */ /* 直角1回目と2回目の間で、まだボールを拾っていない場合 */ if(nCorner == 1 && ballCount >= 0){ /* ボールを認識したら */ if(checkBall()){ PlayTone(880, 100); /* 1秒間ボールを認識すれば */ if(ballCount++ > 10){ /* ボールを拾う */ catchBall(); ballCount = -1; } /* ボールを認識している間はトレースを一時停止 */ Stay(); Wait(99); continue; }else{ ballCount = 0; } } /* トレース */ switch(Light()){ /* 明るさレベル0のとき */ case 0: TurnLeft(); if(turnCount < 0 || goCount < 0){ turnCount = 0; goCount = 0; } turnCount++; break; /* 明るさレベル1のとき */ case 1: GoLeft(); if(turnCount < 0 || goCount < 0){ turnCount = 0; goCount = 0; } goCount++; break; /* 明るさレベル2のとき */ case 2: GoForward(); break; /* 明るさレベル3のとき */ case 3: GoRight(); if(turnCount > 0 || goCount > 0){ turnCount = 0; goCount = 0; } goCount++; break; /* 明るさレベル4のとき */ case 4: TurnRight(); if(turnCount > 0 || goCount > 0){ turnCount = 0; goCount = 0; } turnCount++; break; } /* 直角判定 */ /* もし回転数が多く直進回数が少なければ */ if(turnCount > TURN_COUNT_MAX && goCount < GO_COUNT_MAX){ PlayTone(440, 100); switch(nCorner++){ /* 1,2,4回目の直角のとき */ case 0: case 1: case 3: /* 交差点を渡る */ TurnRight(); Wait(turnCount * 3); Off(OUT_AC); Wait(100); GoForward(); Wait(100); break; /* 5回目の直角のとき */ case 4: /* 向きを訂正して */ /* ボールを離す */ break; } turnCount = 0; goCount = 0; } } } *感想 [#n5075af2] なかなか思っている通りに動かず苦労しました。特に値の調整が大変でした。