September 26, 2021

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[65호]Cable-driven Anthropomorphic Dexterous Robot hand

65 ict robot hand (1)

2020 ICT 융합 프로젝트 공모전 장려상

Cable-driven Anthropomorphic

Dexterous Robot hand

글 | 서울과학기술대학교 김태욱, 금현주, 민성재, 이동현

 

1. 심사평

칩센 보고서가 매우 촘촘하게 잘 작성되었고, 기술의 구현 난이도 또한 매우 높아 보입니다. 기획한 작품이 잘 구현 제작된다면 여러 가지 방면에서 사용이 가능할 듯도 합니다. 메카닉적인 부분과 하드웨어/소프트웨어 부분을 모두 포함하고 있어 수준이 높은 작품이라 판단됩니다만, 작품의 최종 결과물에 대하여 동작 등을 확인할 수 없어 얼마나 세밀하고, 정밀하게 관절의 움직임이 있는지는 알 수가 없어 일부 평가 항목에서 손해를 보았습니다. 하지만 지원자(팀)께서 어떤 의도를 가지고 작품을 개발하는지 충분히 이해가 가능하고, 시도만으로도 충분히 좋은 평가가 가능한 작품입니다.
펌테크 출품된 작품은 순수 기계공학적인 부분으로만 구성된 우수한 작품으로 전기, 전자, 소프트웨어 응용제품을 대상으로 하는 본작품전의 기본취지와는 다소 차이가 있는 제품이 아닌가 판단됩니다.
위드로봇 동작 시연 및 손가락의 모션 제어까지 포함되었으면 아주 훌륭한 작품입니다.

2. 작품 개요

18세기 이후, 산업혁명 초기에는 물체를 손으로 잡고 이동하거나 반복적인 일을 수행할 수 있는 팔 형태의 로봇들을 연구했고 그 로봇들이 사람들을 대신하면서 대규모 제조업이 발달하였다.
시간이 흐르면서 점점 정교하고 빠른 로봇 팔이 연구되었고 최근 들어서는 정해진 환경에서 반복적인 일을 하는 것을 넘어 안드로이드나 의수 등으로 인한 여러 가지 환경에서 적응력이 좋은 유연한 로봇 팔에 대한 필요성이 높아지고 있다.
인간의 한 손은 27개의 자유도가 있어 유연하고 세밀한 작업을 할 수 있다. 이에 많은 연구가 인간의 손을 모방한 로봇 팔을 만들려고 시도 하고 있다.
의인화한 손의 기계적 설계 요구사항은 Anthropomorphic features와 Grasping performance로 나눌 수 있다[5].
Anthropomorphic features: 손가락의 구성, 크기 및 역동적인 행동을 포함하여 가능한 사람의 손을 모방해야 한다[5].
Grasping performance: 로봇 손의 속도와 힘이 충분하여 특정되지 않은 물체도 유연하게 잡을 수 있어야 한다[5].
기존의 로봇손에서 모터를 관절에 부착하는 방식으로는 Anthropomorphic features과 Grasping performance을 모두 충족시키기는 어렵다. Anthropomorphic features을 충족시키기 위해서는 로봇손이 작아져야 하지만 작은 모터는 힘이 약하기 때문에 Grasping performance을 충족시킬 수 없다.
이러한 문제점을 해결하기 위해 본 작품은 Cable을 이용하여 관절에 부착된 모터를 다른 곳으로 이동시키고 관절의 움직임을 제어할 수 있게 디자인을 하였다.
기존 로봇손 디자인에서는 관절모터에 이후 달린 관절들의 모터들이 부하로 작용하였지만, Cable을 이용한 본 작품은 이러한 부하를 없애 줌으로써 페이로드를 높였다.

