14강 PD Controller, Feedback Linearization

이번 시간부터 본격적으로 로봇의 Dynamics를 통한 제어에 대해 배워보려 합니다. “로봇의 제어”라는 말은 결국 원하는 위치/속도/가속도를 갖도록 로봇을 움직이는 것이 되겠지요.

이를 달성하기 위해 로봇 자체의 여러 물성치를 알아야 할 것이고, 또 로봇의 모터에 어느 정도의 힘을 가해야 원하는 움직임을 얻을 수 있는지에 대한 수식, “운동방정식”이 필요합니다.

하지만, 운동방정식을 얻었다고 해서 항상 완벽한 제어가 가능한 것은 아닙니다. 실제 로봇에는 상황에 따라 수많은 외력이 가해지고 이에 대처할 수 있는 강인한 제어기가 필요하지요.

따라서 로봇 제어 파트는 이 제어기를 설계하는 내용을 담고 있으며, 다음과 같은 챕터로 구성되어 있습니다.
  • PD Controller, Feedback Linearization
  • Feedback Linearization and Manipulator
  • Linearization with Traj
  • Linear Control
  • Linear Control - Nonlinear system and Manipulator


제어 공학의 측면에서 17, 18장의 Linear Control을 먼저 이야기하는 것이 옳지만, 이번 강의는 로보틱스의 관점에서 일단 동작하는 시스템의 구현을 우선으로 기획되었습니다.

따라서, 17, 18장의 Linear Control을 통해 이론적인 기초를 닦은 뒤 14장을 시작해도 좋고, 강의 순서에 따라 14장의 구현에 익숙해진 뒤 그 이면의 이론적 기초를 함께 살펴보는 것도 좋을 것 같습니다.

그럼, 로봇의 제어를 위한 첫 시간으로 PD ControllerFeedback Linearization에 대해 배워봅시다!

Spring - Mass - Damper System


시스템의 Euler Lagrange 방정식을 푼 결과였던 운동방정식(EOM)은 다음과 같은 형태로 간소화할 수 있었습니다.

Notation Description
$M(q)$ 질량, 질량 관성모멘트를 담고 있는 행렬로 오로지 position에 대한 행렬입니다.
$C(q,\dot{q})\dot{q}$ Coriolis term이라 불리며, 간단히 말하면 M(q)와 G(q)를 제외한 모든 부분들입니다.
$G(q)$ Gravitational torque라 불리며 운동방정식을 세우며 위치에너지를 고려하였기 때문에 생기는 중력에 대한 항입니다.
$\tau$ 시스템에 가해지는 외력과 제어 입력을 포함한 힘의 항에 해당합니다.


  • 보통 시스템의 모션을 얻기 위해 $\ddot{q}$ term이 필요하게 됩니다. 이는 운동방정식을 $Ax=b$ 꼴로 변형하여 구해낼 수 있게 되며, 이때의 $A, M(q)$ 행렬은 $\ddot{q}$ 에 대한 자코비안을 계산함으로 손쉽게 얻을 수 있습니다.

  • 이제 이 운동방정식을 통해 우리는 다음과 같은 임무를 수행시켜야 합니다.

Method Description
set point control 로봇을 특정 위치로 움직이게 하기
trajectory tracking control 로봇이 계산된 경로를 따라가게 하기


  • 예시를 위해 M, C, G 항을 갖는 가장 간단한 시스템으로 sping-mass-damper를 살펴보겠습니다.

Parameter Description
m 물체의 질량 (현재 병진 운동만 하고 있으므로 회전에 대해서는 무시합니다.)
c 물체의 움직임을 방해하는 Damping 상수
k 위치에너지를 만들어내는 Spring 상수


  • 외력이 없을 때, 이 운동 방정식은 상계수 미분방정식이 되어 아래와 같은 고유 진동수를 갖는 해를 도출할 수 있습니다. 오랜 시간이 흘러 ( $t\rightarrow \infty$ ) 시스템이 정상 상태(steady state)에 도달했을 때 Spring - Mass - Damper 시스템은 고유 진동수를 가진 움직임을 가질 것입니다.

  • 더불어, 정상상태를 기준으로 시스템의 수렴, 진동, 발산 여부도 확인할 수 있습니다. 자세한 내용은 기계진동학과 관련이 있으며 이번 강의에서는 결과에 대해서만 확인하고 넘어가겠습니다.

각 상황에 따라 time-state의 변화를 그래프로 그려보면 다음과 같습니다.

  • under-damped - red
  • overdamped - green
  • critically damped - blue

