April 24, 2018

디바이스마트 미디어:

[39호]Wearable Marionette

2016 ictmain

 

2016 ICT 융합 프로젝트 공모전 참가상

Wearable Marionette

글 | 목원대학교 진선기, 한승원, 김인창

 

심사평
JK전자 3D 모델링툴과 프린터를 이용해서 기구물을 제작하고 모터와 연결해 제어하는 과정에서 굉장한 노력이 보이고, 앞으로 다가올 개인 맞춤형 제품(장치)의 시대에 적합한 제작 방식에 대해서 후한 점수를 주었다. 하지만 소프트웨어 구현 부분이 아직 미흡하고 모터의 위치 제어에 대한 부분이 기성 제품과 소프트웨어의 도움을 받아 너무 간단하게 제작이 된 부분이 아쉽다.

뉴티씨 로봇을 직접 제작하고, 센서로 감지한 팔의 움직임을 로봇의 움직임으로 대체하려고 한 것은 매우 중요한 연구테마의 한 가지이다. 하지만, 현재 제작된 로봇팔의 토크 등이 부족하여 움직임이 자유롭지 못하였을 부분, 팔의 처짐 등이 있었다는 보고가 없으며, 이에 대한 대책 등으로 개선 사항 등이 없는 부분 등을 보면 전반적으로 동작이 원활치 않았음을 알 수 있다. 또한, 현재의 모터로는 필요한 토크를 전부 얻어서 동작하는 것이 어려워 보인다. 모터의 선들은 어떻게 처리하여, 각각의 모터들이 잘 동작할 수 있는 무게나 유연성 등의 부분도 연구가 좀 더 필요해 보인다. 어려운 주제인 로봇팔을 크게 제작하여 어려움을 겪었을 것으로 예상되며, 다음에는 좀 더 작은 것부터 섬세하게 움직이도록 제작하면 좋은 결과를 가져올 것으로 생각된다.

칩센 센서를 이용한 원격 로봇 제어 방식과 유사하다, 실제 로봇과 동일한 형식의 기기를 착용하여 제어한다는 개념은 신선하나, 내용상의 표현 처럼 더 불편 해 보인다. 하지만 나름 어려운 주제를 선택해서 노력한 부분이 보이고 실제 구현 후 얻은 교훈으로 더 발전할 수 있을 것 같다.

위드로봇 master-slave 구조의 tele-robotics 분야에서 master 조작기를 착용형으로 만든 연구 결과로 보여집니다. 시중에서 손쉽게 확보할 수 있는 모터-엔코더 셋트를 조합해서 빠르게 연구 결과를 도출한 아이디어를 높이 평가합니다. 단, 보고서 상에서는 결과 내용이 어떻게 되어 있는지 확인할 방법이 없어 아쉽습니다. 무엇인가를 만드는 것 만큼이나 실험 결과에 대한 분석도 중요합니다. 결과에 대한 분석, 부족한 부분에 대한 추후 보완 방법 등이 정리되었다면 훨씬 높은 점수를 받을 수 있을 겁니다.

작품 개요
작품 소개
· 3D Printer와 Dynamixel을 활용해 Wearable을 통한 로봇 팔 제어
· [그림1]은 작품형태를 이미지화 시켜놓은 그림이다.

39 ict wearable (1)


작품의 개발 배경 및 필요성

여러 탐사로봇을 개발함에 있어 많은 문제점을 발견할 수 있었다. 그 중 탐사로봇을 섬세하게 조종하는데 있어 문제를 발견했고 보다 수월하고 섬세하게 제어할 수 있는 Wearable 제어기를 개발하게 되었다.

작품의 특장점
작품(Wearable)의 특장점
· 3D Printer를 이용한 Wearable 설계 및 제작
· Wearable Dynamixel의 모터 값(목표위치)을 이용한 로봇 제어
· OpenCM보드를 통한 Wearable 모터 값 전송

작품(로봇 팔)의 특장점
· 3D printer를 이용한 로봇 팔 설계 및 제작
· USB2Dynamixel를 이용한 모터 통신
· Dynamixel을 이용한 로봇팔 5자유도 구현

작품 설명
주요 동작 및 특징
3D Printer를 이용한 Wearable 및 로봇 제작
· 3D Printer를 활용 – 비용절감, 경량화

39 ict wearable (2)

· Wearable 설계 및 제작

39 ict wearable (3)

· 로봇 팔 설계 및 제작 : 프로파일 형식으로 프로파일과 연결 가능하도록 설계 및 제작

39 ict wearable (4)

서보모터 Dynamixel을 이용한 Wearable 및 로봇 제어
· Dynamixel AX-18A : 무게 54.6g에 크기 32mm x 50.1mm x 40mm, 기어 비 254 : 1배로 전압 9~12V에서 작동한다. 통신 속도는 115200bps을 이용할 수 있다. 그러므로 DYNAMIXEL AX-18A는 사람과 좀 더 비슷한 자유도를 제작하기 위한 최적의 모터로써 로봇 팔 및 Wearable 관절부분에 사용했다.

