로봇카 기초 배우기

아두이노 로봇카

7. 주행거리 제어하기

Contents

아두이노 로봇카 실습 세부목차


1. 프라이비 에듀 마이컴 보드 시작하기 

2. LED동작과 서보모터 제어 

3. 서보모터 조립과 동작 그리고 주행하기 

4. 더듬이센서로 주행하기 

5. 포토트랜지스터로 주행하기 

6. 적외선센서로 주행하기 

7. 주행거리 제어하기


※ 본 페이지의 내용은 패럴렉스(Learn.Parallax.com)사의 공식 홈페이지에서 제공되는 자료를 참고하여 작성되었습니다. 또한, 본 내용은 아두이노 neo-로봇카v2 또는 아두이노 로봇카N 키트실습에 사용할 수 있습니다.


본 자료의 원문을 참조하려면 패럴렉스 사의 아두이노를 위한 로보틱스 홈페이지를 방문할 수 있습니다. 이 자료의 로봇카 모든 제어명령 및 센서신호 수집작용은 프라이비 보드 또는 아두이노를 통하여 수행됩니다. 프라이비 보드는 아두이노 우노와 동일한 ATmega328P 마이컴이 사용된 호환보드이며, 아두이노 우노와 동일한 사용법이 적용됩니다.


지금까지 로봇카에 장착된 적외선센서로 물체가 있는지 없는지를 감지하고, 로봇카의 주행동작을 제어하였다. 이제 적외선센서 장치에 단순히 물체가 있는지 없는지를 구분하는데 그치지 않고, 물체와의 거리를 측정할 수 있다면 더 다양한 제어동작을 구현할 수 있지 않을까? 이런 질문에 대답할 순서입니다. 


아래 세부 내용들을 살펴볼 수 있습니다.

1) 적외선 센서의 주파수 테스트

2) 양쪽 적외선 센서에서 거리측정하기

3) 전방의 로봇카 추적하기


적외선센서로 주행했던 동일한 하드웨어 센서 장치를 사용하여 물체와의 거리를 측정할 수 있습니다. 이런 직업은 앞에서 주행하는 로봇카와 일정한 거리를 유지하면서 충돌하지 않고 따라가는 차량추적 또는 차량추종 동작을 구현하거나, 레이더의 기초적인 개념을 익히는데 활용될 수 있습니다.


1) 적외선 센서의 주파수 테스트


실습에 사용된 IR 수신기와 유사한 부품의 데이터시트입니다. 그래프에 따르면 38.5 KHz 에서 가장 감도가 좋고, 이보다 주파수가 크거나 작아지면 감도도 급격히 감소하는 특성을 나타내고 있습니다.


그림입니다. 원본 그림의 이름: CLP00001b58003f.bmp 원본 그림의 크기: 가로 221pixel, 세로 281pixel


예를 들어 40 KHz 주파수로 LED를 켜면 38 KHz 조건에서보다 감도가 절반으로 줄어듭니다. 그리고 42 KHz 조건에서는 최대치의 20% 정도만 감지할 수 있습니다. 따라서, IR LED 의 신호가 38 KHz 일때 가장 멀리 있는 물체를 감지할 수 있습니다. 바꿔 말하면 IR LED 의 신호 주파수 조건에 따라 측정 가능한 물체의 거리가 각각 다른 특성이 있다고 할 수 있습니다. 우리는 이런 특성을 사용하여 어떤 물체와의 거리가 얼마인지를 측정할 수 있습니다.


본 실습에서는 물체와의 거리를 적외선 센서로 측정하기 위하여 다양한 주파수 조건으로 스캔하는 실습을 진행합니다.


그림입니다. 원본 그림의 이름: CLP00001b580040.bmp 원본 그림의 크기: 가로 472pixel, 세로 184pixel


소개한 그림처럼 로봇카에 장착된 적외선 센서를 사용하여 측정 주파수를 42000 Hz 에서 38000 Hz 까지 변화시키면서 물체가 감지되는 경계 주파수를 찾을 수 있습니다. 그 경계 값으로부터 물체와의 거리를 추정할 수 있습니다. 매우 정확한 거리 측정방법은 아니지만 로봇카 주행에 매우 유용하게 사용할 수 있습니다.


   int irDistance(int irLedPin, int irReceivePin) {

      int distance = 0;

      for(long f = 38000; f <= 42000; f += 1000) {

         distance += irDetect(irLedPin, irReceivePin, f);

      }

      return distance;

   }


2) 양쪽 적외선 센서에서 거리측정하기


