RC카 장애물 감지시 방향 전환 기초(아두이노)

in #kr-newbie7 years ago (edited)

RC카 장애물 감지시 방향 전환 기초(아두이노)



초음파레이더의 원리는 지난 시간에 기초 실험으로 살펴 보았습니다. 하다보니깐 RC카 자율주행할 때 초음파 센서로 장애물 감지을 할 경우가 문득 떠오르더군요. 그래서 초음파레이더 만들기 소스를 그대로 이용하여 몇부분만 추가하여 코딩을 완성했습니다. 그냥 갑자기 떠오른 생각이라서 코딩은 깔끔하지 않네요. 막 떠오르는데로 코딩한거니 그 점을 감안해서 코딩을 보시기 바랍니다.

1. 회로도 구성


  • 준비물 : 서보모터 2개, 초음파센서 1개, 아두이노우노
  • 내용 :45~ 125도 서보모터를 회전시키면서 초음파센서로 거리를 측정부분은 그대로 유지한 상태에서 RC카 앞바퀴 방향 제어용 서보모터를 추가하자.

머리속에서 각 부품을 실제 RC카에 배치를 상상해 보세요. 첫번째 초음파센서가 서보모터에 부착되어 있고 두번째 서보모터는 RC카 앞바퀴에 연결되었다고 상상 해보세요.

3. 코딩


  • 사용함수 : attach(사용핀), write(각도), pulseIn(입력핀, HIGH), Serial.begin(9600), Serial.print(출력값),Serial.println(출력값)
  • 내용 : 간단히 서보모터가 회전은 45~125도 범위를 잡고 전방의 장애물 탐지를 초음파센서가 담당하게 코딩하고 앞바퀴담당 서보모터는 거리 50이하 일때 전방 90도 기준으로 좌측에 장애물 발견시 우측으로 우측 장애물 발견시 좌측으로 회전시키는 코딩을 한다.

설계

앞바퀴 방향 제어를 하기 위해서 서보모터를 제어해야겠죠.

그래서 서보모터 객체를 하나 더 선언합니다.

Servo servo2;

그리고 핀을 10번을 사용하기 위해서 연결합니다.

int servoPin2 = 10;
servo2.attach(servoPin2); //angle (0~180)

