March 19, 2024

디바이스마트 미디어:

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

2021-06-25

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

2021-05-12

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

2021-02-16

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

2021-01-18

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

2020-09-29

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

2020-08-26

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

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

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

2020-06-30

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

2020-06-30

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

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

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

2015-06-09

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

2015-05-19

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

2015-03-25

[29호] Intel Edison Review -

2015-03-10

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

2015-03-09

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

2015-02-02

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

2015-02-02

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

2015-02-02

[61호]시각장애인을 위한 음성 안내 버스표지판

Cap 2020-10-23 16-30-02-020

2020 ICT 융합 프로젝트 공모전 최우수상

시각장애인을 위한 음성 안내 버스표지판

글 | 인하대학교 박민아, 이상우, 이승화

1. 심사평
칩센 데모에서도 인천시 Bus API를 사용하였듯이 기존 시스템과 연계를 하기 위해서는 보완해야 하는 사항이 많아 보이지만, 이러한 부분을 제외한 장치 자체로는 명확한 목적성을 가진 작품으로 생각됩니다. 기획한 의도에 따른 동작을 보여주긴 하였으나, 비콘등의 무선 장치가 절대적인 데이터를 가지거나, 정확한 거리 측정 등을 할 수가 없으므로 이를 보완할 수 있는 방안을 장치에 어떻게 도입할지에 대한 고민이 필요해 보입니다.
펌테크 세심한 관찰력이 반영된 실생활과 밀접한 아이디어와 실용성이 우수한 작품이라고 생각합니다. 기획 의도에 맞게 전체 시스템을 안정적이고 완성도 높게 구현하였고 제출된 보고서 구성 내용도 명확하고, 충실했다고 생각이 듭니다. 전체적으로 기획 의도, 기술 구현도, 완성도 등에서 상당히 뛰어나고 상업적으로 손색이 없는 우수한 작품으로 생각됩니다.
위드로봇 실제 필요한 기능을 잘 구현한 작품입니다. 좀 더 다듬으면 실제 상품화도 가능할 것으로 보입니다.

2. 작품 개요
2.1. 배경 및 목적
21세기에 들어 장애인과 같은 교통약자들의 사회참여 욕구 및 기회가 증가하면서 이들을 위한 이동수단의 확보와 교통정보제공 문제가 사회적 이슈로 대두되고 있다.[1] 그러나 장애인을 위한 대중교통 서비스는 많은 불편함을 호소하며 해결되지 않은 문제로 남아있다.

Cap 2020-10-23 16-35-30-903

<표 1>에 따르면 시각장애인은 통행 중에 다른 통행자들에게 도움을 받는 비중이 가장 큰 것으로 나타났다. 시각장애인은 스스로 버스정류장의 정보를 알아내기에 많은 제약이 있는 것을 확인할 수 있었다. 또한 <표 2>에 따르면 대중교통의 안전도 또한 불만족의 경우가 많았다. 지하철의 경우와 비교할 때 만족도의 차이가 매우 컸으며 버스정류장 및 버스 시설의 개선이 이루어져야 할 것으로 확인된다.

Cap 2020-10-23 16-35-39-871
MBC 뉴스에서도 실제 버스를 이용하는데 어려움을 겪는 사례를 소개하였다. 시각장애인은 버스 정류시설을 이용하며 도착 버스를 확인하지 못해 혼동을 느끼고 있었으며 이렇게 버스 탑승에 어려움을 겪기 때문에 보통 30~40분의 시간을 허비한다고 대답하였다.
이를 통해 일반 버스정류시설은 시각장애인에게 많은 불편함을 야기시키고 있으며 이를 해결할 시스템이 필요하다고 생각되었다.

Cap 2020-10-23 16-35-45-887

2.2. 문제인식
한 시각장애인 단체에서 청와대 국민청원에 시각장애인의 버스 탑승 문제에 있어 개선이 필요하다는 청원을 발의하였다.[3] 이 청원에 따르면 시각장애인 버스 탑승에 있어 문제점은 크게 두가지이다.