⇒ 우리의 목적은, (controller의 목적은) 적절한 외력, control force를 가해 $\xi$ =1을 만족시키는 것이지요!

PD controller

시스템에 가해주는 힘(혹은 토크), tau를 아래와 같이 선정해보겠습니다.

💡 참고로 $q$와 $\dot{q}$은 모터에 장착된 센서로 알아낼 수 있다고 가정합니다.


  • 이렇게 모델링한 힘을 운동방정식에 넣어, critically damped 조건을 적용하면 아래와 같아집니다.

  • critically damped 조건을 위한 Kp, Kd에 대해 관계식을 얻어낼 수 있는 것이지요.
💡 sqrt에 따라 +, - term이 등장했는데 둘 중 어떤 것을 골라야 할까요? ⇒ -c term을 보상하는 + term을 선택해야 합니다.

⇒ Kp가 정해지면, 그에 따른 Kd는 위 수식에 따라 정해지게 되지만, Kp를 설정하는 것은 오로지 사용자에게 달리게 됩니다. 따라서 실험을 통해 적절한 Kp를 구하는 기준이 필요합니다.

코드 구현

앞서 살펴보았던 spring-mass-damper system을 시뮬레이션 해보고, PD controller도 적용해봅시다.

  • 예제를 먼저 실행해볼까요? 터미널을 실행시키고 다음의 커멘드 라인을 입력해 주세요!
python3 smd_main.py

시간에 대한 질점의 위치를 확인할 수 있습니다. ( 앞선 그림을 상기해보면 under-damped 상태라는 것을 확인할 수 있지요!)

  • 코드 중 smd_rhs 함수를 다음과 같이 수정하여 예제를 다시 실행해보겠습니다.

💡 적절한 제어를 통해 critical damp point에 도달한 모습을 볼 수 있습니다.

지금의 예시를 다시 한 번 정의하고 코드 분석을 해봅시다.

우리의 목표는 0.5에 위치한 질점에 적절한 제어 입력을 가해 위치 0으로 빠르게 도달하도록 하는 것입니다. 이를 위해 PD controller를 사용하고자 하며, Kp, Kd 매개변수를 설정해야 합니다.

  • 따라서, Parameters에는 시스템 매개변수들과 Kp, Kd가 정의되어 있습니다. Kp가 정해지면 Kd는 damping 조건에 따라 자동으로 결정되도록 해두었습니다.


  • main 함수는 간단합니다. 위치 0.5, 속도 0을 갖는 초기조건을 정의한 뒤, 0-20초 동안 odeint를 통해 시뮬레이션을 실행, 실행 결과를 plotting하게 됩니다.


  • odeint의 input이 되는 운동방정식, smd_rhs에는 제어기를 사용하지 않는 경우와 사용하는 상황에 대한 output을 구별해 두었습니다. (앞선 수식에서 살펴본 바 있지요?)

실험해보기


Parameters의 Kp를 100으로 키운 뒤 다시 코드를 실행해봅시다. position 0로 훨씬 빠르게 수렴하는 모습을 확인할 수 있습니다.

⇒ 이처럼 Kp가 커지면 더욱 빠르게 수렴하지만, 이것이 마냥 좋지 많은 않습니다. Kp가 커질수록 시스템의 노이즈에 더욱 취약해진다는 단점이 있답니다.

2D case

이번에는 차원을 확장하여 2개의 모터를 제어하는 시스템을 생각해보겠습니다. 각 모터에 대한 운동 방정식 2개가 주어짐에 따라 Kp, Kd가 2-by-2 행렬로 확장이 됩니다.

이렇게 되면, 미지수는 8개가 된 반면, 주어진 조건은 여전히 2개가 되어버리면서 올바른 우리가 임의로 설정해야 하는 값들이 너무 많아진다는 문제가 발생합니다.

⇒ 따라서 이를 해결하는 새로운 방식으로 Feedback linearization, 혹은 Control partition 이라는 방식을 배워보겠습니다.

Feedback linearization

Feedback linearization의 기본 개념은 다음과 같습니다.

우리는 현재 시스템의 운동 방정식을 알고 있기 때문에, $q, \dot{q}$ 을 측정할 수 있다면 로봇이 어떠한 상태에 처해 있는지 추측할 수 있습니다.

