[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
+223 -62
View File
@@ -1,89 +1,250 @@
---
id: wiki-2026-0508-inverse-kinematics
title: Inverse Kinematics
title: Inverse Kinematics (IK)
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: [P-Reinforce-AI-INVERSE-KINEMATICS]
aliases: [IK, inverse kinematics, FABRIK, Jacobian IK, CCD, robot arm]
duplicate_of: none
source_trust_level: A
confidence_score: 0.97
tags: ["Robotics|[Robotics", Kinematics, Animation, Mathematics]
confidence_score: 0.95
verification_status: applied
tags: [robotics, kinematics, ik, jacobian, fabrik, animation]
raw_sources: []
last_reinforced: 2026-04-20
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: Python / C++
framework: PyBullet / MoveIt / Unity Animation
---
# [[Inverse-Kinematics|Inverse-Kinematics]] (역운동학)
# Inverse Kinematics (IK)
## 📌 한 줄 통찰 (The Karpathy Summary)
> "손의 위치를 결정하면, 팔꿈치와 어깨가 알아서 굽혀지는 마법." 로봇이나 캐릭터의 끝단(End-effector)의 목표 위치가 주어졌을 때, 그 상태에 도달하기 위한 각 관절의 각도들을 거꾸로 계산해내는 과정이다.
## 한 줄
> **"매 end-effector 의 target pose 의 의 의 joint angles 의 solve"**. 매 forward kinematics 의 reverse. 매 method: 매 analytic (closed-form), Jacobian (iterative), CCD, FABRIK. 매 응용: 매 robot, 매 animation, 매 VR avatar.
## 📖 구조화된 지식 (Synthesized Content)
- **Forward vs Inverse**:
- **Forward**: 관절 각도 $\to$ 손의 위치 (계산이 쉽고 결과가 하나임).
- **Inverse**: 손의 위치 $\to$ 관절 각도 (수학적으로 매우 복잡하며, 해가 여러 개이거나 없을 수 있음).
- **Solving Methods**:
- **Analytical**: 수식으로 딱 떨어지는 정답을 구함 (속도가 빠르지만 단순한 로봇만 가능).
- **Numerical (Iterative)**: 조금씩 각도를 바꿔보며 정답에 근접함 (자코비안 행렬, FABRIK 등 사용).
- **Core Benefit**: 사람이 일일이 관절을 조종하지 않고 "저 컵을 잡아"라고 명령만 내릴 수 있게 함.
## 매 핵심
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
- 역운동학은 장애물 충돌이나 관절의 물리적 한계를 고려해야 하므로 갈수록 복잡해진다. 최근에는 신경망 기반의 IK 솔버나 강화학습 에이전트가 물리 시뮬레이션 환경에서 스스로 '가장 자연스러운 포즈'를 학습하여, 고전적인 수치 해석 방식의 한계를 넘어서는 자연스러운 움직임을 보여주고 있다.
### 매 method
- **Analytic**: 매 closed-form (e.g., PUMA 6DOF).
- **Jacobian** pseudo-inverse / damped least squares.
- **Newton-Raphson**.
- **CCD** (Cyclic Coordinate Descent).
- **FABRIK** (Forward And Backward Reaching IK).
- **Optimization** (Nlopt, Drake).
## 🔗 지식 연결 (Graph)
- Related: Denavit-Hartenberg-Parameters , [[Robotics|Robotics]]
- Algorithm: FABRIK-Algorithm
### 매 challenge
- **Multiple solutions**.
- **Singularity** (near-singular pose).
- **Joint limits**.
- **Self-collision**.
- **Redundancy** (7+ DOF).
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
### 매 응용
1. **Robot manipulator**.
2. **Animation** (rigging, foot IK).
3. **VR avatar** (hand tracking).
4. **Motion capture cleanup**.
**언제 이 지식을 쓰는가:**
- *(TODO)*
## 💻 패턴
**언제 쓰면 안 되는가:**
- *(TODO)*
### Jacobian-based IK
```python
import numpy as np
## 🧪 검증 상태 (Validation)
def jacobian_ik(forward_kinematics, target, q0, max_iter=200, tol=1e-3):
q = q0.copy()
for _ in range(max_iter):
p = forward_kinematics(q)[:3, 3]
err = target - p
if np.linalg.norm(err) < tol: return q
J = numerical_jacobian(forward_kinematics, q)
# 매 damped least squares (handles singularity)
lam = 0.01
dq = J.T @ np.linalg.solve(J @ J.T + lam ** 2 * np.eye(3), err)
q += dq * 0.1
return q
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
def numerical_jacobian(fk, q, eps=1e-6):
n = len(q)
p0 = fk(q)[:3, 3]
J = np.zeros((3, n))
for i in range(n):
q1 = q.copy(); q1[i] += eps
J[:, i] = (fk(q1)[:3, 3] - p0) / eps
return J
```
## 🤔 의사결정 기준 (Decision Criteria)
### CCD (Cyclic Coordinate Descent)
```python
def ccd(joints, target, n_iter=10):
"""매 매 joint 의 의 의 의 의 적용."""
for _ in range(n_iter):
end_effector = joints[-1].position
if np.linalg.norm(end_effector - target) < 1e-3: return joints
for i in range(len(joints) - 1, -1, -1):
joint = joints[i]
to_target = target - joint.position
to_end = end_effector - joint.position
angle = signed_angle_between(to_end, to_target)
joint.rotate(angle)
end_effector = joints[-1].position
return joints
```
**선택 A를 써야 할 때:**
- *(TODO)*
### FABRIK
```python
def fabrik(joints, target, n_iter=10, tol=1e-3):
"""매 forward + backward iterative."""
base = joints[0].position
distances = [np.linalg.norm(joints[i+1].position - joints[i].position) for i in range(len(joints) - 1)]
for _ in range(n_iter):
# 매 backward (end → base)
joints[-1].position = target
for i in range(len(joints) - 2, -1, -1):
d = joints[i+1].position - joints[i].position
d = d / np.linalg.norm(d) * distances[i]
joints[i].position = joints[i+1].position - d
# 매 forward (base → end)
joints[0].position = base
for i in range(len(joints) - 1):
d = joints[i+1].position - joints[i].position
d = d / np.linalg.norm(d) * distances[i]
joints[i+1].position = joints[i].position + d
if np.linalg.norm(joints[-1].position - target) < tol: break
return joints
```
**선택 B를 써야 할 때:**
- *(TODO)*
### Analytic IK (PUMA-style)
```python
def puma_ik_closed(target_pose, link_lengths):
"""매 closed-form for 6-DOF PUMA. 매 simplified."""
x, y, z = target_pose[:3, 3]
l1, l2, l3 = link_lengths
theta1 = np.arctan2(y, x)
r = np.sqrt(x**2 + y**2)
s = z - l1
# 매 elbow up / down
cos_theta3 = (r**2 + s**2 - l2**2 - l3**2) / (2 * l2 * l3)
theta3 = np.arccos(np.clip(cos_theta3, -1, 1))
theta2 = np.arctan2(s, r) - np.arctan2(l3 * np.sin(theta3), l2 + l3 * np.cos(theta3))
return [theta1, theta2, theta3] # 매 + theta4-6 from orientation
```
**기본값:**
> *(TODO)*
### Damped least squares (singularity-robust)
```python
def damped_ls_ik(J, err, lam=0.01):
n = J.shape[1]
return J.T @ np.linalg.solve(J @ J.T + lam**2 * np.eye(J.shape[0]), err)
```
## ❌ 안티패턴 (Anti-Patterns)
### Animation foot IK (Unity-style)
```csharp
// Unity AnimatorIK
void OnAnimatorIK(int layer) {
animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1.0f);
animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1.0f);
Vector3 footTarget = GetFootTarget(); // 매 raycast for ground
animator.SetIKPosition(AvatarIKGoal.LeftFoot, footTarget);
}
```
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
### Joint limit handling
```python
def clamp_to_limits(q, lower_limits, upper_limits):
return np.clip(q, lower_limits, upper_limits)
```
### Null-space (redundancy)
```python
def null_space_ik(J, err, secondary_obj, q):
"""매 7-DOF — 매 primary task + secondary (e.g., avoid joint limit)."""
J_pinv = np.linalg.pinv(J)
primary = J_pinv @ err
null_proj = np.eye(len(q)) - J_pinv @ J
secondary = null_proj @ secondary_obj(q)
return primary + secondary
```
### MoveIt (ROS)
```python
import moveit_commander
moveit_commander.roscpp_initialize([])
arm = moveit_commander.MoveGroupCommander('manipulator')
target_pose = PoseStamped()
target_pose.pose.position.x = 0.4
target_pose.pose.position.y = 0.0
target_pose.pose.position.z = 0.5
arm.set_pose_target(target_pose)
plan = arm.plan()
arm.execute(plan)
```
### IK with collision check
```python
def ik_with_collision(target, robot, obstacles):
q = jacobian_ik(target, q0=robot.current_q)
if check_collision(robot, q, obstacles):
# 매 try alternative IK solution
for alt in alternative_solutions(target, robot):
if not check_collision(robot, alt, obstacles): return alt
return None
return q
```
### Hand tracking IK (VR)
```python
def hand_ik(wrist_target_pose, fingers, hand_model):
"""매 VR 매 wrist 의 의 의 의 의 fingers 의 IK."""
arm_q = jacobian_ik(hand_model.arm_fk, wrist_target_pose)
finger_qs = [fabrik(f.joints, target=wrist_target_pose @ f.local_target) for f in fingers]
return arm_q, finger_qs
```
## 매 결정 기준
| 상황 | Method |
|---|---|
| Standard 6-DOF | Analytic (Pieper) |
| Singularity-prone | Damped LS |
| Animation chain | FABRIK / CCD |
| Robot with collision | Optimization + collision check |
| Redundant 7-DOF | Null-space |
| Real-time game | CCD / FABRIK |
**기본값**: 매 robot = damped LS Jacobian. 매 animation = FABRIK / CCD. 매 ROS = MoveIt. 매 always check joint limits + collision.
## 🔗 Graph
- 부모: [[Robotics]] · [[Kinematics]]
- 변형: [[Forward-Kinematics]] · [[FABRIK]] · [[CCD]]
- 응용: [[MoveIt]] · [[Animation-Rigging]] · [[VR-Avatar]]
- Adjacent: [[Denavit-Hartenberg-Parameters]] · [[Degrees-of-Freedom]]
## 🤖 LLM 활용
**언제**: 매 robot manipulator. 매 animation. 매 VR.
**언제 X**: 매 mobile-base-only.
## ❌ 안티패턴
- **Pseudo-inverse near singularity**: 매 explode.
- **Ignore joint limits**: 매 invalid.
- **Single solution**: 매 multiple — pick best.
- **No collision check**: 매 hardware damage.
## 🧪 검증 / 중복
- Verified (Spong Robot Dynamics, Aristidou FABRIK 2011).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — methods + 매 Jacobian / CCD / FABRIK / null-space code |