(1) 버스정류장 정보를 알 수 없다.
시각장애인이 버스정류장에 도착했을 때 해당 정류장이 어느 정류장인지 확인하기 어렵고, 이 때문에 도착하는 버스 정보를 쉽게 파악하기 어렵다.
(2) 버스번호를 파악할 수 없다.
시각장애인이 버스 도착 정보를 알 수가 없어 버스 탑승에 어려움을 겪는다. 정류장에서 ‘–번 버스가 곧 도착합니다.’라는 안내음이 송출된다고 할지라도 버스가 안내된 순서대로 진입하지 않거나, 많은 버스가 한꺼번에 오는 경우 때문에 특정 버스에 탑승하기 어렵다.

2.3. 해결방안
앞서 제시된 문제를 해결하기 위해 음성인식 기반 버스표지판을 제시하였다. 현재 대부분의 버스정류장에는 이미 음성안내 시스템이 존재하지만 기존 시스템의 문제점은 사용자가 알 수 있는 정보가 오직 잠시 후 도착하는 버스 안내밖에 없다는 것이다. 정류장에 정차하는 버스 정보나 버스가 몇분 후 도착하는지는 시각적인 정보로만 제공되기 때문에 시각장애인이 이용하는 데에는 어려움이 존재한다.
따라서 기존 버스정류장 안내 시스템의 한계를 극복하고 시각장애인이 버스탑승 시 느끼는 불편함을 해결하기 위해 음성인식을 기반으로 시각장애인에게 원하는 정보를 제공하는 시스템을 택하였다. 이 시스템에 대한 간략한 도식은 다음과 같다.

Cap 2020-10-23 16-35-55-137

음성안내 버스표지판이 동작하는 방식은 먼저 시각장애인이 비콘을 소지한 상태에서 버스 정류장에 다가가면 버스 음성 안내가 시작된다. 이후 탑승하려는 버스 번호를 마이크에 말하면 이를 인식해 해당 정류장에 정차하는지 여부를 알려주고 남은 시간이 몇분인지 알려준다. 이 탑승버스 번호는 LED에 점등되어 버스 운전기사가 인식하여 시각장애인이 대중교통 서비스를 타는것을 돕도록 한다. 이 정보는 버스기사 뿐만 아니라 주위 사람들도 의식적으로 시각적인 확인이 가능하기 때문에 현재처럼 버스가 오더라도 탑승하지 못하는 문제를 해결할 수 있을 것으로 보인다.

3. 작품 설명
3.1. 주요 동작 및 특징

Cap 2020-10-23 16-36-01-994

그림3. <전체 시스템 동작 순서도>

(1) 사용자 접근 : 하드웨어 사용 전력을 최소화하고 시스템의 남용을 방지하기 위하여 사용자(비콘) 접근시에만 하드웨어가 켜지도록 한다. 사용자가 3m이내에 있는 경우에는 하드웨어에서 “–정류장 입니다.” 소리가 발생하여 정류장 위치를 알리도록 한다.
(2) 탑승 버스 인식 : 표지판에 접근하여 탑승하려는 버스 번호를 마이크에 말하면 버스번호와 도착 예상 시간을 안내한다. 또한 이렇게 인식된 버스 번호는 LED에 표시된다.
(3) 버스 안내 : 버스가 정류장에 도착 예정시 잠시후 도착한다는 안내 메세지를 출력한다. 버스기사는 LED를 통해 탑승하려는 사용자가 있는것을 인지하여 사용자의 탑승을 돕는다.

3.2. 전체 시스템 구성

Cap 2020-10-23 16-37-42-886

