- 追加された行はこの色です。
- 削除された行はこの色です。
[[2014a/Member]]
目次
#contents
* 課題の説明 [#mffb653f]
詳しい説明は[[2014a/Mission1]]を参照
写真の入れかた例え:&ref(2014a/Member/mame/Mission1/sample2-small.jpg.30%);
私はスタート→ゴールの順路をたどった。
* メンバー [#j0ee8e63]
mame
dai
* ロボット本体 [#g0b2bc6e]
&ref(2014a/Member/mame/Mission1/__(1).JPG,70%);
シンプルに作りあげたので容易に取り外し&取り付けが可能。
** ライトセンサー [#jf97ef47]
車体の軸に近づけるように地面に垂直にライトが当たるように工夫した。
** ドライブベース [#ta82ecff]
&ref(2014a/Member/mame/Mission1/__(5).JPG,70%);
&ref(2014a/Member/mame/Mission1/__(3).JPG,70%);
** アーム [#qa948bf2]
* 課題 [#ff560aa8]
クレーン車のようにすくい上げる。
&ref(2014a/Member/mame/Mission1/ペイント1.jpg,40%);
青く囲んだのがアームです。
&ref(2014a/Member/mame/Mission1/image(1).jpeg,70%);
↑つかんだ直後の状態
シュートをする場合はアームを強めに逆回転させてボールを打ちます。
* プログラム [#w9871f04]
** 一連の動作 [#rb37cd95]
黒い線に乗る→
線の右側トレース→
動き始めてから8秒経ったところでボールをつかむ→
動き始めてから29秒経ったところでボールをシュート
** プログラムの概要 [#v140454d]
#define SPEED_HIGH 40
#define SPEED_MEDIUM 30
#define SPEED_LOW 25
#define SPEED_ZERO 0
定義
#define THRESHOLD 39//しきい値
#define SPEED_H 43//最も早い速度
#define SPEED_L 30//最も遅い速度
#define OnRL(speedR,speedL);OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); //右・左車輪のスピード
#define go_forward OnRL(SPEED_H, SPEED_H); //前進のスピード
#define turn_left1 OnRL(SPEED_L, -SPEED_L); //左旋回
#define turn_left0 OnRL(SPEED_H, 0); //左に曲がる
#define turn_right0 OnRL(0, SPEED_H); //右に曲がる
#define turn_right1 OnRL(-SPEED_L,SPEED_L); //右に旋回
#define STEP 1 //白と黒の境界をセンサが読む時間(1/1000秒)
#define nMAX 300 //通常のカーブとして許容できる繰り返しの最大値
#define short_break Off(OUT_BC); Wait(1000); //小休止
#define CROSS_TIME 100 //交差点通過にかかる時間
#define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; //交差点を渡る
#define Catch Off(OUT_BC); OnFwd(OUT_A,40);Wait(500);Off(OUT_A) //アームを前に回し、ボールを取る
#define Shot Off(OUT_BC);OnRev(OUT_A,70);Wait(500);Off(OUT_A) //アームを後ろに回し、ボールを打つ
#define TURN_COUNT_MAX 300
#define GO_COUNT_MAX 150
#define Catch OnFwd(OUT_A,70);Wait(700);Off(OUT_A);
#define shoot OnRev(OUT_B,100);Wait(1000);Off(OUT_B);
#define Catch OnFwd(OUT_B,70);Wait(700);Off(OUT_B);
#define go_forward OnFwd(OUT_AC,50);
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);
}
}
void GoForward(){
On(SPEED_HIGH, SPEED_HIGH);
}
**基本のプログラム [#ea65873e]
task main()
{
SetSensorLight(S1); //光センサーをセット
SetSensorLowspeed(S4); //超音波センサーをセット
int nOnline=0; //黒い線になった回数
long t0 = CurrentTick(); //時間を計算する。
スタート地点にはコースがないため、少し進んでコースに乗せる
OnFwd(OUT_BC,40);
Wait(500);//白い枠から出るために少し進む
void GoLeft(){
On(SPEED_ZERO, SPEED_MEDIUM);
}
while (CurrentTick() <= 29000) { //動き始めてから29秒以内の時の場合
while (nOnline < nMAX) { //カウンターの回数がnMAXを越えないとき
void GoRight(){
On(SPEED_MEDIUM, SPEED_ZERO);
}
ここでシュートとキャッチをする時間を定める
void TurnLeft(){
On(-SPEED_LOW, SPEED_LOW);
}
if(CurrentTick()- t0 == 8000){Catch} //動き始めてから8秒の時にボールをつかむ
if(CurrentTick()- t0 == 29000){Shot} //動き始めてから29秒の時にボールを打つ
void TurnRight(){
On(SPEED_LOW, -SPEED_LOW);
}
**ライントレースのプログラム [#r00dac4b]
右側をトレースする。
void Back(){
On(-SPEED_HIGH, -SPEED_HIGH);
}
光センサーが黒と判断したときにカウントを増やすカウンターを使い、カウンターがnMAXを越えないときは直角カーブをし、nMAXを越えたときに交差点と判断し、通過する。
void BackLeft(){
On(SPEED_ZERO, -SPEED_MEDIUM);
}
void BackRight(){
On(-SPEED_MEDIUM, SPEED_ZERO);
}
bool Light(){
if(SENSOR_1 < 28){
return 0;
}else if(SENSOR_1 < 35){
return 1;
}else if(SENSOR_1 < 40){
return 2;
}else if(SENSOR_1 < 45){
return 3;
}else{
return 4;
if (SENSOR_1 < THRESHOLD -14) { //黒の場合
turn_left1; //左に旋回
Online++; //カウンターを増やす
} else {
if (SENSOR_1 < THRESHOLD-8) { //やや黒の場合
turn_left0; //左に曲がる
} else if (SENSOR_1 < THRESHOLD-3) { //やや白の場合
go_forward; //直進
} else if (SENSOR_1 < THRESHOLD +8) { //白の場合
turn_right0; //右に曲がる
} else {
turn_right1; //右に旋回
}
nOnline=0; //カウントをリセットする
}
Wait(STEP); //(1/1000秒待機)
}
}
short_break; //小休止
turn_right1; Wait(nMAX*STEP); //進行方向修正
cross_line; //交差点を渡る
nOnline=0; //カウントをリセットする
}
}
task main()
{
{SetSensorLowspeed(S4);
go_forward;
* 反省と感想 [#a4021e1b]
if(SensorUS(S4) <=8) { Catch;Off(OUT_BC); }
}
プログラミングは初めてだったので難しかった。しきい値が安定しにくかった。成功率がとても低い。
車体の前半分が重すぎてバランスがとれないこともあった。場所や条件により交差点を認知しない場合がある。
{ int turnCount = 0;
int goCount = 0;
int nCorner = 0;
SetSensorLight(S1);
while(true){
Wait(1);
switch(Light()){
case 0:
TurnLeft();
if(turnCount < 0 || goCount < 0){
turnCount = 0;
goCount = 0;
}
turnCount++;
break;
case 1:
GoLeft();
if(turnCount < 0 || goCount < 0){
turnCount = 0;
goCount = 0;
}
goCount++;
break;
case 2:
GoForward();
break;
case 3:
GoRight();
if(turnCount > 0 || goCount > 0){
turnCount = 0;
goCount = 0;
}
goCount++;
break;
case 4:
TurnRight();
if(turnCount > 0 || goCount > 0){
turnCount = 0;
goCount = 0;
}
turnCount++;
break;
break;
}
if(turnCount > TURN_COUNT_MAX && goCount < GO_COUNT_MAX){
PlayTone(440, 100);
switch(nCorner++){
case 0:
case 1:
case 3:
TurnRight();
Wait(turnCount * 3);
Off(OUT_AC);
Wait(100);
GoForward();
Wait(100);
break;
case 4:OnRev(OUT_A,100);Wait(1000);Off(OUT_B);
}
turnCount = 0;
goCount = 0;
}
}
}
}
赤外線センサーを用いたが、車体が長すぎてセンサーとボールが反応しない。
** ライントレースのプログラム [#r829ca55]
時間を計るのではなく交差点の数を数え、その数に応じてボールをつかむなどのプログラムを作れば成功率を上げられたと思う。
** ボールをつかむプログラム [#gad1054c]
授業外においてとても時間がかかってしまったので細かい作業も効率よく行えると良かったと思う。
電池の残量によって結果が変わってしまうこともあった。
** ボールを放つ(シュートする)プログラム [#vc7dbfbf]
超音波センサーを取り付けたが、機体と玉の距離の関係上、反応しないことが多かった。
task main()
{
OnFwd(OUT_BC);
}
** 良い点 [#l6b3d7cb]
・ライトセンサーを車体の軸に近づけるように工夫することでプログラム通りにライントレースをすることができた。
** 反省と感想 [#a4021e1b]
・機体自体の取り付け&取り外しが容易なのですぐに作業に入ることができた。
難しかった。しきい値が安定しなかった。
・しきい値を細かく調整することでスムーズにライントレースをすることができた。
・アームを回転させてキャッチ&シュートをする案は確実性が増し、非常に良かったと思う。