도망가는 아두이노 RC카 응용 (아두이노)

in #kr-arduino6 years ago (edited)

도망가는 아두이노 RC카 응용 (아두이노)



오늘은 지난시간에 마무리로 이야기 했던 내용 중 하나를 선택하여 한번 실제로 동작을 테스트 해보면 좋을 것 같아서 이렇게 도전해 봤네요. 상황은 초음파센서 아두이노 RC카에 정면에 다가가면 초음파 아두이노 RC카가 다가온 방향의 반대로 일정거리 동안 도망가도록 주행패턴을 만들어서 실험을 하겠습니다.

1. 초음파센서 아두이노 RC카 회로도


  • 준비물 : L293D Motor Shield, DC Motor 2개, Servo Motor 1개, 초음파센서 1개, 외부전원 2개, 아두이노우노
  • 내용 : A4(Trig), A5(Echo)로 초음파센서에 연결하고 Servo Motor는 왼쪽 상당애 Servo Pin(-,+,Sig)에 연결한다. DC Motor 2개는 M3, M4에 연결합니다.

지난시간의 회로도 입니다.

2. 코딩



도망다니는 아두이노 RC카를 상상하여 그 상상을 코딩화 하는 과정을 이야기 할까 합니다. 상상의 내용은 다음과 같습니다.

[도망가는 아두이노 RC카 상상하기]

  1. 전방에 다가오는 사람이 있는지 확인한다.
  2. 초음파센서로 인지거리 내 감지되면 감지된 반대방향으로 도망간다.
  3. 아두이노 RC카가 후면(엉덩이) 흔들기
  4. 다시 180도 회전하여 전방에 다가오는 사람이 있는지 확인한다.
  5. 이 과정을 계속 반복한다.

1) 전방에 다가오는 사람이 있는지 확인한다.


void loop() {
  //초음파센서 회전
  servo.write(angle);
  delay(50);
  
  int distance = sonar.ping_cm();

  //다가오는 사람 확인
  if(distance>0 && distance<10){
    도망가기;   
  }
  //회전 각도
  if (angle == 140) state = -10;    
  else if (angle == 40) state = 10; 
  angle += state;
}

2) 초음파센서로 인지거리 내 감지되면 감지된 반대방향으로 도망간다.


  //다가오는 사람 확인
  if(distance>0 && distance<10){
    movePattern(); //도망가기
  }

여기서, distance의 거리가 10cm 미만이면 다가 온 걸로 간주 하고 movePattern()함수로 반대방향으로 도망을 가 볼까요.

void movePattern(){
     int timeVal=0;
     motor1.run(BACKWARD);
     motor2.run(BACKWARD);
     delay(500);   
    
    motor1.run(FORWARD);
    motor2.run(BACKWARD);
    timeVal=(180-(angle-90))*5.56;
    delay(timeVal);   
    
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    delay(2000);                
}

정면에 다가온 각도 방향의 정 반대로 도망을 갑니다. timeVal은 1초당 1000일때 1도 당 5의 값으로 가정하여 계산하면 해당 방향을 기준으로 180도 회전을 할려면 다음과 같은 식으로 표현할 수 있습니다.

timeVal=(180-(angle-90))*5;

Servo Motor의 회전(angle)각 방향이 100도면 RC카의 전방 진행 방향이 90도 임으로 왼쪽 10도 각이면 위 식으로 계산을 하면

각도 = 180-(100-90) => 170

만약에, angle이 70도이면

각도 = 180-(70-90) => 200

그리고, 이 각도의 회전각 시간을 구하면 timeVal 변수에 5값을 곱하시면 해당 각도에 대한 아두이노 RC카의 회전각이 나오게 됩니다.

뒤로 회전이 된 후 2초동안 도망가게 됩니다.

motor1.run(FORWARD);
motor2.run(FORWARD);
delay(2000);  

이렇게 하면 계속 후진하는 동작이라서 뭔가 전진하거나 자신의 자리로 되돌아오는 그런 명령들이 필요 하다고 생각되실 꺼에요. 오늘 실험은 하나의 패턴 도망자 아두이노 RC카 이기 때문에 하나의 패턴에만 집중하기 위해서 코딩하고 싶지만 생략했습니다.

다른방식으로 표현하면

전방 기준으로 왼쪽은 오른쪽으로 회전하고 오른쪽은 왼쪽으로 회전하고 싶다면 코딩이 좀 길어집니다.