라즈베리파이는 서버로부터 버스정보를 받아오고 음성 텍스트 변환 및 텍스트 음성 변환을 제어한다. 텍스트->음성 변환 파일은 라즈베리파이 상에 저장되므로 스피커는 라즈베리파이에서 출력되도록 한다.
비콘은 단뱡항 통신으로 페어링이 필요하지 않고 비교적 넓은 범위에서부터 인식가능 하고, 비용적인 측면을 고려해서 통신모듈로 사용하였다. 단, 비콘과 LCD에 대해서는 효율적인 구성 코드 효율적인 사용을 위해 아두이노를 이용하여 제어하였다.
버스 정보 데이터셋은 공공데이터포털(www.data.go.kr)에서 제공하는 인천광역시 버스 정보를 사용하였다. 내부 알고리즘을 간소화하기 위해 데이터를 DB화 하지 않고 필요시에 요청하는 형식을 선택하였다.

4. 단계별 제작 과정
4.1. 간트 차트

Cap 2020-10-23 16-37-48-304

4.2. 제작 과정
4.2.1. 하드웨어
아래 첨부한 사진 순서대로 스피커, 마이크 그리고 라즈베리파이를 표지판 내부에 넣고 외부에는 시각장애인 마크 및 LED만 확인할 수 있도록 만들었다.

Cap 2020-10-23 16-37-57-070 Cap 2020-10-23 16-38-05-537

4.2.2. 소프트웨어 개발환경
Raspberry Pi B
- 개발 언어: Python
- Tool: terminal
- 사용 시스템
1) Google Cloud Platform (Sound To Text & Text To Sound)
2) 인천 Bus API

5. 기대효과
사회적 측면
대중교통 또는 여객시설은 누구나 이용할 수 있는 공공재이다. 하지만 현재 국내의 대중교통 시설과 건물들은 비장애인들에게 초점이 맞춰져 있기 때문에 장애인들은 교통 수단 이용에 많은 제약을 받고 있다. 이동권의 제한은 개인적, 사회적 욕구를 원천적으로 제거시키는 것으로까지 이어진다. 따라서 이동권 관련 문제는 단순히 물리적 제약과 관련 된 것이 아니라 인간의 기본적인 권리와도 연관된 사회적인 문제로 볼 수 있다.[4] 따라서 시각장애인을 위한 음성 안내 버스표지판을 통해 시각장애인의 기본적 권리를 보장하며 사회참여 기회를 증진시킬 수 있을 것이다.

경제적 측면
하나의 표지판 당 기기의 개발비용은 약 10만원 전후로 생산이 가능할 것으로 예상된다. 비용 사용 목록은 다음과 같다. 라즈베리파이3 (Model B+ 기준 40,000원) + LED 표시등 + 비콘(HM-10 Module 기준 8000원)로 측정할 수 있다. 이때 공공재 안내 표지판 및 표지판을 설치하는 비용은 지방 정부나 정부의 보조를 생각하여 제외하고 예상 비용을 측정했다. 동시에 많은 기기를 만들어 내면 더욱 저렴한 금액으로 시각장애인에게 쉽게 도움이 될 수 있다.
인천시 버스 정류장의 개수는 5908개(출처: https://www.data.go.kr/, 인천광역시 버스노선별 정류장 현황, 통계 기준일 2020년 1월)이 기기 한개 생산 단가를 약 10만원으로 가정할 때 5억 908만원으로 한 해의 버스재정지원액의 0.0023%를 넘지 않을 것으로 예측할 수 있었다. 이를 확인하더라도 충분한 발전가능성과 효율을 가지고 있다고 할 수 있다. (출처:https://www.incheon.go.kr/open/OPEN030101)

6. 시연영상

Cap 2020-10-23 16-38-21-713

7. 개선방안
시각장애인을 위한 음성안내 표지판에는 몇 가지 개선사항이 존재한다.
1) 라즈베리파이3를 이용하여 표지판을 만들기 때문에 전력의 사용이 원할해야 한다. 마이크로 5핀을 통해 전력을 충분히 끌어 낼 수 있어야 하기 때문에 기존 버스정류장 내의 전력을 이용할 수 있다면 상용화하는데 더 수월할 것이라고 생각한다.
2) LED 제작에 있어서 비용적인 측면에 제한이 있었다. 하지만 비용적인 제한이 없다면 즉, 상용화시킨 표지판에서는 표시등을 더욱 크게하여 시각적으로 잘 보이게 할 수 있을 것이다. 이 방법을 통해서 더욱 완성도가 높은 제품을 만들 수 있을 것으로 기대된다.
3) iBeacon의 인식거리, 음성인식의 정확도, 버스api의 정확도 등 제품의 전체적인 정확도를 향상시킨다면 보다 정확한 결과를 기대할 수 있다.

