모바일 로봇 공학라인 트레이서 보고서자동차 공학과 2008157916조 NDS 하병훈< 목 차 >1. 라인트레이서 정의와 구성요소2. 라인트레이서 팀 구성 및 역할3. 라인트레이서 제작 일지4. 주요 요소 제작 과정5. 라인인식 알고리즘6. Code Vision 프로그래밍7. 대회 참가 및 결과8. 고찰 및 느낀점1. 라인트레이서 정의와 구성요소-라인트레이서란?라인트레이서(Line Tracer)는 바닥에 그려진 선을 인식을 하여 주행할 수 있는 로봇을 말한다. 일반적으로 라인트레이서가 주행을 하는 바닥의 색이 검정색이면 흰선을 인식하여 주행을 하고 바닥의 색이 흰색이면 검정선을 인식을 하여 주행을 할 수 있다. 바닥의 라인을인식하기 위해 적외선센서를 가장 많이 사용하여 CCD 카메라를 이용하는 경우도 있다. 라인트레이서 구동을 위해서는 DC모터와 STEP모터를 가장 많이 사용하는데 DC모터는 가격이 저렴하고 구동방법은 쉽지만 속도나 이동거리를 제어하기 쉽지 않고 부가적으로 엔코더를 사용해야 한다. 이에 비해 STEP모터를 사용하면 모터가 입력한 펄스에 의해 정확하게 움직이므로 모터의 속도나 이동거리를 제어하기가 쉽다.라인트레이서는 다른 로봇들과 비교하였을 때 구조가 간단하고 프로그래밍도 복잡하지 않기 때문에 로봇을 처음 제작해보는 사람들에게 로봇의 구성요소 및 제어에 대해 쉽게 이해시킬 수 있는 장점이 있다.-라인트레이서 구성요소라인트레이서의 구성요소는 하드웨어와 소프트웨어로 구분을 할 수 있으며 하드웨어는 센서, 구동기, 제어기를 들 수 있으며 각각의 예로 적외선 거리 감지센서, DC 모터, ATmega16 마이크로 컨트롤러를 들 수 있다. 그리고 각각의 하드웨어를 인터페이스와 신호처리를 위한 논리회로와 센서신호의 증폭을 위한 Op-amp를 가지고 있다. DC모터의 정역구동을 위해서 H-Bridge 회로를 사용하고, 마이크로컨트롤러에 프로그램을 다운로드 하기 위한 ISP 모듈을 사용하고 있다.(1) 적외선 센서 보드(2) OP-amp보드(3) 마이크로 컨트롤11월 30일 재납땜을 하고 문제점을 제거후 하드웨어를 완성하게 되었다. 제작 과정중 센서의 위치가 기존대로 볼 캐스터 앞에 둘 것인지, 뒤에 둘 것인지 의견차이가 있었지만, 시행착오와 시험운행의 결과 라인트레이서 제일 앞부분에 두는게 안정적인 주행을 하는 것으로 판단하였고, 또 민감한 센서의 오작동을 막기 위해 센서 작동에 필요 없는 빛을 차단 할 수 있는 차양막 설치에도 앞부분에 센서가 있어야 할 수 있는 것이라 센서의 위치의 결정이 하드웨어 제작과정중 제일 중요한 부분이었다 생각한다. 하드웨어 완성후 프로그래밍 하는것에 집중하였고, 시행착오를 계속 반복하면서 대회 당일까지 하드웨어에 맞는 최적화된 코드를 만들고자 최선을 다했다.4. 주요 요소 제작 과정(1) 기어 박스 제작어떤 타입의 기어비가 최적일지에 대해 알지 못해D type(기어비 344.2:1) → C type(기어비 114.7:1) → B type(38.21:1) 의 순으로 만들었고작동해본후 B type의 기어비가 제일 최적이란 결과를 얻게 되었다.첫 사진에 있는 Hex shaft와 Gear hub를 느슨하게 고정하여 제작과정 중간에 분리되는 일이 발생 하였다.그 이후 더 Gear screw를 꽉 조였고, 테스트 중간 중간에도 한번씩Hex wrench를 사용하여 Gear screw를 조여 Gear hub의 분리되는 문제를 해결하였다.←최종 B type(기어비 38.2:1) 기어 박스(2) 납땜납땜 처음에는 납땜 하는것에 대해 익숙하지 않아 납땜이 완벽하게 할 수 없었지만, 서서히 납땜 기술을 익히고, 재납땜을 하면서 오작동의 문제를 해결 할 수 있었다.오른쪽 위에 사진은 PUSH 스위치인데 납땜을 하기 위해 마이크로 컨트롤러 메인 보드에 끼우려 했지만 구멍이 작아 PUSH 스위치 납땜 부분을 갈아 크기를 줄여 구멍에 맞게 만들었다. 납땜을 하면서 안전사고가 나지 않기 위해 집중하였고 더 신중을 기하였다.(3) 몸체(강판) 제작왼쪽 아래 사진을 보면 바퀴와 센서의 수평이 맞지 않는 것을 볼 수 있ckwardunsigned char LBRF=0x09; // L motor backward and R motor forwardunsigned char LBRB=0x05; // L motor backward and R motor backwardunsigned char STOP=0x00; // L motor stop and R robot stop//PWM 설정 함수 절대 수정 금지void timer1_init(void) //타이머 1 초기값{TCCR1A=0xA1; //FAST PWM , 8-BIT//1010 Clear oc1a/oc1b on compare match (set output to low level)TCCR1B=0x0A; // CLK I/O/8 (FROM PRESCALER)// 타이머1을 카운터1으로 사용.(상승에지)TCNT1H=0x00; //16비트라서 8비트씩 설정해줌TCNT1L=0x00; // 0으로 설정시 출력이 됨}// 모터 제어 함수 절대 수정 금지void pwm(char val,char duty,char duty2,unsigned int del) // 함수 pwm(모터 회전 방향, 좌 모터 듀티, 우 모터 듀티, 지연시간){// PORTD |= 0xc0; //0100 0000 Motor EnablePORTC = val; // 모터 방향 DIR(정방향)OCR1AH=0x00; // R motor duty controlOCR1AL=duty2;delay_us(10);OCR1BH=0x00; // L motor duty controlOCR1BL=duty;delay_ms(del);// PORTC=0x00;delay_us(10);}// 메인 프로그램 함수 이 안에 자신의 프로그램을 작성하시오.void main(void){// Declare your local variables hereunsigned char sensor;unsigned char rot; // if 함수를 위한 rot 지정 (rot=1->좌회전 / rot=2->우회전 / rot=3->직진)11 1111case 0x00: //0000 0000if (rot==1)pwm(LBRF,80,180, 1);else if (rot==2)pwm(LFRB,180,80, 1);else if (rot==3)pwm(LBRB,160,160, 1);elsepwm(LFRF,160,160, 1);break;default : pwm(LFRF,180,180, 1); break;}}}●최종 프로그래밍붉은색으로 표시된 수치가 초기 프로그래밍에서 바뀐값을 의미./*****************************************************Project : 2012 Robotics Line TracerVersion : 1.1 (using A/D conversion)Date : 2012-12-10Author : NDSCompany : Kookmin UniversityComments: Mechatronics LAB.Chip type : ATmega16Program type : ApplicationClock frequency : 8.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256****************************************************/#include #include // Declare your global variables here// Motor Direction Configuration 수정 금지unsigned char LFRF=0x0a; // L motor forward and R motor forwardunsigned char LFRB=0x06; // L motor forward and R motor backwardunsigned char LBRF=0x09; // L motor backward and R motor forwardunsigned char LBRB=0x05; // L motor backward and R motor backwardunst==1) pwm(LFRF,160, 100, 1);else pwm(LFRF,100,200, 1); break; //0011 0000case 0x06:if (rot==1) pwm(LFRF,160,120, 1);else pwm(LFRF, 60 ,200, 1); break; //0110 0000case 0x03: pwm(LFRF, 70,190, 1); rot=1 ; break; //1100 0000case 0xe0: pwm(LFRB,200,100, 1); rot=2 ; break; //0000 0111case 0xf0: pwm(LFRB,200,120, 1); rot=2 ; break; //0000 1111case 0xf8: pwm(LFRB,200,120, 1); rot=2 ; break; //0001 1111case 0xfc: pwm(LFRB,200,120, 1); rot=2 ; break; //0011 1111case 0xfe: pwm(LFRB,200,120, 1); rot=2 ; break; //0111 1111case 0x07: pwm(LBRF,100,200, 1); rot=1 ; break; //1110 0000case 0x0f: pwm(LBRF,120,200, 1); rot=1 ; break; //1111 0000case 0x1f: pwm(LBRF,120,200, 1); rot=1 ; break; //1111 1000case 0x3f: pwm(LBRF,120,200, 1); rot=1 ; break; //1111 1100case 0x7f: pwm(LBRF,120,200, 1); rot=1 ; break; //1111 1110case 0xff: pwm(LFRF,250,250, 1); rot=3 ; break; //1111 1111case 0x00: //0000 0000if (rot==1)pwm(LBRF,80,180, 1);else if (rot==2)pwm(LFRB,180,80, 1);else if (rot==3)pwm(LBRB,160,160, 1);else.