void movePattern(){
     int timeVal=0;
     motor1.run(BACKWARD);
     motor2.run(BACKWARD);
     delay(500);   
    if(angle>=90){
      motor1.run(FORWARD);
      motor2.run(BACKWARD);
      timeVal=(180-(angle-90))*5;
      delay(timeVal);   
    }
    else{
      motor1.run(BACKWARD);
      motor2.run(FORWARD);
      timeVal=(180+(angle-90))*5;
      delay(timeVal);         
    }
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    delay(2000);                

if문으로 해서 90도 기준으로 왼쪽인지 오른쪽인지 나누게 됩니다. angle>=90 은 90도 이상이면 우회전하게 되고 90도 미만이면 좌회전을 하게됩니다. 이렇게 하면 timeVal 값을 구하는 식은 한개가 달라집니다.

90도 이상 => timeVal=(180-(angle-90))*5;
90도 미만 => timeVal=(180+(angle-90))*5;

보시면 90도 이상이면 180도에서 빼주지만 90도 미만은 180도에서 더해주면 됩니다. 식이 잘 이해가 안되면 angle(각) 값을 숫자로 대입해 보세요. 그러면 이해가 쉬울 듯 합니다.

3) 아두이노 RC카가 후면(엉덩이) 흔들기


도망 간 다음 아두이노 RC카가 후면을 엉덩이 흔드는 것처럼 흔드는 동작을 추가 해 볼까요.

void movePattern(){
  생략...
    
    for(int i=0;i<3;i++){
     motor1.run(FORWARD);
     motor2.run(BACKWARD);
     delay(300);
     motor1.run(BACKWARD);
     motor2.run(FORWARD);  
     delay(300);
    }
}

우로 0.3초 회전 한 뒤에 좌로 0.3초 회전한다. 이 과정을 3번 반복하면 엉덩이를 흔드는 동작처럼 표현 할 수 있겠죠. 만약에 꼬리 같은 걸 후면에 붙여 놓으면 좀 더 그럴싸 해 지겠죠.

4) 다시 180도 회전하여 전방에 다가오는 사람이 있는지 확인한다.


void movePattern(){
  생략...
    
  motor1.run(BACKWARD);
  motor2.run(FORWARD);
  timeVal=180*5;
  delay(timeVal); 
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  angle=90;
  servo.write(angle);
  delay(100);   
}

좌회전으로 180도 회전하여 다시 아까 다가 온 방향으로 아두이노 RC카는 향하게 회전 시킨 후 아두이노 RC카는 정지 상태가 됩니다. 초음파센서는 다시 정면 90도 방향으로 향하게 합니다. 이렇게 해서 도망갔다가 다시 주변을 탐색을 시작하기 전까지의 동작이 끝나게 됩니다. loop()함수는 끝나고 다시 재호출 되어서 loop()함수는 주변에 사람이 있는지 확인하게 됩니다.

5) 이 과정을 계속 반복한다.


위 과정을 loop()함수에서 계속 반복하게 됩니다.

위 과정을 종합하여 코딩하면,

[기본소스]

#include <AFMotor.h>
#include <Servo.h> 
#include <NewPing.h>

AF_DCMotor motor1(3);
AF_DCMotor motor2(4);

Servo servo;
const int servoPin = 10;
const int TRIG = A4;
const int ECHO = A5;
const int MAX_DISTANCE = 100;
NewPing sonar(TRIG, ECHO, MAX_DISTANCE);

int speed=200;
int state = 10;
int angle = 90;

void setup() {
  //Serial.begin(9600);
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
  motor1.run(RELEASE);
  motor2.run(RELEASE);

  servo.attach(servoPin);
  servo.write(angle);
  delay(1000);
}

void loop() {
  //초음파센서 회전
  servo.write(angle);
  delay(50);
  
  int distance = sonar.ping_cm();
  
  //장애물 감지
  if(distance>0 && distance<10){  
     movePattern(); 
  }   
  //회전 각도
  if (angle == 140) state = -10;    
  else if (angle == 40) state = 10; 
  angle += state;
}

void movePattern(){
    int timeVal=0;
    motor1.run(BACKWARD);
    motor2.run(BACKWARD);
    delay(500);   
    
    //도망
    if(angle>=90){
      motor1.run(FORWARD);
      motor2.run(BACKWARD);
      timeVal=(180-(angle-90))*5;
      delay(timeVal);   
    }
    else{
      motor1.run(BACKWARD);
      motor2.run(FORWARD);
      timeVal=(180+(angle-90))*5;
      delay(timeVal);         
    }
    motor1.run(FORWARD);
    motor2.run(FORWARD);
    delay(2000);  
    
    //후면 흔들기
    for(int i=0;i<3;i++){
      motor1.run(FORWARD);
      motor2.run(BACKWARD);
      delay(300);
      motor1.run(BACKWARD);
      motor2.run(FORWARD);  
      delay(300);
  }
  
    //원위치 전방 보기
    motor1.run(BACKWARD);
    motor2.run(FORWARD);
    timeVal=180*5;
    delay(timeVal); 
    motor1.run(RELEASE);
    motor2.run(RELEASE);
    
    angle=90;
    servo.write(angle);
    delay(100);     
}