8. 소스코드
8.1. 메인 코드

import gspeech
import threading
import time
import re
import sys

import requests
import argparse
from luma.led_matrix.device import max7219
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.core.legacy import text
from luma.core.legacy.font import proportional, LCD_FONT

import urllib.request
from urllib.request import urlopen
from urllib.parse import urlencode
from urllib.parse import quote_plus
from urllib.parse import unquote
from bs4 import BeautifulSoup
import bs4

from Hi import sound_play
from blesca import find

from google.cloud import texttospeech

#전역변수 선언
busrouteID = [] buslistinform = [] buslist = [] bstopnm = [] target_buses = [] led_tag=0

def demo(w, h, block_orientation, rotate, bus1, bus2):
serial = spi(port=0, device=0, gpio=noop())
print(“Created device”)
device = max7219(serial, width=w, height=h, rotate=rotate, block_orientation=block_orientation)

with canvas(device) as draw:
text(draw, (1, 0), bus1, fill=”white”, font=proportional(LCD_FONT))
text(draw, (1, 8), bus2, fill=”white”, font=proportional(LCD_FONT))

def led_control() :
global led_tag
led_tag = 1

# 정류소 경유노선 목록조회
# 공공데이터포털(data.go.kr)으로 url요청을 해 데이터를 받는다
# 받아오는 정보는 정류장 이름, 정류장에 정차하는 버스의 노선 명칭, 노선 고유 번호
# 서버에 데이터를 받아오지 않고 받아온 html에서 크롤링 하는 방식
# 리턴값은 정차 버스 리스트, 정류장 이름, (2차원 리스트)버스 노선 명칭과 고유번호 이다
# 버스 정류장 고유 정보이므로 최초 한번만 받아옴

def get_busstopinfor(buslistinform, bstopId):
decode_key = unquote(”) #개인 고유 발급 키
url = ‘http://apis.data.go.kr/6280000/busStationService/getBusStationViaRouteList’
queryParams = ‘?’ + urlencode({quote_plus(‘ServiceKey’): decode_key,
quote_plus(‘pageNo’): ’1′,
quote_plus(‘numOfRows’): ’10′,
quote_plus(‘bstopId’): bstopId})
request = urllib.request.Request(url + queryParams)
request.get_method = lambda: ‘GET’
response_body = urlopen(request)
a = response_body.read()
soup = BeautifulSoup(a, ‘html.parser’)
num = soup.find(‘numofrows’)
num = int(num.get_text())

table = soup.find(‘serviceresult’)
for tr in table.find_all(‘msgbody’):
tds = list(tr.find_all(‘itemlist’))

blank = 0
for itemlist in tds:
routeno = itemlist.find(‘routeno’).text
routeid = itemlist.find(‘routeid’).text
getbstopnm = itemlist.find(‘bstopnm’).text
buslistinform.append([routeno, routeid, blank])
buslist.append(routeno)
bstopnm.append(getbstopnm)

return buslist, bstopnm, buslistinform

# 버스 도착정보 목록조회
# 받아오는 정보는 버스 노선 고유번호, 버스 도착시간
# 이 데이터셋에서는 버스 고유번호를 제공하지 않는다. 따라서 버스 노선 고유번호를 받아와 앞서 정류소 경유노선 목록조회에서 받아온
# 2차원 리스트 버스 고유번호 / 버스 노선 고유번호에서 버스 노선 고유번호를 비교해 같은 리스트에 도착시간을 추가한다
# 따라서 2차원 리스트 buslistinform의 요소는 [(버스 고유번호, 버스 노선 고유번호, 버스 도착시간)]