3. 작품 설명
3.1. 주요 동작 및 특징
본 작품은 주요 동작 및 특징이 Cable-driven과 Anthropomorphic이 있다.
Cable-driven:
케이블구동 방식은 당길 수만 있는 단방향성을 가진다. 따라서, 이 방식은 직접 모터를 사용하여 양방향성을 가지는 기존의 로봇손과 중요한 차이가 있다[7][8][9]. 케이블의 단방향 특성 때문에 n자유도 모션을 갖는 매커니즘에서 n+1개의 케이블이 필요하다[1][7][10]. 최근에 연구되는 케이블 구동 로봇손은 기존의 양방향성 로봇손보다 더 많은 모터가 사용된다[1]. 그러나 본 작품에서는 케이블 구동을 이용하여 n개의 모터만으로 자연스러운 움직임을 구현하고 기존 양방향성 로봇손과 비교하여 더 큰 작업공간, 더 높은 적재 중량과 생산비용을 제공할 수 있다.
Anthropomorphic:
인간의 몸은 630개의 근육으로 제어되는 244자유도가 있다[3]. 244개의 자유도 중 사람 손에만 총 54개의 자유도를 제공한다[4]. 많은 자유도에 의해 손은 높은 유연성이 있으며 악력이 강하고 물체를 잡는데 능숙하다[2].
실제 인간의 손은 탄성을 가진 피부로 덮여 있고 뼈와 근육, 힘줄, 인대 등과 결합된 복잡한 매커니즘이 있기 때문에 완전히 일치하게 로봇손을 제작하기는 어렵다[2]. 때문에 본 작품은 실제 인간의 손의 구조를 모방하되 자연스러운 움직임을 구동하는데 영향이 적은 관절은 생략 하도록 한다.
실제 사람의 손가락 모형은 크게 엄지와 나머지 4개의 손가락으로 나눌 수 있다. 엄지는 제 1관절로 TM, 제 2관절 MCP, 제3관절을 IP로 표현할 수 있다. 나머지 4개의 손가락에서의 CMC를 제외하고 제 1관절을 MCP, 제 2관절 PIP, 제 3관절을 DIP로 제작하였다. [그림1]의 D와 같이 TM은 사실 2자유도지만 1자유도로 봐도 자연스러운 움직임이 가능하므로 1자유도로 제작하였다. 5개의 모든 손가락의 제 1관절은 2자유도로, 제2, 3관절은 1자유도로 하였다. 2, 3관절은 각각의 자유도를 가지지만 서로 종속된 움직임을 가지기 때문에 스프링을 이용하여 한 개의 모터로 구동시켰다.

65 ict robot hand (2)

3.2. 전체 시스템
3.2.1. 전체디자인
본 작품의 로봇손은 손가락, 손바닥, 모터 및 보빈, 매니퓰레이터로 나눌 수 있으며, 케이블이 손가락의 각 관절에서부터 시작되어 손바닥을 지나 모터 보빈에 연결된다.

65 ict robot hand (3)

3.2.2. 손가락

65 ict robot hand (4)

65 ict robot hand (5)
신체 구조상 손가락을 크게 뼈, 관절, 근육으로 분리해 생각할 수 있다. 손가락의 뼈는 강도와 전체 손의 무게를 고려해 알루미늄 샤프트를 사용하였다[그림3].
관절부분에는 유니버셜 조인트를 사용하였다[그림4]. 제 2,3관절은 1자유도이기 때문에 물리적 제한을 두어 유니버셜 조인트가 한방향으로만 움직일 수 있게 하였다.
마지막으로 근육 및 인대 역할을 하는 케이블을 연결하기 위하여 실이 지나가거나 고정될 수 있는 플레이트를 제작하여 관절에 부착하였다[그림5]. 이 부분을 앞으로 ‘조인트 플레이트’라고 지칭하겠다.

65 ict robot hand (6)

[그림7]은 손가락 한 개를 매트랩을 통하여 시뮬레이션해보았다. 중심을 통과하는 진한 하늘색은 손가락의 뼈대를 구성하는 샤프트를 의미한다. 첫 번째 관절은 상하, 좌우 두 개의 자유도를 가지고 있다. 첫 번째 관절에 초록색, 노란색, 보라색, 하늘색 4개의 실이 묶여 상하와 좌우의 움직임을 정한다. 빨간색과 주황색의 실은 첫 번째 마디와 두 번째 관절을 모두 통과하고 세 번째 관절에서 묶여 두번째, 세번째 관절을 동시에 제어한다. 이는 회전하는 방향이 같기 때문에 가능하다. 인간의 손에서 두 번째 관절은 굽어지는 방향으로 하나의 자유도를 가지고는 있지만, 세 번째 관절의 움직임에 따라 종속적으로 작동한다. 이러한 관계를 스프링과 두개의 실을 이용하여 표현하였다.

65 ict robot hand (7)
첫 번째(MCP)와 세 번째 관절(DIP)은 모터에 실제로 연결되어 있기 때문에 모터를 조절하여 각 관절을 움직일 수 있다. 하지만 첫번째 관절과 달리 세번째 관절과 두번째 관절은 두번째 관절이 특정되지 않기 때문에 위치와 각도는 예측할 수 없다.