39 ict wearable (5)

Wearable Dynamixel의 모터값(목표위치)을 이용한 로봇 제어

39 ict wearable (6)

OpenCM보드를 통한 Wearable 모터 값 전송

39 ict wearable (7)

 

39 ict wearable (8)39 ict wearable (9)

 

USB2Dynamixel를 이용한 모터 통신

39 ict wearable (10)

 

39 ict wearable (11)

Dynamixel을 이용한 로봇 팔 5자유도 구현
· Dynamixel AX-18A 5개를 활용하여 5자유도 구현

39 ict wearable (12) 39 ict wearable (13)

Dynamixel을 이용한 Wearable 관절 구현
· Dynamixel AX-12A 5개를 활용하여 5자유도 구현
· 사람 팔에 착용할 수 있도록 제작

39 ict wearable (14) 39 ict wearable (15)

C#을 이용한 프로그램Form 개발
· OpenCM 보드를 통해 받은 Wearable 모터 데이터 값을 C#으로 받아 프로그램Form에 출력하도록 한다.

39 ict wearable (16)

39 ict wearable (17)
전체 시스템 구성

39 ict wearable (18)

개발환경(개발언어, Tool, 사용 시스템 등)
개발언어
· C# : C++에 기본을 두고 visual basic의 편의성을 결합하여 만든 객체지향 프로그래밍언어이다.(첨부1. C# 소스 첨부)
· ROBOTIS OpenCM : OpenCM9.04 임베디드 보드를 쉽게 프로그래밍하고 다운로드 할 수 있는 통합개발환경 소프트웨어이다.(첨부2. ROBOTIS OpenCM 소스 첨부)

단계별 제작 과정
작품계획 및 자료조사
· 작품계획 : 작품제작 및 일정 계획
· 자료조사 : Wearable 및 로봇 팔에 대한 자료(논문, 기사 등)조사

하드웨어 설계
· Solidworks를 통해 Wearable 및 로봇 팔 설계
· Dynamixel 플랫폼과 연결하기 위한 기구적 설계
· 프로파일 형식으로 프로파일과 연결 가능하도록 설계 및 제작

하드웨어 제작
· 3D Printer를 이용하여 로봇 팔 및 Wearable 제작
· 3D Printer를 활용함으로써 비용절감 및 경량화

프로그램 개발
· USB2Dynamixel를 통한 Dynamixel 제어
· C#으로 동한 프로그램 Form개발 및 데이터를 통한 모터 제어
· OpenCM보드를 통한 Wearable 모터 값을 C#으로 전송
· Wearable 및 로봇 팔에 대한 데이터 값을 PC에서 실시간 확인

테스트
· 진행된 작품의 완성도 및 오작동 여부를 테스트 하였다.
· 여러번의 테스트를 통한 문제점 발견(Wearable 착용 불편함)

작품 보완
· 작품 테스트에서 문제점(Wearable 착용 불편함)이 발견되어 착용감이 편하도록 보완하였다.

작품 제작 종료
· 최종 테스트 및 작품을 보완해 작품을 완성하였다.

기타(회로도, 소스코드, 참고문헌 등)
참고 사이트
· 로보티즈(다이나믹셀, openCM, USB2Dynamixel) 사이트 참조(이미지, 매뉴얼) : http://www.robotis.com/index/index.php
· XYZ 3D Printer 사이트 참조 (프로그램, 이미지) :

http://kr.xyzprinting.com/

C# 소스코드

· Port 설정
//Dynamixel
this.timer.Interval = 200;
this.timer.Tick += new EventHandler(timer_Tick);
this.timer.Enabled = true;
this.seriaport.BaudRate = 1000000;
this.seriaport.Encoding = Encoding.Default;
this.seriaport.Parity = Parity.None;
this.seriaport.DataBits = 8;
this.seriaport.StopBits = StopBits.One;
this.seriaport.Handshake = Handshake.None;
this.seriaport2.BaudRate = 1000000;
this.seriaport2.Encoding = Encoding.Default;
this.seriaport2.Parity = Parity.None;
this.seriaport2.DataBits = 8;
this.seriaport2.StopBits = StopBits.One;
this.seriaport2.Handshake = Handshake.None;

// initialize the components (controls) of the window
this.InitializeComponent();
string[] Ports = SerialPort.GetPortNames();
foreach (string i in Ports)
{
ComboBox1.Items.Add(i);
}
ComboBox1.SelectedIndex = ComboBox1.Items.Count – 1;
myDynamixel = new Dynamixel(this.seriaport);
string[] Ports2 = SerialPort.GetPortNames();
foreach (string i in Ports2)
{
ComboBox2.Items.Add(i);
}
ComboBox2.SelectedIndex = ComboBox1.Items.Count – 1;
myDynamixel2 = new Dynamixel(this.seriaport2);
}

