DevNote

IK Solvers 본문

Graphics

IK Solvers

Ahnda 2020. 11. 5. 22:47

이전 포스트에서는 IK에 대해 간단하게 소개했고, 이번 포스트는 IK Solver에 대해 소개한다. 여러 IK Solvers 들이 있지만, Unreal Engine 4에서 제공되고 있는 IK Solver 위주로 찾아봤다.


 1. Analytic Solver (Two-Bone IK)

 뒤에 설명할 CCD와 FABRIK은 Iterative하게 최적화하는 방법이기 때문에 다소 비용이 비싸다.  IK를 매우 자주 적용해야할 경우에 Closed-Form으로 떨어지는 Two-Bone IK 방법이 굉장히 빛을 발한다(식 하나로 계산이 끝나기 때문에 비용이 적다).

 

 그러나 Joint가 많아지면 계산이 복잡해지는 문제가 있어 아래 <Fig 1>과 같이 Joint 구조가 간단한 경우에 사용하는 것이 좋다.

 

 문제는 간단하다 아래와 같은 본 구조가 있는데, End Effector가 Target으로 가기 위해서는 θ1과 θ2 두 Joint의 각도를 구해야한다. 정답 포즈는 아래 그림에서 확인할 수 있듯 두 가지이다. 

Fig 1. Two-Bone IK; 해당 예제는 두 개의 포즈가 도출될 수 있다.

 

 코사인의 법칙만 알면 모든 Joint에 대한 각도를 구할 수 있다.

 

매우 간단하다. 그러나, 관절각을 구하는 과정은 쉬운데, 어떤 것을 정답으로 골라야할지 참 애매하다. 그래서 제약 조건을 더함으로써 최적의 결과 포즈를 고를 수 있다.

 

한 가지 예를 들어보자면, <Fig 1>의 관절이 사람의 다리를 나타낸다고 가정해보자. 

사람의 다리는 십자인대 파열이 아닌 이상 한 방향으로 밖에 꺾일 수 없기 때문에, θ2의 각도(무릎의 각도)를 제한함으로써 정답 포즈를 한 가지로 추려낼 수 있다. 

 

그런데 이 모든게 사실은 관절이 두 개 밖에 없기 때문에 가능하다. 관절 구조가 복잡하고 여러 개가 되면, 이 방법으로 IK를 풀어내기는 정말 어려운 일이다.

 

어쨌든 치명적인 단점이 있음에도 불구하고, 빠른 속도 때문에 많이 사용되는 Solver이다.


2. Cyclic Coordinate Descent (CCD)

 복잡한 Bone 구조 (2개보다 더 많은?)에 위의 Analytic Solution을 사용하는 것은 어렵다. 이제 설명할 CDD는 굉장히 좋은 대안이 된다. 

 

 관절의 갯수가 5개라고 가정하고 P1이 Base Joint, E는 End Effector일 때, 방법은 아래와 같다. (T는 타겟)

 

 1. Joint마다 순회하며 End Effector와 Target 사이의 거리와 방향 차이가 최소가 되도록 각도를 변환한다.

  1-1. 타겟의 위치 T, 그리고 End Effector와 P4 Joint의 사이각을 θ4라고 할 때(<Fig 2>의 a),  θ4의 각도가 0이

되도록 End Effector를 이동시킨다(P4를 회전한다).

  1-2. End Effector부터 Base까지 역순으로 1-1의 과정을 반복한다.(<Fig 2>의 b->c->d)

 

 2. 모든 Joint에 대해 관절각과 위치가 업데이트 되었으나, 만족스럽지 못한 결과를 얻었다면, 1의 과정을 반복한다.

    (<Fig 2>의 e->f)

Fig 2. Process of CCD

CCD의 과정을 쉽게 보여주는 영상 [Link]

 

 

 위의 과정을 반복할 때, 각 관절의 각도를 구하는 방법은 타겟의 위치와 해당 두 관절의 위치 사이에 생기는 두 벡터(u, v)의 내적으로 쉽게 구할 수 있다.

 

 

 CCD는 위에 설명된 바와 같이, 구현이 간단하고 각 Iterate 마다 비용이 적다. 그러나, 드문 경우지만 Target의 위치 설정이 적절하지 못한 경우 Local Minima에 빠질 수 있다. <Fig 3>은 그 예시를 보여준다.

 

Fig 3. (a) 초기 상태와 타겟, (b) 이상적인 포즈, (c) CCD를 이용한 결과


3. Foward And Backward Reaching Inverse Kinematics (FABRIK)

 CCD에서는 iterative하게 각 Joint의 각도를 회전하며 Target을 추적했다면, FABRIK는 다음 Link의 벡터를 유지하며 Joint의 위치(Location)를 Target으로 추적하는 방식이다. 

 

 FABRIK은 CDD와 마찬가지로 연관된 모든 Joint를 순회하며, iterative하게 정답 포즈를 찾아가는 방식이다.

 

 관절의 갯수가 4개라고 가정하고 P1이 Base Joint, P4는 End Effector일 때, 방법은 아래와 같다. (t는 타겟)

 

 1. Forward

  1-1. P4(End Effector)를 타겟(t)의 위치로 이동한다. P4의 새로운 위치는 P'4 (<Fig 4>의 b)

  1-2. P'4와 P3를 잇는 벡터위에 P'4로부터 거리가 d3가 되는 위치 P'3를 찾는다. (<Fig 4>의 c)

  1-3. 1-2의 과정을 P1까지 반복한다.  (<Fig 4>의 d)

 

 2. Backward

  2-1. Base Joint인 P'1을 다시 원래의 위치로 옮긴다. P'1의 새로운 위치는 P"1 (<Fig 4>의 e)

  2-2. 1의 과정을 역순으로 P'4(End Effector)까지 반복한다. (<Fig 4>의 f)

 

 3. Iteration

  3-1. 모든 Joint에 대해 위치가 업데이트 되었으나, 만족스럽지 못한 결과를 얻었다면, 1과 2의 과정을 반복한다.

 

Fig 4. Process of FABRIK

'Graphics' 카테고리의 다른 글

Inverse Kinematics  (1) 2020.11.04