<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; smart</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/smart/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ntrexgo.com</link>
	<description>엔티렉스, 디바이스마트 컨텐츠 통합 사이트</description>
	<lastBuildDate>Thu, 03 Mar 2022 06:47:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[65호]Simple Touch</title>
		<link>http://www.ntrexgo.com/archives/40140</link>
		<comments>http://www.ntrexgo.com/archives/40140#comments</comments>
		<pubDate>Thu, 22 Apr 2021 00:00:51 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[65호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[smart]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[로봇]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[센서]]></category>
		<category><![CDATA[스마트]]></category>
		<category><![CDATA[융합]]></category>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40140</guid>
		<description><![CDATA[디바이스마트매거진  65호 &#124; 최근 전염병 사태에서 불특정 다수의 손길이 닿은 버스 하차벨을 선뜻 누르기 어려운 경우도 있을 것이다. “직접적인 접촉을 하지 않고 하차벨을 누를 수 있는 방법은 없을까?” 이와 같은 물음에서 작품의 아이디어를 끌어내 보았다.]]></description>
				<content:encoded><![CDATA[<p><span style="font-size: medium"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-1.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40197" alt="65 ict simple touch (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-1-620x176.png" width="620" height="176" /></a>2020 ICT 융합 프로젝트 공모전 장려상</strong></span></p>
<p><span style="font-size: xx-large"><strong>Simple Touch</strong></span></p>
<p style="text-align: right">글 | 동양미래대학교 박재범, 김도경, 김성곤, 김예빈, 김종혁, 이연수, 이정원, 장여원</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 기술 자체가 어려운 것은 아니지만 아이디어가 매우 눈에 띄는 작품입니다. 특히 기존 시스템을 모두 교체하는 것이 아닌 일부만 대체하는 것만으로도 적용 가능하게 하는 부분은 훌륭한 발상입니다. 동작 방식 자체는 매우 심플하게 이해가 되었고, 실제 적용을 위해서 운용에 대한 방식은 조금 더 고민이 필요할 듯 합니다. 블루투스 보다 와이파이가 더 적절해 보이는 판단을 하고 적용하였으나, 이 또한 실제 적용에는 어려움이 있을 수 있습니다(주변 버스와의 구분등). 이러한 추가적인 고민을 통하면 매우 실용적인 장치가 될듯합니다.<br />
<strong>펌테크</strong> 실생활에 활용될 수 있는 아이디어와 실용성을 지닌 작품이라고 생각합니다. 전체적으로 시스템을 꼼꼼하게 잘 구성하였고 생각하며 학부 과정의 학생이 구현하기에 적정한 난이도를 가진 작품이라고 생각합니다.<br />
<strong>위드로봇</strong> 간단하지만 유용한 아이디어를 구현한 작품입니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
보도자료에 따르면 서울시에서만 하루 500만 명 이상의 시민들이 버스를 이용한다. 서울특별시 인구만으로 따져 보아도 2명 중 1명꼴로 버스를 이용하는 셈이다. 그만큼 버스는 우리에게 떼어놓을 수 없는 교통수단이다.<br />
이렇게 많은 이들이 이용하는 까닭에 버스 이용 시 몇몇 불편함을 느낄 수 있는데, 특히 출퇴근 길 “러시아워” 시간대의 버스를 타기란 고통에 가깝다, 가까스로 버스 승차에 성공하더라도 하차하려는 것이 여간 어려운 것이 아닌데, 사람들로 가득 찬 버스 안에서 사람들 사이를 비집고 나아가 손으로 직접 하차벨을 누르기란 참으로 어려운 일이기 때문이다. 이에 최근 운행하는 신형 버스는 구형 버스보다 하차벨이 증설되었지만, 여전히 사람이 많은 버스에서 손으로 벨을 누르기에 불편한 상황임은 사실이다.<br />
한편 최근 대두되고 있는 전염병 사태에서 직접 접촉에 의한 감염 사례도 나오고 있는 것을 보면 불특정 다수의 손길이 닿은 하차벨을 선뜻 누르기 어려운 경우도 있을 것이다. “직접적인 접촉을 하지 않고 하차벨을 누를 수 있는 방법은 없을까?” 이와 같은 물음에서 작품의 아이디어를 끌어내 보았다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #339966"><strong>3.1. 주요 동작 및 특징</strong></span><br />
<span style="color: #33cccc"><strong>3.1.1. 스마트폰 App으로 버스 하차벨 점등</strong></span><br />
· 통신을 위해 모든 하차벨을 교체할 필요 없이 하나의 하차벨 교체만으로도 시스템에 적용 가능함<br />
· 하차벨을 누르기 위한 불필요한 움직임이 줄어들어 버스 내 안전사고 발생확률 감소를 기대할 수 있음<br />
· 코로나19와 같은 전염병 사태에 불특정 다수가 접촉할 우려가 큰 하차벨에 접촉하지 않음으로서 접촉에 의한 전염병 감염사례 감소의 기대와 버스 이용 승객의 심적 안정을 도모할 수 있음</p>
<p><span style="color: #339966"><strong>3.2. 전체 시스템 구성(전체 알고리즘)</strong></span></p>
<p><span style="color: #339966"> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-2.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40199" alt="65 ict simple touch (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-2-620x320.png" width="620" height="320" /></a></span></p>
<p><span style="color: #339966"><strong>3.3. 개발환경</strong></span><br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-3.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40201" alt="65 ict simple touch (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-3-620x122.png" width="620" height="122" /></a></p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-4.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40202" alt="65 ict simple touch (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-4.png" width="611" height="436" /></a></p>
<p><span style="color: #339966"><strong>4.1. 시스템 설계</strong></span><br />
초기 스케치에서와 같이 일대다 통신 구현을 위해 Bluetooth와 WiFi 통신이 논의 되었으나, Bluetooth 통신 방식의 동시 접속 가능 기기 제한으로 인하여 WiFi 통신 방식을 채택한다.<br />
WiFi 통신 모듈 선정</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-5.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40203" alt="65 ict simple touch (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-5.png" width="618" height="216" /></a></p>
<p><span style="color: #339966"><strong>4.2. 하드웨어 제작</strong></span></p>
<p><span style="color: #339966"> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-6.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40204" alt="65 ict simple touch (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-6-579x620.png" width="579" height="620" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-7.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40205" alt="65 ict simple touch (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-7-579x620.png" width="579" height="620" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-1.jpg" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40196" alt="65 ict simple touch (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-1.jpg" width="620" height="341" /></a></span></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-2.jpg" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40198" alt="65 ict simple touch (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-2-590x620.jpg" width="590" height="620" /></a></p>
<p><span style="color: #339966"><strong>4.3. 하차벨 시스템 소프트웨어 작성</strong></span></p>
<p><span style="color: #339966"> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-3.jpg" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40200" alt="65 ict simple touch (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-3.jpg" width="620" height="298" /></a></span></p>
<p><span style="color: #339966"><strong>4.4. 스마트폰 App 소프트웨어 작성</strong></span></p>
<p><span style="color: #339966"> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-8.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40206" alt="65 ict simple touch (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-8.png" width="620" height="332" /></a></span></p>
<p><span style="color: #339966"><strong>4.5. 시스템 구현</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-9.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40207" alt="65 ict simple touch (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-9.png" width="620" height="309" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-10.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40208" alt="65 ict simple touch (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-10.png" width="620" height="589" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-11.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40209" alt="65 ict simple touch (11)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-11.png" width="620" height="607" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-12.png" rel="lightbox[40140]"><img class="alignnone size-full wp-image-40210" alt="65 ict simple touch (12)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-12.png" width="620" height="305" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #339966"><strong>4.6. 결론 및 전망</strong></span><br />
위와 같이 스마트폰 어플리케이션을 통해 버스 벨을 점등하는 테스트를 성공적으로 완료하였다. Java를 처음 다뤄보며 개발한 첫 어플리케이션이었기에 UI나 여러 편의사항 등에서 부족한 부분도 있었지만, 본 목적에 충실하게끔 구현했다는 점에서 큰 만족감을 가질 수 있었다.<br />
본 아이디어는 비용과 시스템 구현 측면에서 여러 이점이 있는데, 제작 시 사용한 Lolin D1 mini를 대체해 ESP8266-01 등의 모듈을 사용한다면 저렴한 비용으로 단 하나의 벨 교체를 통해 무선 하차벨 시스템을 구현 할 수 있을 것으로 보인다.<br />
한편 서울특별시 버스정책과에 문의해본 결과 올해 6월부터는 서울시내 버스 8000여대에서 공공와이파이를 이용할 수 있다고 하였다. 추후 공공와이파이를 이용한 시스템 구축을 통해 더 효율적이고 편리한 무선 하차벨 시스템을 제공할 수 있을 것으로 보인다.<br />
경향신문 기사([‘코로나19’ 확산 비상]버스 하차벨 서로 미루고, 출입문 손 대신 어깨로 열어…‘거리두기’가 바꾼 일상)의 인터뷰에서는 코로나 19로 인한 버스에서의 현 상황이 잘 드러나고 있다. 본 아이디어는 이러한 대규모 전염병 사태에 있어 미약하게나마 감염 전파를 막는 요소가 될 수 있을 것이라 기대한다.</p>
<p><span style="color: #0000ff"><strong>5. 기타</strong></span><br />
<span style="color: #339966"><strong>5.1. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-13.png" rel="lightbox[40140]"><img class="alignnone size-large wp-image-40211" alt="65 ict simple touch (13)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-simple-touch-13-472x620.png" width="472" height="620" /></a><br />
<span style="color: #339966"> <strong>5.2. 소스코드</strong></span><br />
<span style="color: #33cccc"> <strong>5.2.1.Arduino 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>bus_system.ino<br />
int bell_led_1 = 22;<br />
int bell_button_1 = 23;<br />
int bell_test_1 = 24;<br />
int bell_led_2 = 26;<br />
int bell_button_2 = 27;<br />
int bell_test_2 = 28;<br />
int bell_led_3 = 30;<br />
int bell_button_3 = 31;<br />
int bell_test_3 = 32;<br />
int bell_led_4 = 34;<br />
int bell_button_4 = 35;<br />
int bell_test_4 = 36;<br />
int bell_led_5 = 38;<br />
int bell_button_5 = 39;<br />
int bell_test_5 = 40;<br />
int door_button = 42;<br />
boolean bell_signal_1;<br />
boolean bell_signal_2;<br />
boolean bell_signal_3;<br />
boolean bell_signal_4;<br />
boolean bell_signal_5;<br />
boolean door_signal;<br />
boolean total_signal;<br />
boolean state;</p>
<p>void setup() {<br />
pinMode(bell_led_1, OUTPUT);<br />
pinMode(bell_led_2, OUTPUT);<br />
pinMode(bell_led_3, OUTPUT);<br />
pinMode(bell_led_4, OUTPUT);<br />
pinMode(bell_led_5, OUTPUT);<br />
pinMode(bell_button_1, INPUT);<br />
pinMode(bell_button_2, INPUT);<br />
pinMode(bell_button_3, INPUT);<br />
pinMode(bell_button_4, INPUT);<br />
pinMode(bell_button_5, INPUT);<br />
pinMode(bell_test_1, OUTPUT);<br />
pinMode(bell_test_2, OUTPUT);<br />
pinMode(bell_test_3, OUTPUT);<br />
pinMode(bell_test_4, OUTPUT);<br />
pinMode(bell_test_5, OUTPUT);<br />
pinMode(door_button, INPUT);<br />
Serial.begin(115200);<br />
Serial.println(&#8220;Setting done&#8230;.&#8221;);<br />
normal_state();<br />
}</p>
<p>void normal_state() {<br />
digitalWrite(bell_led_1, LOW);<br />
digitalWrite(bell_led_2, LOW);<br />
digitalWrite(bell_led_3, LOW);<br />
digitalWrite(bell_led_4, LOW);<br />
digitalWrite(bell_led_5, LOW);<br />
digitalWrite(bell_test_1, HIGH);<br />
digitalWrite(bell_test_2, HIGH);<br />
digitalWrite(bell_test_3, HIGH);<br />
digitalWrite(bell_test_4, HIGH);<br />
digitalWrite(bell_test_5, HIGH);<br />
state = 0;<br />
}</p>
<p>void pushed_state() {<br />
digitalWrite(bell_led_1, HIGH);<br />
digitalWrite(bell_led_2, HIGH);<br />
digitalWrite(bell_led_3, HIGH);<br />
digitalWrite(bell_led_4, HIGH);<br />
digitalWrite(bell_test_1, LOW);<br />
digitalWrite(bell_test_2, LOW);<br />
digitalWrite(bell_test_3, LOW);<br />
digitalWrite(bell_test_4, LOW);<br />
digitalWrite(bell_test_5, LOW);<br />
state = 1;<br />
}</p>
<p>void read_signal() {<br />
bell_signal_1 = digitalRead(bell_button_1);<br />
bell_signal_2 = digitalRead(bell_button_2);<br />
bell_signal_3 = digitalRead(bell_button_3);<br />
bell_signal_4 = digitalRead(bell_button_4);<br />
bell_signal_5 = digitalRead(bell_button_5);<br />
door_signal = digitalRead(door_button);<br />
Serial.println(&#8220;b1, b2, b3, b4, b5, Door&#8221;);<br />
Serial.print(bell_signal_1);<br />
Serial.print(&#8221; &#8220;);<br />
Serial.print(bell_signal_2);<br />
Serial.print(&#8221; &#8220;);<br />
Serial.print(bell_signal_3);<br />
Serial.print(&#8221; &#8220;);<br />
Serial.print(bell_signal_4);<br />
Serial.print(&#8221; &#8220;);<br />
Serial.print(bell_signal_5);<br />
Serial.print(&#8221; &#8220;);<br />
Serial.println(door_signal);<br />
total_signal = bell_signal_1||bell_signal_2||bell_signal_3||bell_signal_4||bell_signal_5;<br />
}</p>
<p>void self_holding () {<br />
if (state==0) {<br />
if (total_signal == 1) {<br />
pushed_state();<br />
Serial.println(&#8220;bell pushed&#8230;.&#8221;);<br />
}<br />
}<br />
else if (state == 1) {<br />
if (door_signal == 0) {<br />
normal_state();<br />
Serial.println(&#8220;door opend&#8230;.&#8221;);<br />
}<br />
}<br />
}</p>
<p>void loop() {<br />
read_signal();<br />
self_holding();<br />
delay(100);<br />
}<br />
</div>
<p><span style="color: #33cccc"><strong>5.2.2. Lolin D1 mini 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>wifi_module.ino<br />
#include &lt;ESP8266WiFi.h&gt;<br />
#include &lt;WiFiClient.h&gt;<br />
#include &lt;ESP8266WebServer.h&gt;</p>
<p>#ifndef APSSID<br />
#define APSSID &#8220;ICT_TEST&#8221;<br />
#define APPSK &#8220;ict_test&#8221;<br />
#endif</p>
<p>const char *ssid = APSSID;<br />
const char *password = APPSK;</p>
<p>ESP8266WebServer server(80);</p>
<p>uint8_t LED_PIN = 4;<br />
bool LED_PIN_STATUS = LOW;<br />
void handleRoot() {<br />
LED_PIN_STATUS = LOW;<br />
server.send(200, &#8220;text/html&#8221;, &#8220;&lt;h1&gt;You are connected&lt;/h1&gt;&#8221;);<br />
}</p>
<p>void handleRoot_on() {<br />
LED_PIN_STATUS = HIGH;<br />
server.send(200, &#8220;text/html&#8221;, &#8220;&lt;h1&gt; LED ON &lt;/h1&gt;&#8221;);<br />
}</p>
<p>&nbsp;</p>
<p>void setup() {<br />
delay(1000);<br />
pinMode(LED_PIN, OUTPUT);<br />
digitalWrite(LED_PIN, 0);</p>
<p>Serial.begin(115200);<br />
Serial.println();<br />
Serial.print(&#8220;Configuring access point&#8230;&#8221;);<br />
WiFi.softAP(ssid, password);<br />
IPAddress myIP = WiFi.softAPIP();<br />
Serial.print(&#8220;AP IP address: &#8220;);<br />
Serial.println(myIP);</p>
<p>server.on(&#8220;/&#8221;, handleRoot);<br />
server.on(&#8220;/on&#8221;, handleRoot_on);<br />
server.begin();<br />
Serial.println(&#8220;HTTP server started&#8221;);<br />
}</p>
<p>void loop() {<br />
server.handleClient();<br />
if(LED_PIN_STATUS) {<br />
digitalWrite(LED_PIN, HIGH);<br />
delay(200);<br />
digitalWrite(LED_PIN, LOW);<br />
LED_PIN_STATUS =!LED_PIN_STATUS;<br />
}<br />
else<br />
{digitalWrite(LED_PIN, LOW);}<br />
}<br />
</div>
<p><span style="color: #33cccc"><strong>5.2.3. 스마트폰 App 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>AndroidManifest.xml<br />
&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<br />
&lt;manifest xmlns:android=&#8221;http://schemas.android.com/apk/res/android&#8221;<br />
package=&#8221;com.example.pleaseplease&#8221;&gt;<br />
&lt;uses-permission android:name=&#8221;android.permission.ACCESS_WIFI_STATE&#8221; /&gt;<br />
&lt;uses-permission android:name=&#8221;android.permission.CHANGE_WIFI_STATE&#8221; /&gt;<br />
&lt;uses-permission android:name=&#8221;android.permission.ACCESS_FINE_LOCATION&#8221;/&gt;<br />
&lt;uses-permission android:name=&#8221;android.permission.ACCESS_COARSE_LOCATION&#8221;/&gt;<br />
&lt;application<br />
android:allowBackup=&#8221;true&#8221;<br />
android:icon=&#8221;@mipmap/ic_launcher&#8221;<br />
android:label=&#8221;@string/app_name&#8221;<br />
android:roundIcon=&#8221;@mipmap/ic_launcher_round&#8221;<br />
android:supportsRtl=&#8221;true&#8221;<br />
android:theme=&#8221;@style/AppTheme&#8221;&gt;<br />
&lt;activity android:name=&#8221;.MainActivity&#8221;&gt;<br />
&lt;intent-filter&gt;<br />
&lt;action android:name=&#8221;android.intent.action.MAIN&#8221; /&gt;<br />
&lt;category android:name=&#8221;android.intent.category.LAUNCHER&#8221; /&gt;<br />
&lt;/intent-filter&gt;<br />
&lt;/activity&gt;<br />
&lt;/application&gt;<br />
&lt;/manifest&gt;<br />
activity_main.xml<br />
&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<br />
&lt;LinearLayout xmlns:android=&#8221;http://schemas.android.com/apk/res/android&#8221;<br />
xmlns:app=&#8221;http://schemas.android.com/apk/res-auto&#8221;<br />
xmlns:tools=&#8221;http://schemas.android.com/tools&#8221;<br />
android:layout_width=&#8221;match_parent&#8221;<br />
android:layout_height=&#8221;match_parent&#8221;<br />
android:orientation=&#8221;vertical&#8221;<br />
tools:context=&#8221;.MainActivity&#8221;&gt;</p>
<p>&lt;Button<br />
android:id=&#8221;@+id/button&#8221;<br />
android:layout_width=&#8221;match_parent&#8221;<br />
android:layout_height=&#8221;48dp&#8221;<br />
android:text=&#8221;STOP&#8221;<br />
app:layout_constraintEnd_toEndOf=&#8221;parent&#8221;<br />
app:layout_constraintStart_toStartOf=&#8221;parent&#8221;<br />
app:layout_constraintTop_toTopOf=&#8221;parent&#8221; /&gt;<br />
&lt;/LinearLayout&gt;<br />
MainActivity.java<br />
package com.example.pleaseplease;<br />
import androidx.appcompat.app.AppCompatActivity;<br />
import android.content.BroadcastReceiver;<br />
import android.content.Context;<br />
import android.content.Intent;<br />
import android.content.IntentFilter;<br />
import android.net.Uri;<br />
import android.net.wifi.ScanResult;<br />
import android.net.wifi.WifiConfiguration;<br />
import android.net.wifi.WifiInfo;<br />
import android.net.wifi.WifiManager;<br />
import android.os.Bundle;<br />
import android.provider.Settings;<br />
import android.util.Log;<br />
import android.view.View;<br />
import android.webkit.WebChromeClient;<br />
import android.webkit.WebSettings;<br />
import android.webkit.WebView;<br />
import android.webkit.WebViewClient;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.ListView;<br />
import android.widget.Toast;<br />
import java.io.IOException;<br />
import java.lang.reflect.Method;<br />
import java.net.HttpURLConnection;<br />
import java.net.MalformedURLException;<br />
import java.net.URL;<br />
import java.util.ArrayList;<br />
import java.util.List;</p>
<p>public class MainActivity extends AppCompatActivity {<br />
private WebView webview;<br />
private String networkSSID = &#8220;ICT_TEST&#8221;;<br />
private String networkPass = &#8220;ict_test&#8221;;<br />
private WifiManager wifiManager;<br />
private WifiConfiguration wifiConfiguration;<br />
private int size = 0;0<br />
private ArrayList&lt;String&gt; arrayList = new ArrayList&lt;&gt;();<br />
private ArrayAdapter&lt;String&gt; adapter;<br />
private static final String TAG = &#8220;MyActivity&#8221;;<br />
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);</p>
<p>@Override<br />
protected void onCreate(Bundle savedInstanceState) {<br />
super.onCreate(savedInstanceState);<br />
setContentView(R.layout.activity_main);<br />
Button buttonScan = findViewById(R.id.button);<br />
buttonScan.setOnClickListener(new View.OnClickListener() {<br />
@Override<br />
public void onClick(View v) {<br />
scanWifi();<br />
if (wifiManager.isWifiEnabled()) {<br />
String url = &#8220;http://192.168.4.1/on&#8221;;<br />
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));<br />
startActivity(intent);<br />
}<br />
}<br />
});<br />
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);<br />
assert wifiManager != null;<br />
if (!wifiManager.isWifiEnabled()) {<br />
Toast.makeText(this, &#8220;wifi is disabled&#8230; connecting&#8230;&#8221;, Toast.LENGTH_SHORT).show();<br />
wifiManager.setWifiEnabled(true);<br />
}<br />
adapter = new ArrayAdapter&lt;&gt;(this, android.R.layout.simple_list_item_1, arrayList);<br />
scanWifi();<br />
}</p>
<p>private void scanWifi() {<br />
arrayList.clear();<br />
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));<br />
wifiManager.startScan();<br />
Toast.makeText(this, &#8220;Scanning&#8230;..&#8221;, Toast.LENGTH_SHORT).show();<br />
}</p>
<p>BroadcastReceiver wifiReceiver = new BroadcastReceiver() {<br />
@Override<br />
public void onReceive(Context context, Intent intent) {<br />
List&lt;ScanResult&gt; results = wifiManager.getScanResults();<br />
Log.i(TAG, String.format(&#8220;size&#8212;-%d&#8221;, results.size()));<br />
unregisterReceiver(this);<br />
for (ScanResult scanResult : results) {<br />
Log.i(TAG, String.format(&#8220;&#8212;-%s&#8221;, scanResult.SSID));<br />
arrayList.add(scanResult.SSID);<br />
adapter.notifyDataSetChanged();<br />
if (scanResult.SSID.equals(networkSSID)) {<br />
WifiConfiguration wifiConfiguration = new WifiConfiguration();<br />
wifiConfiguration.SSID = networkSSID;<br />
wifiConfiguration.preSharedKey = networkPass;<br />
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);<br />
int netId = wifiManager.addNetwork(wifiConfiguration);<br />
Log.i(TAG, String.format(&#8220;netId = = = =%s&#8221;, netId));<br />
if (netId == -1) {<br />
existconnect();<br />
Log.i(TAG, String.format(&#8220;connect to %s&#8221;, scanResult.SSID));<br />
wifiManager.disconnect();<br />
wifiManager.enableNetwork(netId, true);<br />
wifiManager.reconnect();<br />
} else {<br />
Log.i(TAG, String.format(&#8220;connect to %s&#8221;, scanResult.SSID));<br />
wifiManager.disconnect();<br />
wifiManager.enableNetwork(netId, true);<br />
wifiManager.reconnect();<br />
}<br />
}<br />
}<br />
}<br />
};</p>
<p>public void existconnect() {<br />
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);<br />
assert wifiManager != null;<br />
List&lt;WifiConfiguration&gt; wifiConfigurations = wifiManager.getConfiguredNetworks();<br />
if (wifiConfigurations != null) {<br />
for (WifiConfiguration configuration : wifiConfigurations) {<br />
int id = configuration.networkId;<br />
String ssid = configuration.SSID;<br />
Log.i(TAG, String.format(&#8220;NW&#8212;&#8212;&#8212;-%3d %s&#8221;, id, ssid));<br />
if (ssid.equals(networkSSID)) {<br />
Log.i(TAG, String.format(&#8220;coneect to %3d %s&#8221;, id, ssid));<br />
WifiConfiguration wifiConfiguration = new WifiConfiguration();<br />
wifiConfiguration.SSID = ssid;<br />
wifiConfiguration.preSharedKey = networkPass;<br />
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);<br />
wifiManager.disconnect();<br />
wifiManager.enableNetwork(id, true);<br />
wifiManager.reconnect();<br />
}<br />
}<br />
}<br />
}<br />
}<br />
</div>
<p><span style="color: #339966"><strong>5.3. 참고자료</strong></span><br />
· 서울특별시 보도자료 『2019년 서울 돌아보기(20200211)』<br />
· https://en.wikipedia.org/wiki/Bluetooth_Low_Energy<br />
· https://opengov.seoul.go.kr/mediahub/19181864<br />
· http://news.khan.co.kr/kh_news/khan_art_view.html?art_id=202003052147015</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40140/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[65호]Cable-driven Anthropomorphic Dexterous Robot hand</title>
		<link>http://www.ntrexgo.com/archives/40130</link>
		<comments>http://www.ntrexgo.com/archives/40130#comments</comments>
		<pubDate>Thu, 22 Apr 2021 00:00:50 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[65호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[smart]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[로봇]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[센서]]></category>
		<category><![CDATA[스마트]]></category>
		<category><![CDATA[융합]]></category>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40130</guid>
		<description><![CDATA[디바이스마트 매거진 65호 &#124; 시간이 흐르면서 점점 정교하고 빠른 로봇 팔이 연구되었고 최근 들어서는 정해진 환경에서 반복적인 일을 하는 것을 넘어 안드로이드나 의수 등으로 인한 여러 가지 환경에서 적응력이 좋은 유연한 로봇 팔에 대한 필요성이 높아지고 있다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-1.png" rel="lightbox[40130]"><img alt="65 ict robot hand (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-1-620x177.png" width="620" height="177" /></a></p>
<p><strong>2020 ICT 융합 프로젝트 공모전 장려상</strong></p>
<p><span style="font-size: x-large"><strong>Cable-driven Anthropomorphic</strong></span></p>
<p><span style="font-size: x-large"><strong>Dexterous Robot hand</strong></span></p>
<p style="text-align: right">글 | 서울과학기술대학교 김태욱, 금현주, 민성재, 이동현</p>
<p>&nbsp;</p>
<p><span style="color: #3366ff"><strong>1. 심사평</strong></span></p>
<p><strong>칩센</strong> 보고서가 매우 촘촘하게 잘 작성되었고, 기술의 구현 난이도 또한 매우 높아 보입니다. 기획한 작품이 잘 구현 제작된다면 여러 가지 방면에서 사용이 가능할 듯도 합니다. 메카닉적인 부분과 하드웨어/소프트웨어 부분을 모두 포함하고 있어 수준이 높은 작품이라 판단됩니다만, 작품의 최종 결과물에 대하여 동작 등을 확인할 수 없어 얼마나 세밀하고, 정밀하게 관절의 움직임이 있는지는 알 수가 없어 일부 평가 항목에서 손해를 보았습니다. 하지만 지원자(팀)께서 어떤 의도를 가지고 작품을 개발하는지 충분히 이해가 가능하고, 시도만으로도 충분히 좋은 평가가 가능한 작품입니다.<br />
<strong>펌테크</strong> 출품된 작품은 순수 기계공학적인 부분으로만 구성된 우수한 작품으로 전기, 전자, 소프트웨어 응용제품을 대상으로 하는 본작품전의 기본취지와는 다소 차이가 있는 제품이 아닌가 판단됩니다.<br />
<strong>위드로봇</strong> 동작 시연 및 손가락의 모션 제어까지 포함되었으면 아주 훌륭한 작품입니다.</p>
<p><span style="color: #3366ff"><strong>2. 작품 개요</strong></span></p>
<p>18세기 이후, 산업혁명 초기에는 물체를 손으로 잡고 이동하거나 반복적인 일을 수행할 수 있는 팔 형태의 로봇들을 연구했고 그 로봇들이 사람들을 대신하면서 대규모 제조업이 발달하였다.<br />
시간이 흐르면서 점점 정교하고 빠른 로봇 팔이 연구되었고 최근 들어서는 정해진 환경에서 반복적인 일을 하는 것을 넘어 안드로이드나 의수 등으로 인한 여러 가지 환경에서 적응력이 좋은 유연한 로봇 팔에 대한 필요성이 높아지고 있다.<br />
인간의 한 손은 27개의 자유도가 있어 유연하고 세밀한 작업을 할 수 있다. 이에 많은 연구가 인간의 손을 모방한 로봇 팔을 만들려고 시도 하고 있다.<br />
의인화한 손의 기계적 설계 요구사항은 Anthropomorphic features와 Grasping performance로 나눌 수 있다[5].<br />
Anthropomorphic features: 손가락의 구성, 크기 및 역동적인 행동을 포함하여 가능한 사람의 손을 모방해야 한다[5].<br />
Grasping performance: 로봇 손의 속도와 힘이 충분하여 특정되지 않은 물체도 유연하게 잡을 수 있어야 한다[5].<br />
기존의 로봇손에서 모터를 관절에 부착하는 방식으로는 Anthropomorphic features과 Grasping performance을 모두 충족시키기는 어렵다. Anthropomorphic features을 충족시키기 위해서는 로봇손이 작아져야 하지만 작은 모터는 힘이 약하기 때문에 Grasping performance을 충족시킬 수 없다.<br />
이러한 문제점을 해결하기 위해 본 작품은 Cable을 이용하여 관절에 부착된 모터를 다른 곳으로 이동시키고 관절의 움직임을 제어할 수 있게 디자인을 하였다.<br />
기존 로봇손 디자인에서는 관절모터에 이후 달린 관절들의 모터들이 부하로 작용하였지만, Cable을 이용한 본 작품은 이러한 부하를 없애 줌으로써 페이로드를 높였다.</p>
<p><span style="color: #3366ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 주요 동작 및 특징</strong></span><br />
본 작품은 주요 동작 및 특징이 Cable-driven과 Anthropomorphic이 있다.<br />
Cable-driven:<br />
케이블구동 방식은 당길 수만 있는 단방향성을 가진다. 따라서, 이 방식은 직접 모터를 사용하여 양방향성을 가지는 기존의 로봇손과 중요한 차이가 있다[7][8][9]. 케이블의 단방향 특성 때문에 n자유도 모션을 갖는 매커니즘에서 n+1개의 케이블이 필요하다[1][7][10]. 최근에 연구되는 케이블 구동 로봇손은 기존의 양방향성 로봇손보다 더 많은 모터가 사용된다[1]. 그러나 본 작품에서는 케이블 구동을 이용하여 n개의 모터만으로 자연스러운 움직임을 구현하고 기존 양방향성 로봇손과 비교하여 더 큰 작업공간, 더 높은 적재 중량과 생산비용을 제공할 수 있다.<br />
Anthropomorphic:<br />
인간의 몸은 630개의 근육으로 제어되는 244자유도가 있다[3]. 244개의 자유도 중 사람 손에만 총 54개의 자유도를 제공한다[4]. 많은 자유도에 의해 손은 높은 유연성이 있으며 악력이 강하고 물체를 잡는데 능숙하다[2].<br />
실제 인간의 손은 탄성을 가진 피부로 덮여 있고 뼈와 근육, 힘줄, 인대 등과 결합된 복잡한 매커니즘이 있기 때문에 완전히 일치하게 로봇손을 제작하기는 어렵다[2]. 때문에 본 작품은 실제 인간의 손의 구조를 모방하되 자연스러운 움직임을 구동하는데 영향이 적은 관절은 생략 하도록 한다.<br />
실제 사람의 손가락 모형은 크게 엄지와 나머지 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관절은 각각의 자유도를 가지지만 서로 종속된 움직임을 가지기 때문에 스프링을 이용하여 한 개의 모터로 구동시켰다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-2.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40231" alt="65 ict robot hand (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-2.png" width="617" height="258" /></a></p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 </strong></span><br />
<span style="color: #00ccff"><strong>3.2.1. 전체디자인</strong></span><br />
본 작품의 로봇손은 손가락, 손바닥, 모터 및 보빈, 매니퓰레이터로 나눌 수 있으며, 케이블이 손가락의 각 관절에서부터 시작되어 손바닥을 지나 모터 보빈에 연결된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-3.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40232" alt="65 ict robot hand (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-3.png" width="614" height="360" /></a></p>
<p><span style="color: #00ccff"><strong>3.2.2. 손가락</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-4.png" rel="lightbox[40130]"><img class="alignnone  wp-image-40233" alt="65 ict robot hand (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-4-589x620.png" width="600" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-5.png" rel="lightbox[40130]"><img class="alignnone  wp-image-40234" alt="65 ict robot hand (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-5.png" width="600" /></a><br />
신체 구조상 손가락을 크게 뼈, 관절, 근육으로 분리해 생각할 수 있다. 손가락의 뼈는 강도와 전체 손의 무게를 고려해 알루미늄 샤프트를 사용하였다[그림3].<br />
관절부분에는 유니버셜 조인트를 사용하였다[그림4]. 제 2,3관절은 1자유도이기 때문에 물리적 제한을 두어 유니버셜 조인트가 한방향으로만 움직일 수 있게 하였다.<br />
마지막으로 근육 및 인대 역할을 하는 케이블을 연결하기 위하여 실이 지나가거나 고정될 수 있는 플레이트를 제작하여 관절에 부착하였다[그림5]. 이 부분을 앞으로 ‘조인트 플레이트’라고 지칭하겠다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-6.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40235" alt="65 ict robot hand (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-6.png" width="287" height="430" /></a></p>
[그림7]은 손가락 한 개를 매트랩을 통하여 시뮬레이션해보았다. 중심을 통과하는 진한 하늘색은 손가락의 뼈대를 구성하는 샤프트를 의미한다. 첫 번째 관절은 상하, 좌우 두 개의 자유도를 가지고 있다. 첫 번째 관절에 초록색, 노란색, 보라색, 하늘색 4개의 실이 묶여 상하와 좌우의 움직임을 정한다. 빨간색과 주황색의 실은 첫 번째 마디와 두 번째 관절을 모두 통과하고 세 번째 관절에서 묶여 두번째, 세번째 관절을 동시에 제어한다. 이는 회전하는 방향이 같기 때문에 가능하다. 인간의 손에서 두 번째 관절은 굽어지는 방향으로 하나의 자유도를 가지고는 있지만, 세 번째 관절의 움직임에 따라 종속적으로 작동한다. 이러한 관계를 스프링과 두개의 실을 이용하여 표현하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-7.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40236" alt="65 ict robot hand (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-7.png" width="615" height="271" /></a><br />
첫 번째(MCP)와 세 번째 관절(DIP)은 모터에 실제로 연결되어 있기 때문에 모터를 조절하여 각 관절을 움직일 수 있다. 하지만 첫번째 관절과 달리 세번째 관절과 두번째 관절은 두번째 관절이 특정되지 않기 때문에 위치와 각도는 예측할 수 없다.</p>
[그림8]에 보듯이 두 번째 관절(PIP)의 경우 움직여 첫번째, 세번째 관절사이의 실의 길이가 같은 곳이라면 어디든 존재할 수 있다. 다시 말하면 사람의 실제 손과 다르게 앞으로 굽히는 방향만 있는 것이 아닌 [그림7]의 빨간색처럼 뒤로 꺾이는 방향으로도 존재할 수 있다. 그래서 뒤로 꺾이는 방향으로 움직임을 제한하고 두번째 세번째 관절을 종속해주는 스프링을 두번째 관절(PIP), 세번째 관절(DIP)사이에 부착한다. 손가락을 일자로 폈을 때를 스프링의 최소길이로 고정하여 더 이상 뒤로 굽혀지지 않도록 한다. 케이블의 장력과 스프링 계수를 조절하여 PIP와 DIP의 회전하는 정도를 조절할 수 있다. 스프링 계수에 따라 자연스러운 비율로 두번째 세번째의 관절이 회전할 것이다. 스프링 계수가 높으면 물체에 손가락이 닿기 전까지 세번째 관절이 회전하지 않다가 두번째 세번째 사이의 마디에 물체가 접촉되었을 경우 케이블 장력으로 인해 세번째 관절이 회전하게 될 것이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-8.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40237" alt="65 ict robot hand (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-8.png" width="619" height="273" /></a></p>
[그림9]은 조인트 플레이트와 유니버셜 조인트의 조립품이다. 조인트 플레이트 8개의 구멍 중 서로 180° 반대편에 연결되어 있는 실은 같은 모터에 감기게 된다. 두개의 실이 짝을 이루게 되는데 한 개의 실은 시계방향으로 감기고 나머지 실은 반 시계 방향으로 모터 보빈에 감는다. 한쪽 실을 당기게 되면 반대편에 연결된 실이 풀리기 때문에 조인트가 꺾일 때 실이 끊겨지지 않기 위해서는 조인트 플레이트의 아래 면과 조인트의 중심이 같은 높이에 있어야 한다.<br />
또한 조인트가 중심 축을 기준으로 회전할 때 회전운동에 대한 실이 묶여 있는 양 끝점의 위치와 지정한 손가락 마디의 길이를 가지고 다음 조인트 플레이트의 위치를 기구학적 해석으로 구할 수 있는데, 중심과 다른 높이에 조인트 플레이트가 있다면 회전운동과 평행이동의 두 단계에 걸친 계산이 필요하다.<br />
유니버셜 조인트의 구조적인 문제로 자연스러운 움직임이 가능한 각도가 정해져 있다. 유니버셜 조인트의 자체 최대각도까지 회전하기도 전에 조인트 플레이트가 조인트에 닿아 회전하는 각도에 제한이 생긴다. 또한 실을 계속해서 당기면 실과 조인트 플레이트가 평행하게 접하는 각도가 있다. 이 각도를 넘어서까지 실을 당길 경우 조인트 플레이트에 실이 걸려 반발력이 발생하고 양쪽 두 실의 변화량이 달라질 수 있다. 이러한 각도 제한들의 안에서 손가락이 구동되어야 하므로 최대각도를 다음과 같이 정했다.<br />
-5° &lt; θ &lt; 60°</p>
<p><span style="color: #00ccff"><strong>3.2.3. 손바닥</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-9.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40238" alt="65 ict robot hand (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-9.png" width="620" height="280" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-10.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40239" alt="65 ict robot hand (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-10.png" width="616" height="578" /></a><br />
손바닥은 손가락을 고정할 수 있는 손바닥 뼈대[그림10], 손바닥에서 실이 지나가는 점을 고정해주는 플레이트[그림11], 손바닥 이후에 모터까지 케이블이 지나가는 튜브를 고정해줄 튜브 고정 플레이트 [그림13]가 있다.<br />
손바닥에서 실이 지나가는 점을 고정해주는 플레이트를 앞으로 ‘손바닥 플레이트’라고 지칭하겠다[그림10].<br />
손바닥에서 튜브를 고정해주는 플레이트를 앞으로 ‘튜브 고정 플레이트’라고 지칭하겠다[그림13].<br />
손가락은 손바닥의 연장된 부분이지만 본 작품은 각각 분리된 형태로 존재한다. 만약 네 손가락이 모두 같은 방향으로 있다면, 손가락을 구부려 물체를 잡을 때 손가락들이 한 점에서 모이지 않기 때문에 불리하게 작용한다. 손가락을 구부렸을 때, 한 점에서 모든 손가락이 모이기 위해서 손바닥 뼈대의 각도와 길이를 조절할 필요가 있는데 그 값 은 [그림14]와 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-11.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40240" alt="65 ict robot hand (11)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-11.png" width="614" height="339" /></a></p>
<p>손가락 현재관절의 위치는 이전 관절의 위치와 관절사이의 거리 및 각도를 통해 계산한다. 케이블을 손바닥 끝에 고정시키면, 손바닥 플레이트의 실 고정점을 손가락의 시작점으로 생각하여 관절의 위치를 구할 때 계산을 단순화할 수 있다. 또한 손가락이 움직일 때 케이블이 손바닥에 접촉되어 일어나는 의도치 않은 길이 변화를 제한할 수 있다.</p>
<p><span style="color: #00ccff"><strong>3.2.4. 보빈 및 액츄에이터</strong></span><br />
손가락을 움직이기 위해서 실을 밀고 당기는 역할은 보빈과 액츄에이터가 한다. 보빈[그림16]은 실이 감기는 부분이고 액츄에이터[그림17]는 보빈을 돌려준다.<br />
실을 감기 전에 먼저 보빈에 실구멍을 통해 실을 한번 묶어서 고정해준 뒤 실을 감아 실이 헛도는 것 방지한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-12.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40241" alt="65 ict robot hand (12)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-12.png" width="614" height="586" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-13.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40242" alt="65 ict robot hand (13)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-13.png" width="614" height="274" /></a></p>
<p>케이블은 특성상 당기는 방향으로만 제어할 수 있고 미는 방향으로의 제어가 불가능하여, 하나의 모터로는 한 가닥의 케이블만 조절할 수 있다. 기존의 로봇손은 1개의 자유도를 제어하기 위해서는 두개의 모터가 필요하다. 그러나 본 작품은 한 개의 자유도를 제어하기 위하여 두 가닥의 케이블을 하나의 보빈에 반대방향으로 감아 더 적은 액츄에이터로 1개의 자유도를 제어할 수 있게 하여 모터의 수를 줄였다.<br />
케이블은 보빈의 가운데 원판[그림15]을 기준으로 한쪽은 순방향, 반대쪽은 역방향으로 감겨 있어, 모터가 회전하면 한쪽은 감기고 반대쪽은 풀린다. 제어하고자 하는 조인트 플레이트의 양쪽 끝에 실을 묶어 손가락의 움직임을 제어할 수 있다.</p>
<p><span style="color: #00ccff"><strong>3.2.5. 매니퓰레이터</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-14.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40243" alt="65 ict robot hand (14)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-14.png" width="613" height="345" /></a></p>
<p>매니퓰레이터를 손과 연결하면 사람의 팔과 같은 형태가 되어 더 다양한 방향으로 어플리케이션을 확장할 수 있다. 하지만, 매니퓰레이터를 사용할 경우 매니퓰레이터의 회전과 이동 때문에 몸체사이에 케이블이 걸려 의도치 않은 길이변화가 일어날 수 있다. 이 문제를 해결하기 위해서 손바닥부터 튜브를 연결하여 모터의 전까지 케이블을 감싸고 있으면 위의 문제를 해결할 수 있다.</p>
<p><span style="color: #00ccff"><strong>3.2.6. 기구학</strong></span><br />
로봇 손의 손가락 끝지점은 4X4 회전행렬을 활용한 동차변환으로 기구학을 풀이하여 해석하였다. 동차 변환 행렬은 각 축에 대한 회전 행렬에서 좌표 이동과 크기 조정에 대한 정보를 추가한 행렬으로, 일반적으로 아래의 행렬과 같이 나타난다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-15.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40244" alt="65 ict robot hand (15)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-15.png" width="617" height="124" /></a><br />
본 제품에서는 투시 변환의 경우는 존재하지 않으므로, 투시 변환은 0으로 고정시키고, 크기조정 또한 단위 변환이므로 1으로 고정시킨다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-16.png" rel="lightbox[40130]"><img class="alignnone size-large wp-image-40245" alt="65 ict robot hand (16)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-16-620x153.png" width="620" height="153" /></a><br />
순기구학을 풀이할 시, 동차변환은 각 링크 간의 이동변환과 회전변환의 곱으로 나타난다. 동차 변환에 관한 자세한 원리는 본 서식에서 다루지 않고 참고문헌을 참조한다[14].</p>
<p>매니퓰레이터는 6개의 링크의 조합으로 움직이고 각 관절의 움직임은 다음과 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-17.png" rel="lightbox[40130]"><img alt="65 ict robot hand (17)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-17.png" width="610" height="339" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-18.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40247" alt="65 ict robot hand (18)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-18.png" width="616" height="355" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-19.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40248" alt="65 ict robot hand (19)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-19.png" width="618" height="450" /></a></p>
<p>매니퓰래이터의 동차변환()은 다음 식으로 정리된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-20.png" rel="lightbox[40130]"><img class="alignnone size-large wp-image-40249" alt="65 ict robot hand (20)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-20-620x580.png" width="620" height="580" /></a><br />
로봇 손은 시작점(origin)에서 손가락 끝점까지 2개의 조인트와 3개의 샤프트의 조합으로 이루어져 있다. 따라서, 로봇 손의 동차변환은 총 세 링크와 그 변환들의 조합으로 나타난다. 손바닥의 길이를 L_0, 첫 번째 관절부터 세 번째 관절까지의 손가락 길이를 L_1, 세 번째 관절부터 손가락 끝부분까지의 길이를 L_2라 할 때, 각 움직임은 다음과 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-21.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40250" alt="65 ict robot hand (21)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-21.png" width="612" height="394" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-22.png" rel="lightbox[40130]"><img class="alignnone size-large wp-image-40251" alt="65 ict robot hand (22)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-22-620x388.png" width="620" height="388" /></a></p>
<p>로봇 손의 동차변환(DH)는 다음 식으로 정리된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-23.png" rel="lightbox[40130]"><img class="alignnone size-large wp-image-40252" alt="65 ict robot hand (23)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-23-620x286.png" width="620" height="286" /></a></p>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경</strong></span><br />
<span style="color: #00ccff"><strong>3.3.1. 디자인</strong></span><br />
Cable-driven robot hand를 개발하는데 있어서 대부분의 하드웨어를 3D프린터를 사용하여 만들었다. 프린터로 제작한 부품 이외에는 유니버셜 조인트, 샤프트 등 일반적으로 시중에서 쉽게 구입할 수 있는 공학 재료들을 사용하여 제작하였기 때문에 쉽게 제작할 수 있다. 3D프린터를 이용하여 부품을 제작한 만큼 설계하는 CAD 프로그램 선정 또한 중요했다. 설계를 하는데 사용한 프로그램은 AUTODESK사의 INVENTOR이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-24.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40253" alt="65 ict robot hand (24)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-24.png" width="611" height="580" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-25.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40254" alt="65 ict robot hand (25)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-25.png" width="617" height="253" /></a></p>
<p>인벤터로 디자인을 하고 이를 프로그램 내장된 3D 프린트 기능으로 STL 파일로 모델을 출력하였다. 아래는 인벤터도 디자인한 윈치 와이어가 감기는 보빈이다. 이렇게 디자인한 각 파트들을 위와 같이 인벤터 안에서 조립해볼 수 있다.<br />
또한 인벤터를 사용함으로써 장점은 디자인한 각 파트를 미리 조립을 해보고 간섭이 있는지 검사하거나 어떤 부분이 약할지 시뮬레이션을 해볼 수 있다.<br />
만들어진 STL파일을 3D 프린터로 출력하기 위해 GCODE로 변환하기 위해 사용한 프로그램은 많은 사용자들이 사용하는 ULTIMAKER CURA를 사용했다.<br />
CURA에 STL파일을 넣고 사용할 프린터에 맞게 설정을 해주면 적절한 GCODE가 생성된다. 프린터에 따라 직접 프린터를 컴퓨터에 연결하여 CURA에서 바로 프린트할 수도 있고 생성한 GCODE파일을 이동식 메모리에 넣어 프린터에 꽂아 사용할 수 있다. 아래는 모델링한 STL파일을 열어 GCODE로 변환한 모습이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-26.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40255" alt="65 ict robot hand (26)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-26.png" width="612" height="361" /></a></p>
<p>CURA에는 다양한 설정이 있어 각 부품들의 필요한 속성에 따라 적당한 값으로 조절하여 필요한 특성을 얻을 수 있다.</p>
<p><span style="color: #00ccff"><strong>3.3.2. 시뮬레이션</strong></span><br />
제작하기에 앞서 모델링 한 부품들에 맞춰 실제로 동작하는지 확인해 볼 필요가 있다. 동작 중에 수치적으로 와이어의 길이 변화가 어떻게 일어나는지 또는 그 과정에서 얼마나 오류가 발생하는지 확인해야 한다. 앞에 3-2. 6)절에서 기구학을 풀었는데 이를 코드로 구현하여 설계한 대로 제작했을 때 각도가 변함에 따라 와이어의 길이를 시뮬레이션한다. 이를 위해 MATLAB을 이용해서 기구학 식을 구현해서 시뮬레이션 해보고 그때의 와이어 길이의 변화를 구했다.<br />
아래 3차원 그래프는 각 손가락 관절을 움직일 때 와이어, 플레이트, 샤프트의 위치를 표시한 그래프이다. 또한 이렇게 손가락을 움직일 때 밑에 그래프처럼 각 와이어가 어떻게 얼마나 변하고, 한 관절에 대해서 늘어나고 줄어드는 양의 오차가 얼마인지 그래서 그 양은 모터의 각도로 얼마나 차이 나는지를 확인할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-27.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40256" alt="65 ict robot hand (27)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-27.png" width="616" height="612" /></a></p>
<p><span style="color: #00ccff"><strong>3.3.3. 로봇 손 구동 펌웨어</strong></span><br />
기본적인 모터 구동을 포함한 유저 인터페이스, 어플리케이션과의 연결은 C++로 개발하였다. 사용하는 액츄에이터가 ROBOTIS의 DYNAMIXEL이기 때문에 따로 모터와 엔코더를 위한 개별 제어기를 사용하지 않았고, ROBOTIS에서 제공하는 SDK를 사용하여 제어했다. 따라서 모든 기본적인 제어를 포함한 피드백, 다양한 명령에 대해서 주 제어기인 PC가 대부분의 역할을 수행하게 된다. 초기적인 방법으로 C++ 콘솔 응용프로그램을 사용하여 손가락의 구동 및 유저 인터페이스를 구현하였다. 개발자가 필요에 따라 GUI가 가능하도록 C#을 이용하여 개발하거나 OpenCV나 OpenGL을 이용하여 그래픽으로 표시하게 추가할 수 있다.</p>
<p><span style="color: #3366ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1. 손가락 한 개 시제작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-28.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40257" alt="65 ict robot hand (28)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-28.png" width="614" height="558" /></a></p>
<p><span style="color: #33cccc"><strong>4.2. 로봇손 제작</strong></span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-29.png" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40258" alt="65 ict robot hand (29)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-29.png" width="616" height="309" /></a></p>
[그림28]의 오른쪽 그림은 왼쪽 도안에서 더 튼튼하게 하기 위하여 손바닥 면적을 늘려주었다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-30.png" rel="lightbox[40130]"><img class="alignnone  wp-image-40259" alt="65 ict robot hand (30)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-30.png" width="620" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-1.jpg" rel="lightbox[40130]"><img class="alignnone  wp-image-40228" alt="65 ict robot hand (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-1.jpg" width="620" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-2.jpg" rel="lightbox[40130]"><img class="alignnone size-full wp-image-40230" alt="65 ict robot hand (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-robot-hand-2.jpg" width="614" height="799" /></a></p>
<p><strong style="color: #3366ff">5. 기타</strong></p>
<p><span style="color: #33cccc"><strong>5.1. 소스코드</strong></span><br />
<span style="color: #00ccff"><strong>5.1.1. 매트랩 시뮬레이션 코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>%% Simulate One Finger<br />
clear, clc;<br />
SimMin = 0;<br />
SimMax = 30;<br />
Res = 20;</p>
<p>BobinR = 5;<br />
PlateR = 11;<br />
PlateHallR = 8;<br />
PlateOffset = [0 0 0 0]+1;<br />
SHAFTLENGTH = [15 50 35 25];</p>
<p>disp(['Simuation from ' num2str(SimMin) ' to ' num2str(SimMax) ', with ' num2str(Res) 'steps']);<br />
sim = linspace(SimMin, SimMax, Res);<br />
counter = 1;<br />
clear LWs;<br />
LWs = zeros(6,length(sim));<br />
for i = 1:length(sim)<br />
[SHAFT, WIRE, LW] = OneFinger(eye(4),[sim(i) sim(i) sim(i) 0 0 0 0 0 0],PlateHallR,PlateOffset,SHAFTLENGTH);<br />
LWs(:,counter) = LW;<br />
figure(1);<br />
plot3(SHAFT(1,:),SHAFT(2,:),SHAFT(3,:),&#8217;-o&#8217;,'LineWidth&#8217;,3), hold on;<br />
plot3(WIRE{1}(1,:),WIRE{1}(2,:),WIRE{1}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plot3(WIRE{2}(1,:),WIRE{2}(2,:),WIRE{2}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plot3(WIRE{3}(1,:),WIRE{3}(2,:),WIRE{3}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plot3(WIRE{4}(1,:),WIRE{4}(2,:),WIRE{4}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plot3(WIRE{5}(1,:),WIRE{5}(2,:),WIRE{5}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plot3(WIRE{6}(1,:),WIRE{6}(2,:),WIRE{6}(3,:),&#8217;-.d&#8217;,'LineWidth&#8217;,2);<br />
plotCircle3D(SHAFT(:,1)&#8217;+PlateOffset(1)*(SHAFT(:,2)-SHAFT(:,1))&#8217;/norm((SHAFT(:,2)-SHAFT(:,1))&#8217;),(SHAFT(:,2)-SHAFT(:,1))&#8217;,PlateR,2);<br />
plotCircle3D(SHAFT(:,2)&#8217;+PlateOffset(2)*(SHAFT(:,3)-SHAFT(:,2))&#8217;/norm((SHAFT(:,3)-SHAFT(:,2))&#8217;),(SHAFT(:,3)-SHAFT(:,2))&#8217;,PlateR,2);<br />
plotCircle3D(SHAFT(:,3)&#8217;+PlateOffset(3)*(SHAFT(:,4)-SHAFT(:,3))&#8217;/norm((SHAFT(:,4)-SHAFT(:,3))&#8217;),(SHAFT(:,4)-SHAFT(:,3))&#8217;,PlateR,2);<br />
plotCircle3D(SHAFT(:,4)&#8217;+PlateOffset(4)*(SHAFT(:,5)-SHAFT(:,4))&#8217;/norm((SHAFT(:,5)-SHAFT(:,4))&#8217;),(SHAFT(:,5)-SHAFT(:,4))&#8217;,PlateR,2);<br />
title(&#8216;One Finger&#8217;);<br />
axis equal;<br />
hold off;<br />
drawnow;<br />
counter = counter+1;<br />
end</p>
<p>figure(2);<br />
subplot(2,3,1), plot(sim,LWs(1,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 1 Length&#8217;), grid on;<br />
subplot(2,3,2), plot(sim,LWs(2,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 2 Length&#8217;), grid on;<br />
subplot(2,3,3), plot(sim,LWs(3,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 3 Length&#8217;), grid on;<br />
subplot(2,3,4), plot(sim,LWs(6,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 6 Length&#8217;), grid on;<br />
subplot(2,3,5), plot(sim,LWs(5,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 5 Length&#8217;), grid on;<br />
subplot(2,3,6), plot(sim,LWs(4,:)), axis([SimMin SimMax 0 150]),title(&#8216;Wire 4 Length&#8217;), grid on;</p>
<p>figure(3);<br />
subplot(2,3,1), plot(sim,LWs(1,:)-LWs(6,:)), axis([SimMin SimMax -50 50]),title(&#8216;J2 WL diff&#8217;);<br />
subplot(2,3,2), plot(sim,LWs(2,:)-LWs(5,:)), axis([SimMin SimMax -50 50]),title(&#8216;J1_1 WL diff&#8217;);<br />
subplot(2,3,3), plot(sim,LWs(3,:)-LWs(4,:)), axis([SimMin SimMax -50 50]),title(&#8216;J1_2 WL diff&#8217;);<br />
subplot(2,3,4), plot(sim,LWs(1,:)-LWs(1,1)+LWs(6,:)-LWs(6,1)), axis([SimMin SimMax -15 15]),title(&#8216;J2 WL error&#8217;);<br />
subplot(2,3,5), plot(sim,LWs(2,:)-LWs(2,1)+LWs(5,:)-LWs(5,1)), axis([SimMin SimMax -15 15]),title(&#8216;J1_1 WL error&#8217;);<br />
subplot(2,3,6), plot(sim,LWs(3,:)-LWs(3,1)+LWs(4,:)-LWs(4,1)), axis([SimMin SimMax -15 15]),title(&#8216;J1_2 WL error&#8217;);<br />
disp(['Max J2 wire length error: ' num2str(max(abs(abs(LWs(1,:)-LWs(1,1)+LWs(6,:)-LWs(6,1))))) 'mm']);<br />
disp(['Max J1_1 wire length error: ' num2str(max(abs(abs(LWs(2,:)-LWs(2,1)+LWs(5,:)-LWs(5,1))))) 'mm']);<br />
disp(['Max J1_2 wire length error: ' num2str(max(abs(abs(LWs(3,:)-LWs(3,1)+LWs(4,:)-LWs(4,1))))) 'mm']);</p>
<p>figure(4);<br />
LWCs = LWs-LWs(:,1);<br />
LWCd = rad2deg(LWCs./BobinR);<br />
MotorPos = round(LWCd./360*4096);<br />
subplot(3,3,1), stairs(MotorPos(1,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 1&#8242;);<br />
subplot(3,3,2), stairs(MotorPos(2,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 2&#8242;);<br />
subplot(3,3,3), stairs(MotorPos(3,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 3&#8242;);<br />
subplot(3,3,4), stairs(MotorPos(6,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 6&#8242;);<br />
subplot(3,3,5), stairs(MotorPos(5,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 5&#8242;);<br />
subplot(3,3,6), stairs(MotorPos(4,:)), axis([0 length(LWCs) -4096 4096]), title(&#8216;Motor Pos by wire 4&#8242;);<br />
subplot(3,3,7), stairs(MotorPos(1,:) + MotorPos(6,:)), axis([0 length(LWCs) -256 256]), title(&#8216;J2 Motor Pos Error&#8217;);<br />
subplot(3,3,8), stairs(MotorPos(2,:) + MotorPos(5,:)), axis([0 length(LWCs) -256 256]), title(&#8216;J1_1 Motor Pos Error&#8217;);<br />
subplot(3,3,9), stairs(MotorPos(3,:) + MotorPos(4,:)), axis([0 length(LWCs) -256 256]), title(&#8216;J1_2 Motor Pos Error&#8217;);<br />
MaxPosErr = max([max(abs(MotorPos(1,:) + MotorPos(6,:))) max(abs(MotorPos(2,:) + MotorPos(5,:))) max(abs(MotorPos(3,:) + MotorPos(4,:)))]);<br />
disp(['Max motor position error is: ' num2str(MaxPosErr) ' encoder tics, ' num2str(MaxPosErr/4096) ' rotation, degrees: ' num2str(MaxPosErr*360/4096)]);</p>
</div>
<p><span style="color: #00ccff"><strong>5.1.2. 손가락 구동 코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>// CableOneFinger.cpp : This file contains the &#8216;main&#8217; function. Program execution begins and ends there.<br />
//</p>
<p>#if defined(__linux__) || defined(__APPLE__)<br />
#include &lt;fcntl.h&gt;<br />
#include &lt;termios.h&gt;<br />
#define STDIN_FILENO 0<br />
#elif defined(_WIN32) || defined(_WIN64)<br />
#include &lt;conio.h&gt;<br />
#endif</p>
<p>#include &lt;Windows.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;iostream&gt;</p>
<p>#include &#8220;dynamixel_sdk.h&#8221;<br />
#include &#8220;CableOneFinger.h&#8221;<br />
#include &#8220;DXL_custom.h&#8221;<br />
#include &#8220;DXL_application.h&#8221;<br />
#include &#8220;UserFunction.h&#8221;<br />
#include &#8220;Robotics.h&#8221;</p>
<p>using namespace std;<br />
int main()<br />
{<br />
int dxl_comm_result = COMM_TX_FAIL;<br />
uint8_t dxl_error = 0;</p>
<p>bool dxl_addparam_result = false;<br />
bool dxl_getdata_result = false;</p>
<p>const int DXL_IDs[DXLS] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };<br />
int DXL_REL_MIN_POSs[DXLS];<br />
int DXL_REL_MAX_POSs[DXLS];<br />
int DXL_REL_GRASP_POSs[DXLS];<br />
fill_n(DXL_REL_MIN_POSs, DXLS, 0);<br />
fill_n(DXL_REL_MAX_POSs, DXLS, 3000);<br />
fill_n(DXL_REL_GRASP_POSs, DXLS, 2500);</p>
<p>int DXL_INIT_POSs[DXLS];<br />
int DXL_ABS_GOAL_POSs[DXLS];<br />
int DXL_ABS_PRE_POS_ERRs[DXLS];<br />
int DXL_ABS_PRESENT_POSs[DXLS];<br />
int DXL_ABS_MIN_POSs[DXLS];<br />
int DXL_ABS_MAX_POSs[DXLS];<br />
int DXL_ABS_GRASP_POSs[DXLS];</p>
<p>int16_t DXL_PRESENT_LOAD[DXLS];<br />
bool DXL_GRASPED[DXLS] = { false };</p>
<p>dynamixel::PortHandler *portHandler = dynamixel::PortHandler::getPortHandler(DEVICENAME);<br />
dynamixel::PacketHandler *packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION);</p>
<p>dynamixel::GroupSyncWrite SyncWriteGoalPos(portHandler, packetHandler, ADDR_GOAL_POSITION, LEN_GOAL_POSITION);<br />
dynamixel::GroupSyncRead SyncReadPresentPos(portHandler, packetHandler, ADDR_PRESENT_POSITION, LEN_PRESENT_POSITION);</p>
<p>dynamixel::GroupSyncRead SyncReadPresentLoad(portHandler, packetHandler, ADDR_PRESENT_LOAD, LEN_PRESENT_LOAD);</p>
<p>if (portHandler-&gt;openPort())<br />
cout &lt;&lt; &#8220;Succeeded to open the dynamixel!&#8221; &lt;&lt; endl;<br />
else<br />
{<br />
cout &lt;&lt; &#8220;Failed to open the dynamixel!&#8221; &lt;&lt; endl;<br />
_getch();<br />
return -1;<br />
}</p>
<p>if (portHandler-&gt;setBaudRate(BAUDRATE))<br />
cout &lt;&lt; &#8220;Set baudrate to &#8221; &lt;&lt; BAUDRATE &lt;&lt; endl;<br />
else<br />
{<br />
cout &lt;&lt; &#8220;Failed to change the baudrate!&#8221; &lt;&lt; endl;<br />
_getch();<br />
return -1;<br />
}</p>
<p>if (!(initializeHand(packetHandler, portHandler, SyncReadPresentPos, SyncWriteGoalPos, &amp;dxl_comm_result, &amp;dxl_error, &amp;dxl_addparam_result, &amp;dxl_getdata_result, DXL_IDs, DXL_INIT_POSs, sizeof(DXL_IDs))))<br />
cout &lt;&lt; &#8220;Initializing failed!&#8221; &lt;&lt; endl;<br />
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_GRASP_POSs, DXL_ABS_GRASP_POSs, sizeof(DXL_IDs), &#8216;+&#8217;);<br />
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_MIN_POSs, DXL_ABS_MIN_POSs, sizeof(DXL_IDs), &#8216;+&#8217;);<br />
calculateArrayArithmetic(DXL_INIT_POSs, DXL_REL_MAX_POSs, DXL_ABS_MAX_POSs, sizeof(DXL_IDs), &#8216;+&#8217;);<br />
cout &lt;&lt; &#8220;CABLE-DRIVEN ROBOT HAND Initialized!!!&#8221; &lt;&lt; endl;</p>
<p>grasping(packetHandler, portHandler, SyncReadPresentPos, SyncReadPresentLoad, SyncWriteGoalPos, &amp;dxl_comm_result, &amp;dxl_error, &amp;dxl_addparam_result, &amp;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);<br />
Sleep(5000);<br />
toggleDXLTorque(packetHandler, portHandler, &amp;dxl_comm_result, &amp;dxl_error, DXL_IDs, sizeof(DXL_IDs), TORQUE_DISABLE);</p>
<p>portHandler-&gt;closePort();<br />
return 0;<br />
}</p>
<p>// Run program: Ctrl + F5 or Debug &gt; Start Without Debugging menu<br />
// Debug program: F5 or Debug &gt; Start Debugging menu</p>
<p>// Tips for Getting Started:<br />
// 1. Use the Solution Explorer window to add/manage files<br />
// 2. Use the Team Explorer window to connect to source control<br />
// 3. Use the Output window to see build output and other messages<br />
// 4. Use the Error List window to view errors<br />
// 5. Go to Project &gt; Add New Item to create new code files, or Project &gt; Add Existing Item to add existing code files to the project<br />
// 6. In the future, to open this project again, go to File &gt; Open &gt; Project and select the .sln file<br />
</div>
<p><span style="color: #33cccc"><strong>5.2. 참고문헌</strong></span><br />
[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.<br />
[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.<br />
[3] Zatsiorsky. V. and B. Prilutsky, Biomechanics of skeletal muscles. 2012: Human Kinetics.<br />
[4] Agur, A.M. and A.F. Dalley, Grant&#8217;s atlas of anatomy. 2009: Lippincott Williams &amp; Wilkins.<br />
[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.<br />
[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.<br />
[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.<br />
[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.<br />
[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.<br />
[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.<br />
[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<br />
[12] Dawei Xu, En li and Zize liang, &#8220;Kinematics and Statics Analysis of a Novel Cable-Driven Snake Arm Robot&#8221;, Chinese Automation Congress 2017, IEEE 2017, pp. 439-444.<br />
[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.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40130/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[65호]스마트 차선 변경 시스템</title>
		<link>http://www.ntrexgo.com/archives/40144</link>
		<comments>http://www.ntrexgo.com/archives/40144#comments</comments>
		<pubDate>Thu, 22 Apr 2021 00:00:42 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[65호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[smart]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[로봇]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[센서]]></category>
		<category><![CDATA[스마트]]></category>
		<category><![CDATA[융합]]></category>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40144</guid>
		<description><![CDATA[디바이스마트매거진 65호 &#124; 초음파 센서를 통해 거리를 측정하여 차선 변경 시 운전자에게 위험(빨강색) / 주의(주황색) / 안전(초록색) 세 단계로 나누어 시각화 함으로서 위험을 좀 더 쉽게 감지할 수 있게 돕는다. ]]></description>
				<content:encoded><![CDATA[<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-2.png" rel="lightbox[40144]"><img alt="65 ict 스마트차선 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-2-620x177.png" width="620" height="177" /></a></strong></p>
<p><strong><span style="font-size: medium">2020 ICT 융합 프로젝트 공모전 장려상</span></strong></p>
<p><span style="font-size: x-large"><strong>스마트 차선 변경 시스템</strong></span></p>
<p>글 | 영남대학교 양성은, 박유나, 지준영</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 지원자께서는 &#8216;ADAS(Advanced Driver-Assistance Systems)&#8217; 라는 용어나 시스템을 들어보셨을 수도 있을듯합니다. 최근 많은 차량에 운전, 주차, 안전을 위한 여러 가지 시스템이 적용되고 있고, 그 중 지원자가 구현하고자 한 작품은 ADAS 기능 중 BCW 기능에 해당할 것으로 보입니다. 보고서에도 작성되어 있듯이 실제로는 고려하기 힘든 많은 변수들이 있고 그러한 부분을 이미 진행된 기술의 학습을 통해서 개선이 가능할 것으로 보입니다. 시연 영상에서 실제 도로와 유사한 이미지로 화면이 보이는 것이 매우 흥미로웠습니다.<br />
<strong></strong></p>
<p><strong>펌테크</strong> 현재 상용화되어 널리 사용되는 기술이지만 학생의 눈높이에 맞추어 전체적으로 꼼꼼하게 잘 기획되었고, 간결하게 잘 구성한 작품이라고 생각합니다. 제품 완성도 면에서 우수한 작품이라고 판단됩니다.<br />
<strong></strong></p>
<p><strong>위드로봇</strong> 차량의 BSD 기능을 구현한 작품입니다. 카메라 캘리브레이션을 통해 초음파 센서 거리 값과 융합을 하면 더 좋은 결과를 얻을 수 있습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 구현 배경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-3.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40177" alt="65 ict 스마트차선 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-3.png" width="618" height="331" /></a></p>
<p>TAAS 교통사고분석시스템에 따르면, 2018년 교통사고는 21만 건이 넘는 사고와 3,781명의 사망자가 발생했으며 교통사고로 수년간 인명피해가 많이 발생하고 있다. 이러한 교통사고가 일어나는 경우는 신호 위반, 안전거리 미확보, 중앙선 침범, 과속, 안전운전 의무 불이행, 교차로 통행방법 위반, 보행자 보호의무 위반 등 여러 가지가 있다.<br />
여기서 도로교통공단에서 제시한 안전운전(안전한 도로이용)수칙에는 안전거리 유지, 좌석 안전벨트의 착용, 진로 변경 등을 다루고 있다. 안전거리 유지 관련 기술은 고속도로 주행보조(HDA)로 고속도로와 자동차 전용도로 주행 시 앞차와의 거리를 유지하며 운전자가 설정한 속도로 곡선로에서도 차선을 유지하며 주행하도록 돕는 기술이 있다. 자동차 안전벨트 미착용 알림장치 뿐만 아니라 후진 주차/출차 시 후방 장애물 인식 및 제동을 돕는 후방 주차 충돌방지 보조(PCA)등을 탑재해 안전 편의성을 극대화하였다.<br />
따라서 우리가 구현하고자 하는 기술은 차선 변경에 대한 교통사고를 일으키는 원인의 시발점을 봉쇄하는 동시에 이와 같은 스마트한 시대에 걸 맞는 기술을 접목 시킬 기술을 구현하는 것이다.</p>
<p><span style="color: #33cccc"><strong>2.2. 스마트 차선 변경 시스템이란?</strong></span><br />
스마트 차선 변경 시스템은 운전자가 방향지시등을 키게 되면 변경하고자하는 차선의 운전자 차량 기준에서 가장 가까운 차량과의 거리를 실시간으로 측정하여 운전자의 차량 내 모니터를 이용해 시각적인 정보를 제공함으로써, 운전자가 보다 안전하고 편리하게 차선변경을 할 수 있도록 도움을 주는 시스템이다.<br />
초음파 센서를 통해 거리를 측정하여 차선 변경 시 운전자에게 위험(빨강색) &#8211; 주의(주황색) &#8211; 안전(초록색) 세 단계로 나누어 시각화 함으로서 위험을 좀 더 쉽게 감지할 수 있게 돕는다.</p>
<p><span style="color: #33cccc"><strong>2.3. 대상 및 기대효과</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-4.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40179" alt="65 ict 스마트차선 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-4.png" width="612" height="325" /></a></p>
<p>한국 교통 연구원, 경찰 교통사고자료 분석 결과에 따르면 차선을 변경 시 충돌사고를 많이 내는 것으로 나타났다. 그리고 차선 변경을 하지 못해 부산까지 갔다는 기사를 접할 수 있다. 이와 같이 해당 기술의 초점 대상은 운전에 미숙한 사람으로 해당 기술은 차선 변경에 대한 부담감을 줄이고 안전편의성을 극대화하는 역할을 한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-5.png" rel="lightbox[40144]"><img class="alignnone size-large wp-image-40181" alt="65 ict 스마트차선 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-5-620x268.png" width="620" height="268" /></a></p>
<p>또 운전에 미숙한 사람뿐만 아니라 모든 운전자를 대상으로 확장 할 수 있다. 도로를 나가보면 상당히 많은 운전자들이 차선 변경 시 방향지시등을 켜지 않은 모습을 볼 수 있는데, 이유를 물어보면 대다수가 “귀찮아서”라는 대답을 한다. 운전자들이 대수롭지 않게 생각하여 잘 사용하지 않는 기능을 개선하여 보다 안전하게 운전할 수 있다는 장점을 살려 방향지시등을 사용하게끔 유도하는 효과도 기대해본다.<br />
끝으로 차선 변경 시 일어나는 교통문제를 개선해 조금이라도 더 많은 운전자가 편리하고 안전한 도로 주행을 하길 바라는 기대를 해본다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 주요 동작 및 특징</strong></span><br />
<span style="color: #339966"><strong>3.1.1. 카메라 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-1.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40172" alt="65 ict 스마트차선 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-1.jpg" width="610" height="264" /></a></p>
<p>회로[첨부 1]에 연결된 스위치가 ON 일 때, 차선 변경 알고리즘이 실행되면서 카메라(Logitech사의 960-001063 &#8211; Webcam, HD Pro, 1280 x 720p Resolution, 3MP, Built In Microphone, [첨부 2])가 동작하게 된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-6.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40183" alt="65 ict 스마트차선 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-6.png" width="618" height="207" /></a></p>
[첨부 3]운전자 차량의 뒷면에서 대각선 양쪽 끝에 카메라를 장착한다는 가정에 하에 카메라에 나타나는 화면[첨부 4]은 카메라가 가리키는 곳의 도로 상황을 보여준다. 여기서 카메라는 운전자의 시야를 대신할 뿐 아니라 동시에 Raspberry Pi의 OpenCV의 영상처리를 통해 물체를 인식해 운전자의 차량과 가장 가까운 차량을 인식하는 역할을 한다.</p>
<p><span style="color: #339966"><strong>3.1.2. 초음파 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-2.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40174" alt="65 ict 스마트차선 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-2.jpg" width="608" height="247" /></a></p>
<p>회로[첨부 5]에 연결된 스위치가 ON 일 때, 같이 연결되어 있던 초음파(HC-SR04, [첨부 6])가 동작하게 된다. HC-SR04 초음파 센서는 4가지 핀이 있으며, 순서대로 VCC핀, Trig핀, Echo핀, GND 핀을 가지고 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-7.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40185" alt="65 ict 스마트차선 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-7.png" width="316" height="206" /></a></p>
<p>여기서 초음파 센서의 동작을 살펴보면, Trig핀에 High signal이 들어오면 초음파를 전송하고 전송된 초음파가 사물에 반사되어 돌아오면 High signal에서 Low signal로 바뀐다. High상태에서 Low상태로 바뀐 시간을 이용하여 거리를 측정할 수 있다. 거리 계산 공식은 “거리 = 시간 x 초음파의 속력”이며, 초음파의 속력은 공기 중에서 340m/s로 이동하기에 식에 340m/s를 대입하여 계산하면 된다. 참고로 시간은 왕복시간으로 측정이 되기 때문에 2를 나누어 주며, 마무리로 단위까지 맞춰주어 간단하게 거리를 구할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-8.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40186" alt="65 ict 스마트차선 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-8.png" width="619" height="209" /></a></p>
<p>이러한 초음파를 활용하여 [첨부 8]운전자 차량의 뒷면에서 대각선 양쪽 끝에 초음파 센서를 장착한다는 가정에 하에 초음파 센서는 운전자 차량과 변경하고자 하는 차선의 뒷 차량과의 거리를 측정할 수 있게 된다. 더 나아가 초음파 센서가 측정한 거리를 라즈베리에서 받아 처리함으로써 차선 변경 시 안전 정도를 운전자가 보는 모니터에 영상처리를 통해 간단하게 인지할 수 있게 해주는 역할을 제공한다. [첨부9]같은 경우 위험(빨강색) &#8211; 주의(주황색) &#8211; 안전(초록색) 중 주의 단계로 주황색으로 위험 정도를 표시하고 있는 것을 볼 수 있다.</p>
<p><span style="color: #339966"><strong>3.1.3. 차선 변경 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-9.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40187" alt="65 ict 스마트차선 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-9.png" width="595" height="477" /></a></p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-10.png" rel="lightbox[40144]"><img class="alignnone size-large wp-image-40188" alt="65 ict 스마트차선 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-10-620x334.png" width="620" height="334" /></a></p>
<p><span style="color: #339966"><strong>3.2.1. 하드웨어 구성</strong></span><br />
· Raspberry Pi<br />
· 960-001063 &#8211; Webcam, HD Pro, 1280 x 720p Resolution, 3MP, Built In Microphone<br />
· HC-SR04<br />
· Bread Board<br />
· 저항 1K 2개, 저항 2K1개<br />
· Slide switch<br />
· Google Coral USB Accelerator<br />
· MM,MF 타입 점퍼선</p>
<p><span style="color: #339966"><strong>3.2.2. 소프트웨어 구성</strong></span><br />
· OpenCV 영상인식 source<br />
· Ultrasonic sensor source<br />
· Switch On/Off process source</p>
<p><span style="color: #339966"><strong>3.2.3. 주요 동작 및 특징</strong></span><br />
· 영상처리를 통한 뒷 차량 인식<br />
· 초음파센서를 통한 뒷 차량과의 거리 계산<br />
· 스위치를 통한 깜박이 구현<br />
· 영상처리를 통한 차선 변경 안전도 표시</p>
<p><span style="color: #339966"><strong>3.2.4. 회로 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-11.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40189" alt="65 ict 스마트차선 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-11.png" width="605" height="449" /></a></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Raspberry Pi 2Pin = Register 1K pin = Switch first pin<br />
Raspberry Pi 4pin = ultrasonic sensor Vcc pin<br />
Raspberry Pi 5pin = Switch second pin<br />
Raspberry Pi 6pin = ultrasonic sensor GND pin<br />
Raspberry Pi 16pin = ultrasonic sensor Trig pin<br />
Raspberry Pi 18pin = Register 2K pin = ultrasonic sensor Echo pin<br />
Raspberry Pi 20pin = Register 1K pin = ultrasonic sensor Echo pin<br />
Raspberry Pi 39pin = Switch third pin</p>
</div>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></span><br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-12.png" rel="lightbox[40144]"><img class="alignnone size-large wp-image-40190" alt="65 ict 스마트차선 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-12-504x620.png" width="504" height="620" /></a></p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1. 라즈베리 파이</strong></span><br />
<span style="color: #339966"><strong>4.1.1. 차량인식을 위한 영상처리 구현</strong></span><br />
구현하고자 하는 프로그램의 핵심은 차량인식이다. 차선 변경 시, 해당 도로에서 운전자 차량을 기준으로 대각선 뒤에 있는 차량과의 거리를 시각적인 정보로 운전자에게 표현하기 위해서는 차량을 인식하는 것이 가장 우선이다. 영상 처리를 위한 환경으로 라즈베리에 tensorflow를 설치하였고 코딩을 위해 Open CV tool도 설치하였다. 언어는 Python을 사용하였다. 여러 가지 환경과 쉘 스크립트를 사용하기 위해 https://github.com/EdjeElectronics/ TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi.git 저장소를 사용했고, 감지 모델은 tensorflow 홈페이지에서 제공하는 모델을 기반으로 사용했다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-13.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40191" alt="65 ict 스마트차선 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-13.png" width="617" height="306" /></a></p>
<p>다음은 테스트의 한 부분으로 다음과 같이 차량을 인식하여 차량을 사각형 틀 안에 포함하는 것을 볼 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-3.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40176" alt="65 ict 스마트차선 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-3.jpg" width="612" height="342" /></a></p>
<p>라즈베리 파이 상에서 영상처리를 하였는데 영상 처리가 워낙 많은 연산을 필요로 하다보니 속도가 늦은 단점이 있었다. 이를 개선하기 위해 Google Coral USB Accelerator라는 Edge TPU를 사용하여 속도를 높여주었다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-14.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40192" alt="65 ict 스마트차선 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-14.png" width="613" height="307" /></a><br />
성능을 테스트해보기 위해 FPS를 측정해 보았다. Google Coral USB Accelerator 장착했을 때 FPS가 4배 가까이 증가하는 것을 확인할 수 있었고, 좀 더 빠른 영상처리를 할 수 있었다. 하지만 실시간으로 이용하기에는 조금 부족한 면이 있었지만 이는 라즈베리보다 좀 더 성능이 좋은 소형 컴퓨터를 이용하면 해결될 것이라고 본다. 예들 들면 Nvidia사의 Jetson Nano Board나 Raspberry pi 4 등이다.</p>
<p><span style="color: #339966"><strong>4.1.2. 운전자가 쉽게 차량까지의 거리를 인식할 수 있게 시각화하기</strong></span><br />
운전자 차량을 기준으로 변경하고자 하는 차선의 차량까지의 거리는 cm단위로 초음파 센서를 통해 측정하였으며, 좌측 상단에 “Distance : ”로 출력형태를 갖는다. Python OpenCV를 통해 거리를 선으로 표시하며 색(빨간색, 주황색, 초록색)을 통해 상황에 따라 구별할 수 있도록 한다.<br />
운전자 차량까지의 거리를 인식할 수 있는 구체적인 설명으로는 거리측정을 위한 초음파 센서를 연결하고, 초음파 센서에서 반환값을 받아온다. 여기서 받아온 값은 구하고자 하는 거리가 되며 cm단위(테스트를 모형에서 실시했기 때문에 거리를 cm로 조정)를 갖는다. 여기서 운전자 차량과 변경하고자 하는 차선의 차량과의 거리는 선으로 표시한다. 이 선은 거리에 따라서 색을 다르게 표현하는데, 만약 거리가 16cm이하라면, 해당 선을 빨간색으로 하여 차선변경이 불가능하다고 알려주고, 16cm~ 20cm 사이면 해당 선은 주황색으로 차선 변경 시 주의해야 한다고 알려주며, 20cm이상이면 해당 선은 초록색으로 차선 변경을 하여도 안전하다고 표시하도록 구성하였다.<br />
테스트는 다음과 같이 진행하였다. 카메라는 운전자 차량의 후면에 부착하였다고 가정한 상태에서 빨간색 차량이 운전자의 차량이며 운전자가 좌측 방향 지시등을 켰을 때, 운전자 차량을 기준으로 좌측 도로 상황을 비추게 된다. 카메라는 OpenCV를 통해 차량을 인식하는 동시에 앞서 말한 시각화 과정으로 차선 변경 가능 여부를 선과 색으로 운전자에게 알려준다. 다음의 테스트에서는 라즈베리 파이 모델 3 2015버전을 사용하였고 초음파 센서의 모델명은 HC-SR04, 카메라는 Logitech사의 960-001063 &#8211; Webcam, HD Pro, 1280 x 720p Resolution, 3MP, Built In Microphone을 사용하였다. 실제 차량을 사용할 수 없어 차량 모델을 제작하여 테스트를 진행하였다.</p>
[도로 상황]: 뒤 차량과의 거리가 16cm 이하 일 때</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-4.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40178" alt="65 ict 스마트차선 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-4.jpg" width="616" height="285" /></a></p>
[모니터]: 뒤 차량과의 거리가 16cm(위험-빨강색 선) 이하 일 때</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-5.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40180" alt="65 ict 스마트차선 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-5.jpg" width="616" height="282" /></a></p>
[모니터]: 뒤 차량과의 거리가 16cm~20cm(주의-주황색 선) 사이 일 때</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-6.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40182" alt="65 ict 스마트차선 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-6.jpg" width="616" height="282" /></a></p>
[모니터]: 뒤 차량과의 거리가 20cm(안전-초록색 선) 이상 일 때</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-7.jpg" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40184" alt="65 ict 스마트차선 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-7.jpg" width="615" height="278" /></a></p>
<p>회로 사진 및 라즈베리파이 pin 연결</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-15.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40193" alt="65 ict 스마트차선 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-15.png" width="615" height="284" /></a></p>
<p>초음파 센서 회로도</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-16.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40194" alt="65 ict 스마트차선 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-16.png" width="620" height="398" /></a></p>
<p><span style="color: #339966"><strong>4.1.3. 스위치를 이용한 방향 지시등 구현</strong></span><br />
운전자가 방향 지시등을 켰을 때 다음 프로그램이 실행되므로 슬라이드 스위치를 차량의 방향 지시등으로 가정하여 구현하였다. 슬라이드 스위치가 ON일 때, 프로그램을 시작하거나 프로그램이 지속적으로 실행하도록 한다. 슬라이드 스위치가 OFF일 때, 프로그램을 종료하도록 구성하였다. 실험을 진행 할 때, 일반적인 택트 스위치 같은 경우 직접 스위치를 계속해서 누르고 있어야 ON으로 인식을 하는 번거로움을 가져왔다. 따라서 슬라이드 스위치를 이용하여 실제 차량의 방향지시등의 점멸을 표현하였다. 슬라이드 스위치의 작동 실험은 시연 동영상을 통해 볼 수 있다.</p>
<p>회로 사진</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-15.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40193" alt="65 ict 스마트차선 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-15.png" width="615" height="284" /></a></p>
<p>회로도</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-1.png" rel="lightbox[40144]"><img class="alignnone size-full wp-image-40173" alt="65 ict 스마트차선 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict-스마트차선-1.png" width="612" height="382" /></a></p>
<p><span style="color: #339966"><strong>4.1.4. 주요 소스 코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>import RPi.GPIO as GPIO<br />
from time import sleep<br />
import os<br />
import argparse<br />
import cv2<br />
import numpy as np<br />
import sys<br />
import time<br />
from threading import Thread<br />
import importlib.util<br />
import signal</p>
<p>left_switch = 3 #Switch assumed as signal light</p>
<p>#GPIO Setting<br />
GPIO.setmode(GPIO.BCM)<br />
GPIO.setwarnings(False)<br />
GPIO.setup(left_switch,GPIO.IN,GPIO.PUD_UP)<br />
GPIO.setup(right_switch,GPIO.IN,GPIO.PUD_UP)</p>
<p>def distanceInCm(duration): #Function that returns duration as distance in cm<br />
return (duration/2)/29.1</p>
<p>def print_distance(distance): #A function that sets the distanceMsg differently depending on the distance value.<br />
if distance == 0:<br />
distanceMsg = &#8216;Distance : out of range \r&#8217;<br />
else:<br />
distanceMsg = &#8216;Distance : &#8216;+str(distance)+&#8217;cm&#8217;+&#8217; \r&#8217;<br />
return distanceMsg</p>
<p>#Set pin number of ultrasonic sensor<br />
TRIG = 23 #TRIG Numbering<br />
ECHO = 24 #ECHO Numbering</p>
<p>MAX_DISTANCE_CM = 300<br />
MAX_DURATION_TIMEOUT = (MAX_DISTANCE_CM * 2 * 29.1)</p>
<p>GPIO.setmode(GPIO.BCM)</p>
<p>GPIO.setup(TRIG, GPIO.OUT) #TRIG Ultrasonic Signal Transmission Pin Designation and Specify Output<br />
GPIO.setup(ECHO, GPIO.IN) #Specify ECHO Ultrasonic Signal Receiving Pin and Specify Output</p>
<p>#Thread to manage webcam<br />
class VideoStream:<br />
&#8220;&#8221;"Camera object that controls video streaming from the Picamera&#8221;"&#8221;<br />
def __init__(self, resolution=(640,480), framerate=30):<br />
self.stream = cv2.VideoCapture(0) #Trun on the camera<br />
ret = self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*&#8217;MJPG&#8217;))<br />
#frame size init<br />
ret = self.stream.set(3, resolution[0])<br />
ret = self.stream.set(4, resolution[1])</p>
<p># Read first frame from the stream<br />
(self.grabbed, self.frame) = self.stream.read()</p>
<p># Variable to control when the camera is stopped<br />
self.stopped = False</p>
<p>def start(self): # Start the thread that reads frames from the video stream<br />
Thread(target=self.update,args=()).start()<br />
return self<br />
def update(self): #Keep looping indefinitely until the thread is stopped<br />
while True:<br />
#If the camera is stopped, stop the thread<br />
if self.stopped:<br />
#Close camera resources<br />
self.stream.release()<br />
return<br />
#Otherwise, grab the next frame from the stream<br />
(self.grabbed, self.frame) = self.stream.read()</p>
<p>def read(self): #Return the most recent frame<br />
return self.frame</p>
<p>def stop(self): #Indicate that the camera and thread should be stopped<br />
self.stopped = True</p>
<p>#Define and parse input arguments<br />
parser = argparse.ArgumentParser()<br />
parser.add_argument(&#8216;&#8211;modeldir&#8217;, help=&#8217;Folder the .tflite file is located in&#8217;, required=True)</p>
<p>parser.add_argument(&#8216;&#8211;edgetpu&#8217;, help=&#8217;Use Coral Edge TPU Accelerator to speed up detection&#8217;, action=&#8217;store_true&#8217;)</p>
<p>args = parser.parse_args()</p>
<p>MODEL_NAME = args.modeldir<br />
GRAPH_NAME = args.graph<br />
LABELMAP_NAME = args.labels<br />
min_conf_threshold = float(args.threshold)<br />
resW, resH = args.resolution.split(&#8216;x&#8217;)<br />
imW, imH = int(resW), int(resH)<br />
use_TPU = args.edgetpu</p>
<p>#Import TensorFlow libraries<br />
#If tensorflow is not installed, import interpreter from tflite_runtime, else import from regular tensorflow<br />
#If using Coral Edge TPU, import the load_delegate library<br />
pkg = importlib.util.find_spec(&#8216;tensorflow&#8217;)<br />
if pkg is None:<br />
from tflite_runtime.interpreter import Interpreter<br />
if use_TPU:<br />
from tflite_runtime.interpreter import load_delegate<br />
else:<br />
from tensorflow.lite.python.interpreter import Interpreter<br />
if use_TPU:<br />
from tensorflow.lite.python.interpreter import load_delegate</p>
<p>#If using Edge TPU, assign filename for Edge TPU model<br />
if use_TPU: #If user has specified the name of the .tflite file, use that name, otherwise use default &#8216;edgetpu.tflite&#8217;<br />
if (GRAPH_NAME == &#8216;detect.tflite&#8217;):<br />
GRAPH_NAME = &#8216;edgetpu.tflite&#8217;</p>
<p>#Get path to current working directory<br />
CWD_PATH = os.getcwd()</p>
<p>#Path to .tflite file, which contains the model that is used for object detection<br />
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)</p>
<p>#Path to label map file<br />
PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)</p>
<p>#Load the label map<br />
with open(PATH_TO_LABELS, &#8216;r&#8217;) as f:<br />
labels = [line.strip() for line in f.readlines()]
<p>#Have to do a weird fix for label map if using the COCO &#8220;starter model&#8221; from<br />
#https://www.tensorflow.org/lite/models/object_detection/overview<br />
#First label is &#8216;???&#8217;, which has to be removed.<br />
if labels[0] == &#8216;???&#8217;:<br />
del(labels[0])</p>
<p>#Load the Tensorflow Lite model.<br />
#If using Edge TPU, use special load_delegate argument<br />
if use_TPU:<br />
interpreter = Interpreter(model_path=PATH_TO_CKPT,<br />
experimental_delegates=[load_delegate('libedgetpu.so.1.0')])<br />
print(PATH_TO_CKPT)<br />
else:<br />
interpreter = Interpreter(model_path=PATH_TO_CKPT)</p>
<p>interpreter.allocate_tensors()</p>
<p>#Get model details<br />
input_details = interpreter.get_input_details()<br />
output_details = interpreter.get_output_details()<br />
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
<p>floating_model = (input_details[0]['dtype'] == np.float32)</p>
<p>input_mean = 127.5<br />
input_std = 127.5</p>
<p>#Initialize frame rate calculation<br />
frame_rate_calc = 1<br />
freq = cv2.getTickFrequency()</p>
<p>#Initialize video stream<br />
videostream = VideoStream(resolution=(imW,imH),framerate=30).start()<br />
time.sleep(1)</p>
<p>#for frame1 in camera.capture_continuous(rawCapture, format=&#8221;bgr&#8221;,use_video_port=True):<br />
while True:<br />
if GPIO.input(left_switch) == 1: #Start timer (for calculating frame rate)<br />
t1 = cv2.getTickCount()</p>
<p>#Grab frame from video stream<br />
frame1 = videostream.read()</p>
<p>#Acquire frame and resize to expected shape [1xHxWx3]
frame = frame1.copy()<br />
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)<br />
frame_resized = cv2.resize(frame_rgb, (width, height))<br />
input_data = np.expand_dims(frame_resized, axis=0)</p>
<p>#Normalize pixel values if using a floating model (i.e. if model is non-quantized)<br />
if floating_model:<br />
input_data = (np.float32(input_data) &#8211; input_mean) / input_std</p>
<p>#Perform the actual detection by running the model with the image as input<br />
interpreter.set_tensor(input_details[0]['index'],input_data)<br />
interpreter.invoke()</p>
<p>#Retrieve detection results<br />
boxes = interpreter.get_tensor(output_details[0]['index'])[0] #Bounding box coordinates of detected objects<br />
classes = interpreter.get_tensor(output_details[1]['index'])[0] #Class index of detected objects<br />
scores = interpreter.get_tensor(output_details[2]['index'])[0] #Confidence of detected objects<br />
#num = interpreter.get_tensor(output_details[3]['index'])[0] #Total number of detected objects (inaccurate and not needed)</p>
<p>pulse_start=0<br />
pulse_end=0</p>
<p>GPIO.output(TRIG, False) #Keep the trigger pin off.<br />
time.sleep(2)</p>
<p>GPIO.output(TRIG, True) #Exits 10us pulse.<br />
time.sleep(0.00001) #At Python, this pulse will be almost 100 us.<br />
GPIO.output(TRIG, False)</p>
<p>timeout = time.time()<br />
while GPIO.input(ECHO) == 0:<br />
pulse_start = time.time() #Set the start time when the echo pin is turned on.<br />
if ((pulse_start &#8211; timeout)*1000000) &gt;= MAX_DURATION_TIMEOUT:<br />
fail = True<br />
break</p>
<p>timeout = time.time()<br />
while GPIO.input(ECHO) == 1:<br />
pulse_end = time.time() #Set the reflector receiving time when the echo pin is turned off.<br />
if ((pulse_end &#8211; pulse_start)*1000000) &gt;= MAX_DURATION_TIMEOUT:<br />
print_distance(0)<br />
fail = True<br />
break</p>
<p>pulse_duration = (pulse_end &#8211; pulse_start) * 1000000<br />
pulse_duration=pulse_end-pulse_start #Calculate pulse length<br />
distance = distanceInCm(pulse_duration)<br />
distance=(pulse_duration*34000.0)/2 #The duration is divided in half.<br />
distance = round(distance, 2)<br />
MSG=print_distance(distance)</p>
<p>#Loop over all detections and draw detection box if confidence is above minimum threshold<br />
for i in range(len(scores)):<br />
if ((scores[i] &gt; min_conf_threshold) and (scores[i] &lt;= 1.0)):</p>
<p>#Get bounding box coordinates and draw box<br />
#Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()<br />
ymin = int(max(1,(boxes[i][0] * imH)))<br />
xmin = int(max(1,(boxes[i][1] * imW)))<br />
ymax = int(min(imH,(boxes[i][2] * imH)))<br />
xmax = int(min(imW,(boxes[i][3] * imW)))</p>
<p>cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (10, 255, 0), 2)<br />
a=(xmax-xmin)/2<br />
b = int(a)<br />
if distance &lt; 16:<br />
frame = cv2.line(frame, (650, 720), (xmin+b, ymax), (0, 0, 255), 3)<br />
elif distance &gt;=16 and distance &lt; 20:<br />
frame = cv2.line(frame, (650, 720), (xmin+b, ymax), (0, 150, 255), 3)<br />
else:<br />
frame = cv2.line(frame, (650, 720), (xmin+b, ymax), (0, 255, 0), 3)</p>
<p>#Draw label<br />
object_name = labels[int(classes[i])] #Look up object name from &#8220;labels&#8221; array using class index<br />
label = &#8216;%s: %d%%&#8217; % (object_name, int(scores[i]*100)) #Example: &#8216;person: 72%&#8217;<br />
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) #Get font size<br />
label_ymin = max(ymin, labelSize[1] + 10) #Make sure not to draw label too close to top of window<br />
cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) #Draw white box to put label text in<br />
cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) #Draw label text</p>
<p>#Draw distance in corner of frame<br />
cv2.putText(frame, MSG,(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)</p>
<p>#All the results have been drawn on the frame, so it&#8217;s time to display it.<br />
cv2.imshow(&#8216;Object detector&#8217;, frame)</p>
<p>#Calculate framerate<br />
t2 = cv2.getTickCount()<br />
time1 = (t2-t1)/freq<br />
frame_rate_calc= 1/time1</p>
<p>#Press &#8216;q&#8217; to quit<br />
if cv2.waitKey(1) == ord(&#8216;q&#8217;):<br />
break<br />
else: #Exit program if switch off<br />
break<br />
#Clean up<br />
GPIO.cleanup()<br />
cv2.destroyAllWindows()<br />
videostream.stop()</p>
</div>
<p><span style="color: #0000ff"><strong>5. 추가할 수 있는 기능</strong></span><br />
우리는 도로 모형을 제작하여 실험을 진행하였지만 실제 도로 상황에서는 많은 변수가 존재할 수 있다. 우리가 생각한 변수 중의 하나는 바로 ‘속도’이다. 뒷 차량이 어느 정도 속도로 오는지 알 수 없기 때문에 우리는 거리를 통하여 속도를 계산해 운전자의 모니터에 거리 정보를 나타낼 때 변수가 되는 속도를 반영하여 나타내는 것이다. 우리는 실제로 실험을 할 수 없어 이 부분의 구현은 하지 않았지만 우리가 만든 프로그램을 실제 차량에 이용한다면 이 부분도 고려하면 좋을 것 같다. 아니면 초음파를 받아 오는 시간 간격을 좀 더 줄여도 속도라는 변수를 어느 정도 해결할 수 있을 것 같다.</p>
<p><span style="color: #0000ff"><strong>6. 참고문헌</strong></span><br />
· https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi/blob/master/Raspberry_Pi_Guide.md<br />
· https://www.tensorflow.org<br />
· https://blog.naver.com/ljy9378/221438192568<br />
· https://www.diymaker.net/111<br />
· https://www.diymaker.net/111<br />
· https://make.e4ds.com/make/learn_guide_view.asp?idx=73</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40144/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[65호]초음파센서를 이용한 자동문 쓰레기통</title>
		<link>http://www.ntrexgo.com/archives/40149</link>
		<comments>http://www.ntrexgo.com/archives/40149#comments</comments>
		<pubDate>Thu, 22 Apr 2021 00:00:19 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[65호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[smart]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[로봇]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[센서]]></category>
		<category><![CDATA[스마트]]></category>
		<category><![CDATA[융합]]></category>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40149</guid>
		<description><![CDATA[디바이스마트매거진 65호 &#124; 자동문 쓰레기통을 활용하여 접촉을 줄여 위생상의 문제를 해결하고자 한다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-1.png" rel="lightbox[40149]"><img alt="65 ICT 초음파센서 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-1-620x174.png" width="620" height="174" /></a></p>
<p><span style="font-size: medium"><strong>2020 ICT 융합 프로젝트 공모전 장려상</strong></span></p>
<p><span style="font-size: xx-large"><strong>초음파센서를 이용한 자동문 쓰레기통</strong></span></p>
<p style="text-align: right">글 | 대구대학교 정원용</p>
<p>&nbsp;</p>
<p><span style="color: #3366ff"><strong>1. 심사평</strong></span><br />
칩센 얼핏 간단해 보이지만 주제와 부합되는 명확한 목표와 결과물을 확인할 수 있습니다. 작품으로서는 충분히 아이디어를 실제로 구현한 상황이지만, 실용성 측면에서 쓰레기통에 전원을 포함한 하드웨어 회로가 장착되어야 하므로 일체형이 아닌 기존 쓰레기통에 적용할 수 있는 별도 구조는 어떨까 하는 생각이 듭니다.<br />
펌테크 작품의 하우징 구성이 상당히 깔끔하고 훌륭하며 설계에 고생이 많았으리라 생각됩니다. 최근 코로나 등으로 위생에 관련된 비접촉식 생활용품에 관심이 많은 시기와도 맞물리는 완성도가 높은 출품작으로 생각됩니다.<br />
위드로봇 전력 관리 부분이 추가되면 더욱 좋은 작품이 될 것 같습니다.</p>
<p><span style="color: #3366ff"><strong>2. 작품 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 배경 및 요약</strong></span><br />
<strong> 2.1.1. 더러운 쓰레기통의 위생상 문제</strong><br />
· 쓰레기통 공간이 없어 쓰레기를 쓰레기통 주변에 버려서 쓰레기통이 더러워짐<br />
· 더러운 쓰레기통으로 인해 접촉하기 어려움<br />
· 자동문 쓰레기통을 활용해 접촉을 줄여 위생상의 문제 해결</p>
<p><strong>2.1.2. 쓰레기통 주변 환경 문제</strong><br />
· 쓰레기통의 내용물이 다 찼는지 알지 못해 쓰레기통이 넘치게 됨<br />
· 넘치는 쓰레기통으로 인해 주변이 더러워짐<br />
· 쓰레기통이 다 찼을 시 알림 기능으로 넘치는 쓰레기통 문제 해결</p>
<p><strong>2.1.3. 작품 기능</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-2.png" rel="lightbox[40149]"><img class="alignnone size-large wp-image-40159" alt="65 ICT 초음파센서 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-2-620x234.png" width="620" height="234" /></a><br />
<strong> </strong></p>
<p><strong>2.1.3. 완성본</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-3.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40161" alt="65 ICT 초음파센서 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-3.png" width="618" height="364" /></a><br />
· 평상 시, 초록 LED와 쓰레기통이 닫혀있음<br />
· 물체가 인식될 시, 쓰레기통이 열림<br />
· 쓰레기통이 일정량 채워지면 빨간 LED로 바뀜</p>
<p><span style="color: #3366ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong> 3.1. 주요 동작 및 특징</strong></span><br />
<strong> 3.1.1. 주요 동작 순서도</strong><br />
<strong> </strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-4.png" rel="lightbox[40149]"><img class="alignnone size-large wp-image-40163" alt="65 ICT 초음파센서 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-4-498x620.png" width="498" height="620" /></a></p>
<p><strong>3.1.2. 자동문 휴지통 순서도</strong><br />
· 초음파센서를 통해 정면에 있는 물체와의 거리를 측정<br />
· 측정된 물체와의 거리에 따라 쓰레기통이 열리고 닫힘<br />
· 쓰레기통 천장에 있는 초음파센서로 쓰레기 인식<br />
· 초음파센서로 쓰레기양에 따라 LED의 색깔이 바뀜</p>
<p><strong>3.1.3. 물체 인식</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-5.png" rel="lightbox[40149]"><img class="alignnone size-large wp-image-40164" alt="65 ICT 초음파센서 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-5-620x149.png" width="620" height="149" /></a><br />
· 가까운 거리의 물체 인식을 위한 초음파센서 사용<br />
· 초음파센서로 가까운 거리의 물체와의 거리 측정<br />
· 초음파센서에서 발사된 초음파가 물체로부터 반사되어 돌아온 시간으로 거리산출<br />
· 산출된 거리가 일정 거리보다 작아지면 물체 인식</p>
<p><strong>3.1.4. 쓰레기통의 자동문</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-1.jpg" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40156" alt="65 ICT 초음파센서 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-1.jpg" width="613" height="258" /></a></p>
<p>· 쓰레기통의 덮개 부분이 움직이면서 쓰레기통이 열리고 닫히게 됨<br />
· 서보모터를 축으로 덮개 부분이 돌아가도록 설계<br />
· 물체를 인식하여 덮개가 움직이는 자동문</p>
<p><strong>3.1.5. 쓰레기통 알림 기능</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-6.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40165" alt="65 ICT 초음파센서 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-6.png" width="605" height="355" /></a></p>
<p>· 쓰레기통 알림 기능을 위해 LED를 사용<br />
· 평상시에는 LED에 초록 불이 켜짐<br />
· 쓰레기통이 다 찼을 시에는 LED에 빨간 불이 켜짐</p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span><br />
<strong> 3.2.1. 하드웨어(HW)</strong><br />
아두이노 우노 보드 : 아두이노 가장 보편적이고 기본적인 보드<br />
초음파센서 HC-SR04 : 물체와의 거리 측정을 위해 사용<br />
서보모터 hs-311 : 쓰레기통이 열리고 닫히게 하기위해 사용<br />
RGB 3색 LED : 상태를 LED로 표시해주기 위해 사용</p>
<p><strong>3.2.2. 소프트웨어(SW)</strong><br />
Arduino : 작품의 소프트웨어 설계</p>
<p><strong>3.2.3. 전체 시스템 구성도</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-7.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40166" alt="65 ICT 초음파센서 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-7.png" width="594" height="377" /></a><br />
<span style="color: #33cccc"><strong> 3.3. 개발 환경</strong></span></p>
<p>개발 환경<br />
· OS : windows 10<br />
· 개발 환경(IDE) : Arduino<br />
· 개발 언어 : Arduino</p>
<p>구성 장비<br />
· 디바이스 : 아두이노 우노 보드<br />
· 센서 : 초음파센서(HC-SR04) :<br />
· 사용 장비 : 서보모터 hs-311, RGB 3색 LED</p>
<p><span style="color: #3366ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong> 4.1. Paper Prototype</strong></span></p>
<p><span style="color: #33cccc"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-2.jpg" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40158" alt="65 ICT 초음파센서 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-2.jpg" width="615" height="553" /></a></strong></span></p>
<p>제작 계획</p>
<p>· 작품 기능 구현<br />
· 외부 프레임 설계<br />
· 3D 프린팅<br />
· 외부 프레임 결합<br />
· 완성품 테스트<br />
· 외부 전원 연결</p>
<p><span style="color: #33cccc"><strong>4.2. 외부 프레임 설계</strong></span><br />
프레임 Paper Prototype</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-3.jpg" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40160" alt="65 ICT 초음파센서 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-3.jpg" width="616" height="278" /></a></p>
<p>3D Printing</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-8.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40167" alt="65 ICT 초음파센서 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-8.png" width="611" height="278" /></a></p>
<p>3D 프린터 출력물</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-9.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40168" alt="65 ICT 초음파센서 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-9.png" width="618" height="282" /></a></p>
<p>외부 프레임 결합<br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-4.jpg" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40162" alt="65 ICT 초음파센서 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-4.jpg" width="368" height="350" /></a></p>
<p><span style="color: #3366ff"><strong>5. 참고문헌</strong></span><br />
· 한 권으로 끝내는 아두이노 입문 + 실전(종합편)<br />
· https://www.youtube.com/watch?v=h7yyw6p_tZk&amp;t=1s</p>
<p><span style="color: #3366ff"><strong>6. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-10.png" rel="lightbox[40149]"><img class="alignnone size-full wp-image-40155" alt="65 ICT 초음파센서 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ICT-초음파센서-10.png" width="612" height="436" /></a></p>
<p><span style="color: #0000ff"><strong>7. Arduino 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;Servo.h&gt;<br />
Servo servo;<br />
// 각 핀 번호 설정<br />
int value=0;<br />
int echo1 = 8;<br />
int trig1 = 9;<br />
int echo2 = 10;<br />
int trig2 = 11;<br />
int red=4;<br />
int green=3;<br />
// 각 핀의 입출력 설정<br />
void setup() {<br />
Serial.begin(9600);<br />
pinMode(trig1, OUTPUT);<br />
pinMode(echo1, INPUT);<br />
pinMode(trig2, OUTPUT);<br />
pinMode(echo2, INPUT);<br />
pinMode(red,OUTPUT);<br />
pinMode(green,OUTPUT);<br />
servo.attach(7);<br />
}</p>
<p>void loop() {<br />
// 1번 초음파센서에서 초음파 발사 후 초음파가 다시 돌아오는데 걸리는 시간 저장<br />
digitalWrite(trig1, LOW);<br />
digitalWrite(echo1, LOW);<br />
delayMicroseconds(2);<br />
digitalWrite(trig1, HIGH);<br />
delayMicroseconds(10);<br />
digitalWrite(trig1, LOW);<br />
unsigned long duration1 = pulseIn(echo1, HIGH);<br />
// 2번 초음파센서에서 초음파 발사 후 초음파가 다시 돌아오는데 걸리는 시간 저장<br />
digitalWrite(trig2, LOW);<br />
digitalWrite(echo2, LOW);<br />
delayMicroseconds(2);<br />
digitalWrite(trig2, HIGH);<br />
delayMicroseconds(10);<br />
digitalWrite(trig2, LOW);<br />
unsigned long duration2 = pulseIn(echo2, HIGH);<br />
// 초음파를 발산한 후 다시 돌아온 시간을 가지고 거리 측정<br />
float distance1 = ((float)(340 * duration1) / 10000) / 2;<br />
float distance2 = ((float)(340 * duration2) / 10000) / 2;</p>
<p>// 1번 초음파센서로 측정한 거리가 13cm미만일 경우 (쓰레기통에 근접하는 물체가 감지 될 경우)<br />
if(distance1&lt;13) // 쓰레기통의 문을 연다<br />
{<br />
for(;value&gt;=0;value -=2)<br />
{<br />
servo.write(value);<br />
delay(10);<br />
}<br />
delay(3000); // 문이 열린 후 3초의 지연시간을 준다<br />
}else // 아닐 경우<br />
{<br />
for(;value&lt;=100;value +=2) // 쓰레기통의 문이 닫힌다<br />
{<br />
servo.write(value);<br />
delay(10);<br />
}<br />
}<br />
// 2번 초음파센서로 측정한 거리가 9.5cm초과일 경우(쓰레기통 안의 내용물이 다 찼을 경우)<br />
if(distance2&lt;9.5)<br />
{<br />
// LED 빨간불 ON<br />
digitalWrite(green,HIGH);<br />
digitalWrite(red,LOW);<br />
}<br />
else // 아닐 경우<br />
{<br />
// LED 초록불 ON<br />
digitalWrite(green,LOW);<br />
digitalWrite(red,HIGH);<br />
}<br />
// 측정된 거리 값을 시리얼 모니터에 출력<br />
Serial.print(&#8220;1 : &#8220;);<br />
Serial.print(distance1);<br />
Serial.print(&#8220;cm &#8220;);<br />
Serial.print(&#8220;2 : &#8220;);<br />
Serial.print(distance2);<br />
Serial.println(&#8220;cm&#8221;);<br />
delay(100);<br />
}<br />
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40149/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[65호]AI-Based Guide Robot System for the Blind</title>
		<link>http://www.ntrexgo.com/archives/40126</link>
		<comments>http://www.ntrexgo.com/archives/40126#comments</comments>
		<pubDate>Thu, 22 Apr 2021 00:00:17 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[65호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[smart]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[로봇]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[센서]]></category>
		<category><![CDATA[스마트]]></category>
		<category><![CDATA[융합]]></category>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40126</guid>
		<description><![CDATA[디바이스마트매거진 65호 &#124; 장애인들의 실내·외 활동을 하는 데 있어 제한을 최소화하고 삶의 질 향상을 추구하며 사회의 일원으로서 배제되지 않도록 하는 것을 기술개발 과제의 추진 목표로 한다.]]></description>
				<content:encoded><![CDATA[<p><span style="font-size: large"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-8.png" rel="lightbox[40126]"><img class="alignnone size-large wp-image-40224" alt="65 ict_ai based  (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-8-620x177.png" width="620" height="177" /></a></strong></span></p>
<p><span style="font-size: large"><strong>2020 ICT 융합 프로젝트 공모전 장려상</strong></span></p>
<p><span style="font-size: x-large"><strong>AI-Based Guide Robot System for the Blind</strong></span></p>
<p style="text-align: right">글 | 동양미래대학교 김선우, 김문, 김재아, 최대원</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 개발이 필요한 이유와 사전 정보에 대한 정리가 매우 깔끔하게 되어 있어 목표와 필요한 이유에 대하여 쉽게 이해가 됩니다. AI와 여러 환경에 대응이 가능할 무한궤도 구동 방안 등이 포함되어 있어 작품에 대한 사용자 편의성 또한 충분히 고려된 듯 합니다. 다만 이미 서비스가 제공되고 있는 AI 플래폼과 정형화된 물체(객체)만을 파악하는 형태로는 실생활의 변수를 모두 포함할 수 없다는 점은 고려되어야 할 것으로 보입니다. 이는 차량 ADAS 시스템 또는 무인 자동차 솔루션 조차도 아직도 완벽하지 않은 이유와 동일한 내용으로 볼 수 있습니다. 하드웨어뿐 아니라 소프트웨어 여러 기능 측면에 대한 심도 깊은 연구가 함께 진행되어야 할 것으로 보입니다. 최종 작품이 완성되지 않은 것으로 보여 작품 완성도의 배점 부분이 아쉽습니다.<br />
<strong>펌테크</strong> 아이디어와 창의성을 갖춘 작품이라고 생각이 듭니다. 단 제출된 보고서 내용을 감안하자면 작품에 대한 기획의도는 우수하다고 생각되지만 계획에 대비해서 출품작의 일부 진행과정은 확인이되나 최종적인 완성도를 구체적으로 확인할 수가 없었습니다<br />
<strong>위드로봇</strong> 수행한 내용에 비해 보고서 내용이 빈약합니다. 보고서가 좀 더 충실하면 좋은 점수를 받을 수 있었습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 기술개발 필요성</strong></span><br />
<strong>2.1.1. 사회적 문제</strong><br />
현재 대한민국에서 활동하고 있는 시각장애인 안내견의 수는 약 80마리, 외출할 때 주변 사람이나 보조 기구의 도움이 반드시 필요한 5급 이상의 장애등급을 판정받은 사람은 약 8만 명으로 안내견 수가 턱없이 부족한 편이다. 안내견 한 마리를 교육하고 훈련을 마치는데 필요한 기간은 약 2년, 훈련 기간 소요되는 비용은 약 1억으로 현실적으로 모든 시각장애인들이 안내견을 분양받는 것은 불가능하다. 또한 시각장애인 안내견을 분양받아도 분양 후에는 안내견을 돌보는 비용을 시각장애인 스스로 감당해야 하기 때문에 현실적으로 어려움을 가지고 있다.</p>
<p><span style="color: #33cccc"><strong>2.2. 기술개발 목표와 내용</strong></span><br />
<span style="color: #00ccff"><strong>2.2.1. 기술개발 과제의 추진 목표</strong></span><br />
현재 대한민국에 주거하는 시각장애인들의 실외, 실내 활동을 하는 데 있어 제한을 최소화하고 삶의 질 향상을 추구하며 사회의 일원으로서 배제되지 않도록 하는 것을 기술개발 과제의 추진 목표로 한다.</p>
<p><span style="color: #00ccff"><strong>2.2.2. 기술개발 내용</strong></span><br />
SoftWare<br />
· 카메라를 통해 얻은 영상을 A.I가 내장된 LattePanda Alpha를 통해 약 11가지 객체(장애물) 인지 및 사용자 기준 물체의 방향 알림 역할 수행<br />
· Image Processing, 3축 가속도센서를 사용하여 계단 패턴 분석 및 정확한 계단 및 연석 인지 기능 수행<br />
· 스마트폰 GPS를 이용하여 사용자의 실시간 위치 정보를 Geocoder를 통해 경도와 위도로 변환하여 사용자의 위치를 인지<br />
· 스마트폰에 내장된 GPS의 실시간 위치 정보, Web parsing 기술을 이용한 길 찾기 시스템 구축</p>
<p>HardWare<br />
· Timing Belt Pulley를 이용한 무한궤도 메커니즘 설계를 통한 계단 극복</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 주요 동장 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-1.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40215" alt="65 ict_ai based  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-1.png" width="620" height="367" /></a></p>
<p><span style="color: #00ccff"><strong>3.1.1. S/W</strong></span><br />
위험 요소 감지 및 음성 안내<br />
· YOLO 알고리즘 기반의 YOLO V3 모델을 구현하여 주변 위험 요소 감지<br />
· 주변 위험 요소 11가지의 위치 파악<br />
웹파싱을 이용한 길 안내<br />
· 네이버 지도 API를 사용하여 웹파싱 기술을 통해 가공하여 길 찾기 기능 구현<br />
· 현재 GPS 위치 변화에 따른 음성 안내<br />
Android studio Application 제작<br />
· 스마트폰을 통해 사용자의 현재 위치, 길 안내, 장애물 인지 등 사용자에게 필요한 정보 제공<br />
· 주변 사람들의 도움을 보다 편리하게 받을 수 있는 UI</p>
<p>상용 웹서버 Firebase를 활용한 데이터 통신<br />
· 스마트폰에 내장되어 있는 GPS 값의 실시간 데이터를 웹서버에 uploading 하여 실시간 길 찾기 기능 구현<br />
· A.I Device인 LattePanda Alpha를 통해 인지한 객체를 TTS(Text to Speech)를 통해 사용자에게 청각 알림</p>
<p><span style="color: #00ccff"><strong>3.1.2. H/W</strong></span><br />
Main Device<br />
· Raspberry Pi (MCU/MPU), Sensor(3-axis Acceleration, Ultrasonic), Cooling Fan, Speaker(SP-82557S), Timing Belt, Pully, Battery(Lipo 22.2V 5000mAh)<br />
A.I Device<br />
· LattePanda Alpha (MPU), Webcam(Logitech C930e)</p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성 및 개발 환경</strong></span><br />
<span style="color: #00ccff"><strong>3.2.1. S/W</strong></span><br />
A.I<br />
· Webcam을 이용해 촬영 후 LattePanda Alpha에서 연산<br />
· AI YOLO v3 프로그램을 Python으로 구현하여 객체 인식<br />
· LattePanda Alpha가 연산(YOLO v3)결과를 문자열로 재가공 후 Firebase에 결과 출력</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-2.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40217" alt="65 ict_ai based  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-2.png" width="620" height="451" /></a><br />
Stair Climing<br />
· 3축 가속도센서(3-axis Acceleration) Roll Pitch 값에 따른 로봇의 Motor control<br />
· Image Processing 기반 계단의 pattern 분석 및 정확한 계단 인지</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-3.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40219" alt="65 ict_ai based  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-3.png" width="620" height="165" /></a></p>
<p>Application Functions<br />
· 사용자 스마트폰에 내장된 GPS기반으로 실시간 사용자 위치(경도, 위도) 수신<br />
· Google STT(Speech to Text)를 사용하여 사용자가 목적지를 음성으로 입력하면 Geocoder를 사용해 위도, 경도로 변환<br />
· Google TTS(Text to Speech)를 사용하여 길 찾기 음성 안내, 장애물 발견 시 위험 요소 음성 안내<br />
· 길 찾기 기능을 수행하기 위한 웹파싱 기능 구현<br />
· ‘다음 맵’API 서비스를 이용하여 스마트폰 디스플레이에 map을 구현</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-4.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40220" alt="65 ict_ai based  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-4.png" width="620" height="358" /></a></p>
<p>Application UI</p>
<p>· 주변 사람이 한 눈에 보고 도움을 주기 편한 UI로 제작<br />
· 목적지까지의 방향, 실시간 현 위치, 장애물을 디스플레이에 표시하는 심플한 UI</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-5.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40221" alt="65 ict_ai based  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-5.png" width="620" height="336" /></a></p>
<p><span style="color: #00ccff"><strong>3.2.2. H/W</strong></span><br />
Harness<br />
· 곡면 modeling을 통해 사용자에게 편안한 그립감을 줄 수 있는 외형 제작</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-1.jpg" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40214" alt="65 ict_ai based  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-1.jpg" width="620" height="336" /></a></p>
<p>· 3D 프린터(PLA)를 사용해 장시간 들고 있어도 손에 무리가 가지 않도록 무게 최소화</p>
<p><span style="color: #0000ff"><strong>4. 회로도</strong></span><br />
· 22.2V Lithium Polymer Battery 단일 전원<br />
· Raspberry Pi 3 B+, Latte Panda, SZH-CH076, Fan 총 4개 소자에 공급되며, 각 소자의 정격 전압에 맞게 regulator를 사용</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-6.png" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40222" alt="65 ict_ai based  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-6.png" width="620" height="540" /></a></p>
<p><span style="color: #0000ff"><strong>5. 설계도면</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-7.png" rel="lightbox[40126]"><img class="alignnone size-large wp-image-40223" alt="65 ict_ai based  (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-7-483x620.png" width="483" height="620" /></a></p>
<p><span style="color: #0000ff"><strong>6. 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>from sense_hat import SenseHat<br />
import time<br />
import imageprocessing_03 as stair<br />
import MotorController_03 as motor<br />
import cv2<br />
import os<br />
import RPi.GPIO as GPIO</p>
<p>## MOTOR config setting ##</p>
<p># 모터 상태<br />
STOP = 0<br />
FORWARD = 1<br />
BACKWORD = 2</p>
<p># 모터 채널<br />
CH1 = 0<br />
CH2 = 1</p>
<p># PIN 입출력 설정<br />
OUTPUT = 1<br />
INPUT = 0</p>
<p># PIN 설정<br />
HIGH = 1<br />
LOW = 0</p>
<p># 실제 핀 정의<br />
#PWM PIN<br />
ENA = 26 #37 pin<br />
ENB = 0 #27 pin</p>
<p>#GPIO PIN<br />
IN1 = 19 #35 pin<br />
IN2 = 13 #33 pin<br />
IN3 = 6 #31 pin<br />
IN4 = 5 #29 pin<br />
SW1 = 17 #13 pin<br />
SW2 = 27 #15 pin<br />
SW3 = 16<br />
SW4 = 20</p>
<p># 핀 설정 함수<br />
def setPinConfig(EN, INA, INB):<br />
GPIO.setup(EN, GPIO.OUT)<br />
GPIO.setup(INA, GPIO.OUT)<br />
GPIO.setup(INB, GPIO.OUT)<br />
# 100khz 로 PWM 동작 시킴<br />
pwm = GPIO.PWM(EN, 100)<br />
# 우선 PWM 멈춤.<br />
pwm.start(0)<br />
return pwm</p>
<p># 스위치 핀 함수<br />
def setPinSwitch(SW1, SW2, SW3, SW4) :<br />
GPIO.setwarnings(False)<br />
GPIO.setup(SW1,GPIO.IN,GPIO.PUD_UP)<br />
GPIO.setup(SW2,GPIO.IN,GPIO.PUD_UP)<br />
GPIO.setup(SW3,GPIO.IN,GPIO.PUD_UP)<br />
GPIO.setup(SW4,GPIO.IN,GPIO.PUD_UP)</p>
<p># 모터 제어 함수<br />
def setMotorContorl(pwm, INA, INB, speed, stat):</p>
<p>#모터 속도 제어 PWM<br />
pwm.ChangeDutyCycle(speed)</p>
<p>if stat == FORWARD:<br />
GPIO.output(INA, HIGH)<br />
GPIO.output(INB, LOW)</p>
<p>#뒤로<br />
elif stat == BACKWORD:<br />
GPIO.output(INA, LOW)<br />
GPIO.output(INB, HIGH)</p>
<p>#정지<br />
elif stat == STOP:<br />
GPIO.output(INA, LOW)<br />
GPIO.output(INB, LOW)<br />
# 모터 제어함수 간단하게 사용하기 위해 한번더 래핑(감쌈)<br />
def setMotor(ch, speed, stat):<br />
if ch == CH1:<br />
#pwmA는 핀 설정 후 pwm 핸들을 리턴 받은 값이다.<br />
setMotorContorl(pwmA, IN1, IN2, speed, stat)<br />
else:<br />
#pwmB는 핀 설정 후 pwm 핸들을 리턴 받은 값이다.<br />
setMotorContorl(pwmB, IN3, IN4, speed, stat)</p>
<p>def RC():<br />
if GPIO.input(SW1) == 0 : #forward</p>
<p>SPEED = 12 #LEFT MOTOR<br />
SPEED1 = 12<br />
setMotor(CH1, SPEED, FORWARD)<br />
setMotor(CH2, SPEED1, BACKWORD)<br />
print(&#8220;forward&#8221;)</p>
<p>elif GPIO.input(SW2) == 0 : #back</p>
<p>SPEED = 12 #LEFT MOTOR<br />
SPEED1 = 12<br />
setMotor(CH1, SPEED, BACKWORD)<br />
setMotor(CH2, SPEED1, FORWARD)<br />
print(&#8220;back&#8221;)</p>
<p>elif GPIO.input(SW3) == 0 : #LEFT<br />
SPEED = 1 #LEFT MOTOR<br />
SPEED1 = 15<br />
setMotor(CH1, SPEED, FORWARD)<br />
setMotor(CH2, SPEED1, BACKWORD)<br />
print(&#8220;here&#8221;)<br />
print(&#8220;left&#8221;)</p>
<p>elif GPIO.input(SW4) == 0 : #right<br />
SPEED = 15 #LEFT MOTOR<br />
SPEED1 = 1<br />
setMotor(CH1, SPEED, FORWARD)<br />
setMotor(CH2, SPEED1, BACKWORD)<br />
print(&#8220;right&#8221;)</p>
<p>else :<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 0, STOP)<br />
print(&#8220;stop&#8221;)</p>
<p>###########################</p>
<p>def stair_detection():<br />
while True:<br />
print(&#8216;in rc&#8217;)<br />
RC() #..<br />
i = 0<br />
while i &lt; 50 :<br />
sense.get_orientation_degrees()['pitch']
i = i + 1</p>
<p>if stair_threshold &lt;= sense.get_orientation_degrees()['pitch']:<br />
print(&#8220;up stair&#8221;)<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 0, STOP)<br />
os.system(&#8220;sudo service uv4l_raspicam restart&#8221;)<br />
os.system(&#8220;sudo dd if=/dev/video0 of=image.png bs=11M count=1&#8243;)</p>
<p>return stair.stair_detection()</p>
<p>elif sense.get_orientation_degrees()['pitch'] &lt;= -stair_threshold :<br />
print(&#8220;down stair&#8221;)<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 0, STOP)<br />
os.system(&#8220;sudo service uv4l_raspicam restart&#8221;)<br />
# down stair sound</p>
<p>return &#8216;down&#8217;<br />
if __name__ == &#8220;__main__&#8221; :<br />
os.system(&#8220;sudo service uv4l_raspicam restart&#8221;)<br />
sense = SenseHat()<br />
stair_threshold = 15 # &#8230;<br />
roll_threshold = 10 #</p>
<p># GPIO 모드 설정<br />
GPIO.setmode(GPIO.BCM)</p>
<p>#모터 핀 설정<br />
#핀 설정후 PWM 핸들 얻어옴<br />
pwmA = setPinConfig(ENA, IN1, IN2)<br />
pwmB = setPinConfig(ENB, IN3, IN4)<br />
setPinSwitch(SW1, SW2, SW3, SW4)</p>
<p>SPEED = 12<br />
SPEED1 = 12</p>
<p>while True:<br />
print(&#8221; ##### program start ##### &#8220;)</p>
<p>detection = stair_detection()</p>
<p>if detection == True: #up stair</p>
<p>print(&#8216;up stair&#8217;)<br />
#up stair sound mp3<br />
while sense.get_orientation_degrees()['pitch'] &gt; 3 :</p>
<p>if sense.get_orientation_degrees()['roll'] &gt; roll_threshold:<br />
setMotor(CH1, 10, FORWARD)<br />
setMotor(CH2, 0, STOP)<br />
print(&#8216;left move&#8217;)</p>
<p>elif sense.get_orientation_degrees()['roll'] &lt; -roll_threshold:<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 10, BACKWORD)<br />
print(&#8216;rigth move&#8217;)<br />
elif -roll_threshold &lt; sense.get_orientation_degrees()['roll'] &lt; roll_threshold:<br />
setMotor(CH1, 13, FORWARD)<br />
setMotor(CH2, 13, BACKWORD)<br />
print(&#8216;straight&#8217;)</p>
<p>elif detection == &#8216;down&#8217; :</p>
<p>print(&#8216;down stair&#8217;)<br />
while sense.get_orientation_degrees()['pitch'] &lt; -3 :</p>
<p>if sense.get_orientation_degrees()['roll'] &gt; roll_threshold:<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 13, BACKWORD)<br />
print(&#8216;right move&#8217;)</p>
<p>elif sense.get_orientation_degrees()['roll'] &lt; -roll_threshold:<br />
setMotor(CH1, 13, FORWARD)<br />
setMotor(CH2, 0, STOP)<br />
print(&#8216;left move&#8217;)<br />
elif -roll_threshold &lt; sense.get_orientation_degrees()['roll'] &lt; roll_threshold:<br />
setMotor(CH1, 10, FORWARD)<br />
setMotor(CH2, 10, BACKWORD)<br />
print(&#8216;straight&#8217;)</p>
<p>elif detection == False : #wall or 1 stair</p>
<p>print(&#8220;wall&#8221;)<br />
setMotor(CH1, 0, STOP)<br />
setMotor(CH2, 0, STOP)</p>
<p>GPIO.cleanup()<br />
</div>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>6. 완성이미지</strong></span></p>
<p><span style="color: #0000ff"><strong> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-2.jpg" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40216" alt="65 ict_ai based  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-2.jpg" width="534" height="564" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-3.jpg" rel="lightbox[40126]"><img class="alignnone size-full wp-image-40218" alt="65 ict_ai based  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/04/65-ict_ai-based-3.jpg" width="531" height="560" /></a></strong></span></p>
<p><span style="color: #0000ff"><strong>7. 참고문헌</strong></span><br />
· 김윤구 김진욱 논문「도심지형 최적주행을 위한 휠·무한궤도 하이브리드형 모바일 로봇 플랫폼 및 메커니즘」, 로봇학회 논문지 제5권 제3호, 2010<br />
· 박동일 임성균 곽윤근 논문「계단등반을 위한 가변형 단일 트랙 메커니즘 해석」, 대한기계학회 춘추학술대회, 2005.5<br />
· 김의중 저「인공지능, 머신러닝, 딥러닝 입문」, 위키북스, 2016<br />
· 알 스웨이가트 저, 트랜지스터팩토리 역「파이썬프로그래밍으로 지루한 작업 자동화하기」, 스포트라잇북, 2013<br />
· Sam Abrahams Danijar Hafner Erik Erwitt Ariel Scarpinelli 공저, 정기철 역「엣지있게 설명한 텐서플로우」홍콩과학출판사, 2017<br />
· 아담 스트라우드 저, 오세봉 김기환 역 「안드로이드 데이터베이스」, 에이콘, 2017<br />
· http://kpat.kipris.or.kr/kpat/biblioa.do?method=biblioFrame (특허청에 등재된 유사 기술 검색)</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40126/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