동작 하나하나 패턴을 추가해서 표현하니깐 movePattern()함수 내 동작 패턴이 꽤 길어 졌네요. 아두이노 RC카가 어떻게 움직이길 바라면 그 움직임을 하나씩 원하는 행동을 하도록 상상하고 그 상상을 이렇게 코딩화 하면 됩니다.

위 소스는 그냥 즉흥적으로 간단히 만든 거라서 사실 지져분한 코딩입니다. 맘에 들지 않는 코딩이라는 뜻이죠. 뭔가 축약된 코딩을 좋아하는데 이렇게 길게 늘려서 일일히 코딩하는 것을 싫어하기 때문에 맘에 들지는 않지만 대충 이런 느낌으로 코딩을 한다는 의미만 전달하기 위해서 그냥 이 소스로 마무리 합니다.

여러분들은 한번 다른 방식으로 도망자 아두이노 RC카를 만들어 보세요.

추가사항


위의 코딩만으로는 사실 문제점이 많습니다. 무조건 전방에 다가오는 물체에 대해서 도망만 가기 때문에 계속 후진하는 느낌의 코딩입니다. 또한 뒤로 도망을 갈때 보면 뒤에 장애물에 대한 감지가 빠져 있습니다. 이 부분을 추가할려면 loop()함수의 물체 감지 부분을 사용자 정의함수로 빼서 뒤로 도망가는 로직에 물체 감지 함수부분을 호출하는 식으로 코딩을 변경해야 합니다. 그리고 도망가는 2초간의 시간은 delay(2000) 하면 절대 안되고 delay()함수를 사용하지 않는 post delay()함수 안쓰고 delay 제어하기(아두이노) 의 원리를 이용해서 2초간 도망가는 주행을 하는 동안 장애물을 감지하는 코딩으로 수정해야 합니다. 그리고, 그냥 도망으로만 끝내지 않고 다시 도망을 갔다가 물체 감지된 방향으로 조금직 다시 직립주행을 하면서 물체와의 거리를 측정하면서 자신이 있던 자리로 되돌아가게 코딩을 하면 좀 더 재밌는 코딩으로 변경 됩니다.

지금 열거한 내용만 코딩을 하더라도 수정해야 할 부분과 추가해야할 코딩이 늘어납니다. 그러면 오늘 전달하고자 하는 도망자 아두이노 RC카의 원리가 제대로 전달되지 않기 때문에 코딩에서는 실제 추가하지 않겠습니다. 이부분은 여러분들의 상상코딩에 맡기겠습니다.

3. 결과


코딩은 그럭저럭 되었는데 결과는 썩 마음에 들지 않네요. 원하는 결과는 얻지 못했습니다. 1초를 1000으로 해서 180도를 1초 회전으로 첨에 잡았는데 회전하니깐 180도 이상의 각도로 회전이 일어나서 댜략 눈 짐작으로 900 정도로 180도로 간주하여 회전을 시켰지만 그래도 회전각은 원한 각도로 정교하게 회전을 되지 않았네요. 2~3번의 주행 테스트를 하고 post를 한 거라 정교한 결과를 얻지 못해서 아쉽네요.

위 영상을 보시면 회전각 오차가 크고 도망가는 주행이 직립주행이 되지 않았네요. 건전지가 추가되고 무게중심이 보조 바뀌쪽으로 좀 더 가서 그런지 보조바퀴의 방향각에 의해서 회전이나 직립주행의 오차가 심하게 발생했네요. 아두이노 RC카의 몸체에 대해서 교정을해야하고 수학적으로 DC기어모터의 속도와 시간값을 통해 회전각을 정교하게 해야하는데 단순하게 눈짐작으로 실험을 한계 이런 오차결과를 만들어 내고 말았네요.

결과는 마음에 들지 않지만 코딩은 대충 어떤 느낌으로 설계하는지만 이해하는 시간이 되었으면 합니다. 기본적으로 이렇게 출발하고 조금씩 문제점에 대해서 해결 코딩을 해가면서 좀 더 정교한 프로그램을 만들어가는 것이죠.