[그림8]에 보듯이 두 번째 관절(PIP)의 경우 움직여 첫번째, 세번째 관절사이의 실의 길이가 같은 곳이라면 어디든 존재할 수 있다. 다시 말하면 사람의 실제 손과 다르게 앞으로 굽히는 방향만 있는 것이 아닌 [그림7]의 빨간색처럼 뒤로 꺾이는 방향으로도 존재할 수 있다. 그래서 뒤로 꺾이는 방향으로 움직임을 제한하고 두번째 세번째 관절을 종속해주는 스프링을 두번째 관절(PIP), 세번째 관절(DIP)사이에 부착한다. 손가락을 일자로 폈을 때를 스프링의 최소길이로 고정하여 더 이상 뒤로 굽혀지지 않도록 한다. 케이블의 장력과 스프링 계수를 조절하여 PIP와 DIP의 회전하는 정도를 조절할 수 있다. 스프링 계수에 따라 자연스러운 비율로 두번째 세번째의 관절이 회전할 것이다. 스프링 계수가 높으면 물체에 손가락이 닿기 전까지 세번째 관절이 회전하지 않다가 두번째 세번째 사이의 마디에 물체가 접촉되었을 경우 케이블 장력으로 인해 세번째 관절이 회전하게 될 것이다.

65 ict robot hand (8)

[그림9]은 조인트 플레이트와 유니버셜 조인트의 조립품이다. 조인트 플레이트 8개의 구멍 중 서로 180° 반대편에 연결되어 있는 실은 같은 모터에 감기게 된다. 두개의 실이 짝을 이루게 되는데 한 개의 실은 시계방향으로 감기고 나머지 실은 반 시계 방향으로 모터 보빈에 감는다. 한쪽 실을 당기게 되면 반대편에 연결된 실이 풀리기 때문에 조인트가 꺾일 때 실이 끊겨지지 않기 위해서는 조인트 플레이트의 아래 면과 조인트의 중심이 같은 높이에 있어야 한다.
또한 조인트가 중심 축을 기준으로 회전할 때 회전운동에 대한 실이 묶여 있는 양 끝점의 위치와 지정한 손가락 마디의 길이를 가지고 다음 조인트 플레이트의 위치를 기구학적 해석으로 구할 수 있는데, 중심과 다른 높이에 조인트 플레이트가 있다면 회전운동과 평행이동의 두 단계에 걸친 계산이 필요하다.
유니버셜 조인트의 구조적인 문제로 자연스러운 움직임이 가능한 각도가 정해져 있다. 유니버셜 조인트의 자체 최대각도까지 회전하기도 전에 조인트 플레이트가 조인트에 닿아 회전하는 각도에 제한이 생긴다. 또한 실을 계속해서 당기면 실과 조인트 플레이트가 평행하게 접하는 각도가 있다. 이 각도를 넘어서까지 실을 당길 경우 조인트 플레이트에 실이 걸려 반발력이 발생하고 양쪽 두 실의 변화량이 달라질 수 있다. 이러한 각도 제한들의 안에서 손가락이 구동되어야 하므로 최대각도를 다음과 같이 정했다.
-5° < θ < 60°

3.2.3. 손바닥

65 ict robot hand (9)

65 ict robot hand (10)
손바닥은 손가락을 고정할 수 있는 손바닥 뼈대[그림10], 손바닥에서 실이 지나가는 점을 고정해주는 플레이트[그림11], 손바닥 이후에 모터까지 케이블이 지나가는 튜브를 고정해줄 튜브 고정 플레이트 [그림13]가 있다.
손바닥에서 실이 지나가는 점을 고정해주는 플레이트를 앞으로 ‘손바닥 플레이트’라고 지칭하겠다[그림10].
손바닥에서 튜브를 고정해주는 플레이트를 앞으로 ‘튜브 고정 플레이트’라고 지칭하겠다[그림13].
손가락은 손바닥의 연장된 부분이지만 본 작품은 각각 분리된 형태로 존재한다. 만약 네 손가락이 모두 같은 방향으로 있다면, 손가락을 구부려 물체를 잡을 때 손가락들이 한 점에서 모이지 않기 때문에 불리하게 작용한다. 손가락을 구부렸을 때, 한 점에서 모든 손가락이 모이기 위해서 손바닥 뼈대의 각도와 길이를 조절할 필요가 있는데 그 값 은 [그림14]와 같다.

65 ict robot hand (11)

손가락 현재관절의 위치는 이전 관절의 위치와 관절사이의 거리 및 각도를 통해 계산한다. 케이블을 손바닥 끝에 고정시키면, 손바닥 플레이트의 실 고정점을 손가락의 시작점으로 생각하여 관절의 위치를 구할 때 계산을 단순화할 수 있다. 또한 손가락이 움직일 때 케이블이 손바닥에 접촉되어 일어나는 의도치 않은 길이 변화를 제한할 수 있다.

3.2.4. 보빈 및 액츄에이터
손가락을 움직이기 위해서 실을 밀고 당기는 역할은 보빈과 액츄에이터가 한다. 보빈[그림16]은 실이 감기는 부분이고 액츄에이터[그림17]는 보빈을 돌려준다.
실을 감기 전에 먼저 보빈에 실구멍을 통해 실을 한번 묶어서 고정해준 뒤 실을 감아 실이 헛도는 것 방지한다.

