로봇에서 로봇팔을 이야기하려고 하면 꼭 등장하는 것은 기구학(kinematics)입니다. 힘의 관계를 생각하지 않고 연결된 링크와 조인트만 가지고 좌표를 해석하는 분야인데요. 저도 이 기구학을 공부하는 학생이라면 누구나 보는 Craig의 책을 Python으로 공부한 관련 글들을 올린 적이 있습니다. 그러나 기구학에서 복잡한 분야인 역기구학은 참 어렵습니다. 물론 이것을 손으로 푸는 경우는 요즘 (공부를 위한게 아니라면) 잘 못 봤습니다. 다들 좋은 툴을 사용하는 것 같습니다. 특히 MATLAB을 많이들 사용하죠. 저는 오늘 Python으로 기구학을 역으로 풀려는 분들께 도움이 될 만한 모듈을 하나 소개하려고 합니다.
Phylliade라는 분(?)인데요. 한 때 제가 관심을 가졌던 Poppy 프로젝트에서 발견한 Inverse Kinematics 도구입니다.
여기서 ikpy의 github 페이지를 가면 설치와 소스코드를 볼 수 있습니다. 이제 간편히 설치가 되었다면 간단한 예제를 한 번 보도록 하죠. 한가지 아쉬운건 쉬운 예제가 없어서 제가 일단 얼기설기 만들어 보았습니다. URDF파일을 바로 읽을 수 있다는 큰 장점이 있지만, 오늘 소개할 투토리얼 수준의 소개는 직접 만들려고 합니다.
%matplotlib notebook import matplotlib.pyplot as plt from ikpy.chain import Chain from ikpy.link import OriginLink, URDFLink from ikpy import plot_utils import numpy as np
먼저 설치후 필요 모듈을 import 하구요~
test_link = Chain(name='test_arm', links=[ OriginLink(), URDFLink( name="first_link", translation_vector=[1, 1, 0], orientation=[0, 0, 0], rotation=[0, 0, 1], ), URDFLink( name="second_link", translation_vector=[1, 0, 0], orientation=[0, 0, 0], rotation=[0, 0, 1], ) ])
그리고 frame은 세 개... 링크는 두 개인 심플한 모델을 시험용으로 잡았습니다. first_link의 translation_vector가 (1, 1)이어서 사선으로 한 번 올라가 있어 보일겁니다.
import matplotlib.pyplot from mpl_toolkits.mplot3d import Axes3D ax = matplotlib.pyplot.figure().add_subplot(111, projection='3d') test_link.plot([0,30*np.pi/180,0], ax) matplotlib.pyplot.show()
Forward Kinematics에선 간략하게 0도, 30도, 0도로 각 관절의 회전각도를 명령으로 주었습니다.
네.. 그래프로 보니 시험용 링크들이 잘 자리를 잡은 것 같습니다. 이제 역기구학을 슬쩍 테스트해봐야죠.
target_vector = [ 1, 0, 0] target_frame = np.eye(4) target_frame[:3, 3] = target_vector target_frame
이렇게 (1, 0, 0)을 끝단(end effector)의 목표 좌표로 보고 homogeneous tranform으로 표현합니다.
잘 되었네요~^^
print("The angles of each joints are : ", test_link.inverse_kinematics(target_frame))
슬쩍... inverse_kinematics를 풀면~
이렇게 각 관절이 가져야하는 각도를 계산해줍니다. 역기구학의 목적이죠?^^
real_frame = test_link.forward_kinematics(test_link.inverse_kinematics(target_frame)) print("--> Computed position vector : %s" % real_frame[:3, 3]) print("--> original position vector : %s" % target_frame[:3, 3])
이걸.. 이렇게 내 의도와 맞는지 확인할 수 있습니다.
이 과정이 필요한 이유는 도착이 불가능한 지점이 명령으로 주어졌을때 아직 ikpy 모듈을 에러를 주지 못하기 때문인 것 같습니다. (이 부분은 좀 더 모듈을 공부해야할 것 같습니다. 정확하지 않습니다.)
ax = plot_utils.init_3d_figure() test_link.plot(test_link.inverse_kinematics(target_frame), ax, target=target_vector) plt.xlim(-1, 2) plt.ylim(-1, 2)
그려야죠~
와우~ 제가 원한 (1, 0, 0)으로 기구의 끝단을 가져 놓도록 각 관절의 각도를 잘 잡았음을 알 수 있네요^^. 사용이 간편하지만.. 뭐 있어야할 기능은 다 있는 것 같습니다. 꽤 .. 멋지네요^^
'Robot > Robot Program - ROS' 카테고리의 다른 글
ROS에서 새로운 메세지 유형 만들어 사용하기 (17) | 2019.03.04 |
---|---|
VSCode로 ROS 패키지 생성해서, 간단한 subscribe 노드 만들어 보기 (12) | 2019.02.18 |
ROS의 node와 topic을 예제를 통해 알아볼까? (22) | 2019.02.11 |
ROS에서 아두이노로 만든 로봇 제어하기 - 일단은 LED 깜빡거리기 (19) | 2018.07.13 |
리눅스 민트에 ROS 설치 및 Turtlebot3 터틀봇3 세팅기 (24) | 2018.06.29 |
가제보 Gazebo 맥 Mac에서 설치하기... (22) | 2018.05.10 |
ROS의 개발도구로 VSCODE는 어떤가요 (24) | 2018.03.14 |