[라즈베리파이 + DC모터 + PYTHON] 3. 라즈베리파이로 엔코더DC모터 PID 위치제어하기라즈베리파이 DC모터 드라이버 PYTHON 엔코더 홀센서 PID제어 안녕하세요. [라즈베리파이 + DC모터 + PYTHON] 1. 라즈베리파이와 MD10C로 DC모터 제어하기와 [라즈베리파이 + DC모터 + PYTHON] 1. 라즈베리파이로 엔코더 읽기에 이어서 하는 강좌입니다. 지난번에 아두이노, DC모터 드라이버, 엔코더를 이용해서 위치제어하는 방법을 알아봤는데요. [아두이노 + DC모터]1. L298로 DC모터 제어하기 [아두이노 + DC모터]2. DC모터 엔코더 사용하기 이번에는 아두이노를 라즈베리파이로 바꿔서 해보겠습니다. 이론적인 부분은 위에 아두이노 강좌를 참고하시길 바랍니다. 지난 두 강좌에서 라즈베리파이로 DC모터를 제어하고 엔코더값을 읽어오는 방법을 알아봤습니다. 오늘은 이 두가지를 합쳐서 위치제어를 해보도록 하겠습니다. 회로구성은 아래와 같습니다. 계속해서 말씀드리는 내용이지만, 라즈베리파이는 별도의 PWM 출력과 인터럽트 입력을 받는 하드웨어 없이 소프트웨어로만 구현하기 때문에 핀은 코드와 일치하기만 하면 원하시는대로 변경하셔도 상관없습니다.
코드는 다음와 같습니다. 길이가 좀 있으니 2부분으로 나누겠습니다. 먼저 아래는 여러 기본세팅입니다. 이전 강좌 내용을 합친 것이니 패스하겠습니다. import RPi.GPIO as IO pwmPin = 19 IO.setmode(IO.BCM) p = IO.PWM(19,100) encoderPos = 0 def encoderA(channel): IO.add_event_detect(encPinA, IO.BOTH, callback=encoderA) 여기서부터는 PID가 들어간 핵심코드입니다. PID에 대해서는 코드 밑에서 설명하겠습니다. targetDeg= 360. start_time = time.time() while True: error = targetDeg - motorDeg error_prev = error
마지막으로 간략하게 PID제어에 대해서 알아보겠습니다. 지난 번 아두이노를 이용한 모터 위치제어에서는 P제어만 해봤는데요. 이번에는 마저 해보겠습니다. PID제어란 Propotional(; 비례) Integral(; 적분) Derivative(; 미분)의 약자로 모든 제어의 기본이 되는 제어입니다. 수식은 Output = P + I + D이고, 각각은 Error = Target(; 목표값) - Process(; 현재값), dt는 시간 간격일 때 P = Kp * Error = Kp * (Target - Process) P = Kd * dError/dt = Kd * (e - e_이전값) * (t - t_이전값) = Kd * ((Target - Process)-(Target - Process_이전값)) * dt P = Ki * Error*dt = Kp * (Target - Process) * (t - t_이전값) 가 됩니다. 미적분이라는 것이 수학수업에서는 머리 아픈 개념이지만, 실전 제어에서는 간단하게 이전값과 현재값의 차와 곱으로 이루어집니다. P를 기본으로 필요에 따라 I와 D를 추가합니다. 위 GIF를 보면서 설명을 읽으시면 많은 도움이 됩니다. 보통 Kp값을 먼저 설정하는데, Kp값이 이상적인 값보다 작으면 목표점에 도달하는 시간이 너무 오래 걸리고 크면 아래처럼 목표점에는 빠르게 도착하지만, 목표점에서 멈추지 못하고 지나가는 오버슛이 생기고, 다시 돌아와서도 반대의 현상이 반복되다가 차츰 목표점에 수렴하는 현상이 발생합니다. 너무 크면 목표점에 수렴하지 못하고 주변을 계속 맴도는 현상이 발생합니다. 적당한 Kp값이 잡히면, Ki값을 설정합니다. Ki값은 현재값이 안정은 됬는데 미세하게 목표점과의 남은 거리를 좁혀주는 역할을 합니다. 마지막으로 Kd값을 설정하는데요. Kd값은 앞서 Kp값을 설정할 때 생긴 오버슛(목표값을 지나가는 현상)을 잡는데 쓰입니다. PID값 설정은 전체 시스템에 대해서 하는 것이기 때문에 모터 하나만 혼자서 놔두고 하는 것은 의미가 없습니다. 전체 시스템이 완성되었을 때 모터 축에 연결되어 있는 다양한 형태의 부하에 대해서 설정하는 것이 PID제어입니다. 저도 지금은 실험환경이 없어서 모터 하나만 두고 하니 Ki, Kd 값 설정이 의미가 없어서 Kd만 만져보고 끝났습니다. 보통은 범위 안에만 들어오면 제어가 된 것으로 하면 되는데, error를 0으로 하는게 가능해서 저는 0에 맞춰보았습니다. |
최신댓글