65 ict robot hand (12)

 

65 ict robot hand (13)

케이블은 특성상 당기는 방향으로만 제어할 수 있고 미는 방향으로의 제어가 불가능하여, 하나의 모터로는 한 가닥의 케이블만 조절할 수 있다. 기존의 로봇손은 1개의 자유도를 제어하기 위해서는 두개의 모터가 필요하다. 그러나 본 작품은 한 개의 자유도를 제어하기 위하여 두 가닥의 케이블을 하나의 보빈에 반대방향으로 감아 더 적은 액츄에이터로 1개의 자유도를 제어할 수 있게 하여 모터의 수를 줄였다.
케이블은 보빈의 가운데 원판[그림15]을 기준으로 한쪽은 순방향, 반대쪽은 역방향으로 감겨 있어, 모터가 회전하면 한쪽은 감기고 반대쪽은 풀린다. 제어하고자 하는 조인트 플레이트의 양쪽 끝에 실을 묶어 손가락의 움직임을 제어할 수 있다.

3.2.5. 매니퓰레이터

65 ict robot hand (14)

매니퓰레이터를 손과 연결하면 사람의 팔과 같은 형태가 되어 더 다양한 방향으로 어플리케이션을 확장할 수 있다. 하지만, 매니퓰레이터를 사용할 경우 매니퓰레이터의 회전과 이동 때문에 몸체사이에 케이블이 걸려 의도치 않은 길이변화가 일어날 수 있다. 이 문제를 해결하기 위해서 손바닥부터 튜브를 연결하여 모터의 전까지 케이블을 감싸고 있으면 위의 문제를 해결할 수 있다.

3.2.6. 기구학
로봇 손의 손가락 끝지점은 4X4 회전행렬을 활용한 동차변환으로 기구학을 풀이하여 해석하였다. 동차 변환 행렬은 각 축에 대한 회전 행렬에서 좌표 이동과 크기 조정에 대한 정보를 추가한 행렬으로, 일반적으로 아래의 행렬과 같이 나타난다.

65 ict robot hand (15)
본 제품에서는 투시 변환의 경우는 존재하지 않으므로, 투시 변환은 0으로 고정시키고, 크기조정 또한 단위 변환이므로 1으로 고정시킨다.

65 ict robot hand (16)
순기구학을 풀이할 시, 동차변환은 각 링크 간의 이동변환과 회전변환의 곱으로 나타난다. 동차 변환에 관한 자세한 원리는 본 서식에서 다루지 않고 참고문헌을 참조한다[14].

매니퓰레이터는 6개의 링크의 조합으로 움직이고 각 관절의 움직임은 다음과 같다.

65 ict robot hand (17)

65 ict robot hand (18)

 

65 ict robot hand (19)

매니퓰래이터의 동차변환()은 다음 식으로 정리된다.

65 ict robot hand (20)
로봇 손은 시작점(origin)에서 손가락 끝점까지 2개의 조인트와 3개의 샤프트의 조합으로 이루어져 있다. 따라서, 로봇 손의 동차변환은 총 세 링크와 그 변환들의 조합으로 나타난다. 손바닥의 길이를 L_0, 첫 번째 관절부터 세 번째 관절까지의 손가락 길이를 L_1, 세 번째 관절부터 손가락 끝부분까지의 길이를 L_2라 할 때, 각 움직임은 다음과 같다.

65 ict robot hand (21)

65 ict robot hand (22)

로봇 손의 동차변환(DH)는 다음 식으로 정리된다.

65 ict robot hand (23)

3.3. 개발 환경
3.3.1. 디자인
Cable-driven robot hand를 개발하는데 있어서 대부분의 하드웨어를 3D프린터를 사용하여 만들었다. 프린터로 제작한 부품 이외에는 유니버셜 조인트, 샤프트 등 일반적으로 시중에서 쉽게 구입할 수 있는 공학 재료들을 사용하여 제작하였기 때문에 쉽게 제작할 수 있다. 3D프린터를 이용하여 부품을 제작한 만큼 설계하는 CAD 프로그램 선정 또한 중요했다. 설계를 하는데 사용한 프로그램은 AUTODESK사의 INVENTOR이다.

65 ict robot hand (24)

 

65 ict robot hand (25)

