Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill forward-inverse-kinematics명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | forward-inverse-kinematics |
| description | 正逆运动学技能 - 解析法、雅可比迭代、数值IK、ROS2 IK服务器 |
| argument-hint | 逆运动学 OR IK OR 数值IK OR 雅可比 OR inverse kinematics |
| user-invocable | true |
机器人正逆运动学求解
当需要以下帮助时使用此技能:
import numpy as np
class SerialChainFK:
def __init__(self, dh_params):
"""
dh_params: [(theta, d, a, alpha), ...]
"""
self.dh_params = dh_params
def forward_kinematics(self, joint_angles):
"""计算正运动学"""
T = np.eye(4)
for i, (theta, d, a, alpha) in enumerate(self.dh_params):
theta += joint_angles[i]
ct = np.cos(theta)
st = np.sin(theta)
ca = np.cos(alpha)
sa = np.sin(alpha)
# DH 变换矩阵
Ti = np.array([
[ct, -st*ca, st*sa, a*ct],
[st, ct*ca, -ct*sa, a*st],
[0, sa, ca, d],
[0, 0, 0, 1]
])
T = T @ Ti
return T
def get_jacobian(self, joint_angles):
"""计算雅可比矩阵"""
n_joints = len(joint_angles)
J = np.zeros((6, n_joints))
# 末端位置
T_end = self.forward_kinematics(joint_angles)
p_end = T_end[:3, 3]
# 计算每个关节的雅可比列
T = np.eye(4)
for i in range(n_joints):
# 关节轴方向
z_i = T[:3, 2]
p_i = T[:3, 3]
# 线速度部分
J[:3, i] = np.cross(z_i, p_end - p_i)
# 角速度部分
J[3:, i] = z_i
# 更新 T
Ti = self.compute_dh_transform(self.dh_params[i], joint_angles[i])
T = T @ Ti
return J
class IKResolver:
def __init__(self, fk_solver):
self.fk = fk_solver
def solve(self, target_pose, initial_angles=None, max_iter=100, tol=1e-4):
"""数值 IK 求解"""
if initial_angles is None:
q = np.zeros(len(self.fk.dh_params))
else:
q = np.array(initial_angles)
for _ in range(max_iter):
# 当前末端位姿
T_current = self.fk.forward_kinematics(q)
p_current = T_current[:3, 3]
R_current = T_current[:3, :3]
# 位置误差
p_error = target_pose[:3, 3] - p_current
# 旋转误差 (使用罗德里格斯公式)
R_error = target_pose[:3, :3] @ R_current.T
theta_error = self.rotation_to_angle_axis(R_error)
# 组合误差
error = np.concatenate([p_error, theta_error])
if np.linalg.norm(error) < tol:
break
# 雅可比
J = self.fk.get_jacobian(q)
# 伪逆求解
q_delta = np.linalg.lstsq(J, error, rcond=None)[]
q = q + * q_delta
q
():
theta = np.arccos(np.clip((np.trace(R) - ) / , -, ))
theta < :
np.zeros()
axis = np.array([
R[, ] - R[, ],
R[, ] - R[, ],
R[, ] - R[, ]
]) / ( * np.sin(theta))
theta * axis
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Pose
from manipulation_msgs.srv import SolveIK, SolveIKRequest
class IKServer(Node):
def __init__(self):
super().__init__('ik_server')
self.ik_resolver = IKResolver(self.fk_solver)
self.srv = self.create_service(
SolveIK, 'solve_ik', self.solve_ik_callback)
def solve_ik_callback(self, request, response):
target_pose = self.pose_to_matrix(request.target_pose)
q_solution = self.ik_resolver.solve(
target_pose,
request.seed,
max_iter=100
)
response.joint_angles = q_solution.tolist()
response.success = True
return response