[[ロボティクス入門ゼミ]] #contents *課題 似顔絵 [#p6ce46ed] A4の紙に相棒の似顔絵を書くロボットを作成せよ。 &br;・ひとりにつき一つ以上のプログラムを作成すること。 &br;・ペン以外はキットに含まれる部品を使うこと。 &br;・A4の紙はセロテープ等で固定しないこと &br;・キットに付属の高価な輪ゴムは切れやすいので切れないように細心の注意を払うこと。 &br;・改良や調整をしやすくするため、ロボット本体だけでなく、プログラムについても可能な部分についてはサブルーチンや関数、マクロなどを使って部品に分けること。 **製作過程 [#wfaf4b4c] 使ったモータやセンサの役割を説明する ロボットの種々の機能とプログラム全体の流れを説明する *車体部分 [#ebf7d0fe] #ref(2012a/A5/ITY/M1/photo/CIMG1501.JPG) #ref(2012a/A5/ITY/M1/photo/CIMG1504.JPG,right) #ref(2012a/A5/ITY/M1/photo/CIMG1506.JPG) #ref(2012a/A5/ITY/M1/photo/CIMG1543.JPG,right) #ref(2012a/A5/ITY/M1/photo/CIMG1544.JPG) *ロボットの構造 [#e638f01d] *工夫したところ [#td1f4b47] &br;・車軸上にペンを置くことによって、移動距離が少なくてすむようにした。 &br;・また、ガイドを作りペンが垂直に降りて、紙にしっかりとかけるようにした。 &br;・先に光センサをつけて、センサが紙から外れたら、回転するようにした。 *プログラム [#c3a1f32c] /* 2012/5/18 ITY */ /* 2012a_robo_kadai1 face-8-7 */ /*---------------------------------------------------------------------------------- 別名定義 ----------------------------------------------------------------------------------*/ #define MOVE_TIME 1500 // 前後に必要な時間 #define TURN_TIME 330 // 旋回に必要な時間 #define PWM 100 // PWM(力の大きさ) #define PAI 3 // 円周率3.14 300 200 #define D 50 // タイヤの直径 #define ON 1 // オン #define OFF 0 // オフ #define A_UP 15 // 上げるときの高さ #define A_DOWN 15 // 下げるときの高さ #define TRUN_AC 320 // 90度の回転角度 /*---------------------------------------------------------------------------------- 関数宣言 ----------------------------------------------------------------------------------*/ void ARM_UP(); // ペンを上げる void ARM_DOWN(); // ペンを下げる void MODULATE(); // ぺんの調整 void TURN_R(); // 90度ターン void LCD(); // LCDにモデルを描写 /*---------------------------------------------------------------------------------- グローバル変数 ----------------------------------------------------------------------------------*/ int s1_touch,s2_touch; //タッチセンサ /*---------------------------------------------------------------------------------- メインルーチン ----------------------------------------------------------------------------------*/ task main() { SetSensorLight(IN_4); //アナログセンサの宣言 SetSensorTouch(IN_3); //タッチセンサの宣言 SetSensorTouch(IN_1); //タッチセンサの宣言 int i,j,p,n,num,s_ligh; //変数宣言 i=0,p=0,num=1,s_ligh=0; //変数の初期化 s1_touch = Sensor(IN_3); //タッチセンサの値を取得 s2_touch = Sensor(IN_1); //タッチセンサの値を取得 if((s1_touch == ON) || (s2_touch == ON)){ //スイッチ1か2が押されているとき MODULATE(); //ペンの上下調整 } else{ //スイッチ1と2が押されていないとき Wait(100); while(true){ s_ligh = Sensor(IN_4); //アナログセンサの値を代入 NumOut(10,60,s_ligh,0); //LCDにセンサの値を表示 ResetScreen(); //LCDの表示の初期化 // PlaySound(1); //音を鳴らす NumOut(10,60,num,0); //LCDにセンサの値を表示 switch(num){ case 1: //輪郭を書く for(i=0;i<4;i++){ ARM_DOWN(); //ペンを下げる RotateMotor(OUT_AC,40,180); //左右ACのモータを正転 ARM_UP(); //ペンを上げる TURN_R(); } break; case 2: RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 TURN_R(); //90度回転 break; case 3: RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 ARM_DOWN(); //ペンを下げる RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 break; case 4: ARM_UP(); //ペンを上げる RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 break; case 5: ARM_DOWN(); //ペンを下げる RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 break; case 6: ARM_UP(); //ペンを上げる TURN_R(); //90度回転 TURN_R(); //90度回転 RotateMotor(OUT_C,40,40); //左右ACのモータを正転 TURN_R(); //90度回転 RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 ARM_DOWN(); //ペンを下げる RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 break; case 7: ARM_UP(); //ペンを上げる RotateMotor(OUT_A,40,40); //左右ACのモータを正転 TURN_R(); //90度回転 ARM_DOWN(); //ペンを下げる RotateMotor(OUT_AC,40,40); //左右ACのモータを正転 break; default: } // PlayTone(4000,20); //音を鳴らす num++; //次の処理に移る } } } /*---------------------------------------------------------------------------------- サブルーチン ----------------------------------------------------------------------------------*/ void ARM_UP() //ペンを上げる { RotateMotor(OUT_B,50,-A_UP); // PlaySound(1); //ビープ音 } void ARM_DOWN() //ペンを下げる { RotateMotor(OUT_B,50,A_DOWN); //モータBを回転 Off(OUT_B); //ペンの固定 // PlaySound(2); //ビープ音 } void TURN_R() //90度ターン { int tako_a=0,tako_c=0; //変数宣言 ResetScreen(); //LCDの初期化 OnFwdSyncEx(OUT_AC,40,-100,RESET_NONE); //左右ACのモータを回す while((tako_a < TRUN_AC) && (tako_c < TRUN_AC)){ //90度回転していないとき tako_a = abs(MotorTachoCount(OUT_A)); //タコメータからモータAの値を取得 tako_c = abs(MotorTachoCount(OUT_C)); //タコメータからモータBの値を取得 NumOut(10,48,tako_a,0); //LCDにタコメータ(A)の値を表示 NumOut(10,40,tako_c,0); //LCDにタコメータ(A)の値を表示 } Off(OUT_AC); //モータの停止 } void MODULATE() //ペンの調整用 { int t_count; s1_touch=0,s2_touch=0,t_count=0; //変数宣言 while(true){ //変数の初期化 s1_touch = Sensor(IN_3); //タッチセンサの値を取得 s2_touch = Sensor(IN_1); //タッチセンサの値を取得 NumOut(10,60,s1_touch,0); //LCDにセンサの値を表示 NumOut(10,40,s2_touch,0); //LCDにセンサの値を表示 if((s1_touch == OFF) && (s2_touch == OFF)){ //スイッチ1と2が押されていないとき t_count = 0; //カウンタの初期化 Off(OUT_B); //モータの停止 } else if((s1_touch == ON) || (s2_touch == ON)){ //スイッチ1か2が押されているとき if(t_count < 100){ //0.1秒間押されているか判定 t_count++; //カウンタをまわす } else{ if((s1_touch == ON) && (s2_touch == ON)){ //スイッチ1と2が押されているとき RotateMotor(OUT_B, 50,-14); //ペンを上げる Off(OUT_B); //ペンの固定 while(true){ //調整の終了 LCD(); // ResetScreen(); //LCDの表示の初期化 } } else if(s1_touch == ON){ //スイッチ1が押されているとき OnFwd(OUT_B,20); //ペンを上げる } else if(s2_touch == ON){ //スイッチ2が押されているとき OnRev(OUT_B,20); //ペンを下げる } else Wait(100); //それ以外の時、待つ } } } } void LCD() //LCDにイメージを描写 { TextOut(10,60,"kadai1 face",0); //文字の表示 Wait(1000); ResetScreen(); //画面の初期化 LineOut(30,50,70,50,0); Wait(200); LineOut(70,50,70,10,0); Wait(200); LineOut(70,10,30,10,0); Wait(200); LineOut(30,10,30,50,0); Wait(200); LineOut(30,31,34,35,0); Wait(200); CircleOut(40,35,6,0); Wait(200); LineOut(46,35,54,35,0); Wait(200); CircleOut(60,35,6,0); Wait(200); LineOut(66,35,70,35,0); Wait(200); LineOut(50,30,50,24,0); Wait(200); LineOut(50,24,55,24,0); Wait(200); LineOut(45,15,55,15,0); Wait(2000); } **結果 [#x95cb368] #ref(2012a/A5/ITY/M1/photo/CIMG1565.JPG) 回転する時にタイヤが外側にはみ出してしまい、うまく描写することができなかった。 #ref(2012a/A5/ITY/M1/photo/CIMG1551.JPG) 本来ならこの様に書く予定だった。 [[2012a/A5/ITY/M1/photo]] *反省・感想 [#hf8f1716] &br;・ペンを車軸上に置いた事はよかったが、裏のキャスターに重心が掛かりすぎてしまったために紙を巻き込んでしまい、また車体の重心が高いために走行時にぶらついて、旋回時に片側だけに負荷が加わってしまった。紙が動いてしまうということをもう少し欲考えて、ロボットの設計とプログラムをしたい。