인벤터로 디자인을 하고 이를 프로그램 내장된 3D 프린트 기능으로 STL 파일로 모델을 출력하였다. 아래는 인벤터도 디자인한 윈치 와이어가 감기는 보빈이다. 이렇게 디자인한 각 파트들을 위와 같이 인벤터 안에서 조립해볼 수 있다.
또한 인벤터를 사용함으로써 장점은 디자인한 각 파트를 미리 조립을 해보고 간섭이 있는지 검사하거나 어떤 부분이 약할지 시뮬레이션을 해볼 수 있다.
만들어진 STL파일을 3D 프린터로 출력하기 위해 GCODE로 변환하기 위해 사용한 프로그램은 많은 사용자들이 사용하는 ULTIMAKER CURA를 사용했다.
CURA에 STL파일을 넣고 사용할 프린터에 맞게 설정을 해주면 적절한 GCODE가 생성된다. 프린터에 따라 직접 프린터를 컴퓨터에 연결하여 CURA에서 바로 프린트할 수도 있고 생성한 GCODE파일을 이동식 메모리에 넣어 프린터에 꽂아 사용할 수 있다. 아래는 모델링한 STL파일을 열어 GCODE로 변환한 모습이다.

65 ict robot hand (26)

CURA에는 다양한 설정이 있어 각 부품들의 필요한 속성에 따라 적당한 값으로 조절하여 필요한 특성을 얻을 수 있다.

3.3.2. 시뮬레이션
제작하기에 앞서 모델링 한 부품들에 맞춰 실제로 동작하는지 확인해 볼 필요가 있다. 동작 중에 수치적으로 와이어의 길이 변화가 어떻게 일어나는지 또는 그 과정에서 얼마나 오류가 발생하는지 확인해야 한다. 앞에 3-2. 6)절에서 기구학을 풀었는데 이를 코드로 구현하여 설계한 대로 제작했을 때 각도가 변함에 따라 와이어의 길이를 시뮬레이션한다. 이를 위해 MATLAB을 이용해서 기구학 식을 구현해서 시뮬레이션 해보고 그때의 와이어 길이의 변화를 구했다.
아래 3차원 그래프는 각 손가락 관절을 움직일 때 와이어, 플레이트, 샤프트의 위치를 표시한 그래프이다. 또한 이렇게 손가락을 움직일 때 밑에 그래프처럼 각 와이어가 어떻게 얼마나 변하고, 한 관절에 대해서 늘어나고 줄어드는 양의 오차가 얼마인지 그래서 그 양은 모터의 각도로 얼마나 차이 나는지를 확인할 수 있다.

65 ict robot hand (27)

3.3.3. 로봇 손 구동 펌웨어
기본적인 모터 구동을 포함한 유저 인터페이스, 어플리케이션과의 연결은 C++로 개발하였다. 사용하는 액츄에이터가 ROBOTIS의 DYNAMIXEL이기 때문에 따로 모터와 엔코더를 위한 개별 제어기를 사용하지 않았고, ROBOTIS에서 제공하는 SDK를 사용하여 제어했다. 따라서 모든 기본적인 제어를 포함한 피드백, 다양한 명령에 대해서 주 제어기인 PC가 대부분의 역할을 수행하게 된다. 초기적인 방법으로 C++ 콘솔 응용프로그램을 사용하여 손가락의 구동 및 유저 인터페이스를 구현하였다. 개발자가 필요에 따라 GUI가 가능하도록 C#을 이용하여 개발하거나 OpenCV나 OpenGL을 이용하여 그래픽으로 표시하게 추가할 수 있다.

4. 단계별 제작 과정
4.1. 손가락 한 개 시제작

65 ict robot hand (28)

4.2. 로봇손 제작
65 ict robot hand (29)

[그림28]의 오른쪽 그림은 왼쪽 도안에서 더 튼튼하게 하기 위하여 손바닥 면적을 늘려주었다.

65 ict robot hand (30)

65 ict robot hand (1)

 

65 ict robot hand (2)

5. 기타

5.1. 소스코드
5.1.1. 매트랩 시뮬레이션 코드

%% Simulate One Finger
clear, clc;
SimMin = 0;
SimMax = 30;
Res = 20;

BobinR = 5;
PlateR = 11;
PlateHallR = 8;
PlateOffset = [0 0 0 0]+1;
SHAFTLENGTH = [15 50 35 25];