마무리


원래 상상의 의도는 도망자 아두이노 RC카를 만들고자 했는데 느낌이 꼭 애완동물이 주인을 피해 도망갔다가 꼬리를 흔들고 다시 주인이 있는 방향으로 다시 바라보는 느낌의 코딩이 되어버렸네요.

이 느낌으로 좀 더 추가해 볼까 하는 생각도 드는데 아직 결정은 안했습니다. 따라다니는 아두이노 RC카를 다음편에 이야기 할까 그냥 여기서 끝낼까 고민을 좀 해봐야 겠네요.

코딩은 아직 안했는데 상상을 잠깐 해보고 결정해야 겟네요.

Sort:  

Go here https://steemit.com/@a-a-a to get your post resteemed to over 72,000 followers.

엉덩이 흔들기는 뭐죠? ㅋㅋ 꼬마들한테 인기 좋을 것 같습니다. ㅎㅎ

꼬리 흔들기인데 도망가다가 후면 좌/우 회전을 재밌게 표현한 것이죠.
사실 동물 모형을 만들어서 씌우면 엉덩이를 흔드는 모습으로 연출이 될 듯 싶어서 이렇게 표현했네요. ^^

동물모양 만들면 되게 웃길 것 같습니다. 한 번 해보시면 좋겠네요. 일단 3D프린터라도 모형 간단히 한 번 만들어 보시죠?

3D 프린터가 없는게 한계네요. 앞면 Servo Motor와 초음파센서 고정 틀도 없어서 테이프로 붙여서 실험했네요.
뭔가 표현하고 싶을 때 3D 프린터가 전실하기는 하네요.
손수 만드는 것은 손재수가 없어서 그건 힘들고요.
암튼 동물 모양을 아두이노 RC카에 씌우면 볼만은 할 것 같아요.

codingman 님 수도권이시면, 무료로 해볼 수 있는데가 몇 군데 있습니다. 성수 메이커 스페이스 하고요. 그 다음에 금천구청하고요. 경기 성남에 K-ICT 디바이스랩도 신청하면 사용가능한 걸로 알고 있어요. 3D프린트 가격은 싼 거는 20만원 선도 있어서 여유 있으시면 구매도 나름 괜찮은 선택인 것 같아요. 3D프린트 모델 만들 때는 123D가 쉬운 툴이고 초딩도 쪼금 배우면 할 수 있어요. 그리고 라이노가 중고급 용입니다. 그리고 아예 모델링 못하시면 싱기버스에 검색해서 무료버전을 다운 받아서 바로 출력하시면 됩니다. ㅎㅎㅎ https://www.thingiverse.com/ 재밌을 것 같은데 한 번 해보세요. ㅎㅎ

지방쪽이라서 그게 쉽지 않네요. 3D 프린터도 생각하고 있긴 하는데 사실 한두번 실험에 사용할 틀 제작하는데 3D 프린터 사는 것도 낭비인 것 같아서 그냥 있는 범위내에서 실험하고 있네요.

창조경제혁신센터하고 K-ICT 디바이스랩하코 콘텐츠코리아랩은 전국에 큰 곳에 몇 개 있는데요. 그 중에 codingman 님 있는 도시에 있으시면 사용할 수도 있어요. 그리고 대학에도 일반 사용 가능한데가 가끔 있습니다. 찾아보시면 공짜로 되는데가 은근히 좀 있어요.

창조경제혁신센터는 제가 사는 동네랑 극과 극이네요. 가다가 퍼질 듯이요.
K-ICT 디바이스랩은 제가사는 동네에는 없네요.
3D 프린터 무료로 해주는데 있었던 것 같기는 한데 아무튼 알려주셔서 감사하네요.
근처 대학은 많기는 한데 대학들은 찾아가기가 싫음 ^^
절차도 귀찮고 외부인이 찾아오는 것도 싫어하잖아요 대학들 보면요.
관련 산학협력센터같은데에서 해줄 것 같기는 해요.

신기 방기 ~ ㅎㅎ

이게 하나씩 상상한 동작을 패턴으로 만들어 움직이게 하면 애안동물 RC카로 업그레이드 될 수 있어요.
^^

내용이 정말 알찹니다. 아두이노 공부하는 학생들이 보면 정말 좋은 교제가 될 것 같습니다.

그정도는 아니고요. 그냥 제가 예전에 아두이노 공부했던 것들을 재미로 post하는 수준이에요. ^^

Congratulations @codingman! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published a post every day of the week

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.032
BTC 63330.76
ETH 3090.95
USDT 1.00
SBD 3.80