def get_businfor(bustopid):
decode_key = unquote(”) #개인 고유 발급 키
url = ‘http://apis.data.go.kr/6280000/busArrivalService/getAllRouteBusArrivalList’
queryParams = ‘?’ + urlencode({quote_plus(‘ServiceKey’): decode_key,
quote_plus(‘pageNo’): ’1′,
quote_plus(‘numOfRows’): ’10′,
quote_plus(‘bstopId’): bustopid})
request = urllib.request.Request(url + queryParams)
request.get_method = lambda: ‘GET’
response_body = urlopen(request)
a = response_body.read()

soup = BeautifulSoup(a, ‘html.parser’)
table = soup.find(‘serviceresult’)
for tr in table.find_all(‘msgbody’):
tds = list(tr.find_all(‘itemlist’))

for itemlist in tds:
routeid = itemlist.find(‘routeid’).text
arrivalestimatetime = itemlist.find(‘arrivalestimatetime’).text
for i in range(0, len(buslistinform)):
if (buslistinform[i][1] == routeid):
buslistinform[i][2] = arrivalestimatetime

return buslistinform

# 버스 도착시간을 리턴하는 함수. parameter는 버스 번호이며 buslistinform에서 버스 번호를 조회해 버스번호를 리턴함.
def get_bus_arrivetime(busnum):
for i in range(0, len(buslistinform)):
if buslistinform[i][0] == busnum:
return buslistinform[i][2] def main():

gsp = gspeech.Gspeech()
gsp.pauseMic()
global target_buses
global led_tag
global buslistinform

while True:

find()
gsp.resumeMic()

compare_numbers = [] choosen_bus = []

# Google TTS를 이용하여 정류장 이름+음성안내를 합성해 송출한다
client = texttospeech.TextToSpeechClient()
bus_stop_notice = ‘정류장입니다. 확인할 버스 번호를 말씀해주세요’
bus_stop_name = bstopnm[0] synthesis_input = texttospeech.types.SynthesisInput(text=bus_stop_name + bus_stop_notice)

voice = texttospeech.types.VoiceSelectionParams(
language_code=’ko-KR’,
ssml_gender=texttospeech.enums.SsmlVoiceGender.NEUTRAL)

audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)

response = client.synthesize_speech(synthesis_input, voice, audio_config)

bus_notice = ‘bus.mp3′
with open(bus_notice, ‘wb’) as out:
out.write(response.audio_content)
gsp.pauseMic()
sound_play(bus_notice)
gsp.resumeMic()

# 음성인식 될 때까지 대기. 받아온 음성은 stt에 저장된다

stt = gsp.getText()
if stt is None:
break
# 받아온 음성에서 버스번호만 찾아온다. ex) 511번 알려줘 ==> get_numbers = ['511'] get_numbers = re.findall(“\d+”, stt)

# 구글 STT로 인식된 번호가 정류장 정차 버스 리스트에 존재하는지 확인. 확인후 존재한다면 compare_numbers에 입력
compare_numbers = list(set(buslist).intersection(get_numbers))
# 리스트에 존재한다면 구글 TTS로 음성변환
all_check_num = “번 버스”.join(compare_numbers)

# 일치하는 번호가 없는경우 “해당 버스 번호는 없습니다” 음성 인식 출력
if len(compare_numbers) == 0:
mismatch_notice = “/home/pi/mismatch.mp3″
gsp.pauseMic()
sound_play(mismatch_notice)
gsp.resumeMic()

# 물어본 버스가 하나 이상 존재하는 경우 버스번호와 도착시간 음성 인식 변환 후 출력
else:
for i in range(0, len(compare_numbers)):
target_bus = compare_numbers[i] # 타겟버스 번
target_bus_arrivalestimate = get_bus_arrivetime(target_bus)
minute=int(int(target_bus_arrivalestimate) / 60)
second=int(target_bus_arrivalestimate)-(60*minute) #
synthesis_input_match = texttospeech.types.SynthesisInput(text=target_bus
+ “번 버스 약 ”
+ str(minute)
+ “분”
+ str(second)
+ “초 후 도착합니다” )
response_match = client.synthesize_speech(synthesis_input_match, voice, audio_config)
match_notice = ‘match.mp3′

with open(match_notice, ‘wb’) as out:
out.write(response_match.audio_content)
gsp.pauseMic()

sound_play(match_notice)
gsp.resumeMic()
time.sleep(1)

# 물어본 버스 번호가 1개일 경우
if (len(compare_numbers) == 1):
synthesis_input_match = texttospeech.types.SynthesisInput(text=compare_numbers[0] + “번 버스 도착 시 bus_choice = “몇 번 버스로 안내해드릴까요??”
synthesis_input_match = texttospeech.types.SynthesisInput(text=bus_choice)
response_match = client.synthesize_speech(synthesis_input_match, voice, audio_config)
choice_notice = ‘choice.mp3′

with open(choice_notice, ‘wb’) as out:
out.write(response_match.audio_content)
sound_play(choice_notice)
stt = gsp.getText()
get_choice = re.findall(“\d+”, stt)
choosen_bus = list(set(compare_numbers).intersection(get_choice))

while (len(choosen_bus) == 0) :
time.sleep(0.5)
stt = gsp.getText()
get_choice = re.findall(“\d+”, stt)
choosen_bus = list(set(compare_numbers).intersection(get_choice))
if len(choosen_bus) > 0 :
break

# 선택한 버스 안내 음성
for i in range(0, len(choosen_bus)):
synthesis_input_match = texttospeech.types.SynthesisInput(text=choosen_bus[i] + “번 버스 도착 시 안내해드리겠습니다.”)
response_match = client.synthesize_speech(synthesis_input_match, voice, audio_config)
final_notice = ‘final.mp3′

with open(final_notice, ‘wb’) as out:
out.write(response_match.audio_content)안내해드리겠습니다.”)
response_match = client.synthesize_speech(synthesis_input_match, voice, audio_config)
one_notice = ‘one.mp3′

with open(one_notice, ‘wb’) as out:
out.write(response_match.audio_content)
gsp.pauseMic()

sound_play(one_notice)
gsp.resumeMic()
target_buses.append(compare_numbers[0]) # 타겟 버스 리스트에 추가.
led_control()
print(“led on”)

else: # 물어본 버스가 2개 이상인 경우 선택 음성 안내

gsp.pauseMic()
sound_play(final_notice)
gsp.resumeMic()
target_buses.append(choosen_bus[i]) # 타겟 버스 리스트에 추가
led_control()
print(“led on”)

# 타겟 버스(탑승하려는 버스) 도착시간 확인

while (len(target_buses) > 0 ):
gsp.pauseMic()
for i in range(0, len(target_buses)):
flag = check_bus_arrive(target_buses[i])
# 버스 잔여 시간이 100 초 이하인지 판단
time.sleep(1)
if flag == True: # 100초 미만일경우 버스 도착안내메세지
synthesis_input_match = texttospeech.types.SynthesisInput(text=target_buses[i] + “번 버스 잠시 후 도착합니다”)
response_match = client.synthesize_speech(synthesis_input_match, voice, audio_config)
arrive_notice = ‘arrive.mp3′
with open(arrive_notice, ‘wb’) as out:
out.write(response_match.audio_content)
gsp.pauseMic()
sound_play(arrive_notice)

led_control()

time.sleep(7)
target_buses.remove(target_buses[i])
led_control()
break

if (len(target_buses) == 0):
break
continue

# 버스 url송출해 실시간으로 도착정보 가져오는 함수
def get_realtime_businform():
while True:
global buslistinform
get_businfor(163000167) time.sleep(10)

