2017b/Member/ats/Mission3
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#contents
*1.課題 [#hc472796]
課題はピンポン玉とカップを動かし、別々の場所に置くことが...
#ref(2017b/Member/ats/Mission3/コース.JPG,コース全体)
上の図のようにピンポン玉とカップが配置されている。X地点に...
*2.ロボット [#a012d606]
**ロボット全体 [#yb3111b9]
カップとピンポン玉を分けつつ動かせるようなロボットを1台作...
#ref(2017b/Member/ats/Mission3/ロボット全体.JPG,ロボット...
上の写真のように2つのロボット本体を横にして縦に重ねた。(...
左右の前輪はモーターで動かせるようにして、後ろには左右両...
ロボットの大まかな動きは下のようになる。
1.カップを探し、アームで掴む。掴んだ後にカップを少しだけ...
#ref(2017b/Member/ats/Mission3/カップ移動.JPG,70%,カップ...
2.カップをX地点の枠内まで持ってきて、アームを完全に上げる。
3.カップをY地点の枠内で降ろして離す。
4.2個目以降のときはY地点でセンサーを働かせて1個目のカップ...
**アーム(カップを掴む機構)[#t91fb2a7]
アームには2つのモーターを使った。1つを「つかむ」動作に、...
#ref(2017b/Member/ats/Mission3/アーム.JPG,アーム可動方向)
***つかむ機構 [#x88d9d77]
つかむ部分の構造はクワガタ方式を使った。歯車を4つ用いて、...
#ref(2017b/Member/ats/Mission3/歯車、ハサミ.JPG,クワガタ...
↑この時は手が開く方向に歯車が回っているが、モーターを逆回...
下の写真のように4つのタイヤを使って確実にカップを固定でき...
↓左がきつく締める前、右がきつく締めた後のもの。
&ref(2017b/Member/ats/Mission3/つかむ動作前.jpg,left,50%,...
&ref(2017b/Member/ats/Mission3/つかむ動作後.jpg,right,50%...
***アームの補強 [#wcdc4fb6]
腕の先に重いモーターが付いている構造となっているため、上...
#ref(2017b/Member/ats/Mission3/アーム補強.JPG,アームを支...
**センサー [#ce6a61eb]
ライントレース用の光センサーとカップ探査用の距離センサー...
#ref(2017b/Member/ats/Mission3/センサー.JPG,センサー位置)
*3.プログラム [#o29f8dd7]
プログラムを考えるうえで重要になってくることは以下の2点だ。
1.ピンポン玉の入ったカップや障害物をなるべくずらさないよ...
2.黒線を上手く利用してロボットが確実に走行できること。(〇...
それを考慮に入れたルートが下の図の赤の矢印のようになる。(...
#ref(2017b/Member/ats/Mission3/ルートと番号.JPG,ルートと...
玉の入ったカップに上の図のように番号を付けた。(青背景の吹...
この先は計画で終わってしまったため、ここには1番のカップを...
ロボット本体の役割の分担が以下のようになる。
マスター;ライントレース、カップ探査など
スレーブ;カップの上げ下げ、アームの手の開け閉めなど
**ライントレース [#i9e38461]
ロボットが走行などをするときのために止まるプログラムを書...
#define adjust Off(OUT_AB);Wait(50); //とまる
ライントレースに必要なマクロが以下のようになる。
#define sensor_light SENSOR_2 //センサーの定義
#define black 30 //明るさのおおよその最低値
#define white 60 //明るさのおおよその最大値
#define threshold (black+white)*0.5 //明るさの中央付近...
#define deflection (sensor_light-threshold) //比例制御の...
ライントレースのためのサブルーチンが以下のようになる。
sub linetrase_right(int x) //右側のライントレース用の速...
{
OnFwd(OUT_A,40+deflection*x);
OnFwd(OUT_B,40-deflection*x);
}
sub linetrase_left(int x) //左側のライントレース用の速...
{
OnFwd(OUT_A,40-deflection*x);
OnFwd(OUT_B,40+deflection*x);
}
ライントレースを実行するサブルーチンが以下のようになる。...
sub intertify_right() //交差点識別、右側ライントレース
{
long t = CurrentTick();
while(CurrentTick()-t<100){ //0.1秒黒を認識し続け...
if(sensor_light>white-5){
linetrase_right(1.5);
t = CurrentTick();
}else if(sensor_light>black+5){
linetrase_right(1.5);
t = CurrentTick();
}else{
linetrase_right(1.5);
}
}
adjust;
}
sub intertify_left() //交差点識別、左側ライントレース
{
long t = CurrentTick();
while(CurrentTick()-t<100){ //0.1秒黒を認識し続ける...
if(sensor_light>white-5){
linetrase_left(1.5);
t = CurrentTick();
}else if(sensor_light>black+5){
linetrase_left(1.5);
t = CurrentTick();
}else{
linetrase_left(1.5);
}
}
adjust;
}
開始地点から出るためのサブルーチンが以下のようになる。
sub escape_A() //Aから抜け出す
{
while(sensor_light<white-5){
OnFwd(OUT_B,50);
OnFwd(OUT_A,30);
}
adjust;
}
**コップの探査など [#e7826e9f]
コップ探査に使った定義が以下のようになる。
#define ultrasonic SensorUS(S1) //超音波センサー
const float diameter = 5.45; //タイヤの直径
const float track = 17.5; //タイヤのトレッド幅
const float pi = 3.1415; //円周率
コップ探査に必要な関数やそれに少し変更を加えた関数が以下...
void approach(float d) //距離dcm前進
{
long angle = d/(diameter*pi)*360.0; //必要なタイヤの...
RotateMotorEx(OUT_AB,50,angle,0,true,true);
adjust;
}
void back(float d) //距離dcm後退
{
long angle = d/(diameter*pi)*360.0; //必要なタイヤの...
RotateMotorEx(OUT_AB,-50,angle,0,true,true);
adjust;
}
void spinAng(long ang) //角度ang度の旋回(時計回り)
{
long angle = track/diameter*ang; //必要なタイヤの回...
RotateMotorEx(OUT_AB,50,angle,100,true,true);
adjust;
}
void spinAng_opposite(long ang) //角度ang度の旋回(反時計...
{
long angle = track/diameter*ang; //必要なタイヤの回...
RotateMotorEx(OUT_AB,-50,angle,100,true,true);
adjust;
}
以下は参考資料に乗っていた関数。
int search_distance(long ang) //現在の方向を中心にang...
{
long tacho_min; //最も近い距離を表現するタイヤの回...
int d_min = 300; //最も近い距離の仮の最小値
long angle = (track/diameter)*ang; //旋回角度からタ...
spinAng(ang/2); //指定角度の半分旋回(...
ResetTachoCount(OUT_AB); //角度計算をリセット
OnFwdSync(OUT_AB,50,-100);
while(MotorTachoCount(OUT_A)<=angle){
if(ultrasonic<d_min){
d_min = ultrasonic;
tacho_min = MotorTachoCount(OUT_A);
}
}
OnFwdSyncEx(OUT_AB,50,100,RESET_NONE); //時計回りに...
until(MotorTachoCount(OUT_A)<=tacho_min || ultrasoni...
adjust; //もとはWait(20); Off(OUT_AB);
Wait(500);
return d_min;
}
**通信のための定義(マスター側だけ) [#ocbde45f]
マスター側の本体が通信で使う定義が以下のようになる。
#define ultrasonic SensorUS(S1) //超音波センサーの定義
#define master 0
#define slave 1
#define mail MAILBOX1
#define cup_age_little 20 //紙コップをつかめたときに...
#define cup_age 30 //紙をコップ上げる
#define cup_sage 40 //紙をコップ下げる
#define cup_re 50 //紙をコップ持ち直す
#define fin 9 //終わり
**スレーブ側の定義とサブ関数 [#ve41796a]
スレーブ側に用いた定義が以下のようになる。
#define master 0
#define slave 1
#define mail MAILBOX1
#define cup_age_little 20 //紙コップをつかんだときに...
#define cup_age 30 //紙コップを完全に上げる
#define cup_sage 40 //紙コップを下げる
#define cup_re 50 //紙コップを持ち直す
#define fin 9 //終わり
スレーブ側のサブルーチンが以下のようになる。
sub tukamu() //紙コップをつかむ
{
RotateMotor(OUT_A,50,440);
adjust; //
Off(OUT_A);
Wait(300);
}
sub hanasu() //紙コップをはなす
{
RotateMotor(OUT_A,50,-440);
adjust;
}
sub up_little() //紙コップを少しあげる
{
RotateMotor(OUT_B,60,-180);
adjust;
}
sub ageru() //紙コップを上げる
{
RotateMotor(OUT_B,60,-720);
adjust;
}
sub down_little() //紙コップを少し下げる
{
RotateMotor(OUT_B,60,180);
adjust;
}
sub sageru() //紙コップを下げる
{
RotateMotor(OUT_B,60,720);
adjust;
}
**本文 [#k439fe69]
マスター側のプログラムの本文が以下のようになる。
task main()
{
SetSensorLowspeed(S1);
SetSensorLight(S2);
escape_A(); //Aから抜け出す
intertify_right(); //AからBまでライントレース
int d1 = search_distance(90); //1番の紙コップの方向...
if(d1>10){ //1番の紙コップの5...
approach(d1-5);
}
int msg1; //1番の紙コップを少し上...
while(msg1!=fin){
ReceiveRemoteNumber(mail,true,msg1);
SendRemoteNumber(slave,mail,cup_age_little);
}
back(d1-5); //前進したのと同じだ...
spinAng(80); //Pの方向を向く
while(sensor_light>black+5){ //微調整
OnFwdSync(OUT_AB,50,0);
}
adjust;
while(sensor_light<white-5){ //微調整
OnFwd(OUT_B,50);
}
adjust;
intertify_right(); //BからPまでライントレース
spinAng(5); //場所を把握しやすいよ...
approach(26); //26cm前進→Q-S間に行く
while(sensor_light>black+5){ //向きの調整
OnFwd(OUT_A,50);
}
adjust;
while(sensor_light<white-5){ //向きの調整
OnFwd(OUT_B,50);
}
adjust;
intertify_right(); //Sまでライントレース
spinAng(90); //S地点でFの方を向く
int msg2; //通信 カップを持ち直す
while(msg2!=fin){
ReceiveRemoteNumber(mail,true,msg2);
SendRemoteNumber(slave,mail,cup_re);
}
while(sensor_light>black+5){ //Xの方向に向く
OnFwdSync(OUT_AB,50,100);
}
adjust;
while(sensor_light<white-10){
OnFwd(OUT_A,50);
}
adjust;
intertify_left();
intertify_left(); //Xまでライントレース
int msg3; //通信紙コップを上げる
while(msg3!=fin){
ReceiveRemoteNumber(mail,true,msg3);
SendRemoteNumber(slave,mail,cup_age);
}
adjust;
spinAng(160); //Yの方向を向く
while(sensor_light>black+5){
OnFwdSync(OUT_AB,50,0);
}
adjust;
スレーブ側のプログラムの本文が以下のようになる。
task main()
{
int msg1; //1番の紙コップを少し上げる
until(msg1==cup_age_little)
ReceiveRemoteNumber(mail,true,msg1);
while(msg1==cup_age_little){
sageru();
tukamu();
up_little();
SendResponseNumber(mail,fin);
Wait(500);
msg1 = "";
}
int msg2; //紙コップを持ち直す
until(msg2==cup_re)
ReceiveRemoteNumber(mail,true,msg2);
while(msg2==cup_re){
down_little();
hanasu();
tukamu();
up_little();
SendResponseNumber(mail,fin);
Wait(500);
msg2 = "";
}
int msg3; //紙コップをあげる
until(msg3==cup_age)
ReceiveRemoteNumber(mail,true,msg3);
while(msg3==cup_age){
down_little();
ageru();
SendResponseNumber(mail,fin);
Wait(500);
msg3 = "";
}
int msg4; //1番の紙コップを置く
until(msg4==cup_sage)
ReceiveRemoteNumber(mail,true,msg4);
while(msg4==cup_sage){
sageru();
hanasu();
ageru();
SendResponseNumber(mail,fin);
Wait(500);
msg4 = "";
}
*4.感想 [#qd6a9253]
ロボットは利用する側の人間が適切に指示をしなければ、上手...
終了行:
#contents
*1.課題 [#hc472796]
課題はピンポン玉とカップを動かし、別々の場所に置くことが...
#ref(2017b/Member/ats/Mission3/コース.JPG,コース全体)
上の図のようにピンポン玉とカップが配置されている。X地点に...
*2.ロボット [#a012d606]
**ロボット全体 [#yb3111b9]
カップとピンポン玉を分けつつ動かせるようなロボットを1台作...
#ref(2017b/Member/ats/Mission3/ロボット全体.JPG,ロボット...
上の写真のように2つのロボット本体を横にして縦に重ねた。(...
左右の前輪はモーターで動かせるようにして、後ろには左右両...
ロボットの大まかな動きは下のようになる。
1.カップを探し、アームで掴む。掴んだ後にカップを少しだけ...
#ref(2017b/Member/ats/Mission3/カップ移動.JPG,70%,カップ...
2.カップをX地点の枠内まで持ってきて、アームを完全に上げる。
3.カップをY地点の枠内で降ろして離す。
4.2個目以降のときはY地点でセンサーを働かせて1個目のカップ...
**アーム(カップを掴む機構)[#t91fb2a7]
アームには2つのモーターを使った。1つを「つかむ」動作に、...
#ref(2017b/Member/ats/Mission3/アーム.JPG,アーム可動方向)
***つかむ機構 [#x88d9d77]
つかむ部分の構造はクワガタ方式を使った。歯車を4つ用いて、...
#ref(2017b/Member/ats/Mission3/歯車、ハサミ.JPG,クワガタ...
↑この時は手が開く方向に歯車が回っているが、モーターを逆回...
下の写真のように4つのタイヤを使って確実にカップを固定でき...
↓左がきつく締める前、右がきつく締めた後のもの。
&ref(2017b/Member/ats/Mission3/つかむ動作前.jpg,left,50%,...
&ref(2017b/Member/ats/Mission3/つかむ動作後.jpg,right,50%...
***アームの補強 [#wcdc4fb6]
腕の先に重いモーターが付いている構造となっているため、上...
#ref(2017b/Member/ats/Mission3/アーム補強.JPG,アームを支...
**センサー [#ce6a61eb]
ライントレース用の光センサーとカップ探査用の距離センサー...
#ref(2017b/Member/ats/Mission3/センサー.JPG,センサー位置)
*3.プログラム [#o29f8dd7]
プログラムを考えるうえで重要になってくることは以下の2点だ。
1.ピンポン玉の入ったカップや障害物をなるべくずらさないよ...
2.黒線を上手く利用してロボットが確実に走行できること。(〇...
それを考慮に入れたルートが下の図の赤の矢印のようになる。(...
#ref(2017b/Member/ats/Mission3/ルートと番号.JPG,ルートと...
玉の入ったカップに上の図のように番号を付けた。(青背景の吹...
この先は計画で終わってしまったため、ここには1番のカップを...
ロボット本体の役割の分担が以下のようになる。
マスター;ライントレース、カップ探査など
スレーブ;カップの上げ下げ、アームの手の開け閉めなど
**ライントレース [#i9e38461]
ロボットが走行などをするときのために止まるプログラムを書...
#define adjust Off(OUT_AB);Wait(50); //とまる
ライントレースに必要なマクロが以下のようになる。
#define sensor_light SENSOR_2 //センサーの定義
#define black 30 //明るさのおおよその最低値
#define white 60 //明るさのおおよその最大値
#define threshold (black+white)*0.5 //明るさの中央付近...
#define deflection (sensor_light-threshold) //比例制御の...
ライントレースのためのサブルーチンが以下のようになる。
sub linetrase_right(int x) //右側のライントレース用の速...
{
OnFwd(OUT_A,40+deflection*x);
OnFwd(OUT_B,40-deflection*x);
}
sub linetrase_left(int x) //左側のライントレース用の速...
{
OnFwd(OUT_A,40-deflection*x);
OnFwd(OUT_B,40+deflection*x);
}
ライントレースを実行するサブルーチンが以下のようになる。...
sub intertify_right() //交差点識別、右側ライントレース
{
long t = CurrentTick();
while(CurrentTick()-t<100){ //0.1秒黒を認識し続け...
if(sensor_light>white-5){
linetrase_right(1.5);
t = CurrentTick();
}else if(sensor_light>black+5){
linetrase_right(1.5);
t = CurrentTick();
}else{
linetrase_right(1.5);
}
}
adjust;
}
sub intertify_left() //交差点識別、左側ライントレース
{
long t = CurrentTick();
while(CurrentTick()-t<100){ //0.1秒黒を認識し続ける...
if(sensor_light>white-5){
linetrase_left(1.5);
t = CurrentTick();
}else if(sensor_light>black+5){
linetrase_left(1.5);
t = CurrentTick();
}else{
linetrase_left(1.5);
}
}
adjust;
}
開始地点から出るためのサブルーチンが以下のようになる。
sub escape_A() //Aから抜け出す
{
while(sensor_light<white-5){
OnFwd(OUT_B,50);
OnFwd(OUT_A,30);
}
adjust;
}
**コップの探査など [#e7826e9f]
コップ探査に使った定義が以下のようになる。
#define ultrasonic SensorUS(S1) //超音波センサー
const float diameter = 5.45; //タイヤの直径
const float track = 17.5; //タイヤのトレッド幅
const float pi = 3.1415; //円周率
コップ探査に必要な関数やそれに少し変更を加えた関数が以下...
void approach(float d) //距離dcm前進
{
long angle = d/(diameter*pi)*360.0; //必要なタイヤの...
RotateMotorEx(OUT_AB,50,angle,0,true,true);
adjust;
}
void back(float d) //距離dcm後退
{
long angle = d/(diameter*pi)*360.0; //必要なタイヤの...
RotateMotorEx(OUT_AB,-50,angle,0,true,true);
adjust;
}
void spinAng(long ang) //角度ang度の旋回(時計回り)
{
long angle = track/diameter*ang; //必要なタイヤの回...
RotateMotorEx(OUT_AB,50,angle,100,true,true);
adjust;
}
void spinAng_opposite(long ang) //角度ang度の旋回(反時計...
{
long angle = track/diameter*ang; //必要なタイヤの回...
RotateMotorEx(OUT_AB,-50,angle,100,true,true);
adjust;
}
以下は参考資料に乗っていた関数。
int search_distance(long ang) //現在の方向を中心にang...
{
long tacho_min; //最も近い距離を表現するタイヤの回...
int d_min = 300; //最も近い距離の仮の最小値
long angle = (track/diameter)*ang; //旋回角度からタ...
spinAng(ang/2); //指定角度の半分旋回(...
ResetTachoCount(OUT_AB); //角度計算をリセット
OnFwdSync(OUT_AB,50,-100);
while(MotorTachoCount(OUT_A)<=angle){
if(ultrasonic<d_min){
d_min = ultrasonic;
tacho_min = MotorTachoCount(OUT_A);
}
}
OnFwdSyncEx(OUT_AB,50,100,RESET_NONE); //時計回りに...
until(MotorTachoCount(OUT_A)<=tacho_min || ultrasoni...
adjust; //もとはWait(20); Off(OUT_AB);
Wait(500);
return d_min;
}
**通信のための定義(マスター側だけ) [#ocbde45f]
マスター側の本体が通信で使う定義が以下のようになる。
#define ultrasonic SensorUS(S1) //超音波センサーの定義
#define master 0
#define slave 1
#define mail MAILBOX1
#define cup_age_little 20 //紙コップをつかめたときに...
#define cup_age 30 //紙をコップ上げる
#define cup_sage 40 //紙をコップ下げる
#define cup_re 50 //紙をコップ持ち直す
#define fin 9 //終わり
**スレーブ側の定義とサブ関数 [#ve41796a]
スレーブ側に用いた定義が以下のようになる。
#define master 0
#define slave 1
#define mail MAILBOX1
#define cup_age_little 20 //紙コップをつかんだときに...
#define cup_age 30 //紙コップを完全に上げる
#define cup_sage 40 //紙コップを下げる
#define cup_re 50 //紙コップを持ち直す
#define fin 9 //終わり
スレーブ側のサブルーチンが以下のようになる。
sub tukamu() //紙コップをつかむ
{
RotateMotor(OUT_A,50,440);
adjust; //
Off(OUT_A);
Wait(300);
}
sub hanasu() //紙コップをはなす
{
RotateMotor(OUT_A,50,-440);
adjust;
}
sub up_little() //紙コップを少しあげる
{
RotateMotor(OUT_B,60,-180);
adjust;
}
sub ageru() //紙コップを上げる
{
RotateMotor(OUT_B,60,-720);
adjust;
}
sub down_little() //紙コップを少し下げる
{
RotateMotor(OUT_B,60,180);
adjust;
}
sub sageru() //紙コップを下げる
{
RotateMotor(OUT_B,60,720);
adjust;
}
**本文 [#k439fe69]
マスター側のプログラムの本文が以下のようになる。
task main()
{
SetSensorLowspeed(S1);
SetSensorLight(S2);
escape_A(); //Aから抜け出す
intertify_right(); //AからBまでライントレース
int d1 = search_distance(90); //1番の紙コップの方向...
if(d1>10){ //1番の紙コップの5...
approach(d1-5);
}
int msg1; //1番の紙コップを少し上...
while(msg1!=fin){
ReceiveRemoteNumber(mail,true,msg1);
SendRemoteNumber(slave,mail,cup_age_little);
}
back(d1-5); //前進したのと同じだ...
spinAng(80); //Pの方向を向く
while(sensor_light>black+5){ //微調整
OnFwdSync(OUT_AB,50,0);
}
adjust;
while(sensor_light<white-5){ //微調整
OnFwd(OUT_B,50);
}
adjust;
intertify_right(); //BからPまでライントレース
spinAng(5); //場所を把握しやすいよ...
approach(26); //26cm前進→Q-S間に行く
while(sensor_light>black+5){ //向きの調整
OnFwd(OUT_A,50);
}
adjust;
while(sensor_light<white-5){ //向きの調整
OnFwd(OUT_B,50);
}
adjust;
intertify_right(); //Sまでライントレース
spinAng(90); //S地点でFの方を向く
int msg2; //通信 カップを持ち直す
while(msg2!=fin){
ReceiveRemoteNumber(mail,true,msg2);
SendRemoteNumber(slave,mail,cup_re);
}
while(sensor_light>black+5){ //Xの方向に向く
OnFwdSync(OUT_AB,50,100);
}
adjust;
while(sensor_light<white-10){
OnFwd(OUT_A,50);
}
adjust;
intertify_left();
intertify_left(); //Xまでライントレース
int msg3; //通信紙コップを上げる
while(msg3!=fin){
ReceiveRemoteNumber(mail,true,msg3);
SendRemoteNumber(slave,mail,cup_age);
}
adjust;
spinAng(160); //Yの方向を向く
while(sensor_light>black+5){
OnFwdSync(OUT_AB,50,0);
}
adjust;
スレーブ側のプログラムの本文が以下のようになる。
task main()
{
int msg1; //1番の紙コップを少し上げる
until(msg1==cup_age_little)
ReceiveRemoteNumber(mail,true,msg1);
while(msg1==cup_age_little){
sageru();
tukamu();
up_little();
SendResponseNumber(mail,fin);
Wait(500);
msg1 = "";
}
int msg2; //紙コップを持ち直す
until(msg2==cup_re)
ReceiveRemoteNumber(mail,true,msg2);
while(msg2==cup_re){
down_little();
hanasu();
tukamu();
up_little();
SendResponseNumber(mail,fin);
Wait(500);
msg2 = "";
}
int msg3; //紙コップをあげる
until(msg3==cup_age)
ReceiveRemoteNumber(mail,true,msg3);
while(msg3==cup_age){
down_little();
ageru();
SendResponseNumber(mail,fin);
Wait(500);
msg3 = "";
}
int msg4; //1番の紙コップを置く
until(msg4==cup_sage)
ReceiveRemoteNumber(mail,true,msg4);
while(msg4==cup_sage){
sageru();
hanasu();
ageru();
SendResponseNumber(mail,fin);
Wait(500);
msg4 = "";
}
*4.感想 [#qd6a9253]
ロボットは利用する側の人間が適切に指示をしなければ、上手...
ページ名: