본문 바로가기
Developer/Drone DIY

드론 DIY | 아두이노 프로그래밍

by Doony 2015. 12. 9.

드론 DIY | 아두이노 프로그래밍 


4편. 본격적인 아두이노 탐구



지난 편에, 드론의 두뇌같은 역할을 하는 게 아두이노라고 하였다. 그렇다면 아두이노에 어떻게 프로그래밍하는지, 즉 두뇌라는 녀석을 어떻게 설계하는지를 이번 편에서 다뤄볼 예정이다... 아마 프로그래밍 자체는 안할 것 같긴한데.. 그래서 이번 포스팅이 참 애매하다. 만약에 드론 DIY 포스팅을 책으로 출판한다면야 열심히 해서 아두이노 예제들까지 다 올려볼텐데... 아직 그건 아니므로!!


일단은 아두이노는 C언어 기반이라고 한다. 나도 컴퓨터 전공자는 아니기 때문에, AVR 공부도 딱히 해본 적도 없기 때문에 아주 기초적인 수준에서 이야기를 풀어나가고자 한다.


아두이노는 일종의 중간 매개체이다. 명령을 따르고 수행해주는 녀석이랄까. 음.... 뭔가 예시가 없을까.. 집에 들어왔을 때, 사람이 왔다는 걸 인지하고 불이 켜지지 않는가? 그걸 예로 들어보겠다.


1. 사람이 들어온다.

2. 적외선 센서가 사람이 들어왔다는 신호를 읽어들인다. 신호란 것은, 그냥 전류를 흘려주는 것 뿐이다.

3. 어? 전류가 흘렀네? 라는 걸 인지하여 형광등에 전류를 흘려준다.

4. 형광등에 전류가 들어왔으므로 등이 켜진다.



자 이런 절차가 있다고 하자.


아두이노가 중간 매개체라고 했는데 대체 어떤 역할을 하는걸까?

위의 사례를 보면, 결국 원하는 기능은 '사람 인지 -> 불 켜짐' 이다. 즉, 사람을 인지하고 불을 켜지까지, 화살표로 표시된 모든 부분을 아두이노가 해주는 것이다.


아 쓰고보니 더 어려워진 것 같다. 그냥 아두이노를 쓰면서 꼭 알고 갔으면 하는 것들만 체크해보자.


1. 아두이노는 어렵지 않다. 최대한 쉽게 만들어서 누구나 사용할 수 있게 만들어놓은 녀석이다. 그러므로 쫄 필요없다. 알고보면 다 별거없다.

2. 전기적 신호를 전달하는 것은 말 그대로 전류를 흘려주는 것이다. 기본적으로 신호는 0 (안흐름) 또는 1 (흐름) 이다. 


위 두가지는 거의 진리다. 추후에 PWM 부분에서 좀 더 복잡해지긴 하지만, 사실 이것도 복잡한게 아니라 단순한 것의 연속이다.

깊게 들어가면 물론 복잡해질 수도 있겠지만(나도 공부해보지 않아서 모름. 그러나 드론 만드는데는 굳이 필요하지 않음).



진리를 토대로 예제를 학습해보자. 예제하다보면 금방금방 느낌이 온다.


먼저 아두이노 문법적인 부분들을 살펴보도록 하자. 맘 같아선 실제로 아두이노 예제들도 다 같이 해보고 싶긴한데 그럴려면 포스팅이 너무 길어지므로.

아두이노 입문자라면 가장 많이 드나들 사이트가 아마도 아두이노 공식 사이트일 것이다.


특히 https://www.arduino.cc/en/Reference/HomePage 여기는 자주 가보시길 바란다. 모든 문법이 이 곳에 다 있다고 보면 된다.


이 곳에서 하나하나 설명만 다 봐도 어느정도 기초적인 이해는 할 수 있다.

엥? 너무 책보고 공부하는거랑 비슷하다고? 그렇다. 이건 책보고 공부하는거다.


실습도 해야한다. 실습은 아두이노 IDE - 파일 - 예제에서 많이 해볼 수 있다. 아두이노 예제 따라하기 정도는 이미 많은 블로그에서 하고 있으므로 넘어가기로 하고.

우리는 드론에 필요한 아두이노 부분만 좀 생각해볼 것이다.






자, 드론에 필요한 코딩이란 대체 뭘까?
코딩이란 쉽게 말해서 알고리즘이다.

알고리즘이란 쉽게 말해서, 사람을 인지하고 불이 켜지게 하는 그 모든 과정을 말한다.


생각해보자.

드론을 만드려면 대체 어떤 과정이 필요할까?

