Processing.org |
3년전, 핀란드에서 연구교환 프로그램을 할때, 3D 휴머노이드 로본 손 개발 프로젝트에 참여했다. 즐거운 여름이였다.
나는 비전 기반의 제스쳐 인식 및 액츄에이터 제어부로 값을 전달해주는 기능을 구현했다.
먼저 프로세싱으로 테스트를 해보았다. LeapMotion SDK와 onformative에서 배포하는 LeapmotionP5 라이브러리를 사용했다.
먼저 프로세싱으로 테스트를 해보았다. LeapMotion SDK와 onformative에서 배포하는 LeapmotionP5 라이브러리를 사용했다.
3D 좌표 그리고 내 손 |
웹캠 -> 키넥트 -> 립모션으로 신기하게 나의 분야가 연결되어가는 맛이 아주 재밌다. 2년만에 다시 해봐서 더 재미있는 것 같다.
립모션 라이브러리는 당시 크게 LeapmotionP5와 LeapmotionforProcessing이 오픈되어 있었던 것으로 아는데, 기본적으로 제공하는, 접근할 수 있는 가능성을 후자가 더 많이 주는 것 같다. 나는 LeapmotionP5로 시작했다.
손목과 팔 사이의 각도를 구하는 도중, 벡터의 내적만 사용하면 부호 없는 각도값만 얻는다.
이때 벡터의 외적과 다른 벡터의 y-basis를 내적하면 부호를 알 수 있다.
외적에는 순서(오른손 법칙)가 있어서, 각도가 양에서 음으로 또는 음에서 양으로 바뀌는 순간 외적벡터의 방향이 바뀌기 때문이다. 그림을 그려보면서 해보면 이해가 쉽다.
Leap::Vector xBasisArm = basis.xBasis;
const Vector armV = arm.direction();
const Vector handV = hand.direction();
float wristAngle2 = handV.angleTo(armV) * RAD_TO_DEG;
Vector crossWrist2 = armV.cross(handV);
int sign2 = (crossWrist2.dot(xBasisArm) >= 0) ? -1 : 1;
const Vector armV = arm.direction();
const Vector handV = hand.direction();
float wristAngle2 = handV.angleTo(armV) * RAD_TO_DEG;
Vector crossWrist2 = armV.cross(handV);
int sign2 = (crossWrist2.dot(xBasisArm) >= 0) ? -1 : 1;
계산을 위해 간단히 그려본 그림 |
댓글
댓글 쓰기