#contents
*課題3 [#i7bb9d12]
今回の課題については[[2019a/Mission3]]の通りである。
&ref(./2019a-mission3-2.png,50%);
私たちは以下のルートで走行し、ボールを運搬するプログラムを作成することにした。
A'(出発) → K' → L'(ボール�,鬚弔�む) → K' → J'(ボール� ̄身卒偉�) → K' → M' → N' → N → B → M → K → L(ボール�△鬚弔�む) → K → J(ボール�△鰺憧錣貌�れる。容器を持ち上げる。) → C → B → N → C' → I' (ボール�↓��け身卒偉�)
*ロボットの構造 [#r33d348f]
**ロボット全体について [#i6e6edad]
&ref(./unnamed.jpg,20%);
今回のロボットは2台のNXTを通信してプログラムを制御するので、「2台のNXTを別々に制御する」または「2台のNXTを一体化させてロボットを作る」という2つの方針が考えられるが私たちは、2台のNXTを一体化させてロボットを作った。また、容器内のボールをつかむのは難しいと考えたので、ボールの入った容器ごと持ち上げ、ちゃぶ台返しのようにして容器内のボールを運搬することにした。その際、容器内のボールがどうしてもロボットに降りかかってしまうので、ロボットの上に坂を付け、ボールをロボットの上で転がすことで容器内のボールを運搬させることにした。
ボール�´△鬚弔�むアームと容器をつかむアームの計2つのアームを作った。
**ボールをつかむアーム [#zf3e8572]
&ref(./IMG_2712.jpeg,20%);
モーターを2つ使用した。1つはボールをつかみ、もう1つは上下に動かす役割をしている。
**容器をつかむアーム [#b5b9756c]
&ref(./IMG_2713.jpeg,20%);
ボールをつかむアームと同じ機構である。容器を落とさないためにアームにタイヤを計4つ付けた。
**ロボットに取り付けた坂 [#y9f7be16]
&ref(./IMG_2708.jpeg,20%);
アームを持ち上げたときの最高点にちょうど坂がくるようにした。
**光センサー [#rec52c42]
&ref(./IMG_2710.jpeg,20%);
写真にあるように光センサーを2つ使用した。
*プログラム [#ve457ea5]
**ライントレース [#rc18d139]
&ref(./hikari.png,50%);
上図のように線を2つの光センサーで挟んだ。
&ref(./hikari2.png,50%);
光センサーは図のような値をとった。この3つの値に、38と53の間の45と53と68のの間の60を加えて、光センサーの値を5段階に分けた。
課題2と同様に1つの光センサーを用いて下図のように光センサーの取る値とロボットの動きを対応させた。
&ref(./hikari3.png,50%);
ただし、交差点では2つの光センサーが38となるので、2つ光センサーが一定の時間38となったときに止まるようにした。また、この時間を変化させることで下図のような場所でも止まれるようにした。
&ref(./hikari4.png,50%);
**define [#f77fd09f]
***光センサーの取る値 [#qbf2e711]
#define BLACKS 38
#define BLACK 45
#define THRESHOLD 53
#define WHITE 60
#define WHITES 68
***光センサーに対応した動き [#ya1e3ee1]
#define left_s OnFwd(OUT_A,60);OnRev(OUT_B,60);
#define left OnFwd(OUT_A,60);Off(OUT_B);
#define right_s OnFwd(OUT_B,60);OnRev(OUT_A,90);
#define right OnFwd(OUT_B,60);Off(OUT_A);
#define forward OnFwd(OUT_AB,60);
***その他define [#y1f5da39]
#define CONN 1
#define SIGNALON1 10
#define SIGNALOFF1 11
#define SIGNALON2 20
#define SIGNALOFF2 21
#define SIGNALON3 30
#define SIGNALOFF3 31
#define HALF 1900
#define QUARTER 950
**サブルーチン(親機) [#gd0e715d]
***交差点で止まるプログラム(左側をライントレース) [#hd7cd065]
sub follow_line_left()
{
SetSensorLight(S1);
SetSensorLight(S2);
long t0=0,t1=0,stop_time=3;
while(t1-t0<stop_time){
if((SENSOR_1<BLACKS)&&(SENSOR_2<BLACKS)){
t0=CurrentTick();
forward;
until((SENSOR_1<THRESHOLD)&&(SENSOR_2<THRESHOLD));
t1=CurrentTick();
}else if(SENSOR_1<BLACKS){
left_s;
}else if(SENSOR_1<BLACK){
left;
}else if(SENSOR_1<THRESHOLD){
forward;
}else if(SENSOR_1<WHITE){
right;
}else if(SENSOR_1<WHITES){
right_s;
}
}
Off(OUT_AB);
Wait(1000);
}
***交差点で止まるプログラム(右側をライントレース) [#p6fbb547]
sub follow_line_right()
{
SetSensorLight(S1);
SetSensorLight(S2);
long t0=0,t1=0,stop_time=3;
while(t1-t0<stop_time){
if((SENSOR_1<BLACKS)&&(SENSOR_2<BLACKS)){
t0=CurrentTick();
forward;
until((SENSOR_1<THRESHOLD)&&(SENSOR_2<THRESHOLD));
t1=CurrentTick();
}else if(SENSOR_2<BLACKS){
right_s;
}else if(SENSOR_2<BLACK){
right;
}else if(SENSOR_2<THRESHOLD){
forward;
}else if(SENSOR_2<WHITE){
left;
}else if(SENSOR_2<WHITES){
left_s;
}
}
Off(OUT_AB);
Wait(1000);
}
***T字路で止まるプログラム(左側をライントレース) [#cedceab8]
sub follow_line_leftT()
{
SetSensorLight(S1);
SetSensorLight(S2);
long t0=0,t1=0,stop_time=1;
while(t1-t0<stop_time){
if((SENSOR_1<BLACKS)&&(SENSOR_2<BLACKS)){
t0=CurrentTick();
forward;
until((SENSOR_1<THRESHOLD)&&(SENSOR_2<THRESHOLD));
t1=CurrentTick();
}else if(SENSOR_1<BLACKS){
left_s;
}else if(SENSOR_1<BLACK){
left;
}else if(SENSOR_1<THRESHOLD){
forward;
}else if(SENSOR_1<WHITE){
right;
}else if(SENSOR_1<WHITES){
right_s;
}
}
Off(OUT_AB);
Wait(1000);
}
***T字路で止まるプログラム(右側をライントレース) [#de88804b]
sub follow_line_rightT()
{
SetSensorLight(S1);
SetSensorLight(S2);
long t0=0,t1=0,stop_time=1;
while(t1-t0<stop_time){
if((SENSOR_1<BLACKS)&&(SENSOR_2<BLACKS)){
t0=CurrentTick();
forward;
until((SENSOR_1<THRESHOLD)&&(SENSOR_2<THRESHOLD));
t1=CurrentTick();
}else if(SENSOR_2<BLACKS){
right_s;
}else if(SENSOR_2<BLACK){
right;
}else if(SENSOR_2<THRESHOLD){
forward;
}else if(SENSOR_2<WHITE){
left;
}else if(SENSOR_2<WHITES){
left_s;
}
}
Off(OUT_AB);
Wait(1000);
}
***その他サブルーチン [#f6458069]
sub start_right()
{
right;
Wait(500);
}
sub start_left()
{
left;
Wait(500);
}
***子機に命令を出すプログラム [#f6458069]
sub send_msg1()
{
int msg;
while(msg!=SIGNALOFF1){
SendRemoteNumber(CONN,MAILBOX1,SIGNALON1);
ReceiveRemoteNumber(MAILBOX1,true,msg);
}
}
sub send_msg2()
{
int msg;
while(msg!=SIGNALOFF2){
SendRemoteNumber(CONN,MAILBOX2,SIGNALON2);
ReceiveRemoteNumber(MAILBOX2,true,msg);
}
}
**サブルーチン(子機) [#x7ba3b6f]
***ボールをつかむプログラム [#a7ed61f9]
sub ball_catch1()
{
OnFwd(OUT_A,40);
Wait(200);
OnRev(OUT_B,50);
Wait(500);
OnRev(OUT_A,60);
Wait(700);
Off(OUT_AB);
}
sub receive_msg1()
{
int msg;
while(msg!=SIGNALON1){
ReceiveRemoteNumber(MAILBOX1,true,msg);
}
ball_catch1();
PlaySound(SOUND_UP);
SendResponseNumber(MAILBOX1,SIGNALOFF1);
}
***ボールを容器に入れるプログラム [#i70e3e81]
sub ball_throw1()
{
OnFwd(OUT_A,40);
Wait(100);
OnFwd(OUT_B,50);
Wait(500);
OnRev(OUT_A,60);
Wait(700);
Off(OUT_AB);
}
sub receive_msg2()
{
int msg;
while(msg!=SIGNALON2){
ReceiveRemoteNumber(MAILBOX2,true,msg);
}
ball_throw1();
PlaySound(SOUND_UP);
SendResponseNumber(MAILBOX2,SIGNALOFF2);
}
**プログラム全体(親機) [#n1632a72]
task main()
{
follow_line_leftT();//A'からK'へ
right_s;
Wait(200);
forward;
Wait(900);
Off(OUT_AB);//L’へ
send_msg1();//子機でボールをつかむ
right_s;
Wait(HALF);
follow_line_right();//J'へ
send_msg2();//ボールを容器に入れる
}
**プログラム全体(子機) [#m32a04fa]
task main()
{
receive_msg1();//ボールをつかむ
receive_msg2();//ボールを容器に入れる
}
*反省と感想 [#te26a530]
今回の課題ではロボット製作に力を入れてしまい、1つのボールを容器に入れるところまでしかプログラムを作れなかった。また、本番ではその1つのボールさえ容器に入れることができなかった。その理由は光センサーの値の調整がしっかり出来ていなかったことだと思う。
今回の課題ではロボット製作に力を入れてしまい、1つのボールを容器に入れるところまでしかプログラムを作れなかった。また、本番ではその1つのボールさえ容器に入れることができなかった。その理由は光センサーの値の調整がしっかり出来ていなかったことだと考えられる。
今回の課題は今まで授業で学んだことの集大成であり、ロボット制御の基礎や問題解決力を身につけることができた。