양쪽 IR LED/수신기가 각각 동일한 거리를 측정하는 것은 로봇카의 주행동작에 있어서 매우 중요합니다. 전방의 로봇카를 자율적으로 따라가게 하려면 좌측과 우측의 측정거리가 매우 중요하게 작용하기 때문입니다. 그래서 좌측과 우측 적외선 센서의 측정거리가 너무 차이난다면 하드웨어적으로 저항의 크기를 변경하여 측정감도 차이를 최소화할 필요가 있습니다.


두 개 센서의 측정거리 감도를 관찰하기 위하여 아래 스케치를 참고하십시오.


void setup(){

  tone(4,   3000, 1000);

  delay(1000);  

  pinMode(10,   INPUT); pinMode(9, OUTPUT);

  pinMode(3,   INPUT); pinMode(2, OUTPUT);

  Serial.begin(9600);  

void loop(){

  int   irLeft = irDistance(9, 10);

  int   irRight = irDistance(2, 3);

  Serial.print(irLeft);  

  Serial.print("   ");

  Serial.println(irRight);  

  delay(100);  

}

int irDistance(int irLedPin, int   irReceivePin){

  int   distance = 0;

  for(long   f = 38000; f <= 42000; f += 1000) {

       distance += irDetect(irLedPin, irReceivePin, f);

  }

  return   distance;

}

int irDetect(int irLedPin, int   irReceiverPin, long frequency){

  tone(irLedPin,   frequency, 8);

  delay(1);  

  int   ir = digitalRead(irReceiverPin);

  delay(1);  

  return   ir;


3) 전방의 로봇카 추적하기


전방의 로봇카를 따라가기 위해서는 어느 정도 거리를 유지해야 하는지 인식해야 합니다. 전방의 로봇카로부터 거리가 멀어지면 더 빨리 주행해야 하고, 거리가 좁아지면 더 천천히 주행해야 하기 때문입니다. 그래서 일정한 거리를 유지하면서 여러 대의 로봇카를 일렬로 주행하도록 할 수 있습니다.


그림입니다. 원본 그림의 이름: CLP00001b580041.bmp 원본 그림의 크기: 가로 282pixel, 세로 175pixel


앞에 위치한 로봇카와의 거리를 측정하고 일정한 거리보다 멀면 거리를 좁히는 주행을 하고 사이의 거리가 좁으면 넓히는 주행을 하려면 피드백 제어(feedback control)를 적용해야 합니다. 아래 제어개념은 닫힌 루프에서의 제어를 위한 블록 다이어그램입니다.


그림입니다. 원본 그림의 이름: CLP00001b580042.bmp 원본 그림의 크기: 가로 357pixel, 세로 122pixel

그림입니다. 원본 그림의 이름: CLP00001b580043.bmp 원본 그림의 크기: 가로 342pixel, 세로 121pixel


제어 블럭에서는 측정된 거리값에 따라 maneuver() 함수에 적용하는 속도 및 방향 값이 각각 다르게 변경되어 적용되는 원리를 소개하고 있습니다.


아래 예제 스케치를 참고하세요.


#include <Servo.h>

Servo servoLeft;

Servo servoRight;

const int setpoint = 2;

const int kpl = -50;

const int kpr = -50;

void setup() {

  pinMode(10,   INPUT); pinMode(9, OUTPUT);

  pinMode(3,   INPUT); pinMode(2, OUTPUT);

  tone(4,   3000, 1000);

  delay(1000);  

  servoLeft.attach(13);  

  servoRight.attach(12); 

void loop() {

  int   irLeft = irDistance(9, 10);

  int   irRight = irDistance(2, 3);

  int   driveLeft = (setpoint - irLeft) * kpl;

  int   driveRight = (setpoint - irRight) * kpr;

  maneuver(driveLeft,   driveRight, 20);

}

int irDistance(int irLedPin, int   irReceivePin) {

  int   distance = 0;

  for(long   f = 38000; f <= 42000; f += 1000) {

       distance += irDetect(irLedPin, irReceivePin, f);

  }

  return   distance;

}

int irDetect(int irLedPin, int   irReceiverPin, long frequency) {

  tone(irLedPin,   frequency, 8);

  delay(1);  

  int   ir = digitalRead(irReceiverPin);

  delay(1);  

  return   ir;

void maneuver(int speedLeft, int   speedRight, int msTime) {

  servoLeft.writeMicroseconds(1500   + speedLeft);

  servoRight.writeMicroseconds(1500   - speedRight);

  if(msTime==-1)   {

       servoLeft.detach();

       servoRight.detach();

  }

  delay(msTime);  

}


실습에서처럼 제어 블럭에서 Kpr 과 Kpl 값을 조절하여 로봇카의 추종 주행하기 동작을 조금 더 다르게 구현할 수도 있습니다.



이전 페이지로