앞바퀴 장애물 방향전환 조건문을 만듭니다.(하나의 패턴으로 자율주행 첫단추로 접근하는 시작 코딩)

  if(m_distance<=50 && m_angle>90) {    
    servo2.write(45);
    delay(50);   
  }
  else if (m_distance<=50 && m_angle<90){
    servo2.write(125);
    delay(50);   
  }
  else {
    servo2.write(90);
    delay(50);   
  }
  if(m_distance<=50 && m_angle>90) {    

if조건문

  • 첫번째 조건식 : "장애물(벽) 거리가 50cm 이하이고 각도가 90도 보다 큰가?" (왼쪽장애물확인)
    그러면 왼쪽 장애물이 너무 가까우니깐 오른쪽으로 핸들을 꺽어야 겠죠.
  • 두번째 조건식 : "그게 아니면 장애물(벽) 거리가 50cm 이하이고 각도가 90도보다 작은가?"(오른쪽장애물확인)
    그러면 오른쪽 장애물이 너무 가까우니깐 왼쪽으로 핸들을 꺽어야 겠죠.
  • 거짓이면 : 그냥 앞바퀴 방향각 90도로 정중앙 정면을 향하게 한다.

즉, 조건식으로 50cm이하일때 현재 방향에 따른 핸들의 방향을 결정하게 됩니다. 50cm이하에 장애물이 없으면 그냥 정면으로 계속 진행하도록 로직을 짜봤습니다.
여기서 핸들 각도를 변수로 빼면 중복되는 코딩이 3번 반복되는데 이걸 하나로 줄일 수 있겠지만 우선은 동작을 좀 더 직관적으로 이해할 수 있도록 하기 위해서 수정은 안했습니다.

초음파레이더 소스와 위에 방향전환 로직을 합쳐서 전체코딩을 을 살펴보면

#include <Servo.h>

Servo servo1;
Servo servo2;
int servoPin1 = 9;
int servoPin2 = 10;
int m_distance=0;
int m_angle=45;
int m_chk=0;

void setup() {
  Serial.begin(9600);
  servo1.attach(servoPin1); //angle (0~180)
  servo2.attach(servoPin2); //angle (0~180)
}

void loop() {
  
  //초음파센서 몸체 회전
  servo1.write(m_angle);
  delay(50);
  
  m_distance=CalDistance(7);  //초음파센서로 거리계산함수   
  Serial.print("d : ");
  Serial.println(m_distance);
  
  //앞바퀴 장애물 방향전환
  if(m_distance<=50 && m_angle>90) {    
    servo2.write(45);
    delay(50);   
  }
  else if (m_distance<=50 && m_angle<90){
    servo2.write(125);
    delay(50);   
  }
  else {
    servo2.write(90);
    delay(50);   
  }
  
  //초음파센서 회전각
  if(m_chk==0){
    if(m_angle<125)m_angle+=1;
    else m_chk=1;
  }
  else{
    if(m_angle>45)m_angle-=1;
    else m_chk=0;
  }
  
}

int CalDistance (int Pin){  //초음파센서(3핀) 예제를 그대로 외부함수로 빼냄
  pinMode(Pin,OUTPUT); //출력모드로  사용
  digitalWrite(Pin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(Pin,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(Pin,LOW); 
  
  pinMode(Pin,INPUT);    //입력모드로 사용
  int duration = pulseIn(Pin, HIGH);
  
  int distance = duration / 57.5;  //가상시뮬레이션의 오차율을 줄이기 위해 이걸로 테스트 함.

  return distance; //거리값 리턴
}

5. 결과


설계과정은 이번에 생략하고 결과만 시뮬레이터로 돌려 보는 장면만 보여 드립니다. 지난시간에 회로도 만드는 과정을 해봤으니 구지 중복해서 다시 똑같은 것을 찍을 필요는 없고 서보모터만 하나 추가했기 때문에 결과만으로 충분해서 회로도 배치과정은 생략했네요.

마무리


오늘은 아두이노 RC카에 주행에 관한 첫 단추인 방향전환에서 하나의 패턴을 기초 패턴으로 로직을 만들었습니다. 이걸로 주행이 가능하지 않습니다. 단지 이렇게 코딩해 놓고 조금씩 패턴을 늘리고 로직을 늘려가야 합니다.

여기서는 단적으로 왼쪽 장애물 감지시 레드존에 들어가고 바로 오른쪽으로 45도 회전을 시켜서 그린존으로 탈출하는 코딩입니다. 어떤 문제가 있을까요 바로 현재 RC카의 주행 속력에 대한 장애물과의 거리별로 방향전환 각도를 가변적으로 해야합니다. 그래야 매끄렇게 회전이 됩니다. 그리고 또 문제는 가령 전방 직선도로로 달릴때 통과 할 수 공간이 충분하지만 가력 왼쪽이나 오른쪽 방향에 장애물이나 벽과의 거리가 50 이하면 그냥 방향핸들을 반대 방향으로 꺽어버리는 문제가 방생합니다. 즉, 전방에 안전거리 확보가 확인되면 그상태로 주행하고 안전거리가 미확인시 좌우측에 위험거리가 감지되면 방향을 전환하더록 로직을 수정해야겠죠.

이렇게 주행에서의 문제들을 하나씩 찾아내고 그걸 해결하는 패턴들을 하나씩 만들어 내야합니다. 그래야 자율주행이 가능해지는 것이죠. 다른 방식으로 장애물 감지되면 그상태에서 주행이 정지되고 안전거리 확보 패턴로직 주행을 하고 다시 안전거리가 확보되면 주행을 다시 시작하는 방식으로도 변경할 수 있겠죠.

코딩을 쉽게 하기 위해서는 실제 장난감 자동차를 방에서 손으로 밀면서 주행을 시켜보세요 그리고 관찰하면 이런 상황일때 이걸 어떻게 어떻게 빠져나올지 손으로 자동차를 움직이시고 그 움직을 잘 기억했다가 그 움직이는 동작 패턴을 코딩화 하시면 됩니다.

암튼 집에 굴러다니는 장단감을 가지고 한번 손으로 밀면서 띠따! 빵빵! 하면서 가지고 노세요. 그리고 나서 그 움직임을 기역했다가 코딩을 상상해보세요.

Sort:  

스스로 홍보하는 프로젝트에서 나왔습니다.
오늘도 좋은글 잘 읽었습니다.
오늘도 여러분들의 꾸준한 포스팅을 응원합니다.

오늘도 방문해 주셔서 감사합니다.

좋은 글 잘 읽고갑니다:)

감사합니다.

코딩은 진짜 어려운거 같아요 컴퓨터에게 하나하나 일을 다 시켜야 하니 말니죠 ㅠㅠ 한번 머릿속으로라도 그려봐야 겠어요

불이 켜자라! => digitalWrite(해당핀, HIGH);
1초대기해! => delay(1000);
불이 꺼져라! => digitalWrite(해당핀, LOW);
1초 대기해! =>delay(1000);

이렇게 글을 순서대로 쓰고 그 관련 함수를 불러다 배치하면 어렵지 않고 해당핀을 통해 LED를 깜박이게 됩니다.
어려워하는 것은 글을 쓰고 그 글에 대한 함수를 배치하는게 잘 연상이 안될 뿐이죠.
그리고 남이 코딩한 코딩줄을 보고 수십줄 넘어가면 저걸 어떻게 코딩해라고 어려워 하는것 같아요.

한줄의 글을 코딩으로 연상하는 연습을 하시면 수십줄 아니 수백줄의 코딩을 보더라도 나중에 어렵지 않을거에요

한줄의 글을 연상 코딩화를 하시면 코딩은 그리 어렵지 않고 일상의 코딩화가 되어 무지 재밌고 다양한 것들을 표현하고 싶어져요

쉬운듯 하면서도 어려운것 같아요.
좋은 글 감사합니다
팔로합니다

두개이상의 부품을 합쳐서 제어 하다보니간 오늘 건 복잡해 보일 수 있었겠네요
개별 부품 제어는 별거 없어서 그냥 코딩만 복잡해 보일 뿐이죠

아..이런 것 하시는 분들 정말 존경스럽습니다.
조금이라도 배우고 싶네요~

가상 시뮬레이터로 따라해보세요. 아두이노에 재미 붙이면 실제로 부품 사서 재밌는 주제로 만들고 싶은 욕망이 쌓이게 됩니다.

오... 이런 포스팅을 왜 이제야 봤을까요 ㅎㅎㅎ 앞글부터 정독해봐야겠네요 .

글쓰는 능력이 부족해서 좀 더 자세히 설명드리고 싶은데 쉽지 않네요

아두이노 갖고 놀고 싶었는데 하는 분이 있어서 반갑네요.

저도 만나게 되어 반갑습니다.

3월의 시작을 아름답게 보내세요^^
그리고 진정한 스팀KR 에어드롭!
[골든티켓x짱짱맨x워니프레임] 9차 옴팡이 이모티콘 증정 천명 이벤트! 그 첫번째 250명 !
https://steemkr.com/kr/@goldenticket/x-x-9-250

옴빵!
화이팅이요!

Coin Marketplace

STEEM 0.18
TRX 0.15
JST 0.028
BTC 63615.94
ETH 2475.04
USDT 1.00
SBD 2.54