
DC 모터 위치제어는 PID Gain보다 전류, 엔코더, 기구의 한계를 먼저 봐야 한다.
직접 제작한 델타로봇에서 저가형 DC Gear Motor를 제어했던 경험을 바탕으로 Current Loop와 Position Loop를 어떻게 구성했고, 실제로 어떤 문제가 생겼는지 설계 순서대로 설명한다.
DC 모터 위치제어를 처음 시작하면 보통 Encoder 값을 읽고 목표 위치와의 오차를 PID에 넣은 뒤 PWM Duty를 조절하는 구조부터 만든다. 간단한 장치라면 이 방법으로도 움직일 수 있다. 하지만 로봇처럼 부하가 변하고 가감속이 반복되며 위치 정확도가 필요한 시스템에서는 어느 순간부터 PID Gain만 조절해서 해결되지 않는 문제가 생긴다.
필자도 과거 델타로봇을 직접 설계하고 제작하면서 비슷한 과정을 겪었다. 저가형 Encoder DC Gear Motor를 사용했고, 처음에는 Current-Speed-Position의 3중 Cascade Control을 고려했다. 하지만 실제 Encoder Resolution과 Gear Backlash를 확인해보니 이론대로 모든 Loop를 넣는 것이 오히려 적절하지 않았다. 결국 Hardware의 실제 한계를 기준으로 Control Architecture를 다시 정리했다.
좋은 Motor Control은 PID Gain부터 시작하지 않는다.
Motor의 전기적 특성, Current Feedback, Encoder Resolution, Gear Backlash, Sampling 조건을 먼저 확인하고 그 Hardware가 제공할 수 있는 정보만큼 Control Loop를 구성해야 한다.
1. DC 모터 위치제어는 무엇을 제어하는 것일까?
Position Control의 최종 목적은 간단하다. 목표각도와 현재각도의 차이를 줄이는 것이다.
여기까지만 보면 PID Controller의 Output을 바로 PWM Duty로 보내면 될 것 같다. 실제로 간단한 Position Control 예제에서 많이 사용하는 구조다.
하지만 Motor에서 PWM은 곧 Torque가 아니다. PWM은 Motor에 인가되는 평균 Voltage에 영향을 주고, Voltage는 Motor의 Resistance, Inductance, Back EMF에 의해 Current를 만든다. 그리고 일정한 자속을 가정한 DC Motor에서 Torque는 Armature Current에 비례한다.
즉 Robot Joint에 필요한 힘을 직접적으로 만드는 것은 Current다. 그래서 정밀한 Motor Drive에서는 Current를 별도의 빠른 Inner Loop로 제어하는 구조가 중요해진다.
2. 왜 Position PID 하나로 끝내지 않고 Cascade Control을 사용할까?
Cascade Control은 하나의 Controller가 모든 문제를 처리하도록 두는 대신, 빠르게 반응해야 하는 물리량과 느리게 반응하는 물리량을 여러 Loop로 나누는 방식이다.
Position Loop는 "어디까지 가야 하는가"를 결정하고, Current Loop는 "그 위치로 가기 위해 지금 어느 정도 Torque를 만들어야 하는가"에 가깝다.
이 구조의 장점은 Load가 변하거나 Motor 전압이 흔들리더라도 Position Controller가 직접 Power Stage의 모든 특성을 상대하지 않아도 된다는 점이다. 먼저 빠른 Current Loop가 Motor Torque 쪽을 안정화하고 그 바깥에서 Position Loop를 설계할 수 있다.
일반적인 Servo Drive는 Current, Velocity, Position의 3중 Cascade 구조를 많이 사용한다. 하지만 실제 Sensor Resolution과 목적에 따라 2중 Loop도 충분히 실용적인 선택이 될 수 있다. 이번 프로젝트가 그 사례였다.
3. 실무에서는 Controller보다 먼저 Motor Parameter를 확인했다
당시 사용한 저가형 DC Gear Motor에는 제어 설계에 필요한 상세 Motor Parameter가 충분히 제공되지 않았다. 그래서 Datasheet에 없는 값을 추측해서 PID를 조절하기보다 실제 Motor를 측정하기로 했다.
Current Controller를 설계하려면 최소한 Motor Winding의 Resistance R과 Inductance L을 알아야 한다.
Motor Shaft를 고정하면 ω = 0으로 둘 수 있고, Current가 정상상태에 도달하면 di/dt = 0이 된다. 따라서 정상상태에서는 식이 단순해진다.
이 원리를 이용해 여러 Voltage와 Current 데이터를 측정한 뒤 최소자승법으로 R을 구했다. 당시 측정에서는 R ≈ 1.41Ω이 도출되었다.
Motor Shaft를 고정하면 Back EMF가 없어지고 Current가 크게 증가할 수 있다. 당시에도 전원장치의 Current Limit을 이용해 전류를 제한하면서 측정했다. 이런 시험은 Motor와 Driver의 정격, 권선 온도와 시험시간을 먼저 확인해야 한다.
4. Inductance L은 전류가 얼마나 빨리 올라가는지 보고 구했다
Resistance를 구한 다음에는 Motor Shaft를 고정한 상태에서 Step 형태의 Voltage를 인가하고 Current Response를 Oscilloscope로 확인했다.
RL Circuit에서 Step Voltage를 인가하면 Current는 즉시 최종값으로 올라가지 않는다.
1τ가 지난 시점의 Current는 최종값의 약 63.2%에 도달한다. 따라서 Oscilloscope Waveform에서 63.2% 지점의 시간을 측정하면 L을 역으로 계산할 수 있다.
당시 측정한 Time Constant는 약 540µs였고, 앞에서 구한 R을 이용해 계산한 Inductance는 약 760µH였다.
Datasheet에 Parameter가 없다고 바로 제어를 포기할 필요는 없다. 단순한 DC Motor라면 R은 정상상태 V-I 측정, L은 Step Current Response를 이용해 실험적으로 추정할 수 있다.
5. Current Loop는 왜 PI로 설계했을까?
Motor의 Current Dynamics를 단순화하면 다음과 같은 RL Plant로 볼 수 있다. Back EMF는 운전점과 설계 목적에 따라 Disturbance로 다루거나 모델에 포함할 수 있다.
이번 프로젝트에서는 측정한 R과 L을 기반으로 Pole-Zero Cancellation 방식의 PI Current Controller를 설계했다.
여기서 ωcc는 목표 Current Loop Cutoff Angular Frequency다. 논문 실험에서는 Current Loop의 Cutoff Frequency를 6Hz로 정했고, 측정한 Motor Parameter를 대입해 Kp = 0.0287, Ki = 53.2로 설계했다.
이 설정에서 1차계로 단순화한 Current Response의 Time Constant는 약 26.5ms이고, 이론상 약 5τ인 132ms 부근에서 99% 수준까지 도달하는 응답을 예상할 수 있었다. 실제 Oscilloscope 결과와 비교해 설계한 Current Loop가 의도한 응답을 보이는지 확인했다.
이 값은 당시 사용한 Motor, Driver, Sensor, Sampling과 실험목적에 맞춘 결과다. Motor R과 L, PWM Frequency, ADC Sampling, Current Sensor Bandwidth가 달라지면 Controller Gain도 다시 설계해야 한다.
6. Position Loop는 Current Loop보다 느리게 설계한다
Cascade Control에서 Inner Loop가 Outer Loop보다 충분히 빨라야 한다. 그래야 Position Controller 입장에서 Current Loop를 빠르게 따라오는 하나의 Actuator처럼 볼 수 있다.
당시 설계에서는 Outer Position Loop가 Inner Current Loop보다 약 5배에서 10배 느린 영역에서 동작하도록 잡았다.
가장 먼저 설계하고 응답을 확인한다.
Current가 Reference를 제대로 따라가는지 확인한다.
그보다 느린 Bandwidth로 설계한다.
Step Command가 너무 거칠지 확인한다.
실제 Load와 Backlash에서 재검증한다.
Position Controller는 이론적으로 PD만으로 접근할 수 있지만, 실제 시스템의 Model Uncertainty와 Disturbance를 고려해 PID 구조로 설계했다.
7. 원래는 Current-Speed-Position 3중 Loop를 하려고 했다
일반적인 Servo Control을 공부하면 Current Loop 안에 Velocity Loop가 있고 그 바깥에 Position Loop가 있는 구조를 많이 보게 된다. 당시에도 처음에는 이 구조를 시도했다.
문제는 실제 Encoder였다. 사용한 Encoder 일체형 Gear Motor는 4체배 기준 1404 PPR였고, 한 Count에 해당하는 각도는 약 0.26°였다.
Position을 읽는 용도로는 사용할 수 있었지만, 낮은 Speed에서 짧은 Sampling Period마다 Speed를 계산하면 들어오는 Pulse 수가 적어진다. 그러면 Speed Feedback이 계단형으로 거칠어지거나 0과 특정 값 사이를 오갈 수 있다.
실제로 Current-Speed-Position Cascade를 구성했을 때 Speed Control이 원하는 수준으로 동작하지 않았다. 그래서 "Servo는 원래 3중 Loop니까 반드시 Speed Loop를 넣어야 한다"는 생각을 버리고, Current-Position 2중 Cascade로 구조를 바꿨다.
8. Speed Loop를 뺐더니 다른 문제가 생겼다
Current-Position만으로 Point-to-Point 이동은 가능했다. 하지만 그림을 그리는 것처럼 End-effector가 일정한 속도로 부드럽게 움직여야 하는 작업에서는 Step 형태의 Position Command가 문제였다.
목표 Position이 한 번에 크게 바뀌면 Position Error가 순간적으로 커지고, Position PID는 큰 Current Reference를 요구한다. 그 결과 Motor가 급하게 가속하거나 기구가 흔들릴 수 있다.
그래서 당시에는 Path Planning 단계에서 Rise Limit을 추가했다. 목표점을 바로 Step으로 넣지 않고 점과 점 사이의 Position Command가 일정한 Rate로 증가하도록 제한했다.
지금 관점에서 보면 간단한 Trajectory Generator 또는 Slew Rate Limiter를 Position Command 앞에 둔 것과 유사하다. 중요한 점은 PID Gain을 낮춰서 억지로 부드럽게 만든 것이 아니라 Reference 자체를 물리적으로 수행 가능한 형태로 만들었다는 것이다.
9. PID가 안 맞는 줄 알았는데 실제 원인은 Gear Backlash였다
프로젝트에서 또 하나 크게 경험한 문제는 Gear Backlash였다. Motor Gearbox의 Backlash를 측정했을 때 약 ±1° 수준의 유격이 있었다.
Direction이 바뀌는 순간 Motor Shaft는 움직이는데 Output Link는 바로 반응하지 않는 Dead Zone이 생겼다. 이 구간을 PID 입장에서 보면 Position Error가 줄지 않으니 Controller는 더 큰 명령을 내보낸다. Gear가 반대쪽 Tooth에 닿는 순간에는 그 명령이 한꺼번에 기구로 전달될 수 있다.
Encoder가 Motor Shaft에 있고 Backlash가 Gear 이후에 존재한다면 Controller는 실제 End-effector의 기계적 유격을 직접 보지 못할 수 있다. Sensor 위치와 기구 유격까지 함께 봐야 한다.
당시에는 기구에 일정한 Load를 추가해 양방향으로 나타나던 Backlash를 한쪽 방향으로 Bias시키는 방법을 사용했다. 정교한 Backlash Compensation Algorithm은 아니지만, 제작된 Hardware와 일정한 작업방향이라는 조건에서 문제를 줄일 수 있는 현실적인 방법이었다.
위치가 떨리면 무조건 PID가 잘못된 것이 아니다. Encoder Resolution, Gear Backlash, Joint 유격, Friction, Saturation, Current Limit과 Command Profile을 먼저 확인해야 한다.
10. Current Sensor는 보호용 부품이 아니라 Control Sensor였다
이 시스템에서는 Motor 3개 각각에 Current Sensor를 두고 MCU의 ADC로 Current를 읽었다. Encoder는 Position Feedback을 담당하고 Current Sensor는 Inner Current Loop의 Feedback을 담당했다.
| Signal | 측정 대상 | Controller에서 하는 일 | 설계 시 확인할 것 |
|---|---|---|---|
| Encoder A/B | Motor Position | 현재각도 계산 | PPR, 4체배, Sampling |
| Current Sensor | Motor Current | Torque에 대응하는 Feedback | Offset, Gain, Bandwidth, Noise |
| ADC | Current Sensor Voltage | Digital Current 값으로 변환 | Resolution, Reference, Sampling |
| PWM | Motor Applied Voltage | Driver 출력 제어 | Frequency, Duty, Dead Time |
| DIR | 회전방향 | Motor Direction 제어 | 전환조건과 Current |
그래서 ADC는 단순히 Analog Voltage를 읽는 기능이 아니라 Motor Control에서는 Feedback Loop의 일부다. ADC Sample이 느리거나 Noise가 크면 Current PI가 보는 Feedback 자체가 흔들린다.
이 부분은 별도의 ADC 실무 글에서 Resolution, Sampling Rate, Reference Voltage, Quantization까지 따로 다루는 것이 좋다.
11. 실제 성능 검증은 Controller Graph만 보고 끝내지 않았다
Simulation에서 잘 따라간다고 실제 Robot도 잘 움직이는 것은 아니다. 최종적으로는 End-effector에 펜을 장착하고 실제 위치 정확도를 측정했다.
4개의 Target Point를 설정해 반복 실험했고, 종이 위에 표시된 실제 위치를 0.1cm 눈금으로 측정했다. 논문에 정리된 결과에서는 최대 약 2mm 위치 오차가 확인되었고, 12회 반복 실험에서 약 10cm 이동 후 정지까지 약 0.1초 수준의 동작을 확인했다.
다른 Motor나 Gear Ratio, Link Length, Load에서 같은 성능을 보장하는 값이 아니다. 여기서 중요한 것은 Simulation 결과만 제시하지 않고 실제 End-effector 위치를 별도로 측정해 System Level에서 검증했다는 점이다.
12. 내가 다시 DC 모터 위치제어를 설계한다면 이 순서로 한다
- 먼저 필요한 Position Accuracy, Speed, Torque와 Load를 정의한다.
- Motor와 Gearbox의 Rated Current, Peak Current, Gear Ratio, Backlash를 확인한다.
- Encoder Resolution이 Position뿐 아니라 Speed Estimation에도 충분한지 계산한다.
- Motor R, L 등 필요한 Parameter가 없으면 안전한 시험방법으로 측정한다.
- Current Sensor의 Range, Bandwidth, Offset과 ADC 조건을 정한다.
- 가장 안쪽 Current Loop부터 설계하고 실제 Step Response를 확인한다.
- Inner Loop보다 충분히 느린 Position 또는 Velocity Loop를 설계한다.
- Command를 Step으로만 넣지 말고 Acceleration, Velocity, Rise Limit을 고려한다.
- Position Error가 남는다면 PID보다 먼저 Backlash, Friction, Saturation을 확인한다.
- 마지막에는 Motor Shaft가 아니라 실제 Mechanism 또는 End-effector의 성능을 측정한다.
13. 이 프로젝트에서 가장 크게 배운 5가지
R, L, Encoder Resolution과 Backlash를 모르면 Controller Gain을 조정해도 원인을 정확히 찾기 어렵다.
Position Controller와 Power Stage 사이에 Current Loop를 두면 Motor의 힘을 별도 Loop로 관리할 수 있다.
Speed Feedback의 품질이 부족하면 Velocity Loop를 억지로 구성하는 것이 오히려 불리할 수 있다.
Step Command를 부드럽게 바꾸는 것만으로도 Current Peak와 기구 충격을 크게 줄일 수 있다.
Backlash와 Joint 유격은 PID만으로 해결하기 어렵다. Mechanism과 Controller를 같이 봐야 한다.
14. 단순 Position PID와 Cascade Control은 언제 나눠서 생각할까?
| 상황 | 단순 Position PID | Current-Position Cascade |
|---|---|---|
| 간단한 Hobby Mechanism | 구현이 빠름 | 복잡도가 불필요할 수 있음 |
| Torque 변화가 큰 Robot | Load 변화 대응이 어려울 수 있음 | Current Loop 활용이 유리 |
| Current Limit 필요 | 별도 보호가 필요 | Current Feedback과 연계 가능 |
| 정밀 Position Control | 기구와 부하에 민감 | Loop 분리로 설계가 체계적 |
| Sensor가 부족한 저가 System | 단순 구조의 장점 | 사용 가능한 Feedback만으로 구성 필요 |
따라서 Cascade가 무조건 고급이고 Single Loop가 나쁘다는 식으로 볼 필요는 없다. 목표 Performance와 Sensor, Actuator, MCU 성능에 맞게 필요한 Loop만 구성하는 것이 더 중요하다.
마무리
DC Motor Position Control을 공부할 때는 PID 공식부터 시작하기 쉽다. 하지만 실제 Robot을 만들어보면 Controller보다 먼저 확인해야 할 것이 훨씬 많다.
당시 프로젝트에서도 문제는 단순한 Gain 부족이 아니었다. Encoder Resolution 때문에 Speed Loop를 포기해야 했고, Gear Backlash 때문에 Position Error가 발생했으며, 부드러운 경로를 만들기 위해 Rise Limit까지 추가해야 했다.
결국 실제 Motion Control은 Motor Model → Sensor → Current Loop → Position Loop → Trajectory → Mechanism → Measurement 가 하나의 시스템으로 연결되어야 한다.
PID는 마지막 조정도구에 가깝다.
실제로 잘 움직이는 Robot을 만들려면 먼저 Motor와 Sensor, Gearbox가 어떤 한계를 가지고 있는지 측정하고 그 한계 안에서 Control Architecture를 설계해야 한다.
2020년 한국전자통신학회 논문지 제15권 제2호, 「델타 로봇의 전류-위치 Cascade PID 제어」
직접 수행한 델타로봇 설계, Motor Parameter 측정, Current-Position Cascade Control과 위치 정확도 실험 자료를 기반으로 실무 관점에서 다시 정리하였다.