먼저 조종기에서 아두이노로 뭔가 신호를 쏴줄텐데, 그걸 인식하는 과정도 필요하다. 또한 그 인식된 신호를 통해 모터의 출력을 조절하는 과정도 필요하다. 또한 모터의 출력값을 적당히 상황에 맞게 잘 조절해서, 가만히 안정적으로 떠있게 만드는 과정도 필요하다. 또한 내가 좌측으로 움직이라고 조종기로 명령을 줬을 때, 안정적으로 좌측으로 움직일 수 있도록 하는 과정도 필요하다. 또한 내가 긴급 정지 버튼을 눌렀을 때 모터 출력을 모두 0으로 만드는 과정도 필요하다. 각도센서로부터 각도값을 잘 얻어오는 과정도 필요하다. ...


수 없이 많은 과정들이 필요하고, 이 과정들을 모두 통틀어서 알고리즘이라고 보면 된다.



가장 기본적인 드론, 즉 조종기로 그냥 조종만 하는 드론의 경우에는 딱 한가지 과정만 잘 맞추면 된다.

바로, 자세 제어.


자세 제어가 드론 코딩에 있어서 거의 핵심이라고 볼 수 있다. 


일반적으로 드론의 자세 제어는 PID 제어라는 것을 통해서 이루어진다. Proportional, Integrate, Differential... 맞나. 아무튼 비례, 적분, 미분이라고 보면 된다.

이게 대체 무슨 의미냐고? 자세한건 다음 포스팅에서 다룰 예정이지만, 확실한건 이건 어려운 개념이 아니라는 것이다.

PID제어의 장점 중에 하나가 직관적이고 모델링 없이 바로 적용할 수 있다는 점이다. 아무튼 이건 다음에 다루기로 하고. PID제어를 위해 알아야할 아두이노 문법은 대체 뭘까?


문법이라고 할 것 까지도 없다.

그냥 +-*/ 사칙연산만 잘 해주면 된다. 아두이노는 loop가 무한반복되는 시스템이기 때문에, 그 loop안에 사칙연산만 잘해서 말그대로 계산하는 알고리즘만 짜주면 모든게 끝! 아주 간단하다. 물론 간단하다고 시간이 짧게 걸리는건아니지만.. 





음... 아두이노에서 또 한가지 좋은 점은 라이브러리가 있다는 것이다. 요즘 오픈소스의 시대니뭐니 하는 말을 많이들 들어보셨을 텐데 오픈 소스의 개념이라고 보면 된다. 오픈 소스란, 사람을 인지하여 불을 켜는 것과 같은 '알고리즘'들, 혹은 세부적인 하나하나의 과정들을 사람들이 다 공유해놓은 것이다.

이를테면, 드론 PID 제어하는 코드도 오픈 소스로서 이미 웹상에서 찾아볼 수 있다. 


우리가 사용할 오픈소스는 바로 각도센서로부터 각도값을 얻어오는 것이다. 

각도 센서에 해당되는 코딩이 보기에는 매우 어려워보인다. 한번 참고하기 위해 가져와보겠다.



void kalman() {

  Wire.begin();

  i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz

  i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling

  i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s

  i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g

  while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once

  while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode

  while (i2cRead(0x75, i2cData, 1));

  if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register

    Serial.print(F("Error reading sensor"));

    while (1);


  }


  delay(100); // Wait for sensor to stabilize


  /* Set kalman and gyro starting angle */

  while (i2cRead(0x3B, i2cData, 6));

  accX = ((i2cData[0] << 8) | i2cData[1]);

  accY = ((i2cData[2] << 8) | i2cData[3]);

  accZ = ((i2cData[4] << 8) | i2cData[5]);

  // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2

  // We then convert it to 0 to 2π and then from radians to degrees

  accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;

  accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;


  kalmanX.setAngle(accXangle); // Set starting angle

  kalmanY.setAngle(accYangle);

  gyroXangle = accXangle;

  gyroYangle = accYangle;

  compAngleX = accXangle;

  compAngleY = accYangle;


  timer = micros();


}



이게 전부가 아니고 이건 일부분에 불과하다. 아니 사칙연산만 하면된다면서 대체 [] 대괄호는 뭐고 대체 뭐꼬

결론부터 말하면, 굳이 알 필요는 없다. 왜냐? 오픈소스이기 때문이다. 주어진 자료를 통해 우리는 원하는 값만 얻어내면 된다는 말이다. 

여기에 쓰인 알고리즘은 물론 수학적으로도 의미가 있고 하나하나가 다 의미있는 것들이지만 굳이 몰라도 된다는 얘기.


그니까 쫄 필요없다!!!! 누구나 드론 DIY를 할 수 있다는 의미.



다음 포스팅에서 계속...



질문 사항은 댓글이나, 카카오톡 아이디 yngneers를 찾아주세요!



댓글