[아두이노 쿼드콥터] pid 제어 테스트 영상

Posted by Doony
2015. 12. 4. 01:45 아두이노 드론 프로젝트

안녕하세요! 와이엔지니어스입니다.

정말 오랜만에 포스팅을 또 제대로 하는 것 같습니다.


한동안 포스팅이 뜸했던 이유는 사실 pid 게인값 찾고 있었기 때문인데요. 아무리해도 찾을 수가 없어 원점으로 다시 돌아가 생각해보니, 이런저런 문제가 좀 있었습니다.


먼저 저희가 지금까지 한 내용을 요약해드리죠!!


지난 포스팅을 보시면 아시겠지만, 지금까지는 봉으로 축을 만들고 X자형으로 실험을 진행중에 있었습니다. 

(http://yngneers.tistory.com/39 참고하고 넘어오시면 됩니다.)


포스팅에서 영상 보시면 아시겠지만 비교적 잘 되었습니다. 특히 평형을 유지하란 명령과, 외란을 주었을 때의 반응은 어느정도 잡혀가고 있다고 생각했는데요.  이부분에서 한 2주 정도 시간 소비를 한 것 같은데... 좀 문제가 있었죠.


1. 10도 기울이란 명령, 20도 기울이란 명령을 제대로 듣지 않는다.

이게 무슨 말이냐면, 10도 기울이라고 하면 15~20도까지 기울이고, 20도 기울이라 하면 30도까지 기우는 겁니다.

물론 I게인까지 임의로 넣으면 어느정도 시간이 지난 후에 각도를 잡는 것을 확인하긴 했습니다만,

저희가 생각했을 때는 P게인 2개 만으로도 어느정도 잡혀야 한다고 봤거든요.

그래서 좀 이상했습니다.


2. 큰 봉 안으로 작은 봉이 들어가 있기 때문에 유격과 마찰이 발생한다.

아무래도 큰것과 작은 봉 사이즈가 딱 맞지는 않았습니다. 유격이 다소 있었기 때문에 외란주거나 각도 기울이라는 명령 때 드론 기체가 흔들리는 현상이 있었습니다. 단순히 추력이 약하거나 강해서 그런건 아니었거든요. 그래서 봉의 유격과 마찰 때문에 제대로 pid 테스트가 안될것 같았습니다.



여기서 결론을 냈습니다.

바로 봉으로 만든 축을 바꾸는 것입니다. 어떻게? 다시 줄로 돌아왔죠. 이왕 돌아온거 다시 처음부터 해보기로 했습니다. X자형으로 센서모듈을 둔 것을 다시 +자형, 즉 x, y축이 독립적으로 제어되도록 하는 시스템으로 복구했습니다. 처음 시도했던 방식대로요. (이건 http://yngneers.tistory.com/33 참고하고 넘어오시면 됩니다.)



아아 테스트 해보니 감탄사가 나왔습니다.

이 모든게 봉 때문이었다니!!!!!!!!!!! 줄이 불안정해서 봉으로 바꾼건데, 불안정하진 않았지만 오히려 그 안정성 때문에 더 pid제어가 제대로 되지 않았던 겁니다.


영상부터 보시죠..



이건 외부p, 내부p만 주고 d gain, I gain은 모두 0을 준 상태입니다. 아직 게인값을 잡지 않은 상태라 좀 흔들리긴하죠?

보시다시피 +자로 다시 돌려놓은 거고, 줄로 매달아 놓은 형태입니다. 

각도는 기울이라는 명령에 한 80~90% 정도만 따르는 듯 합니다. 10도 기울이라면 8~9도만 기울어지는 셈이지요.


아직 진동이 좀 셉니다. 두번째 p, 즉 내부 p게인이 크면 클수록 이렇게 진동이 세집니다.

외부 p가 크고 내부 p가 너무 작으면, 아주 천천히 각도 명령에 움직이는 것을 확인할 수 있었습니다. (영상엔 없습니다. 그 경향성이 그렇다는 겁니다.)


아무튼 봉으로 했을 때보다 훨씬 제어가 잘 되는 것을 확인하였습니다. 그냥 오감으로 느껴지는 게 다릅니다... 


이 상태에서 p값 조금 잡고 d 게인까지 좀 잡아봤는데요.



D를 잡으면서 느꼈던 가장 큰 차이는 무게 중심적인 느낌입니다.

이론상으로 제가 알기로는 D게인이 잡히면 오버슛과 settling time, 즉 안정화에 드는 시간이 단축되는 걸로 알고 있습니다. 저희는 정확한 측정보다는 일단 느낌을 잡기 위해 해봤는데...


이게 보니까 무게 중심이 안맞는 것도 어느정도 커버를 해주는 듯 싶었습니다. p게인만 사용했을 경우는 기체가 회전함에 따라 무게 중심이 이동하게 되고, 진동할 때도 무게 중심쪽으로 좀 치우치는 걸 확인했었는데요. d게인을 사용하고 나니, 무게 중심쪽으로 치우치는 게 많이 줄어드는 것을 볼 수 있었습니다.



아래는 I 게인도 대충 잡아본 값입니다.



I 게인이 있기 때문에 오차는 0으로 줄어듦니다. 물론 시간은 좀 걸리지만요. 

각도 컨트롤도 10도 기울이라면 정확히 10도만 갑니다. 물론 시간이 조~~금 걸리지만요.


이로써 대~~~~충 pid 값을 모두 잡아보았는데요. 아직 정밀하게 잡진 않고 그냥 컨셉 영상정도라고만 보시면 됩니다.

좀 더 다듬으면 정말로 이젠 pid 게인값 찾기가 끝날 것 같네요.





이건 실험 환경입니다. 의자에 줄 매달아 묶어놨고, 줄은 좀 흔들리는 경향이 있어서 손으로 살짝 잡아주기도 했습니다.



배터리도 동일한 녀석으로 하나 더 구매했습니다. 엘레파츠에서 주문했는데... 3일이면 온다더니 10일만에 왔네요. 전화해서 언제오냐고 항의하니까 바로 내일 발송해준다고 했다는... 주문이 누락된게 아닌가 뭔가 의심스러웠는데요. 아무튼 항의 전화 후 바로 다음 날 이렇게 도착했습니다. 



오늘 실험이 끝나고 그냥 한번 찍어봤습니다. 아두이노와 센서, 전선들이 어지럽혀지지 않게 검은테이프와 케이플타이로 좀 묶어줬습니다.



오늘은 여기까지!!

시험기간이라 또 언제 많이 해볼지 모르겠습니다만.. 최대한 되는대로 포스팅올리도록 하겠습니다.

이제 정말 축 제어만 끝나면 날려보는 영상........... 올리도록 해봐야겠죠?

오늘은 뿅!!


블로그 주소 및 이름 변경

Posted by Doony
2015. 11. 25. 11:21 와이엔지니어스 소개

안녕하세요! 와이 엔지니어스입니다.


아라미르 드론을 만드는 게 첫번째 프로젝트라 아직 공식 이름을 얘기하기가 좀 부끄럽긴합니다만,

앞으로 꾸준히 여러가지 해나갈 생각이라 블로그 이름과 주소를 부득이하게 변경하게 되었습니다.


기존 : Aramir Drone Project

http://aramir.tistory.com 


변경 후 : Y. NGneers

http://yngneers.tistory.com



아무래도 변경하고 나니, 기존 구글이나 네이버에 노출되었던 검색 결과는 모두 잘못된 주소라고 나올텐데요.


글들은 그대로 살아있으니 이 주소로 넘어오셔서 확인해보시면 되겠습니다.


감사합니다.

[아두이노 쿼드콥터] 앱인벤터로 만드는 안드로이드 블루투스 통신앱

Posted by Doony
2015. 11. 25. 01:10 아두이노 드론 프로젝트


안녕하세요 Y.NGneers입니다.


이번에 블로그 개편좀 해봤는데 어떤가요?

변화를 잘 모르시겠다구요? 옆에 카카오톡 친구 추가 버튼을 하나 추가했습니다....ㅋㅋㅋㅋ

모바일에서도, 컴퓨터에서도 잘 되는 것을 확인하였으니...

서로서로 카톡으로 정보 주고받으면서 도움이 되었으면 좋겠습니다.



이번 포스팅은 안드로이드 블루투스 앱을 만드는 편입니다.

궁극적으로는 핸드폰을 통해 실시간영상+조종을 하는 것인데요. 저희가 자바에 대한 지식이 아주 미니멀하기 때문에 앱인벤터를 활용하여 만들기로 했습니다.


일단 실시간 영상부는 라즈베리파이로 따로 실험해보고 있기 때문에 조종기를 어떻게 만드는지만 보도록 하겠습니다.

일단 구동방식은 이렇습니다.


슬라이더를 이용하여 드론의 출력값 조절

핸드폰 기울기를 통해 드론의 움직임 조절


따라서 총 3개의 변수를 안드로이드에서 아두이노로 전송해줘야하는데요. 첫번째는 슬라이더의 값, 두번째는 x축에 해당하는 값, 세번째는 y축에 해당하는 값입니다.





1. 시리얼 통신을 통해 값을 입력받는 알고리즘


기존 저희 포스팅을 보신 분들이라면 아시겠지만, 먼저 저희가 변수를 받는 알고리즘을 설명드리겠습니다.

저희는 현재 시리얼 통신을 통해 드론을 조종하고 있습니다. 따라서 변수를 받는 부분이 아래와 같습니다.



min_output = Serial.parseInt();

x_angle = Serial.parseInt();

y_angle = Serial.parseInt();


네..

입력값은 이런 형태를 띄어야 합니다.


40;170;190


이렇게 되면, min_output인 모터 출력값은 40을, x앵글은 170도(즉 평형인 180도에서 10도 차이나는 기울기), y앵글도 그 반대로 10도 차이나는 값을 입력하는 꼴인데요.


지금은 아두이노 시리얼모니터를 통해 직접 숫자를 입력하고 있죠.

따라서 앱인벤터로 위와 같은 명령을 보내는 앱을 만들어야했습니다.



앱인벤터로 넘어가볼까요?


2. 앱인벤터 코딩


앱인벤터는 누구나? 쉽게 안드로이드 앱을 만들 수 있도록 여러가지 기능을 지원해주고 있는데요.

기본적인 C코딩만 익히신 분들도 충분히 따라하실 수 있으시리라 믿습니다. 




앱인벤터는 굉장히 인터페이스에 충실한듯합니다.

일단 위와 같이 화면을 만들어줍니다. 


하나씩 뜯어볼까요? 위에서부터 보시길.


- Text for ListPicker1 : 블루투스 장치를 확인하기 위한 리스트픽커, 일종의 버튼입니다.


- 노란색슬라이더 : 실제로 앱 실행해보면 좌우로 넓게 퍼져있습니다. 0부터 180까지의 값을 가지게 할겁니다. 왜? 모터가 0부터 180까지의 출력치를 가지니까요.


- Throttle Control : 슬라이더가 가지는 값을 표시하게 될겁니다.


- Text for Label2,3,4 : 핸드폰의 orientation, 즉 기울기 값을 측정하여 각각 표시할겁니다. roll, pitch, yaw가 되겠죠?


이제 이렇게 인터페이스를 구성했으면 블록으로 넘어갑시다. 블록은 크게 2단계로 이루어져 있습니다.

선언부와, 실제 코딩부라고 보면 되는데요. 먼저 선언부를 봅시다.



아두이노 코딩과 마찬가지로 여기서도 변수를 선언해야합니다.


- initialize global (name, x_angle, y_angle) to [] : 괄호 안에 든 변수 3개의 초기값을 0,180 등으로 지정하는 것입니다. 참고로 left는 무시하세요 지우는걸 깜빡했네요.


- When screen1.initialize : 아까 구성한 화면이 screen1입니다. 그 화면이 켜지면, 즉 앱이 실행되면

do set slider1.min, max value to ~~ : 슬라이더의 최소값과 최대값을 0과 180으로 제한하라는 의미입니다.


- when listPicker1.before, after ~~ : 블루투스 쓰신다면 이 부분 복붙하시면 됩니다. 블루투스 장치 찾고 연결하는 코딩입니다.


이제 본격정긴 코딩부로 넘어가봅시다.




복잡해보이지만 크게 2가지로 이루어져 있죠? Orientation 센서, 즉 핸드폰 기울기 센서랑 Slider 부분입니다.


- when Slider.position changed : 슬라이더의 포지션이 바뀌면~~

do set [global name] to ~~thumbposition : 아까 선언한 name이란 변수에 슬라이더의 position을 저장하라는 의미. 즉 아까 0부터 180까지의 수 중에 하나가 저장이 되겠죠 위치에 따라.

do set label1~~~ : name이란 숫자를 label1 의 텍스트로 저장하란 의미입니다. 인터페이스상에서 숫자가 표시됩니다.


- when orientationsensor.orientationchanged : 오리엔테이션, 즉 기울기 센서 값이 변경되면 (실시간적으로 바뀝니다)

do set x_angle,y_angle : 슬라이더와 마찬가지로, x앵글, y앵글이란 변수에 기울기값을 저장합니다.

do label2 to~~ : 마찬가지로 label 텍스트에 기울기값을 띄우라는 것이죠.


if bluetooth.isconnected : 만약 블루투스가 현재 연결이 되어있다면

then call bluetooth~~ join name + ; + x_angle + ; + y_angle

블루투스 장치로 [name;x_angle;y_angle] 이란 텍스트로 명령어를 보내란 소립니다.



어때요, 참 쉽죠?



3. 아두이노 코딩


이제 아두이노 코딩으로 넘어가보죠. 간단하게 하기 위해 예제를 준비했습니다.


int a=0;

int b=0;

int c=0;



void setup() {

  // put your setup code here, to run once:

Serial.begin(115200);

Serial.setTimeout(10);

}


void loop() {

  // put your main code here, to run repeatedly:



Serial.print(a);

Serial.print('\t');

Serial.print(b);

Serial.print('\t');

Serial.print(c);

Serial.println('\t');


}


void serialEvent() {

  while (Serial.available()) {


    a=Serial.parseInt();

    b=Serial.parseInt();

    c=Serial.parseInt();


  }

}


네 단순한 구조입니다.
먼저 정수형 변수 a, b, c 3개를 선언하고, 시리얼 통신으로 그 값을 입력받습니다.
parseInt 를 사용하기 때문에 선언 받는 과정에서 딜레이가 생기는데요.
그 딜레이는 setTimeout() 을 통해 해결할 수 있습니다.

여기서 주의할 점은, 안드로이드와 통신하는 과정에서 위 딜레이를 적절한 수치로 잘 맞춰주어야 변수를 받는데 무리가 없다는 겁니다. 타이밍이 엇나가면 서로 뒤바뀐 수로 통신을 하기도 하더라구요.
저는 10 을 주었습니다. 10ms 죠.


이렇게 해보면, 다음과 같은 영상을 얻을 수 있습니다.




이렇습니다..

시리얼 모니터로 3개의 값을 출력하고 있습니다. 첫번째는 슬라이더값, 두번째는 x기울기값, 세번째는 y기울기값입니다.

화질이 선명하진 않네요..


드론을 조종하기 위해서 이 앱을 사용할 생각입니다. 

pid 튜닝만 완료되는대로 한번 테스트해보도록 하겠습니다!!!