·Wearable 값 읽기
private void serialPort_DataReceived2 (object sender,Serial Data Received Event Argse)
{
string buff;
buff = this.seriaport2.ReadLine();
if (buff.Length < 32) return;
//Console.WriteLine(buff.Length);
if (buff.Substring(0, 2) == “WM”)
{
_sensor[0] = Convert.ToInt32(buff.Substring(3, 4));
_sensor[1] = Convert.ToInt32(buff.Substring(8, 4));
_sensor[2] = Convert.ToInt32(buff.Substring(13, 4));
_sensor[3] = Convert.ToInt32(buff.Substring(18, 4));
_sensor[4] = Convert.ToInt32(buff.Substring(23, 4));
_sensor[5] = Convert.ToInt32(buff.Substring(28, 4));
}
}

· 모터 속도 조절
private void MotorSpeed()
{
if (this.seriaport.IsOpen)
{
for (int i = 0; i <= 10; i++)
{
myDynamixel.ax12_write2(i, Dynamixel.AX_GOAL_SPEED_L, 1023);
myDynamixel.ax12_write2(i, Dynamixel.AX_TORQUE_LIMIT_L, 1023);
}

}
}
void SendSerialData(SerialPort _serial, byte[] buffer)
{
try
{
_serial.Write(buffer, 0, buffer.Length);
}
catch
{ }
}
void SendSerialData(SerialPort _serial, byte[] buffer, int Length)
{
try
{
_serial.Write(buffer, 0, Length);
}
catch
{ }
}

· 모터 움직이기
private void moveVactor()
{
if (this.seriaport.IsOpen)
{
_motorData[0] = (1024 – (int)_sensor[1]);
_motorData[1] = (1024 – (int)_sensor[2]);
_motorData[2] = (1024 – (int)_sensor[3]);
_motorData[3] = (1024 – (int)_sensor[4]);
_motorData[4] = (1024 – (int)_sensor[5]);
if (_sensor[0] > 1000)
_motorData[5] = (int)(512 – ((int)((_sensor[0] – 7) / 100) * 1024 / 31));
else
_motorData[5] = 512;
myDynamixel.ax12_sync_write(Dynamixel.AX_GOAL_POSITION_L, 2, 10, _motorData);
}
}

· ROBOTIS OpenCM 소스코드
/* Minimum_Source*/
#include <stdio.h>
#define AX_START 255

#define AX_READ_DATA 2
#define AX_WRITE_DATA 3
#define AX_LENGTH 5
#define AX_TORQIUELIMIT 34
#define AX_NOW 36
#define sendData(args) (Serial1.write(args))
Dynamixel Dxl(1);
int pp[5];
char buff[50]={0};
int temp=0;
void setup() {
// put your setup code here, to run once:
Dxl.begin(3);
for(int i=1;i<=5;i++){
settorque(i);
}
}

void settorque(unsigned char ID)
{
unsigned int Checksum;
unsigned int MaxTorque = 1;
Checksum = (~(ID + AX_LENGTH + AX_WRITE_DATA + AX_TORQIUELIMIT + MaxTorque + (MaxTorque>>8)))&0xFF; //패킷설정
gpio_write_bit(PORT_TXRX_DIRECTION, PIN_TXRX_DIRECTION, 1);

sendData(AX_START); //시리얼 통신 보내기
sendData(AX_START);
sendData(ID);
sendData(AX_LENGTH);
sendData(AX_WRITE_DATA);
sendData(AX_TORQIUELIMIT);
sendData(MaxTorque);
sendData((MaxTorque>>8));

sendData(Checksum);
}

void stoptorque(unsigned char ID)
{
unsigned int Checksum;
unsigned int MaxTorque = 1023;

Checksum = (~(ID + AX_LENGTH + AX_WRITE_DATA + AX_TORQIUELIMIT + MaxTorque + (MaxTorque>>8)))&0xFF; //패킷설정
gpio_write_bit(PORT_TXRX_DIRECTION, PIN_TXRX_DIRECTION, 1);
sendData(AX_START); //시리얼 통신 보내기
sendData(AX_START);
sendData(ID);
sendData(AX_LENGTH);
sendData(AX_WRITE_DATA);
sendData(AX_TORQIUELIMIT);
sendData(MaxTorque);
sendData((MaxTorque>>8));
sendData(Checksum);
}
void loop() {
int AdcData = analogRead(2);
for(int i=1;i<=5;i++)
{
temp=pp[i-1];
pp[i-1] = Dxl.readWord(i,AX_NOW);
if(pp[i-1]>1000)
pp[i-1]=temp;
}
sprintf(buff,”WM %04d %04d %04d %04d %04d %04d”, AdcData,pp[0],pp[1],pp[2],pp[3],pp[4],pp[5]);
SerialUSB.println(buff);
}

 

 

 

Leave A Comment

*