f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.4 KiB
7.4 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-inverse-kinematics | Inverse Kinematics (IK) | 10_Wiki/Topics | verified | self |
|
none | A | 0.95 | applied |
|
2026-05-10 | pending |
|
Inverse Kinematics (IK)
매 한 줄
"매 end-effector 의 target pose 의 의 의 joint angles 의 solve". 매 forward kinematics 의 reverse. 매 method: 매 analytic (closed-form), Jacobian (iterative), CCD, FABRIK. 매 응용: 매 robot, 매 animation, 매 VR avatar.
매 핵심
매 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).
매 challenge
- Multiple solutions.
- Singularity (near-singular pose).
- Joint limits.
- Self-collision.
- Redundancy (7+ DOF).
매 응용
- Robot manipulator.
- Animation (rigging, foot IK).
- VR avatar (hand tracking).
- Motion capture cleanup.
💻 패턴
Jacobian-based IK
import numpy as np
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
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
CCD (Cyclic Coordinate Descent)
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
FABRIK
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
Analytic IK (PUMA-style)
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
Damped least squares (singularity-robust)
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)
Animation foot IK (Unity-style)
// 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);
}
Joint limit handling
def clamp_to_limits(q, lower_limits, upper_limits):
return np.clip(q, lower_limits, upper_limits)
Null-space (redundancy)
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)
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
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)
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
- 변형: FABRIK · CCD
- 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 |