⇒ 따라서 8개의 Kp, Kd 변수들을 직접 최적화하지 않아도 현재 상태를 기반으로(Feedback) 제어기를 훨씬 간소화할 수 있게 됩니다.

  • 위 그림을 간단히 설명하면, 원하는 reference point가 존재할 시, 운동 방정식에 기반하여 이를 위한 reference torque $\tau_{ref}$를 계산하는 과정입니다.

  • 단, 이 모든 것이 동작하기 위한 전제조건은, 운동 방정식을 구성하는 $M, C, G$와 $q, \dot{q}$를 정확하게 알고 있어야 한다는 것인데요. 실제 로봇 시스템에서는 각종 외란과 센서 노이즈, 제어 노이즈로 인해 정확한 모델링이 사실상 불가합니다. 따라서 이러한 불확실성(uncertainty)을 고려한 항을 $\hat{M}, \hat{C}, \hat{G}$ 이라고 지칭하겠습니다.

구현 측면에서 Feedback linearization은 다음과 같습니다.

  • uncertainty를 고려한 $\hat{M}, \hat{C}, \hat{G}$ 을 통해 tau를 선정합니다.

  • 이렇게 되면, 양변의 C, G term이 상쇄되면서 M term만 남게 되지요. 결국, M C G와 같은 물성치에 대한 항 없이, 순수 state만의 미분 방정식이 남게 됩니다.

  • M term에 대해 정리한 수식에 이전 정상 상태의 조건을 적용하면, kp와 kd 사이의 조건식을 다시 얻어낼 수 있게 됩니다.

  • Feedback Linearization의 가장 큰 전제 조건이자 특징은 시스템의 M, C, G와 매우 근사한 $\hat{M}, \hat{C}, \hat{G}$ 를 사용하여 제어입력을 선정한다는 것입니다. 이 부분에서 너무 큰 노이즈가 포함되거나, 모종의 이유로 근사하지 못한 수치를 사용하면 Feedback Linearization은 정상적으로 동작하지 못합니다.

코드 구현


  • 코드의 실행은 다음과 같습니다.
cd ./lec12_feedback_linearization/2_control_partitioning_pd
python3 control_partition_main.py


  • Parameter 클래스에서 각종 시스템의 물성치와 목표 위치, P,D Gain을 설정합니다.

Kp가 결정되면, Kd는 앞선 결과에 따라 자동 계산되도록 구현하였습니다. EOM을 결정짓는 M, C, G와, $\hat{M}, \hat{C}, \hat{G}$ 사이에 random한 불확실성을 부여한 모습도 보입니다.


  • 코드는 main 함수와 odeint의 input이 되는 시스템 방정식 control_partition_rhs로 이루어져있습니다. 주어진 시간 0 ~ 10초 동안 적절한 control signal을 적용하여 q1, q2가 q_des에 도달하도록 하는 것이 목표입니다.


  • odeint의 input이 되는 운동방정식 control_partition_rhs에서는 $\hat{M}, \hat{C}, \hat{G}$ 를 사용하는 tau와 Ax = b를 통해 계산하는 $\ddot{q}$ 에 대한 계산이 이루어집니다.

💡 $q_{des}$를 반영하기 위해 $q$ 대신 ($q$ - $q_{des}$)를 사용하였습니다.


실험해보기


  • 코드 구현을 완료하였으니, 실행도 해보고 실험들을 통해 Feedback Linearization에 대한 감을 익혀봅시다.
python3 control_partition_main.py

⇒ Feedback Linearization을 통해 q1: 0.5 / q2: 1.0 위치에 빠르게 도달하는 모습을 확인할 수 있습니다.

  • 이번에는 코드의 Parameter 부분에서 self.Kp를 좀 더 작은 값으로 변경해보겠습니다.
# self.Kp = 100 * np.identity(2)
self.Kp = 10 * np.identity(2)

# self.Kp = 1 * np.identity(2)
self.Kd = 2 * np.sqrt(self.Kp)

⇒ 확실히 이전 보다 좀 더 느리게 목표 지점에 도달하는 것을 확인할 수 있지요.

  • 이번에는 hat 행렬들에 적용되는 Random Noise를 조절해보겠습니다.
self.uncertainty = 5.0
self.M_hat = self.M + self.uncertainty * np.random.rand(2, 2)
self.C_hat = self.C + self.uncertainty * np.random.rand(2, 2)
self.G_hat = self.G + self.uncertainty * np.random.rand(2, 2)

⇒ 실제 모터 제어를 시도하면 아마 위와 같이 over/under damping이 발생할 것입니다.

Complete and Continue