disp(['Simuation from ' num2str(SimMin) ' to ' num2str(SimMax) ', with ' num2str(Res) 'steps']);
sim = linspace(SimMin, SimMax, Res);
counter = 1;
clear LWs;
LWs = zeros(6,length(sim));
for i = 1:length(sim)
[SHAFT, WIRE, LW] = OneFinger(eye(4),[sim(i) sim(i) sim(i) 0 0 0 0 0 0],PlateHallR,PlateOffset,SHAFTLENGTH);
LWs(:,counter) = LW;
figure(1);
plot3(SHAFT(1,:),SHAFT(2,:),SHAFT(3,:),’-o’,'LineWidth’,3), hold on;
plot3(WIRE{1}(1,:),WIRE{1}(2,:),WIRE{1}(3,:),’-.d’,'LineWidth’,2);
plot3(WIRE{2}(1,:),WIRE{2}(2,:),WIRE{2}(3,:),’-.d’,'LineWidth’,2);
plot3(WIRE{3}(1,:),WIRE{3}(2,:),WIRE{3}(3,:),’-.d’,'LineWidth’,2);
plot3(WIRE{4}(1,:),WIRE{4}(2,:),WIRE{4}(3,:),’-.d’,'LineWidth’,2);
plot3(WIRE{5}(1,:),WIRE{5}(2,:),WIRE{5}(3,:),’-.d’,'LineWidth’,2);
plot3(WIRE{6}(1,:),WIRE{6}(2,:),WIRE{6}(3,:),’-.d’,'LineWidth’,2);
plotCircle3D(SHAFT(:,1)’+PlateOffset(1)*(SHAFT(:,2)-SHAFT(:,1))’/norm((SHAFT(:,2)-SHAFT(:,1))’),(SHAFT(:,2)-SHAFT(:,1))’,PlateR,2);
plotCircle3D(SHAFT(:,2)’+PlateOffset(2)*(SHAFT(:,3)-SHAFT(:,2))’/norm((SHAFT(:,3)-SHAFT(:,2))’),(SHAFT(:,3)-SHAFT(:,2))’,PlateR,2);
plotCircle3D(SHAFT(:,3)’+PlateOffset(3)*(SHAFT(:,4)-SHAFT(:,3))’/norm((SHAFT(:,4)-SHAFT(:,3))’),(SHAFT(:,4)-SHAFT(:,3))’,PlateR,2);
plotCircle3D(SHAFT(:,4)’+PlateOffset(4)*(SHAFT(:,5)-SHAFT(:,4))’/norm((SHAFT(:,5)-SHAFT(:,4))’),(SHAFT(:,5)-SHAFT(:,4))’,PlateR,2);
title(‘One Finger’);
axis equal;
hold off;
drawnow;
counter = counter+1;
end

figure(2);
subplot(2,3,1), plot(sim,LWs(1,:)), axis([SimMin SimMax 0 150]),title(‘Wire 1 Length’), grid on;
subplot(2,3,2), plot(sim,LWs(2,:)), axis([SimMin SimMax 0 150]),title(‘Wire 2 Length’), grid on;
subplot(2,3,3), plot(sim,LWs(3,:)), axis([SimMin SimMax 0 150]),title(‘Wire 3 Length’), grid on;
subplot(2,3,4), plot(sim,LWs(6,:)), axis([SimMin SimMax 0 150]),title(‘Wire 6 Length’), grid on;
subplot(2,3,5), plot(sim,LWs(5,:)), axis([SimMin SimMax 0 150]),title(‘Wire 5 Length’), grid on;
subplot(2,3,6), plot(sim,LWs(4,:)), axis([SimMin SimMax 0 150]),title(‘Wire 4 Length’), grid on;

figure(3);
subplot(2,3,1), plot(sim,LWs(1,:)-LWs(6,:)), axis([SimMin SimMax -50 50]),title(‘J2 WL diff’);
subplot(2,3,2), plot(sim,LWs(2,:)-LWs(5,:)), axis([SimMin SimMax -50 50]),title(‘J1_1 WL diff’);
subplot(2,3,3), plot(sim,LWs(3,:)-LWs(4,:)), axis([SimMin SimMax -50 50]),title(‘J1_2 WL diff’);
subplot(2,3,4), plot(sim,LWs(1,:)-LWs(1,1)+LWs(6,:)-LWs(6,1)), axis([SimMin SimMax -15 15]),title(‘J2 WL error’);
subplot(2,3,5), plot(sim,LWs(2,:)-LWs(2,1)+LWs(5,:)-LWs(5,1)), axis([SimMin SimMax -15 15]),title(‘J1_1 WL error’);
subplot(2,3,6), plot(sim,LWs(3,:)-LWs(3,1)+LWs(4,:)-LWs(4,1)), axis([SimMin SimMax -15 15]),title(‘J1_2 WL error’);
disp(['Max J2 wire length error: ' num2str(max(abs(abs(LWs(1,:)-LWs(1,1)+LWs(6,:)-LWs(6,1))))) 'mm']);
disp(['Max J1_1 wire length error: ' num2str(max(abs(abs(LWs(2,:)-LWs(2,1)+LWs(5,:)-LWs(5,1))))) 'mm']);
disp(['Max J1_2 wire length error: ' num2str(max(abs(abs(LWs(3,:)-LWs(3,1)+LWs(4,:)-LWs(4,1))))) 'mm']);

figure(4);
LWCs = LWs-LWs(:,1);
LWCd = rad2deg(LWCs./BobinR);
MotorPos = round(LWCd./360*4096);
subplot(3,3,1), stairs(MotorPos(1,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 1′);
subplot(3,3,2), stairs(MotorPos(2,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 2′);
subplot(3,3,3), stairs(MotorPos(3,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 3′);
subplot(3,3,4), stairs(MotorPos(6,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 6′);
subplot(3,3,5), stairs(MotorPos(5,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 5′);
subplot(3,3,6), stairs(MotorPos(4,:)), axis([0 length(LWCs) -4096 4096]), title(‘Motor Pos by wire 4′);
subplot(3,3,7), stairs(MotorPos(1,:) + MotorPos(6,:)), axis([0 length(LWCs) -256 256]), title(‘J2 Motor Pos Error’);
subplot(3,3,8), stairs(MotorPos(2,:) + MotorPos(5,:)), axis([0 length(LWCs) -256 256]), title(‘J1_1 Motor Pos Error’);
subplot(3,3,9), stairs(MotorPos(3,:) + MotorPos(4,:)), axis([0 length(LWCs) -256 256]), title(‘J1_2 Motor Pos Error’);
MaxPosErr = max([max(abs(MotorPos(1,:) + MotorPos(6,:))) max(abs(MotorPos(2,:) + MotorPos(5,:))) max(abs(MotorPos(3,:) + MotorPos(4,:)))]);
disp(['Max motor position error is: ' num2str(MaxPosErr) ' encoder tics, ' num2str(MaxPosErr/4096) ' rotation, degrees: ' num2str(MaxPosErr*360/4096)]);

5.1.2. 손가락 구동 코드

// CableOneFinger.cpp : This file contains the ‘main’ function. Program execution begins and ends there.
//

#if defined(__linux__) || defined(__APPLE__)
#include <fcntl.h>
#include <termios.h>
#define STDIN_FILENO 0
#elif defined(_WIN32) || defined(_WIN64)
#include <conio.h>
#endif

#include <Windows.h>
#include <stdlib.h>
#include <iostream>

#include “dynamixel_sdk.h”
#include “CableOneFinger.h”
#include “DXL_custom.h”
#include “DXL_application.h”
#include “UserFunction.h”
#include “Robotics.h”

using namespace std;
int main()
{
int dxl_comm_result = COMM_TX_FAIL;
uint8_t dxl_error = 0;

bool dxl_addparam_result = false;
bool dxl_getdata_result = false;

const int DXL_IDs[DXLS] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int DXL_REL_MIN_POSs[DXLS];
int DXL_REL_MAX_POSs[DXLS];
int DXL_REL_GRASP_POSs[DXLS];
fill_n(DXL_REL_MIN_POSs, DXLS, 0);
fill_n(DXL_REL_MAX_POSs, DXLS, 3000);
fill_n(DXL_REL_GRASP_POSs, DXLS, 2500);

int DXL_INIT_POSs[DXLS];
int DXL_ABS_GOAL_POSs[DXLS];
int DXL_ABS_PRE_POS_ERRs[DXLS];
int DXL_ABS_PRESENT_POSs[DXLS];
int DXL_ABS_MIN_POSs[DXLS];
int DXL_ABS_MAX_POSs[DXLS];
int DXL_ABS_GRASP_POSs[DXLS];

int16_t DXL_PRESENT_LOAD[DXLS];
bool DXL_GRASPED[DXLS] = { false };

dynamixel::PortHandler *portHandler = dynamixel::PortHandler::getPortHandler(DEVICENAME);
dynamixel::PacketHandler *packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION);

dynamixel::GroupSyncWrite SyncWriteGoalPos(portHandler, packetHandler, ADDR_GOAL_POSITION, LEN_GOAL_POSITION);
dynamixel::GroupSyncRead SyncReadPresentPos(portHandler, packetHandler, ADDR_PRESENT_POSITION, LEN_PRESENT_POSITION);

dynamixel::GroupSyncRead SyncReadPresentLoad(portHandler, packetHandler, ADDR_PRESENT_LOAD, LEN_PRESENT_LOAD);

if (portHandler->openPort())
cout << “Succeeded to open the dynamixel!” << endl;
else
{
cout << “Failed to open the dynamixel!” << endl;
_getch();
return -1;
}

if (portHandler->setBaudRate(BAUDRATE))
cout << “Set baudrate to ” << BAUDRATE << endl;
else
{
cout << “Failed to change the baudrate!” << endl;
_getch();
return -1;
}

if (!(initializeHand(packetHandler, portHandler, SyncReadPresentPos, SyncWriteGoalPos, &dxl_comm_result, &dxl_error, &dxl_addparam_result, &dxl_getdata_result, DXL_IDs, DXL_INIT_POSs, sizeof(DXL_IDs))))
cout << “Initializing failed!” << endl;
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_GRASP_POSs, DXL_ABS_GRASP_POSs, sizeof(DXL_IDs), ‘+’);
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_MIN_POSs, DXL_ABS_MIN_POSs, sizeof(DXL_IDs), ‘+’);
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_MAX_POSs, DXL_ABS_MAX_POSs, sizeof(DXL_IDs), ‘+’);
cout << “CABLE-DRIVEN ROBOT HAND Initialized!!!” << endl;

grasping(packetHandler, portHandler, SyncReadPresentPos, SyncReadPresentLoad, SyncWriteGoalPos, &dxl_comm_result, &dxl_error, &dxl_addparam_result, &dxl_getdata_result, DXL_IDs, DXL_ABS_GRASP_POSs, DXL_ABS_PRESENT_POSs, DXL_ABS_PRE_POS_ERRs, DXL_PRESENT_LOAD, DXL_GRASPED, sizeof(DXL_IDs), DXL_MOVING_POS_THRESHOLD);
Sleep(5000);
toggleDXLTorque(packetHandler, portHandler, &dxl_comm_result, &dxl_error, DXL_IDs, sizeof(DXL_IDs), TORQUE_DISABLE);

portHandler->closePort();
return 0;
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file

5.2. 참고문헌
[1] G.Z. Lum, S.K. Mustafa, H.R. Lim, W.B. Lim, G.Yang and S.H. Yeo, “Design and Motion Control of a Cable-driven Dexterous Robotic Arm”, 2010 IEEE Conference on Sustainable Utilization and Development in Engineering and Technology Universiti Tunku Abdul Rahman, pp. 106-111.
[2] Li Tian, Nadia Magnenat-Thalmann, Daniel Thalmann and Jianmin Zheng, “A Methodology to Model and Simulate Customized Realistic Anthropomorphic Robotic Hands”, CGI 2018, June11-14,2018, bintan Island, Indonesia, pp. 153-162.
[3] Zatsiorsky. V. and B. Prilutsky, Biomechanics of skeletal muscles. 2012: Human Kinetics.
[4] Agur, A.M. and A.F. Dalley, Grant’s atlas of anatomy. 2009: Lippincott Williams & Wilkins.
[5] Ming Cheng, Li Jiang, Fenglei Ni, Shaowei Fan, Yuan Liu and Hong Liu, “Design of a Highly Integrated Underactuated Finger towards Prosthetic Hand”, 2017 IEEE international Conference on Advanced Intelligent Mechatronics (AIM), pp. 1035-1040.
[6] Li Tian, Nadia Magnenat-Thalmann, Daniel Thalmann and Jianmin Zheng, “The Making of a 3D-Printed, Cable-Driven, Single-Model, Lightweight Humanoid Robotic Hand”, frontiers in Robotics and AI, Volume4, Article 65, published in 04 December 2017, pp. 1-10.
[7] P. Gholami, M.A. Mohammad and H.D. Taghirad, “On the control of the KNTU CDRPM: A cable driven redundant parallel manipulator”, 2008 IEEE/RSJ International Conference on Intelligent Robots and Systems, Nice, France, pp. 2404-2409.
[8] I. Ebert-Uphoff and P.A. Voglewede, “On the connections between cable-driven robots, parallel manipulators and grasping”. 2004 IEEE International Conference on Robotics and Automation, New Orleans, LA, pp. 4521-4526.
[9] E. Ottaviano, M. Ceccarelli, A. Paone and G. Carbone, “A low-cost easy operation 4-cable driven parallel manipulator”. 2005 IEEE International Conference on Robotics and Automation, Barcelona, Spain, pp. 4019-4024.
[10] A. Ming and T. Higuchi, “Study on multiple degree-of- freedom positioning mechanism using wires (part 1)”, Int. Journal of the Japan Society of Precision Engineering, Vol. 28, No. 2, 1994, pp. 131-138.
[11] W.K. Jung, J.H. Park, I.S. Kwon, J.B. Song, Y.J. Choi, and K.H. Kim, The Experimental RoboticsⅠ: Manipulation and Vision, Institute of Control, Robotics and Systems, Korea Robotics Society (KRoS), pp. 1-335, 2011
[12] Dawei Xu, En li and Zize liang, “Kinematics and Statics Analysis of a Novel Cable-Driven Snake Arm Robot”, Chinese Automation Congress 2017, IEEE 2017, pp. 439-444.
[13] Maria Chlara Carrozza, Bruno Massa, Fabrizio Vecchi and R.Lazzarini, “The SPRING Hand: Development of a Self-Adaptive Prosthesis for Restoring Natural Grasping”, Autonomous Robots 16(2004), pp.125-141.

Leave A Comment

*