You are looking for information, articles, knowledge about the topic nail salons open on sunday near me 아두 이노 pid 제어 on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://chewathai27.com/to team, along with other related topics such as: 아두 이노 pid 제어 DC 모터 PID 제어 소스, PID 제어 코드, PID 제어 예시, PID 제어 쉽게, 파이썬 PID 제어, pid제어 실생활, PID 제어 원리, 서보모터 pid 제어
프로토타이핑 – 12. 아두이노 PID 튜토리얼 + PID제어기(wiki) :: 집밖은 위험해
- Article author: throwexception.tistory.com
- Reviews from users: 43925 Ratings
- Top rated: 4.0
- Lowest rated: 1
- Summary of article content: Articles about 프로토타이핑 – 12. 아두이노 PID 튜토리얼 + PID제어기(wiki) :: 집밖은 위험해 1.1 비례 제어. 1.2 적분 제어. 1.3 미분 제어. 2. PID 제어 구현. 3. 아두이노 PID 라이브러리. 4. 마치면서. 1. PID란 무엇일까? PID는 비례, 적분, … …
- Most searched keywords: Whether you are looking for 프로토타이핑 – 12. 아두이노 PID 튜토리얼 + PID제어기(wiki) :: 집밖은 위험해 1.1 비례 제어. 1.2 적분 제어. 1.3 미분 제어. 2. PID 제어 구현. 3. 아두이노 PID 라이브러리. 4. 마치면서. 1. PID란 무엇일까? PID는 비례, 적분, … https://www.teachmemicro.com/arduino-pid-control-tutorial https://ko.m.wikipedia.org/wiki/PID_%EC%A0%9C%EC%96%B4%EA%B8%B0 제어 시스템에서 제어기는 시스템의 출력이 목표 입력값이 되도록 고쳐나가야..집밖은 위험해OTL
- Table of Contents:
프로토타이핑 – 12 아두이노 PID 튜토리얼 + PID제어기(wiki)
티스토리툴바
8-2. Arduino Car로 PID 제어
- Article author: kingpodo.tistory.com
- Reviews from users: 44430 Ratings
- Top rated: 4.3
- Lowest rated: 1
- Summary of article content: Articles about 8-2. Arduino Car로 PID 제어 PID Control을 사용하여 Arduino Car에 Cruise System을 구현하기 전에 PID Control이 무엇인지 알아보겠습니다. PID 제어는 실제 응용분야에서 많이 … …
- Most searched keywords: Whether you are looking for 8-2. Arduino Car로 PID 제어 PID Control을 사용하여 Arduino Car에 Cruise System을 구현하기 전에 PID Control이 무엇인지 알아보겠습니다. PID 제어는 실제 응용분야에서 많이 … 1. PID 제어 Cruise System구현에 들어가에기 전에 전에 작성한 글에서는 PID 제어를 사용하지 않은 Cruise System을 구현하였고 그것에 문제점에 대하여 이야기했습니다. 아무런 지식이 없는 상태에서 바로 이글..그래, 우린 반드시 성공한다.
- Table of Contents:
드론 DIY | 아두이노 PID 제어 코드 (코드 첨부)
- Article author: hyongdoc.tistory.com
- Reviews from users: 17191 Ratings
- Top rated: 4.3
- Lowest rated: 1
- Summary of article content: Articles about 드론 DIY | 아두이노 PID 제어 코드 (코드 첨부) 지난 포스팅에서 PID의 원리가 뭔지, 대체 왜 필요한지에 대해 구구절절 설명했다. 따라서 이번 포스팅에서는 사실 가장 중요한? 아두이노 코드에 … …
- Most searched keywords: Whether you are looking for 드론 DIY | 아두이노 PID 제어 코드 (코드 첨부) 지난 포스팅에서 PID의 원리가 뭔지, 대체 왜 필요한지에 대해 구구절절 설명했다. 따라서 이번 포스팅에서는 사실 가장 중요한? 아두이노 코드에 … 지난 포스팅에서 PID의 원리가 뭔지, 대체 왜 필요한지에 대해 구구절절 설명했다. 따라서 이번 포스팅에서는 사실 가장 중요한? 아두이노 코드에 대해 쓰려고 한다. 서술하기에 앞서, 아두이노라는 녀석이 어떻게..
- Table of Contents:
태그
관련글
댓글111
광고
공지사항
최근글
인기글
최근댓글
태그
전체 방문자
티스토리툴바
Arduino uno, PID control, 아두이노 우노 PID 제어 라이브러리 활용
- Article author: setoo0922.tistory.com
- Reviews from users: 49871 Ratings
- Top rated: 4.8
- Lowest rated: 1
- Summary of article content: Articles about Arduino uno, PID control, 아두이노 우노 PID 제어 라이브러리 활용 아두이노 라이브러리 폴더에, 알집을 푸시면 됩니다. (libraries 폴더 안에 PID-1.2.0, 압축파일 안의 폴더를 푸시면 됩니다.) PID 제어 코드 분석. …
- Most searched keywords: Whether you are looking for Arduino uno, PID control, 아두이노 우노 PID 제어 라이브러리 활용 아두이노 라이브러리 폴더에, 알집을 푸시면 됩니다. (libraries 폴더 안에 PID-1.2.0, 압축파일 안의 폴더를 푸시면 됩니다.) PID 제어 코드 분석. – PID (proportional integral derivative control) control – PID 제어 라이브러리 다운 – PID 제어 코드 분석 PID (proportional integral derivative control) control 2020/09/20 – [정리, 공부해요/전기,..
- Table of Contents:
우선 Input값을 쉽게 바꿔주기 위해 가변저항 연결
화질이 별로지만 위의 궁금증 해결
태그
관련글
댓글0
공지사항
최근글
인기글
최근댓글
티스토리툴바
PID 제어와 아두이노 예제 코드 | Hard Copy World
- Article author: www.hardcopyworld.com
- Reviews from users: 1229 Ratings
- Top rated: 4.9
- Lowest rated: 1
- Summary of article content: Articles about PID 제어와 아두이노 예제 코드 | Hard Copy World PID 제어를 쓸 일이 생길수 있을 것 같아서 자료를 정리중입니다. 어차피 저도 이론적인 내용을 상세히 알지는 못하므로… 이론을 쉽게 정리하고 아두 … …
- Most searched keywords: Whether you are looking for PID 제어와 아두이노 예제 코드 | Hard Copy World PID 제어를 쓸 일이 생길수 있을 것 같아서 자료를 정리중입니다. 어차피 저도 이론적인 내용을 상세히 알지는 못하므로… 이론을 쉽게 정리하고 아두 … PID 제어를 쓸 일이 생길수 있을 것 같아서 자료를 정리중입니다. 어차피 저도 이론적인 내용을 상세히 알지는 못하므로… 이론을 쉽게 정리하고 아두이노 코드로 옮기는 작업을 해야죠. 정리되는대로 이 페이지는 업데이트 됩니다. [출처] PID제어란!!|작성자 화이팅 1. PID 제어란? 자동제어 방식 가운데서 가장 흔히 이용되는 제어방식으로 PID 제어라는 방식이 있다. 이 PID란, P: Proportinal(비례) I: Integral(적분) D: Differential(미분) 의 3가지 조합으로 제어하는 것으로 유연한 […]
- Table of Contents:
아두이노 드론과 PID 제어 :: 찬찬히 로봇 메이커
- Article author: sally241.tistory.com
- Reviews from users: 10117 Ratings
- Top rated: 3.4
- Lowest rated: 1
- Summary of article content: Articles about 아두이노 드론과 PID 제어 :: 찬찬히 로봇 메이커 드론의 제어법을 구글에서 여러번 찾아보았다. 기본은 PID제어를 사용하였고 여기에 추가적으로 P제어를 두번한 PPID(?)제어라던가 D제어를 두번한 PIDD … …
- Most searched keywords: Whether you are looking for 아두이노 드론과 PID 제어 :: 찬찬히 로봇 메이커 드론의 제어법을 구글에서 여러번 찾아보았다. 기본은 PID제어를 사용하였고 여기에 추가적으로 P제어를 두번한 PPID(?)제어라던가 D제어를 두번한 PIDD … 사실 드론의 하드웨어도 중요하지만(모든 로봇들이 그러하듯) 더욱 중요한 것은 제어법이라고 생각한다. 드론의 제어법을 구글에서 여러번 찾아보았다. 기본은 PID제어를 사용하였고 여기에 추가적으로 P제어를..
- Table of Contents:
아두이노 드론과 PID 제어
티스토리툴바
DC Mouse 3. 아두이노 DC 모터 PID 제어
- Article author: maxpulse.tistory.com
- Reviews from users: 38979 Ratings
- Top rated: 4.3
- Lowest rated: 1
- Summary of article content: Articles about DC Mouse 3. 아두이노 DC 모터 PID 제어 아두이노 나노로 모터 2개의 엔코더 입력에 문제없음을 확인함 (DC Mouse 2 참조). PID 제어를 구현해본다. 마이크로 마우스에서 직진과 회전 구간을 … …
- Most searched keywords: Whether you are looking for DC Mouse 3. 아두이노 DC 모터 PID 제어 아두이노 나노로 모터 2개의 엔코더 입력에 문제없음을 확인함 (DC Mouse 2 참조). PID 제어를 구현해본다. 마이크로 마우스에서 직진과 회전 구간을 … 아두이노 나노로 모터 2개의 엔코더 입력에 문제없음을 확인함 (DC Mouse 2 참조) PID 제어를 구현해본다 마이크로 마우스에서 직진과 회전 구간을 구분해서 동작하는데 직진 구간에서는 벽에 부딪히지 않도록 양..
- Table of Contents:
태그
‘로봇 만들기 – AVR마이크로 마우스’ Related Articles
공지사항
최근 포스트
태그
검색
전체 방문자
See more articles in the same category here: https://chewathai27.com/to/blog.
프로토타이핑 – 12. 아두이노 PID 튜토리얼 + PID제어기(wiki)
728×90
https://ko.m.wikipedia.org/wiki/PID_%EC%A0%9C%EC%96%B4%EA%B8%B0
제어 시스템에서 제어기는 시스템의 출력이 목표 입력값이 되도록 고쳐나가야 합니다. 가장 유명한 제어기중 하나는 PID 제어기로 비례, 적분, 미분의 약어라고 할수 있습니다. 이번에는 아두이노 PID 튜토리얼에 대해서 살펴보면서 이 프로젝트에 제어기가 어떻게 사용되는지 알아봅시다.
앞으로 볼 내용은 아래와 같겠습니다.
1. PID가 뭘까?
1.1 비례 제어
1.2 적분 제어
1.3 미분 제어
2. PID 제어 구현
3. 아두이노 PID 라이브러리
4. 마치면서
1. PID란 무엇일까?
PID는 비례, 적분, 미분의 줄임말이라고 할수 있습니다. 또한 시스템에서 제어기가 요란을 대처하는 방법이라고도 할수 있는데요. 여기서 말하는 제어기는 피드백 시스템에 존재하는 제어기를 말합니다. 그래서 특정 수치값을 읽고 내가 할수있는 일을 하는거라고 할수 있겠습니다.
피드벡 시스템은 출력 결과를 입력으로 되돌려주는 시스템이라고 할수 있는데요. 난로의 불을 제어하는 예제로 한번 배워보겠습니다. 간단한 그림은 아래와 같아요.
여러분들이 일정 온도를 유지하고 싶으면, 센서는 매 시간마다 온도를 측정해주고, 이 측정한 온도가 희망 기준 온도에서 증가하거나 감소했을탠대 이 차이를 오차로 피드백하게 해줍니다.
1.1 비례 제어 Proportional Control
비례 제어는 에러를 얼마나 많이 비례해서 제어할수 있는지를 말하고 있습니다. 예를들자면 위 난로에서 연료를 조절하는 전기 밸브가 있다고 합시다. 오차가 작다면, 설정 값과 측정 값이 일치하도록 밸브는 작은 양의 연료를 줄것이고, 오차가 크다면 벨브로 더 많은 연료를 줄겁니다.
=> 현재 상태에서 오차 값 크기에 비례하여 제어(원하는 값에 빨리 도달)
– 좌측은 제어이전, 우측은 P 제어 이후
=> 제어 이전에는 출력이 목표 값(1)에 도달하지 못함
=> P 제어 이후 오차 값(목표 값 – 현재 값)만큼 비례해서 신호를 증폭한다.
1.2 적분 제어 Integral Control
비례제어가 요란을 제거해 주었다면, 적분 제어는 이 오프셋 오차를 제거해서 에러를 0으로 만들어줍니다. 제어기는 시간에 대해 오차가 누적되므로 적분 제어기 없이는 오차에 제대로 대응할수 없습니다.
이전의 예시 계속 보면 연료 출력이 증가하거나 감소한 이후에도 초기 위치가 아닌 지점에서 가만히 있게 됩니다. 적분 제어는 이를 감지해서 연료 밸브를 기존의 자리로 돌려주는 역활을 하겠습니다.
=> 정상상태 오차를 제거(누적된 오차로 인해 원하는 값에 수렴하지 못하는 부분을 제거)
– 좌측은 비례제어만 한 결과, 우측은 PI 제어 결과
=> 비례제어만 한 경우 존재하는 정상상태 오차를 적분 제어를 통해 제거함
=> 하지만 오버슛이 심각해짐
1.3 미분 제어 Derivative Control
마지막으로 미분 졔어는 오차의 변화율을 조절시킵니다. 만약 적분 제어에 누적 오차가 보이는 경우에 미분 제어가 이 오차를 예측하여 얼마나 오차가 빠르게 변하는지를 보고 얼마나 고쳐야 할지 찾아냅다. 비례 제어와 적분 제어가 대처하지 못하는 동역학적 에러에 대해서 최적의 동작을 한다고 할수 있겠습니다.
위 난로 예제에서 120도를 설정했지만 130도에서 140도로 올라가는 상황이라고 해봅시다. 비례적분 제어기는 오차의 크기에 대응해서 동작하고는 있지만, 오차가 빠르게 발생하는 경우에서는 대처하기가 어려우나 미분 제어기는 오치의 변화율을 보고 이에 맞게 조절할수가 있습니다.
– 좌측은 PI 제어기, 우측은 PID 제어기
=> 기존의 출력갑이 크게 변하는데 미분 제어를 통해 오버슛을 줄이고 안정하게 만든다
– PID는 위와 같은 형태로 사용하기도 되지만 P 제어기, PI 제어기, PD 제어기만 사용하는 경우도 있음
– PID 제어시 발생가능한 문제
1) 계산된 제어값이 구동기가 동작할수 있는 한계 보다 커 구동기 포화(sturation)이 발생하는 경우
2) 오차 적분값이 크게 누적되어 출력이 설정에 가까워지면 제어가 작아져야하나 큰 값을 출력하여
설정값에 도달하는데 많은 시간이 걸리는 경우
-> 위 문제를 적분기의 와이드업이라 함 => 안티 와이드업 기법으로 PID 제어기를 보완해주어야함
– 제어 파라미터 K_p, K_i, K_d를 제어 이득, 게인이라 부름. 적절한 이득값을 얻는 과정을 튜닝(tunning)이라고 함.
https://ko.m.wikipedia.org/wiki/PID_%EC%A0%9C%EC%96%B4%EA%B8%B0
다시 돌아와서
설정 입력값 r(t)가 있고, 출력으로 y(t), 제어 입력 u(t). 오차 e(t)가 있겠습니다. 위 난로 예제에서 보면 r(t)는 희망 온도, y(t)는 실제 온도라 할수 있습니다. e(t)는 실제 온도와 희망 온도의 차이라할수있고, u(t)는 PID 제어기로 교정한 신호의 총합이라 할수 있겠습니다.
원하는 성능을 얻을수 있또록 PID 제어기의 값들을 고치는 작업을 튜닝이라 부르며, 위 그림에서 K 상수들을 잘 조절해주어야 합니다.
코드로 PID 제어하기
아두이노 스캐치에서 PID 제어기를 구현하려면 5개의 파라미터가 필요합니다
-> 비례, 적분, 미분 상수와 입력값과 기준 설정 값
PID 계산은 반드시 내부 루프 함수에 있어야하며, 함수 시작시에는 수행 시간 (elapsed time)을 설정해주어야 합니다. 현재 시간은 millis()로 얻겠습니다.
currentTime = millis(); elapsedTime = currentTime – previousTime;
오차는 설정 지점과 입력의 차이로 얻겠습니다.
error = setPoint – input;
적분 오차는 시간에 대한 누적 오차라 하였으니 아두이노로 구현하려면 다음과 같이 경과시간 * 오차를 해주면 되겠습니다.
cumError += error * elapsedTime;
미분 오차는 에러의 변화율이므로 다음과 같이 하겠습니다.
rateError = (error – lastError)/elapsedTime;
이제 제어 입력 u(t)를 정리하면 아래와 같겠습니다. 여기서 Kp, Ki, Kd는 이전에 설정한 상수가 됩니다.
output = Kp * error + Ki * cumError + Kd * rateError;
마지막으로 다음 반복회차를 위해서 변수들을 아래와 같이 지정해줍시다.
lastError = error; previousTime = currentTime;
이제 조금 더 제대로 해보면, 다음과같은 휠이 달린 모터가 있다고 해봅시다. 우리는 휠이 저 위치에 있기를 바라고 있습니다. 바퀴에 로터리 엔코더가 재 바퀴 각도에 대한 정보를 알려주므로 우리가 바라는 지점에서의 각도를 0이라 합시다.
휠이 위치를 벗어날떄마다 조정을 해주어야 하는데, 보통 모터는 PWM 펄스 폭 변조를 통해 제어됩니다. 펄스가 넓을수록 모터 회전이 더 빨라집니다.
이제 아두이노에서 다음과 같이 간단한 제어 예시를 구현해봅시다.
//PID constants double kp = 2 double ki = 5 double kd = 1 unsigned long currentTime, previousTime; double elapsedTime; double error; double lastError; double input, output, setPoint; double cumError, rateError; void setup(){ setPoint = 0; //set point at zero degrees } void loop(){ input = analogRead(A0); //read from rotary encoder connected to A0 output = computePID(input); delay(100); analogWrite(3, output); //control the motor based on PID value } double computePID(double inp){ currentTime = millis(); //get current time elapsedTime = (double)(currentTime – previousTime); //compute time elapsed from previous computation error = Setpoint – inp; // determine error cumError += error * elapsedTime; // compute integral rateError = (error – lastError)/elapsedTime; // compute derivative double out = kp*error + ki*cumError + kd*rateError; //PID output lastError = error; //remember current error previousTime = currentTime; //remember current time return out; //have function return the PID output }
위 루프 함수에서는 로터리 엔코더가 휠의 현재 위치를 주고, 그 값이 commputePID()함수의 파라미터로 사용됩니다. 이 함수는 PWM으로 모터 제어에 사용할 값을 반환해 줍니다.
300×250
8-2. Arduino Car로 PID 제어
반응형
1. PID 제어 Cruise System구현에 들어가에기 전에
전에 작성한 글에서는 PID 제어를 사용하지 않은 Cruise System을 구현하였고 그것에 문제점에 대하여 이야기했습니다. 아무런 지식이 없는 상태에서 바로 이글을 보신다면 이해가 어려운 부분이 생길 수 있습니다. 이전 글을 참고하시면서 보시는것을 추천드립니다. 또한 갑자기 난이도가 높아지는것을 느끼실 겁니다. 천천히 내용을 읽어보시고 다른 자료도 참고 부탁드립니다.
2. PID Control
PID Control을 사용하여 Arduino Car에 Cruise System을 구현하기 전에 PID Control이 무엇인지 알아보겠습니다. PID 제어는 실제 응용분야에서 많이 사용되는 제어기법입니다. 이러한 PID는 드론, 자동차, 온도등 안정적인 모터를 제어하는 부분에서 사용됩니다. 그러면 Cruise System에 PID Control이 어떻게 사용되는지 알아보겠습니다. 전에 올렸던 글을 보시면 안정적인 속도를 제어하기 위해서는 거리별 단계를 나누어 속도를 통제한다고 하였습니다. 그러면 그 단계가 무수히 많아진다면 좀더 좋은 속도제어가 될것이며 이를 가능하게 하는것이 PID 제어입니다. 아래 그림을 보시면 이해가 편하실 것입니다.
1) PID Control이란?
PID Control의 명칭의 P는 Proportional(비례), I는 Integral(적분), Differential(미분)의 앞글자를 따온 단어입니다. 즉 비례와 적분, 미분을 사용하여 적절한 값을 도출해 제어에 응용하는 기법입니다. 이는 대상의 출력값을 측정하여 이를 원하는 설정값과 비교하여 오차를 계산하고, 이 오차를 이용하여 제어에 필요한 제어값을 계산하는 구조입니다.
표준적인 형태의 PID 제어기는 아래의 식과 같이 세개의 항을 더하여 제어 값을 계산하도록 되어있습니다.
PID 제어서 각각의 항들은 오차값, 오차값의 적분, 오차값의 미분에 비례하기 때문에 비례-적분-미분 제어기라는 명칭을 가집니다.
비례항 : 현재 상태에서의 오차값의 크기에 비례한 제어작용을 한다.
적분항 : 정상상태 오차를 없애는 작용을한다.
미분항 : 출력값의 급격한 변화에 제동을 걸어 안정성을 향샹시킨다.
PID 제어기는 위와 같은 표준식으로 사용하기도 하지만, 경우에 따라서는 약간 변형된 형태로 사용되는 경우도 많습니다. 그 예가 P제어
PI제어, PD제어가 있습니다. 아래 사진은 PID를 이해하는데 많은 도움이 될꺼같아 위키백과에서 가져왔습니다. 나머지 설명들도 그래프를 같이 봐주시기 바랍니다.
<출처 - 위키백과>
2) P Control
비례 제어라고 불리며 설정값과 출력값의 편차에 비례해 연속적으로 변화하는 제어 방식으로, 출력값이 설정값에 근접할수록 미세하게 제어가 가능합니다. 비례제어는 출력값과 설정값이 차이가 적어질수록 서서히 감도가 좋아져 규칙적인 사이클이 발생하지만 잔류 편차로 인해 출력값이 설정값과 정확하게 일치하지 못하는 상태가 지속됩니다.
3) PI Control
비례 제어에서 발생하는 잔류 편차를 적분 동작으로 제어해 오차를 줄이기 위한 제어 방법입니다. 이 적분 제어는 정상 상태이때 오차를 제거하는 동작을 합니다. 전류 편차를 누적한 후 출력량을 늘려 오차를 제거하는 방식으로 적분 동작을 이용해 설정값에 빠르게 도달할 수 있다는 장점이 있습니다.
4) PD Control
비례 제어에서 과출력 상태에서 생기는 오차를 미분 동작으로 제어하기 위한 제어 방법입니다. 미분 제어는 급격한 출력값의 변동이 필요할 때, 기존 동작의 편차를 파악해서 출력값을 조절해 오차를 줄이고 다시 안정상태로 돌아가는 동작을 합니다. 미분 제어는 안정성을 향상시킬 수 있는 장점이 있습니다.
5) PID Control
비례 제어를 기본으로, 적분, 미분 제어를 결합한 최종형태입니다. 적분 제어를 통해 정상적 상태에서 오차를 줄이고와 응답속도를 높여주고 미분제어를 통해서 과출력 상태에서의 오차를 줄여 안정적인 상태로만듭니다. PID제어는 이런식으로 서로 단점을 보안하고 장점을 극대화 해줍니다.
5) Gain 값(제어 파라메터)
위에 그래프와 식을 보시면 라는 값이 있는데 이것이 Gain값입니다. 이는 위 그래프를 보시면 gain값이 변화에 따라 어떠한 그래프가 만들어지는지 아실 수 있습니다. 이러한 적절한 Gain값을 구하는 방식은 수학적 방법과 실험적 방법이 있는데 이를 구하여 수정하는 것을 튜닝이라고 합니다. 수학적으로 구하는 방법으로 대표적인 것은 지글러-니콜스 방법이라고합니다. 하지만 매우 어려워서 보통 실험을 통해서 gain값을 수정한다고합니다. 저도 gain값을 직접 넣어 실험을 해보면서 이 값을 구하였습니다.
3. PID Control Sample Code
아래 소스코드는 PID Control의 샘플코드입니다. 아래 코드를 활용해서 PID제어를 하시면 됩니다. 단 요즘 Arduino Library를 보시면 PID를 제공하고 있습니다. 저는 사용해본적이 없지만 그것도 해보시면 좋을꺼 같습니다.
/*gain값 실험을 통해서 직접 수정해 보시는것이 좋습니다. */ float Kp = 0.3; float Ki = 1.2; float Kd = 1.5; float error; // error값이란 설정값과 출력값의 편차를 말합니다. float errorPrevious; //전에 error값을 기억해둡니다. float safeDistance; //안전거리, 설정값입니다. float distance; // 현재 거리, 출력값입니다. double PControl, IControl, DControl; // 비례, 적분, 미분 제어항의 결과 값입니다. double Time = 0.004; //한번의 연산을 하는데 걸리는 시간입니다. 1회 loop의 시간입니다. double PIDControl; // P,I,D Contorl의 결과값입니다. void setup() { } void loop() { distance = 갱신 코드; // 장애물과의 거리를 가져옵니다. error = safeDistance – distance; // 안전거리와 장애물과의 거리를 빼서 error값을 구합니다. PControl = Kp * error; //비례항 입니다. IControl += Ki * error * Time; // 적분항 입니다. DControl = Kd * (error – errorPrevious) / Time; // 미분항입니다. PIDControl = PControl + IControl + DControl; // P, I, D 결과값을 더해줍니다. PIDControl = constrain(PIDControl, 0, 255); // constrain이라는 함수는 입력값은 값을 0 ~ 255사이 값으로 변환해서 반환합니다. analogWrite(6, PIDControl); //모터를 PIDControl값으로 PWM신호를 보내 움직입니다. errorPrevious = error; //이전 에러값를 기억합니다. }
다음글에서는 이 PID Control을 활용해서 Cruise 시스템을 구현해보겠습니다.
반응형
드론 DIY | 아두이노 PID 제어 코드 (코드 첨부)
지난 포스팅에서 PID의 원리가 뭔지, 대체 왜 필요한지에 대해 구구절절 설명했다.
따라서 이번 포스팅에서는 사실 가장 중요한? 아두이노 코드에 대해 쓰려고 한다.
서술하기에 앞서, 아두이노라는 녀석이 어떻게 동작하는지 알 필요가 있다. 이미 C언어를 어느정도 아는 사람이라면 척보면 다 알지만, 코딩을 처음 해보는 사람들에게는 매우 생소할 것이므로!
처음 C를 배우는 사람도 할 수 있게끔 설명하고자 한다.
1. 아두이노 코딩을 위해 반드시 알아야할 팩트들
아두이노 IDE를 먼저 받아야하는데, 그건 지난 포스팅에 있으므로!
오늘은 바로 코딩을 보도록 하겠다.
아두이노 IDE를 실행시키면 다음과 같은 문구들이 뜬다.
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
}
void가 뭔지, setup은 뭔지, loop는 뭔지 ()는 뭐고 {}는 뭔지. 아마 처음하는 사람이라면 아무것도 모를 것이다. 그런데 모든 걸 다 알아야 코딩을 할 수 있는게 아니다. 코딩이 뭔가? 알고리즘아닌가? 결국 아두이노 드론을 만드는데 있어서 가장 중요한건 알고리즘이다!
C언어(컴퓨터 프로그래밍 언어)라는 건 결국 우리가 생각한 알고리즘을 언어적으로 풀어주는 데 필요할 뿐, 알고리즘 자체가 될 수는 없기 때문이다.
고로 알고리즘을 짜고, 그 알고리즘을 코딩으로 적용할 줄만 알면 된다. 물론 엄밀히 말하면 프로그래밍 언어에 대한 지식이 있어야 응답속도와 반응성 등과 같은 정밀한 곳에서 더 이점을 가질 수 있겠지만.. 흔히 만드는 아두이노 드론 정도는 딱히 몰라도 가능하다. 고로 시작해보자.
아두이노는 크게 2부분으로 나뉘어져 있다.
void setup, void loop 가 바로 그것이다.
먼저 셋업 부분은 뭘까?
void setup() {
// put your setup code here, to run once:
}
친절하게 아두이노에서 설명해주고 있다. PUT YOUR SETUP CODE HERE, TO RUN ONCE:
즉, 딱 한번만 실행될 코드를 setup 부분에 채워넣으라는 것이다.
void loop() {
// put your main code here, to run repeatedly:
}
다음은 루프 부분. PUT YOUR MAIN CODE HERE, TO RUN REPEATEDLY:
즉, 루프 안에 들어가 있는 코드는 리피트!! 반복된다. 아두이노에 업로드하는 순간부터 영원히 반복된다. loop 안에 있는 건 그냥 영원히~~~ 위에서부터 아래로 코드가 실행되게 되는 것이다. setup은 위에서부터 아래로 한차례 실행되고 마는 부분이고, loop는 영원히 계속 반복되면서 실행되게 된다.
따라서 PID를 코딩으로 한다면, 어떤 부분을 setup에 넣고 어떤 부분을 loop에 넣을지를 생각해야한다.
PID는 이전 포스팅에서 말했지만, P, I, D 제어를 각각 한 후 그 제어값을 모두 더하여 적용 하게 된다.
즉, P제어 + I제어 + D제어 = PID 제어값 이 되는 것이다.
그리고 PID는 오차와 관련된 개념이라고 했다. loop가 어느정도 주기를 갖고 계속 반복되면서 실행될텐데, 매번 실행될때마다 오차가 달라질 것이다. 따라서 loop안에는 매번 달라지는 오차를 가지고 P, I, D 제어값을 새롭게 갱신해주어야 할 필요가 있다.
프로그래밍언어에서는 변수라는 게 있다. 말그대로 변하는 수다. P, I, D 게인값들은 변하지 않는 상수로 지정되어야 하고 오차가 변수로 지정되어야 할 것이다. (꼭 그런건 아니지만 일반적으로!)
그런데 아두이노는 P, I, D 라는 개념이 없다. 아무것도 모른다. 고로 그게 뭔지, 미리 선언해줄 필요가 있다.
예를 들어, Kp, Ki, Kd를 각각 PID의 게인값이라고 생각해보자. 그리고 난 그 값에 각각 1.2, 2.5, 3.2을 지정해주고 싶다.
그렇다면 아래와 같이 선언해주면 된다.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
}
자, 우측은 이해하기가 쉽다. Kp = 1.2 이런 부분은 직관적으로 와닿을 것이다. 그런데 좌측에 double은 뭔가?
아두이노는 우리가 선언하려는 숫자가 정수인지, 실수인지도 모른다. 그걸 우리가 말해주지 않으면 얘는 해석을 못한다. 1.2는 정수가 아니라 실수 영역에 있기 때문에 실수 변수를 얘기하는 double로 선언해주어야 한다. 정수 변수는 int 로 바꿔주면 된다.
자 이제 게인값들을 선언했으니, 오차도 선언해주도록 하자. 오차는 error 라고 하겠다. 오차는 정수보다는 실수인게 더 섬세하고 좋을 것 같으니 실수로 선언!
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
}
이 경우는 error에 특정 값을 넣지 않았다. 왜? 이건 변수니까 말이다. Kp, i, d는 상수로 고정시킬 것이기 때문에 저렇게 미리 선언해놓은 거고, error는 루프가 계속 반복실행됨에 따라 변하는 수이기 때문에 굳이 넣지 않았다. 저렇게 아무것도 넣지 않으면 초기값이 0으로 자동배정되는 걸로 알고 있다.
이제, 오차에 필요한 현재값과 목표값을 선언해보도록 하자.
목표값은 이전 포스팅에서 예를 든 것처럼, 10도라고 하고 desired_angle로 선언하겠다. 그리고 현재값은 mpu6050을 통해 추출한 각도값으로, 실제 코드는 있다고 가정하고 그 값은 current_angle 이라고 하겠다.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error;
double desired_angle = 10; double current_angle;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
}
자, 이게 error을 정의할 필요가 있다. error는 오차이다. 즉, 목표값에서 현재값을 뺀 수치가 될 것이다. 그리고 이 오차는 매 순간순간 달라질 것이다. 드론이 첨엔 10도 오차가 있다가, 그 쪽으로 회전을 시작하면 9도 8도 … 1도 0도까지 점점 오차가 줄어들게 아닌가. 고로 매 순간순간 갱신해줘야하는 변수가 되는 것이다. 그렇다면? 당연히 loop안에서 선언되어야 한다.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error;
double desired_angle = 10; double current_angle;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
current_angle갱신 코드; error = desired_angle – current_angle;
}
처음에 넣은 current_angle갱신코드란? 이건 현재 각도값을 의미하는데, 현재 드론이 기울어진 각도값도 mpu6050의 연산에 의해 실시간으로 변화되어야만 한다. 따라서 loop안에 넣어준거고, 이 부분은 mpu6050에 관련된 코딩이 필요하기 때문에 생략하고 위와 같이 표시하였다.
자, 이제 오차인 error가 아두이노에서 선언되어 해석가능해졌으므로, 본격적으로 PID 제어를 시작해보자.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error; double error_previous;
double desired_angle = 10; double current_angle;
double P_control, I_control, D_control; double Time = 0.004;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
current_angle갱신 코드; error = desired_angle – current_angle;
P_control = Kp * error; I_control = I_control + Ki * error * Time; D_control = Kd * (error – error_previous) / Time;
error_previous = error;
}
이번엔 추가된 게 좀 많다. 먼저 loop안을 보면, P컨트롤, I컨트롤, D컨트롤, 그리고 error_previous, Time 등과 같은 새로운 변수들이 선언된 것을 알 수 있다.
고로 맨 윗부분에 선언해준 것이다. 특히 Time은 한 루프가 도는 데 걸리는 시간을 의미한다. 내가 만든 드론은 한 루프 도는데 걸리는 시간이 약 3~4ms기 때문에 0.004로 해준건데, 사실 꼭 이렇게 할 필요는 없다. 그냥 4로 해도되고 4000으로 해도되고. Time이 수식적으로 가지는 의미는 그냥 ‘상수’일 뿐이다. 따라서 아무렇게나 지정해줘도, 또 다른 상수인 Kd나 Ki로 커버할만한 수준이기만 하면 되는것이다.
쉽게 생각해서, 4 * 6이나, 3 * 8이나 똑같은 수 아닌가. 곱해서 똑같이 나오게 숫자를 조정할 수 있기 때문에 꼭 time을 주기로 맞춰줄 필요는 없다는 것이다.
그리고 가장 아래보면 error_previous = error라고 선언한 부분이 있다. 아두이노에서는 이럴 때 우측에 있는 녀석을 좌측값으로 저장하라고 해석한다.
즉, error_previous라는건 지금 루프가 아니라 바로 이 전에 루프가 실행될 때의 error값을 의미한다.
만약 처음 error가 3이라고 해보자. 그러면 loop는 위에서부터 아래로 실행될 것이므로 error_previous에도 3이 저장 될 것이다.
그리고 loop가 다시 돌았을 때, 갱신된 현재각도에 의해 오차인 error가 5가 되었다고 해보자. 그리고 D_control을 보면, Kd * (5 – 3) / 0.004 가 될 것이다.
즉 컨트롤 부분에서 계산할 때 바로 직전의 에러 값이 previous에 저장되는 것이다.
I_control 부분은, 기존 I_control 값에다가 추가로 I 제어를 통해 얻은 값을 더하라는 것이다. 이전 포스팅에서 I 제어의 역할이 오차를 누적시켜 최종적으로 오차를 0으로 보내는 데 있다고 했는데, 이와 같은 방법으로 ‘누적’ 시킨다.
다만 언어적으로 좀 더 편하게 쓸 수 있다.
I_control += Ki * error * Time
이렇게 +=라고 하면, 위와 똑같은 의미를 가진다. 그냥 언어적인 것이니까 외우고 사용하면 된다.
이제 다음으로 넘어가보자.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error; double error_previous;
double desired_angle = 10; double current_angle;
double P_control, I_control, D_control; double Time = 0.004; double PID_control;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly:
current_angle갱신 코드; error = desired_angle – current_angle;
P_control = Kp * error; I_control += Ki * error * Time; D_control = Kd * (error – error_previous) / Time;
PID_control = P_control + I_control + D_control; PID_control = constrain(PID_control, 0, 255); analogWrite(6, PID_control);
error_previous = error;
}
PID_control이라는 변수를 또 만들었다. 말했듯이, PID제어값은 P, I, D 제어를 통해 나온 값들을 모두 더한 값이므로 그냥 더해준 것이다.
그 뒤에 나오는 constrain은, 아두이노에서 제공하는 함수이다.
저걸 쉽게 얘기하면, PID_control이라는 값이 0부터 255까지의 숫자 범위를 가지도록 제한하는 것이다.
예를들어 PID_control이 -100이라는 값이 되면, 0으로 저장이 되고, 1000이라는 값이 되면 255로 저장이 된다. 0과 255사이의 값은 그 값 그대로 저장된다.
이렇게 해주는 이유는, 그 뒤에 나오는 anaglogWrite이라는 함수가 0부터 255사이의 숫자만 받아들이기 때문이다.
analogWrite은 전압을 인가하는 함수로, 6번 핀에 0~255 사이에 해당하는 전압을 주라는 명령신호다. 0은 0V, 255는 5V를 주게 되는데
사실 실제 드론을 만들 때는 이 함수를 쓰지 않을 것이다. servo 라이브러리를 활용하여 다른 함수를 쓸 예정인데
이 포스팅의 목적은 아무튼 PID 제어 코드의 기본을 설명하는 것이기 때문에 그냥 그대로 가는걸로..
최종적으로 나온 PID_control 이라는 값이 가장 중요하다. 이게 PID 제어를 통해 구한 제어값이 되기 때문이다.
다음으로, 조금 보기좋게 코드를 정리하기 위해 다음과 같이 해보았다.
double Kp = 1.2; double Ki = 2.5; double Kd = 3.2; double error; double error_previous;
double desired_angle = 10; double current_angle;
double P_control, I_control, D_control; double Time = 0.004; double PID_control;
void setup() { // put your setup code here, to run once:
}
void loop() { // put your main code here, to run repeatedly: pidcontrol();
}
void pidcontrol() {
current_angle갱신 코드; error = desired_angle – current_angle;
P_control = Kp * error; I_control += Ki * error * Time; D_control = Kd * (error – error_previous) / Time;
PID_control = P_control + I_control + D_control; PID_control = constrain(PID_control, 0, 255); analogWrite(6, PID_control);
error_previous = error;
}
뭐가 달라졌나?
바로 void pidcontrol 이라는걸 만들었다는 데 있다. 이건 쉽게 말해, 그냥 그룹으로 묶어놓는거라고 보면 된다.
loop가 가장 중요한 부분인데, 위위처럼 loop안에 모든 코드를 작성하게 되면 보기가 매우 불편하다. 때문에 항목별로 묶어서 따로 이렇게 정리해놓는 것이다. loop안에는 pidcontrol() 이라고만 선언해주면, pidcontrol이라고 선언된 그룹이 실행되게 된다.
고로 위랑 위위는 똑같은 코드이다! 정리해서 보기가 더 수월할 뿐!
이게 전부다!
PID 제어는 이렇게 하면 된다. 시작할때 오차는 10도였겠지만 시간이 흐르면 0으로 점점 줄어들어 원하는 목표값에 도달할 것이다.
단, Kp, Ki, Kd라는 게인값을 잘 맞추었다면 말이다. 이전 포스팅에서 움짤을 하나 사용했었는데, 그것처럼 반응을 보일 것이다. 제대로 게인값을 맞추지 않으면 오차가 오히려 더 커질 수도 있다. 드론이라는 시스템에 맞춰 적당한 값을 맞춰주어야 하는데 이 부분은 실험을 통해서 검증할 수 있다.
아무튼 제어 코드는 이와 같다. 실제 드론을 날릴때는 이중 pid라고 하여, pid 제어를 겹으로 싸서 이중으로 만든 걸 쓸텐데 별로 어려울 건 없다. 똑같다! 그냥 겹으로 한번 싸주기면 하면 된다.
최종 코드는 계속 포스팅하면서 써가는 걸로.
*** 19.12 수정사항
안녕하세요.
많은 분들이 아두이노 코드를 요청하셔서 제작했던 코드를 아래 포스팅에 첨부하였습니다.
https://hyongdoc.tistory.com/270
So you have finished reading the 아두 이노 pid 제어 topic article, if you find this article useful, please share it. Thank you very much. See more: DC 모터 PID 제어 소스, PID 제어 코드, PID 제어 예시, PID 제어 쉽게, 파이썬 PID 제어, pid제어 실생활, PID 제어 원리, 서보모터 pid 제어