# parameter 값에 대해 도착시간이 90초 미만인지 확인해주는 함수
def check_bus_arrive(target_bus):
target_bus_arrivalestimate = int(get_bus_arrivetime(target_bus))
if (target_bus_arrivalestimate < 90): # 90초 미만이면 True, else False
return True
else:
return False

# led 제어하는 함수
def led_controller():
global target_buses
global led_tag

while True:
parser = argparse.ArgumentParser(description=’matrix_demo arguments’,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument(‘–width’, type=int, default=32, help=’Width’)
parser.add_argument(‘–height’, type=int, default=16, help=’height’)
parser.add_argument(‘–block-orientation’, type=int, default=-90, choices=[0, 90, -90],
help=’Corrects block orientation when wired vertically’)
parser.add_argument(‘–rotate’, type=int, default=0, choices=[0, 1, 2, 3], help=’Rotation factor’)

args = parser.parse_args()
# led tag= 1 일때마다 led 표시 값 갱신
if (led_tag==1) :

if len(target_buses) == 1 :
demo(args.width, args.height, args.block_orientation, args.rotate,target_buses[0], “”)
elif len(target_buses) > 1 :
demo(args.width, args.height, args.block_orientation, args.rotate,target_buses[0], target_buses[1])
else :
demo(args.width, args.height, args.block_orientation, args.rotate, “”, “”)
led_tag=0

if __name__ == “__main__” :
get_busstopinfor(buslistinform, 163000167)
t = threading.Thread(target=main)
t2 = threading.Thread(target=get_realtime_businform)
t3 = threading.Thread(target=led_controller)
t.start()
t2.start()
t3.start()

8.2. find() : 비콘 검색함수

from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
print (“Discovered device”, dev.addr)
elif isNewData:
print (“Received new data from”, dev.addr)
def find():
beacon = 1
scanner = Scanner()

while (beacon ==1):
devices = scanner.scan(3.0)
for dev in devices:
print (“Device %s (%s), RSSI=%d dB” % (dev.addr, dev.addrType, dev.rssi))
for (adtype, desc, value) in dev.getScanData():
print (“%s = %s” % (desc, value))
if(value == ‘Helper’and dev.rssi > -52):
beacon = 0
break
else:
beacon = 1
if beacon ==0:
break

if __name__ == ‘__main__’:
find()


8.3. sound_play() : 음성안내 실행 함수

import pygame
import time

def sound_play(name):
file = name
pygame.mixer.init()
pygame.mixer.music.load(file)
pygame.mixer.music.play()
clock = pygame.time.Clock()
while pygame.mixer.music.get_busy():
clock.tick(3)
pygame.mixer.quit()

8.4. Gspeech module : 구글에서 제공하는 샘플코드 사용
· TTS : https://cloud.google.com/text-to-speech/docs/samples?hl=ko
· STT : https://cloud.google.com/speech-to-text/docs/samples?hl=ko

9. 참고문헌
[1] 김원호, 이유화, 김시현, 이유화, 김시현. “시각장애인 대중교통 이용실태 분석 및 대중교통시설 내 보행지원 시스템 구축방안.” 서울도시연구 10 no.3 (2009): 97-114.
[2] MBCNEWS. (2019, 12 25). [소수의견] 버스 탄 시각장애인 봤나요…타고 내리는 게 전쟁 [비디오파일]. 검색경로 https://www.youtube.com/watch?v=saoX-lR-iJ0&feature=emb_title
[3] “시각장애인도 버스를 탈 수 있게 해주세요.” (2020년 3월 1일). 청와대. n.d. 수정, https://www1.president.go.kr/petitions/583770.
[4] “인간공학적 시선으로 본 장애인의 이동권.” LG챌린저스. n.d. 수정, 2020년 3월 20일 접속, http://www.lgchallengers.com/wp-content/uploads/global/global_pdf/S0410.

 

 

 

Leave A Comment

*